import type { ReplyPayload as InternalReplyPayload } from "../auto-reply/reply-payload.js"; import type { ChannelOutboundAdapter } from "../channels/plugins/outbound.types.js"; import { createReplyToFanout } from "../infra/outbound/reply-policy.js"; import { normalizeLowercaseStringOrEmpty, readStringValue } from "../shared/string-coerce.js";
export type { MediaPayload, MediaPayloadInput } from "../channels/plugins/media-payload.js";
export { buildMediaPayload } from "../channels/plugins/media-payload.js";
export type ReplyPayload = Omit<InternalReplyPayload, "trustedLocalMedia">;
/** Wrap a deliverer so callers can hand it arbitrary payloads while channels receive normalized data. */
export function createNormalizedOutboundDeliverer(
handler: (payload: OutboundReplyPayload) => Promise<void>,
): (payload: unknown) => Promise<void> { return async (payload: unknown) => { const normalized =
payload && typeof payload === "object"
? normalizeOutboundReplyPayload(payload as Record<string, unknown>)
: {};
await handler(normalized);
};
}
/** Prefer multi-attachment payloads, then fall back to the legacy single-media field. */
export function resolveOutboundMediaUrls(payload: {
mediaUrls?: string[];
mediaUrl?: string;
}): string[] { if (payload.mediaUrls?.length) { return payload.mediaUrls;
} if (payload.mediaUrl) { return [payload.mediaUrl];
} return [];
}
/** Resolve media URLs from a channel sendPayload context after legacy fallback normalization. */
export function resolvePayloadMediaUrls(payload: SendPayloadContext["payload"]): string[] { return resolveOutboundMediaUrls(payload);
}
/** Count outbound media items after legacy single-media fallback normalization. */
export function countOutboundMedia(payload: { mediaUrls?: string[]; mediaUrl?: string }): number { return resolveOutboundMediaUrls(payload).length;
}
/** Check whether an outbound payload includes any media after normalization. */
export function hasOutboundMedia(payload: { mediaUrls?: string[]; mediaUrl?: string }): boolean { return countOutboundMedia(payload) > 0;
}
/** Check whether an outbound payload includes text, optionally trimming whitespace first. */
export function hasOutboundText(payload: { text?: string }, options?: { trim?: boolean }): boolean { const text = options?.trim ? payload.text?.trim() : payload.text; returnBoolean(text);
}
/** Check whether an outbound payload includes any sendable text or media. */
export function hasOutboundReplyContent(
payload: { text?: string; mediaUrls?: string[]; mediaUrl?: string },
options?: { trimText?: boolean },
): boolean { return hasOutboundText(payload, { trim: options?.trimText }) || hasOutboundMedia(payload);
}
/** Preserve caller-provided chunking, but fall back to the full text when chunkers return nothing. */
export function resolveTextChunksWithFallback(text: string, chunks: readonly string[]): string[] { if (chunks.length > 0) { return [...chunks];
} if (!text) { return [];
} return [text];
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.