UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

77 lines (76 loc) 3.08 kB
import { a as normalizeLowercaseStringOrEmpty } from "./string-coerce-mnp54Vah.js"; import { _ as resolvePinnedHostnameWithPolicy } from "./ssrf-CvPEXMGn.js"; import { t as createMessageReceiptFromOutboundResults } from "./receipt-B3SXxhHV.js"; import "./string-coerce-runtime-CEGJWkQ_.js"; import "./channel-outbound-B3_Zy-kG.js"; import "./ssrf-runtime-BOGN5pUi.js"; //#region extensions/line/src/outbound-media.ts const LINE_OUTBOUND_MEDIA_SSRF_POLICY = { allowPrivateNetwork: false }; async function validateLineMediaUrl(url) { let parsed; try { parsed = new URL(url); } catch { throw new Error(`LINE outbound media URL must be a valid URL: ${url}`); } if (parsed.protocol !== "https:") throw new Error(`LINE outbound media URL must use HTTPS: ${url}`); if (url.length > 2e3) throw new Error(`LINE outbound media URL must be 2000 chars or less (got ${url.length})`); await resolvePinnedHostnameWithPolicy(parsed.hostname, { policy: LINE_OUTBOUND_MEDIA_SSRF_POLICY }); } function isHttpsUrl(url) { try { return new URL(url).protocol === "https:"; } catch { return false; } } function detectLineMediaKindFromUrl(url) { try { const pathname = normalizeLowercaseStringOrEmpty(new URL(url).pathname); if (/\.(png|jpe?g|gif|webp|bmp|heic|heif|avif)$/i.test(pathname)) return "image"; if (/\.(mp4|mov|m4v|webm)$/i.test(pathname)) return "video"; if (/\.(mp3|m4a|aac|wav|ogg|oga)$/i.test(pathname)) return "audio"; } catch { return; } } async function resolveLineOutboundMedia(mediaUrl, opts = {}) { const trimmedUrl = mediaUrl.trim(); if (isHttpsUrl(trimmedUrl)) { await validateLineMediaUrl(trimmedUrl); const previewImageUrl = opts.previewImageUrl?.trim(); if (previewImageUrl) await validateLineMediaUrl(previewImageUrl); return { mediaUrl: trimmedUrl, mediaKind: opts.mediaKind ?? (typeof opts.durationMs === "number" ? "audio" : void 0) ?? (opts.trackingId?.trim() ? "video" : void 0) ?? detectLineMediaKindFromUrl(trimmedUrl) ?? "image", ...previewImageUrl ? { previewImageUrl } : {}, ...typeof opts.durationMs === "number" ? { durationMs: opts.durationMs } : {}, ...opts.trackingId ? { trackingId: opts.trackingId } : {} }; } try { if (new URL(trimmedUrl).protocol !== "https:") throw new Error(`LINE outbound media URL must use HTTPS: ${trimmedUrl}`); } catch (e) { if (e instanceof Error && e.message.startsWith("LINE outbound")) throw e; } throw new Error("LINE outbound media currently requires a public HTTPS URL"); } //#endregion //#region extensions/line/src/send-receipt.ts function createLineSendReceipt(params) { const messageId = params.messageId.trim(); const chatId = params.chatId.trim(); return createMessageReceiptFromOutboundResults({ results: messageId ? [{ channel: "line", messageId, chatId, conversationId: chatId, meta: { messageCount: params.messageCount ?? 1 } }] : [], ...chatId ? { threadId: chatId } : {}, kind: params.kind ?? "unknown" }); } //#endregion export { resolveLineOutboundMedia as n, validateLineMediaUrl as r, createLineSendReceipt as t };