openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
254 lines (253 loc) • 9.74 kB
JavaScript
import { c as normalizeOptionalString } from "./string-coerce-mnp54Vah.js";
import { n as resolveChannelGroupRequireMention } from "./group-policy-CShy7eWv.js";
import { i as createLazyRuntimeNamedExport } from "./lazy-runtime-D-7_JraP.js";
import { i as readRemoteMediaBuffer } from "./fetch-2npQWHQh.js";
import { t as sanitizeForPlainText } from "./sanitize-text-BOGhD8MR.js";
import { t as createMessageReceiptFromOutboundResults } from "./receipt-B3SXxhHV.js";
import { t as adaptScopedAccountAccessor } from "./channel-config-helpers-lj5quus3.js";
import { n as missingTargetError } from "./target-errors-B0SYsRYn.js";
import { a as resolveChannelMediaMaxBytes } from "./media-runtime-fgpmX6eL.js";
import "./string-coerce-runtime-CEGJWkQ_.js";
import { t as chunkTextForOutbound } from "./text-chunking-D45TeeEs.js";
import { _ as createAllowlistProviderOpenWarningCollector, m as composeAccountWarningCollectors } from "./channel-policy-CIW58SA5.js";
import { t as createChannelDirectoryAdapter } from "./directory-runtime-om8jJAZt.js";
import { f as listResolvedDirectoryGroupEntriesFromMapKeys, p as listResolvedDirectoryUserEntriesFromAllowFrom } from "./directory-config-helpers-DEDTHx2P.js";
import { T as defineChannelMessageAdapter } from "./channel-outbound-B3_Zy-kG.js";
import { n as loadOutboundMediaFromUrl } from "./outbound-media-MHBXtJsJ.js";
import { t as PAIRING_APPROVED_MESSAGE } from "./pairing-message-DNhqI-OE.js";
import { i as resolveGoogleChatAccount } from "./accounts-BedKEwKe.js";
import { T as shouldSuppressGoogleChatManualExecApprovalFollowupPayload, i as resolveGoogleChatOutboundSpace, n as isGoogleChatUserTarget, r as normalizeGoogleChatTarget } from "./targets-BIe3h2UJ.js";
import "./runtime-api-Dp_Hh2eL.js";
import { r as formatGoogleChatAllowFromEntry } from "./channel-base-D9bH8n7T.js";
//#region extensions/googlechat/src/group-policy.ts
function resolveGoogleChatGroupRequireMention(params) {
return resolveChannelGroupRequireMention({
cfg: params.cfg,
channel: "googlechat",
groupId: params.groupId,
accountId: params.accountId
});
}
//#endregion
//#region extensions/googlechat/src/channel.adapters.ts
const loadGoogleChatChannelRuntime = createLazyRuntimeNamedExport(() => import("./channel.runtime-DtxTFBoI.js"), "googleChatChannelRuntime");
function createGoogleChatSendReceipt(params) {
const messageId = params.messageId?.trim();
return createMessageReceiptFromOutboundResults({
results: messageId ? [{
channel: "googlechat",
messageId,
chatId: params.chatId,
conversationId: params.chatId
}] : [],
threadId: params.chatId,
kind: params.kind
});
}
const formatAllowFromEntry = formatGoogleChatAllowFromEntry;
const collectGoogleChatSecurityWarnings = composeAccountWarningCollectors(createAllowlistProviderOpenWarningCollector({
providerConfigPresent: (cfg) => cfg.channels?.googlechat !== void 0,
resolveGroupPolicy: (account) => account.config.groupPolicy,
buildOpenWarning: {
surface: "Google Chat spaces",
openBehavior: "allows any space to trigger (mention-gated)",
remediation: "Set channels.googlechat.groupPolicy=\"allowlist\" and configure channels.googlechat.groups"
}
}), (account) => account.config.dm?.policy === "open" && "- Google Chat DMs are open to anyone. Set channels.googlechat.dm.policy=\"pairing\" or \"allowlist\".");
const googlechatGroupsAdapter = { resolveRequireMention: resolveGoogleChatGroupRequireMention };
const googlechatDirectoryAdapter = createChannelDirectoryAdapter({
listPeers: async (params) => listResolvedDirectoryUserEntriesFromAllowFrom({
...params,
resolveAccount: adaptScopedAccountAccessor(resolveGoogleChatAccount),
resolveAllowFrom: (account) => account.config.dm?.allowFrom,
normalizeId: (entry) => normalizeGoogleChatTarget(entry) ?? entry
}),
listGroups: async (params) => listResolvedDirectoryGroupEntriesFromMapKeys({
...params,
resolveAccount: adaptScopedAccountAccessor(resolveGoogleChatAccount),
resolveGroups: (account) => account.config.groups
})
});
const googlechatSecurityAdapter = {
dm: {
channelKey: "googlechat",
resolvePolicy: (account) => account.config.dm?.policy,
resolveAllowFrom: (account) => account.config.dm?.allowFrom,
allowFromPathSuffix: "dm.",
normalizeEntry: (raw) => formatAllowFromEntry(raw)
},
collectWarnings: collectGoogleChatSecurityWarnings
};
const googlechatThreadingAdapter = {
scopedAccountReplyToMode: {
resolveAccount: (cfg, accountId) => resolveGoogleChatAccount({
cfg,
accountId
}),
resolveReplyToMode: (account, _chatType) => account.config.replyToMode,
fallback: "off"
},
buildToolContext: ({ cfg, accountId, context, hasRepliedRef }) => {
const currentChannelId = normalizeGoogleChatTarget(context.To);
const replyToId = normalizeOptionalString(context.ReplyToIdFull) ?? normalizeOptionalString(context.ReplyToId);
return {
currentChannelId,
currentMessageId: replyToId,
currentThreadTs: replyToId,
replyToMode: resolveGoogleChatAccount({
cfg,
accountId
}).config.replyToMode,
hasRepliedRef
};
}
};
const googlechatPairingTextAdapter = {
idLabel: "googlechatUserId",
message: PAIRING_APPROVED_MESSAGE,
normalizeAllowEntry: (entry) => formatAllowFromEntry(entry),
notify: async ({ cfg, id, message, accountId }) => {
const account = resolveGoogleChatAccount({
cfg,
accountId
});
if (account.credentialSource === "none") return;
const user = normalizeGoogleChatTarget(id) ?? id;
const space = await resolveGoogleChatOutboundSpace({
account,
target: isGoogleChatUserTarget(user) ? user : `users/${user}`
});
const { sendGoogleChatMessage } = await loadGoogleChatChannelRuntime();
await sendGoogleChatMessage({
account,
space,
text: message
});
}
};
const googlechatOutboundAdapter = {
base: {
deliveryMode: "direct",
chunker: chunkTextForOutbound,
chunkerMode: "markdown",
textChunkLimit: 4e3,
sanitizeText: ({ text }) => sanitizeForPlainText(text),
normalizePayload: ({ payload }) => shouldSuppressGoogleChatManualExecApprovalFollowupPayload(payload) ? null : payload,
resolveTarget: ({ to }) => {
const trimmed = normalizeOptionalString(to) ?? "";
if (trimmed) {
const normalized = normalizeGoogleChatTarget(trimmed);
if (!normalized) return {
ok: false,
error: missingTargetError("Google Chat", "<spaces/{space}|users/{user}>")
};
return {
ok: true,
to: normalized
};
}
return {
ok: false,
error: missingTargetError("Google Chat", "<spaces/{space}|users/{user}>")
};
}
},
attachedResults: {
channel: "googlechat",
sendText: async ({ cfg, to, text, accountId, replyToId, threadId }) => {
const account = resolveGoogleChatAccount({
cfg,
accountId
});
const space = await resolveGoogleChatOutboundSpace({
account,
target: to
});
const thread = typeof threadId === "number" ? String(threadId) : threadId ?? replyToId ?? void 0;
const { sendGoogleChatMessage } = await loadGoogleChatChannelRuntime();
const messageId = (await sendGoogleChatMessage({
account,
space,
text,
thread
}))?.messageName ?? "";
return {
messageId,
chatId: space,
receipt: createGoogleChatSendReceipt({
messageId,
chatId: space,
kind: "text"
})
};
},
sendMedia: async ({ cfg, to, text, mediaUrl, mediaAccess, mediaLocalRoots, mediaReadFile, accountId, replyToId, threadId }) => {
if (!mediaUrl) throw new Error("Google Chat mediaUrl is required.");
const account = resolveGoogleChatAccount({
cfg,
accountId
});
const space = await resolveGoogleChatOutboundSpace({
account,
target: to
});
const thread = typeof threadId === "number" ? String(threadId) : threadId ?? replyToId ?? void 0;
const effectiveMaxBytes = resolveChannelMediaMaxBytes({
cfg,
resolveChannelLimitMb: ({ cfg: cfgLocal, accountId: accountIdLocal }) => (cfgLocal.channels?.googlechat)?.accounts?.[accountIdLocal]?.mediaMaxMb ?? (cfgLocal.channels?.googlechat)?.mediaMaxMb,
accountId
}) ?? (account.config.mediaMaxMb ?? 20) * 1024 * 1024;
const loaded = /^https?:\/\//i.test(mediaUrl) ? await readRemoteMediaBuffer({
url: mediaUrl,
maxBytes: effectiveMaxBytes
}) : await loadOutboundMediaFromUrl(mediaUrl, {
maxBytes: effectiveMaxBytes,
mediaAccess,
mediaLocalRoots,
mediaReadFile
});
const { sendGoogleChatMessage, uploadGoogleChatAttachment } = await loadGoogleChatChannelRuntime();
const upload = await uploadGoogleChatAttachment({
account,
space,
filename: loaded.fileName ?? "attachment",
buffer: loaded.buffer,
contentType: loaded.contentType
});
const messageId = (await sendGoogleChatMessage({
account,
space,
text,
thread,
attachments: upload.attachmentUploadToken ? [{
attachmentUploadToken: upload.attachmentUploadToken,
contentName: loaded.fileName
}] : void 0
}))?.messageName ?? "";
return {
messageId,
chatId: space,
receipt: createGoogleChatSendReceipt({
messageId,
chatId: space,
kind: "media"
})
};
}
}
};
const googlechatMessageAdapter = defineChannelMessageAdapter({
id: "googlechat",
durableFinal: { capabilities: {
text: true,
media: true,
thread: true,
messageSendingHooks: true
} },
send: {
text: googlechatOutboundAdapter.attachedResults.sendText,
media: googlechatOutboundAdapter.attachedResults.sendMedia
}
});
//#endregion
export { googlechatPairingTextAdapter as a, googlechatOutboundAdapter as i, googlechatGroupsAdapter as n, googlechatSecurityAdapter as o, googlechatMessageAdapter as r, googlechatThreadingAdapter as s, googlechatDirectoryAdapter as t };