UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

159 lines (158 loc) 5.62 kB
import { t as createSubsystemLogger } from "./subsystem-BzXSmsuh.js"; import "./runtime-env-D_2q8-VK.js"; import { t as buildChannelApprovalNativeTargetKey } from "./approval-native-target-key-BgRxMHOp.js"; import { r as createChannelApprovalNativeRuntimeAdapter } from "./approval-handler-runtime-CFLINLFC.js"; import { n as buildChannelApprovalResolvedText, r as resolvePreparedApprovalAccountId, t as buildChannelApprovalExpiredText } from "./approval-handler-runtime-DF66dgbE.js"; import "./approval-native-runtime-BeD_vgZw.js"; import { i as buildApprovalReactionPendingContent } from "./approval-reaction-runtime-BQQ1cR5g.js"; import { c as parseIMessageTarget, o as normalizeIMessageHandle } from "./targets-BhNdlUSi.js"; import { d as unregisterIMessageApprovalReactionTarget, l as registerIMessageApprovalReactionTarget, n as normalizeIMessageMessagingTarget } from "./normalize-BfDcnrra.js"; import { t as sendMessageIMessage } from "./send-CjeAdmmw.js"; //#region extensions/imessage/src/approval-handler.runtime.ts const log = createSubsystemLogger("imessage/approvals"); function buildPendingPayload(params) { const pendingContent = buildApprovalReactionPendingContent({ request: params.request, view: params.view, nowMs: params.nowMs }); return { text: pendingContent.reactionPayload.text ?? "", allowedDecisions: pendingContent.reactionPayload.allowedDecisions }; } function buildConversationKeyForTarget(to) { try { const parsed = parseIMessageTarget(to); if (parsed.kind === "chat_id") return { chatId: parsed.chatId }; if (parsed.kind === "chat_guid") return { chatGuid: parsed.chatGuid }; if (parsed.kind === "chat_identifier") return { chatIdentifier: parsed.chatIdentifier }; const handle = normalizeIMessageHandle(parsed.to); return handle ? { handle } : null; } catch { return null; } } function shouldThreadApprovalUpdate(to) { try { const parsed = parseIMessageTarget(to); if (parsed.kind === "handle" && parsed.service === "sms") return false; } catch { return true; } return true; } const imessageApprovalNativeRuntime = createChannelApprovalNativeRuntimeAdapter({ eventKinds: ["exec", "plugin"], availability: { isConfigured: ({ context }) => Boolean(context), shouldHandle: ({ context }) => Boolean(context) }, presentation: { buildPendingPayload: ({ request, approvalKind, nowMs, view }) => buildPendingPayload({ request, approvalKind, nowMs, view }), buildResolvedResult: ({ request, resolved, view }) => ({ kind: "update", payload: { text: buildChannelApprovalResolvedText({ request, resolved, view }) } }), buildExpiredResult: ({ request, view }) => ({ kind: "update", payload: { text: buildChannelApprovalExpiredText({ request, view }) } }) }, transport: { prepareTarget: ({ plannedTarget, accountId }) => { const to = normalizeIMessageMessagingTarget(plannedTarget.target.to); if (!to) return null; const prepared = { to, accountId: resolvePreparedApprovalAccountId({ plannedAccountId: plannedTarget.target.accountId, contextAccountId: accountId }) }; return { dedupeKey: `${prepared.accountId ?? ""}:${buildChannelApprovalNativeTargetKey({ to: prepared.to })}`, target: prepared }; }, deliverPending: async ({ cfg, preparedTarget, pendingPayload }) => { const guid = (await sendMessageIMessage(preparedTarget.to, pendingPayload.text, { config: cfg, ...preparedTarget.accountId ? { accountId: preparedTarget.accountId } : {} })).guid; if (!guid) return null; const conversation = buildConversationKeyForTarget(preparedTarget.to); if (!conversation) return null; return { ...preparedTarget.accountId ? { accountId: preparedTarget.accountId } : {}, to: preparedTarget.to, conversation, messageId: guid }; }, updateEntry: async ({ cfg, entry, payload }) => { await sendMessageIMessage(entry.to, payload.text, { config: cfg, ...entry.accountId ? { accountId: entry.accountId } : {}, ...shouldThreadApprovalUpdate(entry.to) ? { replyToId: entry.messageId } : {} }); } }, interactions: { bindPending: ({ entry, request, view, pendingPayload }) => { const accountId = entry.accountId?.trim(); if (!accountId) { log.error(`imessage approvals: refusing to bind reaction target for ${request.id}; missing accountId in prepared entry`); return null; } const ttlMs = view.expiresAtMs - Date.now(); if (ttlMs <= 0) { log.error(`imessage approvals: refusing to bind reaction target for ${request.id}; approval already expired at bind time`); return null; } return registerIMessageApprovalReactionTarget({ accountId, conversation: entry.conversation, messageId: entry.messageId, approvalId: request.id, allowedDecisions: pendingPayload.allowedDecisions, ttlMs }) ? true : null; }, unbindPending: ({ entry }) => { const accountId = entry.accountId?.trim(); if (!accountId) return; unregisterIMessageApprovalReactionTarget({ accountId, conversation: entry.conversation, messageId: entry.messageId }); }, cancelDelivered: ({ entry }) => { const accountId = entry.accountId?.trim(); if (!accountId) return; unregisterIMessageApprovalReactionTarget({ accountId, conversation: entry.conversation, messageId: entry.messageId }); } }, observe: { onDeliveryError: ({ error, request }) => { log.error(`imessage approvals: failed to send request ${request.id}: ${String(error)}`); } } }); //#endregion export { imessageApprovalNativeRuntime };