@qihoo/tuitui-openclaw-channel 1.0.42 → 1.0.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/package.json +1 -1
- package/dist/src/accounts.d.ts +1 -1
- package/dist/src/accounts.js +11 -2
- package/dist/src/accounts.js.map +1 -1
- package/dist/src/inbound.js +9 -2
- package/dist/src/inbound.js.map +1 -1
- package/dist/src/tools.js +6 -6
- package/dist/src/tools.js.map +1 -1
- package/package.json +1 -1
package/dist/package.json
CHANGED
package/dist/src/accounts.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export declare const getAccountInfo: (acct?: any) => {
|
|
|
16
16
|
emojiReaction: boolean;
|
|
17
17
|
monitorEnabled: any;
|
|
18
18
|
};
|
|
19
|
-
export declare const resolveAccount: (cfg: any, accountId?: string | null) => {
|
|
19
|
+
export declare const resolveAccount: (cfg: any, accountId?: string | null, agentId?: string | null) => {
|
|
20
20
|
enabled: boolean;
|
|
21
21
|
appId: any;
|
|
22
22
|
appSecret: any;
|
package/dist/src/accounts.js
CHANGED
|
@@ -23,8 +23,17 @@ export const getAccountInfo = (acct) => ({
|
|
|
23
23
|
emojiReaction: isEnabled(acct?.emojiReaction ?? emojiReactionDefault),
|
|
24
24
|
monitorEnabled: acct?.monitorEnabled ?? monitorEnabledDefault,
|
|
25
25
|
});
|
|
26
|
-
export const resolveAccount = (cfg, accountId) => {
|
|
27
|
-
|
|
26
|
+
export const resolveAccount = (cfg, accountId, agentId) => {
|
|
27
|
+
// If agentId is provided, try to resolve accountId from cfg.bindings first
|
|
28
|
+
let resolvedAccountId = accountId;
|
|
29
|
+
if (agentId) {
|
|
30
|
+
const bindings = cfg?.bindings || [];
|
|
31
|
+
const matched = bindings.find((b) => b.agentId === agentId && b.match?.channel === CHANNEL_ID && typeof b.match?.accountId === 'string' && b.match.accountId !== '');
|
|
32
|
+
if (matched) {
|
|
33
|
+
resolvedAccountId = matched.match.accountId;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const accId = resolvedAccountId || DEFAULT_ACCOUNT_ID;
|
|
28
37
|
const defAccount = cfg?.channels?.[CHANNEL_ID] || {};
|
|
29
38
|
let currAccount = defAccount;
|
|
30
39
|
if (accId === DEFAULT_ACCOUNT_ID) {
|
package/dist/src/accounts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accounts.js","sourceRoot":"","sources":["../../src/accounts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAEpE,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,CAAC;AACnC,MAAM,CAAC,MAAM,eAAe,GAAG,SAAS,CAAC;AACzC,MAAM,CAAC,MAAM,kBAAkB,GAAG,WAAW,CAAC;AAC9C,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAC1C,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,CAAC;AACzC,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAE1C,MAAM,SAAS,GAAG,CAAC,IAAS,EAAE,IAAS,EAAE,EAAE;IACzC,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACxD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,IAAU,EAAE,EAAE,CAAC,CAAC;IAC7C,OAAO,EAAE,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC;IACjC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE;IACxB,SAAS,EAAE,IAAI,EAAE,SAAS,IAAI,SAAS,EAAE,wCAAwC;IACjF,QAAQ,EAAE,IAAI,EAAE,QAAQ,IAAI,eAAe;IAC3C,SAAS,EAAE,eAAe,CAAC,IAAI,EAAE,SAAS,IAAI,EAAE,CAAC;IACjD,iBAAiB;IACjB,WAAW,EAAE,IAAI,EAAE,WAAW,IAAI,kBAAkB;IACpD,cAAc,EAAE,eAAe,CAAC,IAAI,EAAE,cAAc,IAAI,EAAE,CAAC;IAC3D,cAAc,EAAE,SAAS,CAAC,IAAI,EAAE,cAAc,IAAI,qBAAqB,CAAC;IACxE,aAAa,EAAE,SAAS,CAAC,IAAI,EAAE,aAAa,IAAI,oBAAoB,CAAC;IACrE,cAAc,EAAE,IAAI,EAAE,cAAc,IAAI,qBAAqB;CAC9D,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,GAAQ,EAAE,SAAyB,EAAE,EAAE;
|
|
1
|
+
{"version":3,"file":"accounts.js","sourceRoot":"","sources":["../../src/accounts.ts"],"names":[],"mappings":"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","sourcesContent":["import { parseAllowFroms, isEnabled } from './utils';\nimport { CHANNEL_ID } from './const';\nimport { DEFAULT_ACCOUNT_ID } from 'openclaw/plugin-sdk/account-id';\n\nexport const enabledDefault = true;\nexport const dmPolicyDefault = 'pairing';\nexport const groupPolicyDefault = 'allowlist';\nexport const requireMentionDefault = true;\nexport const emojiReactionDefault = true;\nexport const monitorEnabledDefault = true;\n\nconst mergeArrs = (arr1: any, arr2: any) => {\n return [...new Set([...(arr1 || []), ...arr2 || []])];\n};\n\nexport const getAccountInfo = (acct?: any) => ({\n enabled: isEnabled(acct?.enabled),\n appId: acct?.appId || '',\n appSecret: acct?.appSecret || undefined, // 避免默认值覆盖用户输入的空字符串 Secret 空字串系统也会认为是已填写\n dmPolicy: acct?.dmPolicy || dmPolicyDefault,\n allowFrom: parseAllowFroms(acct?.allowFrom || []),\n // 群组策略与白名单、群组级覆盖\n groupPolicy: acct?.groupPolicy || groupPolicyDefault,\n groupAllowFrom: parseAllowFroms(acct?.groupAllowFrom || []),\n requireMention: isEnabled(acct?.requireMention ?? requireMentionDefault),\n emojiReaction: isEnabled(acct?.emojiReaction ?? emojiReactionDefault),\n monitorEnabled: acct?.monitorEnabled ?? monitorEnabledDefault,\n});\n\nexport const resolveAccount = (cfg: any, accountId?: string | null, agentId?: string | null) => {\n // If agentId is provided, try to resolve accountId from cfg.bindings first\n let resolvedAccountId = accountId;\n if (agentId) {\n const bindings: any[] = cfg?.bindings || [];\n const matched = bindings.find(\n (b: any) => b.agentId === agentId && b.match?.channel === CHANNEL_ID && typeof b.match?.accountId === 'string' && b.match.accountId !== ''\n );\n if (matched) {\n resolvedAccountId = matched.match.accountId;\n }\n }\n const accId = resolvedAccountId || DEFAULT_ACCOUNT_ID;\n const defAccount = cfg?.channels?.[CHANNEL_ID] || {};\n let currAccount = defAccount;\n if (accId === DEFAULT_ACCOUNT_ID) {\n // 如果在 channels.tuitui.accounts 中也配置了默认账号信息,则覆盖 channels.tuitui 中的默认账号信息,保持兼容性(openclaw 有个\"自动合并默认账号信息到 accounts\" 的 cli 选项)\n const subDefInfo = defAccount.accounts?.[DEFAULT_ACCOUNT_ID];\n if (subDefInfo) {\n const { enabled, dmPolicy, groupPolicy, requireMention, emojiReaction, monitorEnabled } = subDefInfo;\n currAccount = {\n enabled: enabled === undefined || enabled === enabledDefault ? defAccount.enabled : enabled,\n appId: subDefInfo.appId || defAccount.appId,\n appSecret: subDefInfo.appSecret || defAccount.appSecret,\n dmPolicy: !dmPolicy || dmPolicy === dmPolicyDefault ? defAccount.dmPolicy : dmPolicy,\n allowFrom: mergeArrs(subDefInfo.allowFrom, defAccount.allowFrom),\n groupPolicy: !groupPolicy || groupPolicy === groupPolicyDefault ? defAccount.groupPolicy : groupPolicy,\n groupAllowFrom: mergeArrs(subDefInfo.groupAllowFrom, defAccount.groupAllowFrom),\n requireMention: requireMention === undefined || requireMention === requireMentionDefault ? defAccount.requireMention : requireMention,\n emojiReaction: emojiReaction === undefined || emojiReaction === emojiReactionDefault ? defAccount.emojiReaction : emojiReaction,\n monitorEnabled: monitorEnabled === undefined || monitorEnabled === monitorEnabledDefault ? defAccount.monitorEnabled : monitorEnabled,\n };\n }\n } else {\n currAccount = currAccount.accounts?.[accId];\n }\n return { accountId: accId, ...getAccountInfo(currAccount) };\n};\n"]}
|
package/dist/src/inbound.js
CHANGED
|
@@ -421,7 +421,14 @@ export async function handleInboundMessage({ json, account, apiRuntime, log }) {
|
|
|
421
421
|
const cfg = await apiRuntime.config.loadConfig();
|
|
422
422
|
const sessionKey = getSessionKey(cfg, payload, account, apiRuntime);
|
|
423
423
|
log?.info?.(`[${CHANNEL_ID}] AccountId: ${accountId}, dispatching to agent session=${sessionKey}, chatType: ${payload.chatType}, chatId ${payload.chatId}, routeSenderFrom: ${routeSenderFrom}`);
|
|
424
|
-
|
|
424
|
+
let finalBody = payload.text || ' ';
|
|
425
|
+
if (payload.text && payload.botName) {
|
|
426
|
+
const stripped = payload.text.replace(`@${payload.botName}`, '').trim();
|
|
427
|
+
if (stripped.startsWith('/')) {
|
|
428
|
+
finalBody = stripped;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
if (finalBody.startsWith("/new") || finalBody.endsWith("/new")) {
|
|
425
432
|
// 清理agent上下文时,同时清空历史
|
|
426
433
|
popUnmentionedHistories(accountId, payload.chatId);
|
|
427
434
|
}
|
|
@@ -429,7 +436,7 @@ export async function handleInboundMessage({ json, account, apiRuntime, log }) {
|
|
|
429
436
|
// src\auto-reply\reply\inbound-meta.ts
|
|
430
437
|
// buildInboundUserContextPrefix()
|
|
431
438
|
const ctx = {
|
|
432
|
-
Body:
|
|
439
|
+
Body: finalBody,
|
|
433
440
|
From: String(routeSenderFrom),
|
|
434
441
|
To: CHANNEL_ID,
|
|
435
442
|
SessionId: sessionKey,
|
package/dist/src/inbound.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inbound.js","sourceRoot":"","sources":["../../src/inbound.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * TuiTui inbound message handler — pure business logic.\n *\n * channel.ts owns the WebSocket frame layer (JSON parse, ACK, keepalive\n * filtering) and calls handleInboundMessage with an already-parsed object.\n *\n * Usage:\n * ws.on('message', async (wsData) => {\n * // ... parse JSON, send ACK, filter keepalive ...\n * await handleInboundMessage(json, { account, accountId, apiRuntime, log });\n * });\n */\nimport type { TuiTuiInboundMessage, TuiTuiOutboundDeliverOptions } from './types';\nimport { CHANNEL_ID } from './const';\nimport {CHAT_TYPE_DIRECT,CHAT_TYPE_GROUP,CHAT_TYPE_CHANNEL,ChatType,teamsParseChatId,teamsBuildChatId} from \"./chat_base\"\nimport {tuituiEmojiReaction, sendTextMsg, sendPageMsg, sendMediaMsg } from \"./outbound\";\nimport { teams_get_members, teams_get_members_text, teams_get_announcement } from \"./teams_api\"\nimport { parseChatMessageBody } from './inbound_body_parse';\nimport { parseAllowFroms } from './utils';\nimport { addUnmentionedHistory, popUnmentionedHistories } from \"./histories\";\nimport { StringDeduplicator } from \"./deduplicator\"\nimport { getPostChainByChatId } from \"./chat_record\"\n\n// 会话上下文注入排重\nlet _session_ctx_injected = new StringDeduplicator(1000, 3600);\n\n/** 子函数共享的可变上下文,子函数直接修改字段,外层读取结果 */\ninterface ChatPayload {\n chatType: ChatType;\n chatId: string | undefined;\n botName: string;\n text: string | undefined;\n groupName: string | undefined;\n channelName: string | undefined;\n mediaUrls: string[] | undefined;\n replyToId: string | undefined; // 引用ID\n msgId?: string; // 消息ID\n tuituiAccount: string;\n tuituiUid: string | undefined;\n tuituiUserName: string | undefined;\n timestamp: Number | undefined;\n WasMentioned: boolean | undefined;\n}\n\nexport interface InboundAccount {\n accountId: string;\n appId: string;\n appSecret: string;\n dmPolicy: string;\n allowFrom: string[];\n groupPolicy: string;\n groupAllowFrom: string[];\n requireMention: boolean;\n emojiReaction: boolean;\n}\nexport interface InboundHandlerOptions {\n json: any\n account: InboundAccount;\n apiRuntime: any;\n log: any;\n}\n\nfunction getSessionKey(cfg: any, payload: ChatPayload, account: InboundAccount, apiRuntime: any): string {\n const { chatId, chatType } = payload;\n const { accountId } = account;\n // 你自己只需要拼接与定义 peer.id\n // 关于 sessionKey 格式的解释: https://docs.openclaw.ai/channels/channel-routing#sessionkey-%E5%8F%82%E8%80%83%E6%A0%BC%E5%BC%8F\n let id = chatId;\n if(chatType == CHAT_TYPE_CHANNEL) {\n const { channel_id, parent_id } = teamsParseChatId(chatId!);\n id = `${channel_id}`;\n if(parent_id) {\n id += `:thread:${parent_id}`;\n }\n }\n\n // sessionKey 不能自己拼字符串,需要用系统api识别,他会根据 bindings 路由规则处理\n const { sessionKey } = apiRuntime.channel.routing.resolveAgentRoute({\n cfg,\n accountId,\n channel: CHANNEL_ID,\n peer: { kind: chatType, id: id },\n });\n return String(sessionKey).replace(/\\//g, '_');\n}\n\nfunction getMediaUrls({ msg_type, images, voice, video, file }: any): string[] | undefined {\n if (msg_type === 'image' || msg_type === 'mixed') {\n if (images?.length) return images;\n } else if (msg_type === 'voice') {\n if (voice) return [voice];\n } else if (msg_type === 'video') {\n if (video) return [video];\n } else if (msg_type === 'file') {\n if (file?.url) return [file.url];\n }\n return undefined;\n}\n\nasync function dispatchReply(ctx: any, cfg: any, account: InboundAccount, payload: ChatPayload, apiRuntime: any, log: any) {\n const { accountId } = account;\n await apiRuntime.channel.reply.dispatchReplyWithBufferedBlockDispatcher({\n ctx,\n cfg,\n dispatcherOptions: {\n deliver: async (outbound: TuiTuiOutboundDeliverOptions) => {\n // Custom message (e.g. page)\n if (outbound.custom) {\n const { msgtype, page, tousers, togroups } = outbound.custom;\n if (msgtype === 'page' && page) {\n await sendPageMsg(account, payload.chatId, payload.chatType, page, 'tuitui.deliver.page', tousers, togroups);\n return;\n }\n log?.warn?.(`[${CHANNEL_ID}] AccountId: ${accountId}, Unsupported custom message type: ${msgtype}`);\n return;\n }\n\n // Media message\n const mediaUrl = outbound.mediaUrl || outbound.mediaUrls?.[0];\n if (mediaUrl) {\n await sendMediaMsg(account, payload.chatId, payload.chatType, mediaUrl, 'tuitui.deliver.media', [payload.tuituiAccount]);\n return;\n }\n\n // Text message\n const replyText = outbound?.text || outbound?.body;\n if (replyText) {\n // 群消息回复时不再使用 reference_msgid 避免并发时引用错乱,依靠 @ 来提醒用户\n await sendTextMsg(account, payload.chatId, payload.chatType, replyText, 'tuitui.deliver.text', [payload.tuituiAccount]);\n return;\n }\n log?.info?.(`[${CHANNEL_ID}] AccountId: ${accountId}, no_reply_content`);\n },\n\n onReplyStart: () => {\n log?.info?.(`[${CHANNEL_ID}] AccountId: ${accountId}, Agent is typing to ${payload.tuituiAccount}`);\n },\n },\n });\n}\n\n/*** 配对节流映射 - 用于防止短时间内大量重复配对请求消息发出\n * key: `${accountId}-${chatId}`\n * val: timestamp */\nconst pairingThrottleMap = new Map<string, number>();\n// 暂时控制为 2 分钟内同一个用户只能触发一次配对请求\nconst needPairingThrottle = (accountId: string | undefined, chatId: string, throttleMs = 2 * 60 * 1000): boolean => {\n const key = `${accountId}-${chatId}`;\n const now = Date.now();\n const lastTime = pairingThrottleMap.get(key) || 0;\n if (now - lastTime < throttleMs) {\n return true;\n }\n pairingThrottleMap.set(key, now);\n return false;\n}\n\nasync function sendSingleChatPairingMsg(account: any, payload: any, log: any, apiRuntime: any) {\n const { accountId } = account;\n const { chatId, chatType } = payload;\n if (needPairingThrottle(accountId, chatId)) {\n return log?.info?.(`[${CHANNEL_ID}] AccountId: ${accountId}, pairing throttled for sender=${chatId}`);\n }\n try {\n log?.debug?.(`[${CHANNEL_ID}] AccountId: ${accountId}, pairing flow: checking if pairing request exists for sender=${chatId}`);\n const req = await apiRuntime.channel.pairing.upsertPairingRequest({ channel: CHANNEL_ID, accountId, id: chatId });\n log?.debug?.(`[${CHANNEL_ID}] AccountId: ${accountId}, pairing flow: upsertPairingRequest result=${JSON.stringify(req)}`);\n // 只要没配对,会每次和机器人聊,都会返回配对信息。\n const replyText = apiRuntime.channel.pairing.buildPairingReply({ channel: CHANNEL_ID, code: req.code });\n await sendTextMsg(account, chatId, chatType, replyText, 'tuitui.pairing.reply');\n } catch (err) {\n log?.warn?.(`[${CHANNEL_ID}] AccountId: ${accountId}, pairing failed for ${chatId}: ${String(err)}`);\n }\n}\n\n//tuituiAccounts列表中是否存在至少1个允许私聊的用户(私聊白名单、配对、或者open)\nasync function isAllowOneOfAccount(tuituiAccounts: string[], apiRuntime: any, account: InboundAccount) {\n if(!tuituiAccounts) return false;\n const { accountId, allowFrom, dmPolicy } = account;\n if (dmPolicy === 'open') return true;\n\n // 是否包含任意一个元素\n if (tuituiAccounts.some(item => allowFrom.includes(item))) return true;\n\n try {\n let storeAllowFrom = parseAllowFroms(\n await apiRuntime?.channel?.pairing?.readAllowFromStore?.({ channel: CHANNEL_ID, accountId })\n );\n if (tuituiAccounts.some(item => storeAllowFrom.includes(item))) return true;\n } catch {}\n return false; \n}\n\nasync function isAllowAccount(tuituiAccount: string, apiRuntime: any, account: InboundAccount) {\n return await isAllowOneOfAccount([tuituiAccount], apiRuntime, account);\n}\n\nasync function isChannelCoordAuthorized(tuituiAccount: string, apiRuntime: any, account: InboundAccount, team_id:string, chat_id:string) {\n // 协调员身份校验\n if (tuituiAccount != \"bot-FiwwCeDw\" && tuituiAccount != \"bot-sUwUeknd\") return false;\n\n // 当前 thread 中有白名单用户发帖,则协调员继承该权限\n const [members, posts] = await Promise.all([\n teams_get_members(account, team_id),\n getPostChainByChatId(account, chat_id),\n ]);\n if (!members?.length || !posts?.length) return false;\n\n const from_uids = posts.map((p: any) => p.from_uid).filter(Boolean);\n if (!from_uids.length) return false;\n\n //console.log(\"from_uids\", from_uids);\n\n // 将 uid 映射到 user_account\n const from_accounts: string[] = members\n .filter((m: any) => from_uids.includes(m.uid) && m.account)\n .map((m: any) => String(m.account));\n if (!from_accounts.length) return false;\n\n //console.log(\"from_accounts\", from_accounts);\n return await isAllowOneOfAccount(from_accounts, apiRuntime, account);\n}\n\n\n/**\n * 处理单聊(single_chat)、群聊、团队帖子分支,直接修改并校验 payload。\n * 返回 false 表示消息不合法,外层应提前 return;返回 true 表示校验通过,继续执行。\n */\nasync function parse_single_chat(payload: ChatPayload, msgData: any, account: InboundAccount, apiRuntime: any, log: any): Promise<boolean> {\n const { accountId, dmPolicy, allowFrom } = account;\n const chatId = payload.tuituiAccount ? String(payload.tuituiAccount || '').toLowerCase().trim() : '';\n if (dmPolicy === 'disabled') { //['pairing', 'allowlist', 'open', 'disabled'],\n log?.warn?.(`[${CHANNEL_ID}] AccountId: ${accountId}, DM disabled sender=${chatId}`);\n return false;\n }\n\n payload.chatType = CHAT_TYPE_DIRECT;\n payload.chatId = chatId;\n payload.text = parseChatMessageBody(msgData);\n payload.msgId = msgData.msgid;\n log?.debug?.(\n `[${CHANNEL_ID}] AccountId: ${accountId}, inbound single_chat:\n userAccount=${chatId},\n tuituiUid=${payload.tuituiUid},\n tuituiUserName=${payload.tuituiUserName},\n dmPolicy=${dmPolicy},\n allowFrom=${JSON.stringify(allowFrom)}`);\n\n if (!chatId && !payload.tuituiUid) {\n log?.info?.(`[${CHANNEL_ID}] AccountId: ${accountId}, Missing user_account or uid in single_chat event`);\n return false;\n }\n\n if (dmPolicy === 'open') return true;\n\n if(await isAllowAccount(chatId, apiRuntime, account)){\n return true;\n }\n\n if (dmPolicy === 'pairing') {\n sendSingleChatPairingMsg(account, payload, log, apiRuntime);\n log?.info?.(`[${CHANNEL_ID}] AccountId: ${accountId}, pairing required`);\n return false;\n }\n // allowlist\n log?.warn?.(`[${CHANNEL_ID}] AccountId: ${accountId}, Blocked unauthorized sender (allowlist): sender=${chatId} allowFrom=${JSON.stringify(allowFrom)}`);\n return false;\n}\n\nasync function parse_group_chat(payload: ChatPayload, msgData: any, account: InboundAccount, apiRuntime: any, log: any): Promise<boolean> {\n const { accountId, groupPolicy, groupAllowFrom } = account;\n payload.chatType = CHAT_TYPE_GROUP;\n const chatId = msgData.group_id ? String(msgData.group_id).toLowerCase().trim() : '';\n payload.chatId = chatId;\n payload.groupName = msgData.group_name;\n payload.msgId = msgData.msgid;\n payload.text = parseChatMessageBody(msgData);\n payload.WasMentioned = msgData.at_me;\n const { tuituiAccount } = payload;\n log?.debug?.(\n `[${CHANNEL_ID}] AccountId: ${accountId}, inbound group_chat:\n tuituiAccount=${tuituiAccount},\n tuituiUid=${payload.tuituiUid},\n tuituiUserName=${payload.tuituiUserName},\n groupId=${chatId},\n groupPolicy=${groupPolicy},\n groupAllowFrom=${JSON.stringify(groupAllowFrom)},\n at_me=${JSON.stringify(msgData.at_me)},\n at=${JSON.stringify(msgData.at)}`);\n\n if (groupPolicy === 'disabled') {\n log?.info?.(`${CHANNEL_ID} AccountId: ${accountId}, groupPolicy disabled`);\n return false;\n }\n\n if (!tuituiAccount || !chatId) {\n log?.info?.(`[${CHANNEL_ID}] AccountId: ${accountId}, Missing tuituiAccount or chatId in group_chat event`);\n return false;\n }\n\n if (!msgData.at_me && account.requireMention) {\n log?.info?.(`[${CHANNEL_ID}] AccountId: ${accountId}, ignore group message (not mentioned), add to history key: ${chatId}`);\n await addUnmentionedHistory(apiRuntime, accountId, chatId, payload.tuituiUserName, tuituiAccount, payload.text, payload.timestamp);\n return false;\n }\n\n // 私聊白名单对群聊仍然生效,当群里只想特定人@时,可以不配置groupAllowFrom,而是配置 allowFrom\n if(await isAllowAccount(tuituiAccount, apiRuntime, account)){\n return true;\n }\n\n if (!groupAllowFrom.includes(chatId)) {\n if (needPairingThrottle(accountId, chatId)) {\n log?.info?.(`[${CHANNEL_ID}] AccountId: ${accountId}, group pairing throttled for groupId=${chatId}`);\n return false;\n }\n\n const msgTxt=`当前 OpenClaw(AccountId: ${accountId})的群聊策略为白名单模式。\n需由龙虾主人在配置中添加白名单(两种方式二选一即可):\n\n- 允许群中所有人用,在群白名单(Group Allow From)添加当前群ID: ${chatId}\n\n- 不想群所有人用,只想特定人用,在私聊白名单(Allow From)添加当前用户 ${payload.tuituiAccount} ,私聊白名单对群仍然有效`\n\n await sendTextMsg(account, chatId, payload.chatType, msgTxt, 'tuitui.groupPolicy.reply');\n return false;\n }\n\n return true; \n}\n\n\nasync function parse_teams_post(payload: ChatPayload, msgData: any, account: InboundAccount, apiRuntime: any, log: any): Promise<boolean> {\n const { accountId, groupPolicy, groupAllowFrom } = account;\n payload.chatType = CHAT_TYPE_CHANNEL;\n const { team_id, channel_id, parent_id, post_id, content, team_name, channel_name } = msgData;\n const thread_id = (parent_id && parent_id != \"0\")?parent_id: post_id;\n const chatId = teamsBuildChatId(team_id, channel_id, thread_id);\n payload.chatId = chatId;\n payload.msgId = post_id;\n payload.text = content;\n payload.channelName = channel_name;\n payload.replyToId = \"\";\n payload.WasMentioned = msgData.at_me;\n const { tuituiAccount } = payload;\n log?.debug?.(\n `[${CHANNEL_ID}] AccountId: ${accountId}, inbound teams:\n tuituiAccount=${tuituiAccount},\n tuituiUid=${payload.tuituiUid},\n tuituiUserName=${payload.tuituiUserName},\n chatId=${chatId},\n groupPolicy=${groupPolicy},\n groupAllowFrom=${JSON.stringify(groupAllowFrom)},\n at_me=${JSON.stringify(msgData.at_me)},\n at=${JSON.stringify(msgData.at)}`,\n );\n\n if (groupPolicy === 'disabled') {\n log?.info?.(`${CHANNEL_ID} AccountId: ${accountId}, groupPolicy disabled`);\n return false;\n }\n\n if (!tuituiAccount) {\n log?.info?.(`[${CHANNEL_ID}] AccountId: ${accountId}, Missing tuituiAccount or chatId in event`);\n return false;\n }\n\n \n {\n // 频道帖子文件、附件处理。必须放在正文里\n const {images, files} = msgData;\n if (images) {\n payload.text += \"\\n\\n附录上文提到的图片列表\\n\"\n for (const image of images) {\n payload.text += image + \"\\n\";\n }\n }\n if (files) {\n payload.text += \"\\n\\n附录上文提到的文件列表\\n\"\n for (const file of files) {\n payload.text += `[文件] ${file?.name} : ${file?.url} \\n`;\n }\n }\n }\n\n if (!msgData.at_me && account.requireMention) {\n log?.info?.(`[${CHANNEL_ID}] AccountId: ${accountId}, ignore teams post (not mentioned), add to history ${chatId} -> ${payload.text}`);\n await addUnmentionedHistory(apiRuntime, accountId, chatId, payload.tuituiUserName, tuituiAccount, payload.text, payload.timestamp);\n return false;\n }\n\n if(_session_ctx_injected.checkAndRecord(accountId + \"_\" + payload.chatId)) {\n // 注入上下文\n // 解决机器人不知道自己是谁的问题\n if(payload.botName) {\n payload.text += `\\n\\n*** 参考信息: 你在当前session中的名字叫: ${payload.botName} 如果有人@这个名字,就是在命令你 ***\\n`;\n }\n // 公告\n const annnouncement = await teams_get_announcement(account, channel_id, false);\n if(annnouncement) {\n payload.text += \"\\n\\n*** 参考信息: 当前公告内容如下 ***\\n\";\n payload.text += \"```\\n\" + annnouncement + \"\\n```\";\n }\n\n // 成员\n const members = await teams_get_members_text(account, team_id);\n if(members) {\n payload.text += \"\\n\\n*** 参考信息: 当前团队成员清单如下,每行一个成员名。如果需要询问成员、或者发送给成员时,需要用 @名字 的语法;并且@时必须从如下清单中匹配到最接近的,禁止@不存在的成员 ***\\n\";\n payload.text += \"```\\n\" + members + \"\\n```\";\n }\n }\n\n // 私聊白名单对团队仍然生效,限制特定人@时,可以不配置groupAllowFrom,而是配置 allowFrom\n if(await isAllowAccount(tuituiAccount, apiRuntime, account)){\n return true;\n }\n \n if (!groupAllowFrom.includes(String(team_id)) && !groupAllowFrom.includes(String(channel_id)) ) {\n if (!msgData.at_me) {\n // 解决这个case:requireMention=false时,团队里发任意帖子都会回复加白,搞得没法用\n // 要求必须@才触发回复加白\n log?.info?.(`[${CHANNEL_ID}] AccountId: ${accountId}, ignore teams post (not mentioned)`);\n return false;\n }\n\n // 频道中允许协调员@自己(且帖子里有白名单用户发帖)\n if (await isChannelCoordAuthorized(tuituiAccount, apiRuntime, account, team_id, chatId)) {\n return true;\n }\n\n if (needPairingThrottle(accountId, chatId)) {\n log?.info?.(`[${CHANNEL_ID}] AccountId: ${accountId}, teams pairing throttled for teamsChatId=${chatId}`);\n return false;\n }\n\n const msgTxt=`当前 OpenClaw(AccountId: ${accountId})的群聊/团队策略为白名单模式。\n需由龙虾主人在配置中添加白名单(3种方式选一种即可):\n\n- 允许团队中所有人用,在群白名单(Group Allow From)添加当前团队ID: ${team_id}\n- 仅允许当前频道使用,在群白名单(Group Allow From)添加当前频道ID: ${channel_id}\n- 仅允许特定人使用,在私聊白名单(Allow From)添加当前用户: ${payload.tuituiAccount} ,私聊白名单对团队仍然有效`\n\n await sendTextMsg(account, chatId, payload.chatType, msgTxt, 'tuitui.groupPolicy.reply');\n return false;\n }\n\n return true;\n}\n\nconst parseAndVerifyPayload: Record<string, Function> = {\n single_chat: parse_single_chat,\n group_chat: parse_group_chat,\n teams_post_create: parse_teams_post,\n //teams_post_modify: parse_teams_post,\n} as const;\n\n/**\n * 处理长链接消息\n * account: 长连接初始化时,对应的Account配置信息\n * accountId: 长连接启动初始化,对应的配置ID\n */\nexport async function handleInboundMessage({ json, account, apiRuntime, log }: InboundHandlerOptions) {\n // Signature / AppId validation\n const { accountId, appId, appSecret } = account;\n if (appSecret && appId && json.header['X-Tuitui-Robot-Appid'] !== appId) {\n log?.info?.(`[${CHANNEL_ID}] Invalid appId`);\n return;\n }\n\n // Decode message\n const msg = json.body as TuiTuiInboundMessage;\n const msgData = msg.data;\n const { ref } = msgData;\n const payload: ChatPayload = {\n chatType: CHAT_TYPE_DIRECT,\n chatId: undefined, \n botName: json.header['X-Tuitui-Robot-AppName'],\n text: undefined,\n groupName: undefined,\n WasMentioned: undefined,\n channelName: undefined,\n mediaUrls: getMediaUrls(msgData),\n replyToId: ref?.is_me && ref?.msgid ? ref.msgid : undefined,\n tuituiAccount: msg.user_account || \"\",\n tuituiUid: msg.uid || \"\",\n tuituiUserName: msg.user_name || \"\",\n timestamp: msg.timestamp ? parseInt(msg.timestamp, 10)*1000 : undefined\n };\n const wsEvent = json.body.event;\n // 按event类型,标准化并校验基础数据\n const parseAndVerifyPayloadFun = parseAndVerifyPayload[wsEvent] as Function | undefined;\n if (!parseAndVerifyPayloadFun) {\n log?.info?.(`[${CHANNEL_ID}] ignore unknown event ${wsEvent}`);\n return;\n }\n if (!(await parseAndVerifyPayloadFun(payload, msgData, account, apiRuntime, log))) return;\n\n if (!payload.chatId || !payload.msgId) {\n log?.info?.(`[${CHANNEL_ID}] ignore unknown mseeage, missing chatId or msgId`, payload);\n return;\n }\n\n if (account.emojiReaction) {\n // 因为回复较慢,先回复一个表情\n try{\n await tuituiEmojiReaction(account, payload.chatId, payload.chatType, payload.msgId, '收到');\n } catch (err) {\n // 出错不影响后续逻辑\n }\n }\n\n // 路由判断\n const routeSenderFrom = payload.tuituiAccount || payload.tuituiUid || 'unknown';\n\n const cfg = await apiRuntime.config.loadConfig();\n const sessionKey = getSessionKey(cfg, payload, account, apiRuntime);\n log?.info?.(`[${CHANNEL_ID}] AccountId: ${accountId}, dispatching to agent session=${sessionKey}, chatType: ${payload.chatType}, chatId ${payload.chatId}, routeSenderFrom: ${routeSenderFrom}`);\n\n if(payload.text?.startsWith(\"/new\") || payload.text?.endsWith(\"/new\")) {\n // 清理agent上下文时,同时清空历史\n popUnmentionedHistories(accountId, payload.chatId);\n }\n\n // 字段意义 参考 openclaw 代码\n // src\\auto-reply\\reply\\inbound-meta.ts\n // buildInboundUserContextPrefix()\n const ctx: any = {\n Body: payload.text! || ' ',\n From: String(routeSenderFrom),\n To: CHANNEL_ID,\n SessionId: sessionKey,\n SessionKey: sessionKey,\n AccountId: accountId,\n OriginatingChannel: CHANNEL_ID,\n OriginatingTo: payload.chatId,\n ChatType: payload.chatType!,\n Surface: CHANNEL_ID,\n Provider: CHANNEL_ID,\n SenderName: payload.tuituiUserName,\n SenderId: payload.tuituiAccount,\n SenderUsername: payload.tuituiAccount, \n UserAccount: payload.tuituiAccount,\n Timestamp: payload.timestamp,\n CommandAuthorized: true, // 允许 /new 等内置命令\n };\n if (payload.chatType == CHAT_TYPE_GROUP && payload.chatId) {\n ctx.WasMentioned = payload.WasMentioned;\n ctx.GroupSubject = payload.groupName;\n ctx.GroupId = payload.chatId;\n ctx.InboundHistory = popUnmentionedHistories(accountId, payload.chatId);\n }\n if (payload.chatType == CHAT_TYPE_CHANNEL) {\n ctx.WasMentioned = payload.WasMentioned;\n ctx.IsForum = true;\n ctx.GroupSubject = payload.channelName;\n ctx.GroupChannel = payload.chatId;\n ctx.InboundHistory = popUnmentionedHistories(accountId, payload.chatId);\n }\n if (payload.mediaUrls?.length) ctx.MediaUrls = payload.mediaUrls;\n if (payload.replyToId) ctx.ReplyToId = payload.replyToId;\n\n log?.info?.(`[${CHANNEL_ID}] AccountId: ${accountId}, handleInboundMessage dispatchReply ctx: ${JSON.stringify(ctx, null, ' ')}`);\n try {\n await dispatchReply(ctx, cfg, account, payload, apiRuntime, log);\n } catch (err) {\n log?.error?.(`[${CHANNEL_ID}] AccountId: ${accountId}, dispatchReply failed:`, err);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"inbound.js","sourceRoot":"","sources":["../../src/inbound.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAC,gBAAgB,EAAC,eAAe,EAAC,iBAAiB,EAAU,gBAAgB,EAAC,gBAAgB,EAAC,MAAM,aAAa,CAAA;AACzH,OAAO,EAAC,mBAAmB,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAC/F,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AAEpD,YAAY;AACZ,IAAI,qBAAqB,GAAG,IAAI,kBAAkB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAsC/D,SAAS,aAAa,CAAC,GAAQ,EAAE,OAAoB,EAAE,OAAuB,EAAE,UAAe;IAC7F,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IACrC,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IAC9B,sBAAsB;IACtB,yHAAyH;IACzH,IAAK,EAAE,GAAG,MAAM,CAAC;IACjB,IAAG,QAAQ,IAAI,iBAAiB,EAAE,CAAC;QACjC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,gBAAgB,CAAC,MAAO,CAAC,CAAC;QAC5D,EAAE,GAAG,GAAG,UAAU,EAAE,CAAC;QACrB,IAAG,SAAS,EAAE,CAAC;YACZ,EAAE,IAAI,WAAW,SAAS,EAAE,CAAC;QAChC,CAAC;IACH,CAAC;IAED,sDAAsD;IACtD,MAAM,EAAE,UAAU,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC;QAClE,GAAG;QACH,SAAS;QACT,OAAO,EAAE,UAAU;QACnB,IAAI,EAAE,EAAG,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAK,EAAE,EAAE;KACrC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,YAAY,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAO;IACjE,IAAI,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjD,IAAI,MAAM,EAAE,MAAM;YAAE,OAAO,MAAM,CAAC;IACpC,CAAC;SAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QAChC,IAAI,KAAK;YAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;SAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QAChC,IAAI,KAAK;YAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;SAAM,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QAC/B,IAAI,IAAI,EAAE,GAAG;YAAE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,GAAQ,EAAE,GAAQ,EAAE,OAAuB,EAAE,OAAoB,EAAE,UAAe,EAAE,GAAQ;IACvH,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IAC9B,MAAM,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,wCAAwC,CAAC;QACtE,GAAG;QACH,GAAG;QACH,iBAAiB,EAAE;YACjB,OAAO,EAAE,KAAK,EAAE,QAAsC,EAAE,EAAE;gBACxD,6BAA6B;gBAC7B,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;oBACpB,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC;oBAC7D,IAAI,OAAO,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC;wBAC/B,MAAM,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,qBAAqB,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;wBAC7G,OAAO;oBACT,CAAC;oBACD,GAAG,EAAE,IAAI,EAAE,CAAC,IAAI,UAAU,gBAAgB,SAAS,sCAAsC,OAAO,EAAE,CAAC,CAAC;oBACpG,OAAO;gBACT,CAAC;gBAED,gBAAgB;gBAChB,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC9D,IAAI,QAAQ,EAAE,CAAC;oBACb,MAAM,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,sBAAsB,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC;oBACzH,OAAO;gBACT,CAAC;gBAED,eAAe;gBACf,MAAM,SAAS,GAAG,QAAQ,EAAE,IAAI,IAAI,QAAQ,EAAE,IAAI,CAAC;gBACnD,IAAI,SAAS,EAAE,CAAC;oBACd,kDAAkD;oBAClD,MAAM,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,EAAE,SAAS,EAAE,qBAAqB,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC;oBACxH,OAAO;gBACT,CAAC;gBACD,GAAG,EAAE,IAAI,EAAE,CAAC,IAAI,UAAU,gBAAgB,SAAS,oBAAoB,CAAC,CAAC;YAC3E,CAAC;YAED,YAAY,EAAE,GAAG,EAAE;gBACjB,GAAG,EAAE,IAAI,EAAE,CAAC,IAAI,UAAU,gBAAgB,SAAS,wBAAwB,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;YACtG,CAAC;SACF;KACF,CAAC,CAAC;AACL,CAAC;AAED;;oBAEoB;AACpB,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAkB,CAAC;AACrD,6BAA6B;AAC7B,MAAM,mBAAmB,GAAG,CAAC,SAA6B,EAAE,MAAc,EAAE,UAAU,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,EAAW,EAAE;IACjH,MAAM,GAAG,GAAG,GAAG,SAAS,IAAI,MAAM,EAAE,CAAC;IACrC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,QAAQ,GAAG,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAClD,IAAI,GAAG,GAAG,QAAQ,GAAG,UAAU,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,kBAAkB,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACjC,OAAO,KAAK,CAAC;AACf,CAAC,CAAA;AAED,KAAK,UAAU,wBAAwB,CAAC,OAAY,EAAE,OAAY,EAAE,GAAQ,EAAE,UAAe;IAC3F,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IAC9B,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IACrC,IAAI,mBAAmB,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC;QAC3C,OAAO,GAAG,EAAE,IAAI,EAAE,CAAC,IAAI,UAAU,gBAAgB,SAAS,kCAAkC,MAAM,EAAE,CAAC,CAAC;IACxG,CAAC;IACD,IAAI,CAAC;QACH,GAAG,EAAE,KAAK,EAAE,CAAC,IAAI,UAAU,gBAAgB,SAAS,iEAAiE,MAAM,EAAE,CAAC,CAAC;QAC/H,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QAClH,GAAG,EAAE,KAAK,EAAE,CAAC,IAAI,UAAU,gBAAgB,SAAS,+CAA+C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC1H,2BAA2B;QAC3B,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QACxG,MAAM,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,sBAAsB,CAAC,CAAC;IAClF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,EAAE,IAAI,EAAE,CAAC,IAAI,UAAU,gBAAgB,SAAS,wBAAwB,MAAM,KAAK,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACvG,CAAC;AACH,CAAC;AAED,mDAAmD;AACnD,KAAK,UAAU,mBAAmB,CAAC,cAAwB,EAAE,UAAe,EAAE,OAAuB;IACnG,IAAG,CAAC,cAAc;QAAE,OAAO,KAAK,CAAC;IACjC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IACnD,IAAI,QAAQ,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAErC,aAAa;IACb,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAEvE,IAAI,CAAC;QACH,IAAI,cAAc,GAAG,eAAe,CAClC,MAAM,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAC7F,CAAC;QACF,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;IAC9E,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IACV,OAAO,KAAK,CAAC;AACf,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,aAAqB,EAAE,UAAe,EAAE,OAAuB;IAC3F,OAAO,MAAM,mBAAmB,CAAC,CAAC,aAAa,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;AACzE,CAAC;AAED,KAAK,UAAU,wBAAwB,CAAC,aAAqB,EAAE,UAAe,EAAE,OAAuB,EAAE,OAAc,EAAE,OAAc;IACrI,UAAU;IACV,IAAI,aAAa,IAAI,cAAc,IAAI,aAAa,IAAI,cAAc;QAAE,OAAO,KAAK,CAAC;IAErF,gCAAgC;IAChC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACzC,iBAAiB,CAAC,OAAO,EAAE,OAAO,CAAC;QACnC,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC;KACvC,CAAC,CAAC;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC,KAAK,EAAE,MAAM;QAAE,OAAO,KAAK,CAAC;IAErD,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACpE,IAAI,CAAC,SAAS,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAEpC,sCAAsC;IAEtC,yBAAyB;IACzB,MAAM,aAAa,GAAa,OAAO;SACpC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;SAC1D,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IACtC,IAAI,CAAC,aAAa,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAExC,8CAA8C;IAC9C,OAAO,MAAM,mBAAmB,CAAC,aAAa,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;AACvE,CAAC;AAGD;;;GAGG;AACH,KAAK,UAAU,iBAAiB,CAAC,OAAoB,EAAE,OAAY,EAAE,OAAuB,EAAE,UAAe,EAAE,GAAQ;IACrH,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IACnD,MAAM,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACrG,IAAI,QAAQ,KAAK,UAAU,EAAE,CAAC,CAAE,+CAA+C;QAC7E,GAAG,EAAE,IAAI,EAAE,CAAC,IAAI,UAAU,gBAAgB,SAAS,wBAAwB,MAAM,EAAE,CAAC,CAAC;QACrF,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,CAAC,QAAQ,GAAG,gBAAgB,CAAC;IACpC,OAAO,CAAC,MAAM,GAAK,MAAM,CAAC;IAC1B,OAAO,CAAC,IAAI,GAAO,oBAAoB,CAAC,OAAO,CAAC,CAAC;IACjD,OAAO,CAAC,KAAK,GAAM,OAAO,CAAC,KAAK,CAAC;IACjC,GAAG,EAAE,KAAK,EAAE,CACV,IAAI,UAAU,gBAAgB,SAAS;kBACzB,MAAM;gBACR,OAAO,CAAC,SAAS;qBACZ,OAAO,CAAC,cAAc;eAC5B,QAAQ;gBACP,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAE3C,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QAClC,GAAG,EAAE,IAAI,EAAE,CAAC,IAAI,UAAU,gBAAgB,SAAS,oDAAoD,CAAC,CAAC;QACzG,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,QAAQ,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAErC,IAAG,MAAM,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,EAAC,CAAC;QACpD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,wBAAwB,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC;QAC5D,GAAG,EAAE,IAAI,EAAE,CAAC,IAAI,UAAU,gBAAgB,SAAS,oBAAoB,CAAC,CAAC;QACzE,OAAO,KAAK,CAAC;IACf,CAAC;IACD,YAAY;IACZ,GAAG,EAAE,IAAI,EAAE,CAAC,IAAI,UAAU,gBAAgB,SAAS,qDAAqD,MAAM,cAAc,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACzJ,OAAO,KAAK,CAAC;AACf,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,OAAoB,EAAE,OAAY,EAAE,OAAuB,EAAE,UAAe,EAAE,GAAQ;IACpH,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC;IAC3D,OAAO,CAAC,QAAQ,GAAI,eAAe,CAAC;IACpC,MAAM,MAAM,GAAO,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACzF,OAAO,CAAC,MAAM,GAAK,MAAM,CAAC;IAC1B,OAAO,CAAC,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC;IACvC,OAAO,CAAC,KAAK,GAAI,OAAO,CAAC,KAAK,CAAC;IAC/B,OAAO,CAAC,IAAI,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC7C,OAAO,CAAC,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC;IACrC,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC;IAClC,GAAG,EAAE,KAAK,EAAE,CACV,IAAI,UAAU,gBAAgB,SAAS;oBACvB,aAAa;gBACjB,OAAO,CAAC,SAAS;qBACZ,OAAO,CAAC,cAAc;cAC7B,MAAM;kBACF,WAAW;qBACR,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC;YACvC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC;SAChC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAErC,IAAI,WAAW,KAAK,UAAU,EAAE,CAAC;QAC/B,GAAG,EAAE,IAAI,EAAE,CAAC,GAAG,UAAU,eAAe,SAAS,wBAAwB,CAAC,CAAC;QAC3E,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC,aAAa,IAAI,CAAC,MAAM,EAAE,CAAC;QAC9B,GAAG,EAAE,IAAI,EAAE,CAAC,IAAI,UAAU,gBAAgB,SAAS,uDAAuD,CAAC,CAAC;QAC5G,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;QAC7C,GAAG,EAAE,IAAI,EAAE,CAAC,IAAI,UAAU,gBAAgB,SAAS,+DAA+D,MAAM,EAAE,CAAC,CAAC;QAC5H,MAAM,qBAAqB,CAAC,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,cAAc,EAAE,aAAa,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;QACnI,OAAO,KAAK,CAAC;IACf,CAAC;IAED,6DAA6D;IAC7D,IAAG,MAAM,cAAc,CAAC,aAAa,EAAE,UAAU,EAAE,OAAO,CAAC,EAAC,CAAC;QAC3D,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACrC,IAAI,mBAAmB,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC;YAC3C,GAAG,EAAE,IAAI,EAAE,CAAC,IAAI,UAAU,gBAAgB,SAAS,yCAAyC,MAAM,EAAE,CAAC,CAAC;YACtG,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,MAAM,GAAC,0BAA0B,SAAS;;;6CAGP,MAAM;;4CAEP,OAAO,CAAC,aAAa,eAAe,CAAA;QAE5E,MAAM,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,0BAA0B,CAAC,CAAC;QACzF,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAGD,KAAK,UAAU,gBAAgB,CAAC,OAAoB,EAAE,OAAY,EAAE,OAAuB,EAAE,UAAe,EAAE,GAAQ;IACpH,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC;IAC3D,OAAO,CAAC,QAAQ,GAAI,iBAAiB,CAAC;IACtC,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC;IAC9F,MAAM,SAAS,GAAK,CAAC,SAAS,IAAI,SAAS,IAAI,GAAG,CAAC,CAAA,CAAC,CAAA,SAAS,CAAA,CAAC,CAAC,OAAO,CAAC;IACvE,MAAM,MAAM,GAAQ,gBAAgB,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;IACrE,OAAO,CAAC,MAAM,GAAM,MAAM,CAAC;IAC3B,OAAO,CAAC,KAAK,GAAO,OAAO,CAAC;IAC5B,OAAO,CAAC,IAAI,GAAQ,OAAO,CAAC;IAC5B,OAAO,CAAC,WAAW,GAAG,YAAY,CAAC;IACnC,OAAO,CAAC,SAAS,GAAG,EAAE,CAAC;IACvB,OAAO,CAAC,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC;IACrC,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC;IAClC,GAAG,EAAE,KAAK,EAAE,CACV,IAAI,UAAU,gBAAgB,SAAS;oBACvB,aAAa;gBACjB,OAAO,CAAC,SAAS;qBACZ,OAAO,CAAC,cAAc;aAC9B,MAAM;kBACD,WAAW;qBACR,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC;YACvC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC;SAChC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAClC,CAAC;IAEF,IAAI,WAAW,KAAK,UAAU,EAAE,CAAC;QAC/B,GAAG,EAAE,IAAI,EAAE,CAAC,GAAG,UAAU,eAAe,SAAS,wBAAwB,CAAC,CAAC;QAC3E,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,GAAG,EAAE,IAAI,EAAE,CAAC,IAAI,UAAU,gBAAgB,SAAS,4CAA4C,CAAC,CAAC;QACjG,OAAO,KAAK,CAAC;IACf,CAAC;IAGD,CAAC;QACC,sBAAsB;QACtB,MAAM,EAAC,MAAM,EAAE,KAAK,EAAC,GAAG,OAAO,CAAC;QAChC,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,IAAI,mBAAmB,CAAA;YACnC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,OAAO,CAAC,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC;YAC/B,CAAC;QACH,CAAC;QACD,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,CAAC,IAAI,IAAI,mBAAmB,CAAA;YACnC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,OAAO,CAAC,IAAI,IAAI,QAAQ,IAAI,EAAE,IAAI,MAAM,IAAI,EAAE,GAAG,KAAK,CAAC;YACzD,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;QAC7C,GAAG,EAAE,IAAI,EAAE,CAAC,IAAI,UAAU,gBAAgB,SAAS,uDAAuD,MAAM,OAAO,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACvI,MAAM,qBAAqB,CAAC,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,cAAc,EAAE,aAAa,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;QACnI,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAG,qBAAqB,CAAC,cAAc,CAAC,SAAS,GAAG,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1E,QAAQ;QACR,kBAAkB;QAClB,IAAG,OAAO,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO,CAAC,IAAI,IAAI,mCAAmC,OAAO,CAAC,OAAO,yBAAyB,CAAC;QAC9F,CAAC;QACD,KAAK;QACL,MAAM,aAAa,GAAG,MAAM,sBAAsB,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;QAC/E,IAAG,aAAa,EAAE,CAAC;YACjB,OAAO,CAAC,IAAI,IAAI,8BAA8B,CAAC;YAC/C,OAAO,CAAC,IAAI,IAAI,OAAO,GAAG,aAAa,GAAG,OAAO,CAAC;QACpD,CAAC;QAED,KAAK;QACL,MAAM,OAAO,GAAG,MAAM,sBAAsB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC/D,IAAG,OAAO,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,IAAI,oGAAoG,CAAC;YACrH,OAAO,CAAC,IAAI,IAAI,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,0DAA0D;IAC1D,IAAG,MAAM,cAAc,CAAC,aAAa,EAAE,UAAU,EAAE,OAAO,CAAC,EAAC,CAAC;QAC3D,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,EAAG,CAAC;QAC/F,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACnB,sDAAsD;YACtD,eAAe;YACf,GAAG,EAAE,IAAI,EAAE,CAAC,IAAI,UAAU,gBAAgB,SAAS,qCAAqC,CAAC,CAAC;YAC1F,OAAO,KAAK,CAAC;QACf,CAAC;QAED,4BAA4B;QAC5B,IAAI,MAAM,wBAAwB,CAAC,aAAa,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC;YACxF,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,mBAAmB,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC;YAC3C,GAAG,EAAE,IAAI,EAAE,CAAC,IAAI,UAAU,gBAAgB,SAAS,6CAA6C,MAAM,EAAE,CAAC,CAAC;YAC1G,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,MAAM,GAAC,0BAA0B,SAAS;;;+CAGL,OAAO;+CACP,UAAU;uCAClB,OAAO,CAAC,aAAa,gBAAgB,CAAA;QAExE,MAAM,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,0BAA0B,CAAC,CAAC;QACzF,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,qBAAqB,GAA6B;IACtD,WAAW,EAAE,iBAAiB;IAC9B,UAAU,EAAE,gBAAgB;IAC5B,iBAAiB,EAAE,gBAAgB;IACnC,sCAAsC;CAC9B,CAAC;AAEX;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAyB;IAClG,+BAA+B;IAC/B,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IAChD,IAAI,SAAS,IAAI,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC,KAAK,KAAK,EAAE,CAAC;QACxE,GAAG,EAAE,IAAI,EAAE,CAAC,IAAI,UAAU,iBAAiB,CAAC,CAAC;QAC7C,OAAO;IACT,CAAC;IAED,iBAAiB;IACjB,MAAM,GAAG,GAAG,IAAI,CAAC,IAA4B,CAAC;IAC9C,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC;IACzB,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;IACxB,MAAM,OAAO,GAAgB;QAC3B,QAAQ,EAAM,gBAAgB;QAC9B,MAAM,EAAQ,SAAS;QACvB,OAAO,EAAO,IAAI,CAAC,MAAM,CAAC,wBAAwB,CAAC;QACnD,IAAI,EAAU,SAAS;QACvB,SAAS,EAAK,SAAS;QACvB,YAAY,EAAE,SAAS;QACvB,WAAW,EAAG,SAAS;QACvB,SAAS,EAAK,YAAY,CAAC,OAAO,CAAC;QACnC,SAAS,EAAK,GAAG,EAAE,KAAK,IAAI,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;QAC9D,aAAa,EAAE,GAAG,CAAC,YAAY,IAAI,EAAE;QACrC,SAAS,EAAM,GAAG,CAAC,GAAG,IAAI,EAAE;QAC5B,cAAc,EAAE,GAAG,CAAC,SAAS,IAAI,EAAE;QACnC,SAAS,EAAM,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,CAAC,GAAC,IAAI,CAAC,CAAC,CAAC,SAAS;KAC5E,CAAC;IACF,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;IAChC,sBAAsB;IACtB,MAAM,wBAAwB,GAAG,qBAAqB,CAAC,OAAO,CAAyB,CAAC;IACxF,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAC9B,GAAG,EAAE,IAAI,EAAE,CAAC,IAAI,UAAU,0BAA0B,OAAO,EAAE,CAAC,CAAC;QAC/D,OAAO;IACT,CAAC;IACD,IAAI,CAAC,CAAC,MAAM,wBAAwB,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;QAAE,OAAO;IAE1F,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACtC,GAAG,EAAE,IAAI,EAAE,CAAC,IAAI,UAAU,mDAAmD,EAAE,OAAO,CAAC,CAAC;QACxF,OAAO;IACT,CAAC;IAED,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;QAC1B,iBAAiB;QACjB,IAAG,CAAC;YACF,MAAM,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC5F,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,YAAY;QACd,CAAC;IACH,CAAC;IAED,OAAO;IACP,MAAM,eAAe,GAAG,OAAO,CAAC,aAAa,IAAI,OAAO,CAAC,SAAS,IAAI,SAAS,CAAC;IAEhF,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;IACjD,MAAM,UAAU,GAAG,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IACpE,GAAG,EAAE,IAAI,EAAE,CAAC,IAAI,UAAU,gBAAgB,SAAS,kCAAkC,UAAU,eAAe,OAAO,CAAC,QAAQ,YAAY,OAAO,CAAC,MAAM,sBAAsB,eAAe,EAAE,CAAC,CAAC;IAEjM,IAAI,SAAS,GAAG,OAAO,CAAC,IAAI,IAAI,GAAG,CAAC;IACpC,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACxE,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,SAAS,GAAG,QAAQ,CAAC;QACvB,CAAC;IACH,CAAC;IAED,IAAG,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9D,qBAAqB;QACrB,uBAAuB,CAAC,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,CAAC;IAED,sBAAsB;IACtB,uCAAuC;IACvC,kCAAkC;IAClC,MAAM,GAAG,GAAQ;QACf,IAAI,EAAgB,SAAS;QAC7B,IAAI,EAAgB,MAAM,CAAC,eAAe,CAAC;QAC3C,EAAE,EAAkB,UAAU;QAC9B,SAAS,EAAW,UAAU;QAC9B,UAAU,EAAU,UAAU;QAC9B,SAAS,EAAW,SAAS;QAC7B,kBAAkB,EAAE,UAAU;QAC9B,aAAa,EAAO,OAAO,CAAC,MAAM;QAClC,QAAQ,EAAY,OAAO,CAAC,QAAS;QACrC,OAAO,EAAa,UAAU;QAC9B,QAAQ,EAAY,UAAU;QAC9B,UAAU,EAAU,OAAO,CAAC,cAAc;QAC1C,QAAQ,EAAY,OAAO,CAAC,aAAa;QACzC,cAAc,EAAM,OAAO,CAAC,aAAa;QACzC,WAAW,EAAS,OAAO,CAAC,aAAa;QACzC,SAAS,EAAW,OAAO,CAAC,SAAS;QACrC,iBAAiB,EAAG,IAAI,EAAG,gBAAgB;KAC5C,CAAC;IACF,IAAI,OAAO,CAAC,QAAQ,IAAI,eAAe,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QAC1D,GAAG,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;QACxC,GAAG,CAAC,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC;QACrC,GAAG,CAAC,OAAO,GAAQ,OAAO,CAAC,MAAM,CAAC;QAClC,GAAG,CAAC,cAAc,GAAG,uBAAuB,CAAC,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1E,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,IAAI,iBAAiB,EAAE,CAAC;QAC1C,GAAG,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;QACxC,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC;QACnB,GAAG,CAAC,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;QACvC,GAAG,CAAC,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;QAClC,GAAG,CAAC,cAAc,GAAG,uBAAuB,CAAC,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1E,CAAC;IACD,IAAI,OAAO,CAAC,SAAS,EAAE,MAAM;QAAG,GAAG,CAAC,SAAS,GAAI,OAAO,CAAC,SAAS,CAAC;IACnE,IAAI,OAAO,CAAC,SAAS;QAAW,GAAG,CAAC,SAAS,GAAI,OAAO,CAAC,SAAS,CAAC;IAEnE,GAAG,EAAE,IAAI,EAAE,CAAC,IAAI,UAAU,gBAAgB,SAAS,6CAA6C,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;IACnI,IAAI,CAAC;QACH,MAAM,aAAa,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;IACnE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,EAAE,KAAK,EAAE,CAAC,IAAI,UAAU,gBAAgB,SAAS,yBAAyB,EAAE,GAAG,CAAC,CAAC;IACtF,CAAC;AACH,CAAC","sourcesContent":["/**\n * TuiTui inbound message handler — pure business logic.\n *\n * channel.ts owns the WebSocket frame layer (JSON parse, ACK, keepalive\n * filtering) and calls handleInboundMessage with an already-parsed object.\n *\n * Usage:\n * ws.on('message', async (wsData) => {\n * // ... parse JSON, send ACK, filter keepalive ...\n * await handleInboundMessage(json, { account, accountId, apiRuntime, log });\n * });\n */\nimport type { TuiTuiInboundMessage, TuiTuiOutboundDeliverOptions } from './types';\nimport { CHANNEL_ID } from './const';\nimport {CHAT_TYPE_DIRECT,CHAT_TYPE_GROUP,CHAT_TYPE_CHANNEL,ChatType,teamsParseChatId,teamsBuildChatId} from \"./chat_base\"\nimport {tuituiEmojiReaction, sendTextMsg, sendPageMsg, sendMediaMsg } from \"./outbound\";\nimport { teams_get_members, teams_get_members_text, teams_get_announcement } from \"./teams_api\"\nimport { parseChatMessageBody } from './inbound_body_parse';\nimport { parseAllowFroms } from './utils';\nimport { addUnmentionedHistory, popUnmentionedHistories } from \"./histories\";\nimport { StringDeduplicator } from \"./deduplicator\"\nimport { getPostChainByChatId } from \"./chat_record\"\n\n// 会话上下文注入排重\nlet _session_ctx_injected = new StringDeduplicator(1000, 3600);\n\n/** 子函数共享的可变上下文,子函数直接修改字段,外层读取结果 */\ninterface ChatPayload {\n chatType: ChatType;\n chatId: string | undefined;\n botName: string;\n text: string | undefined;\n groupName: string | undefined;\n channelName: string | undefined;\n mediaUrls: string[] | undefined;\n replyToId: string | undefined; // 引用ID\n msgId?: string; // 消息ID\n tuituiAccount: string;\n tuituiUid: string | undefined;\n tuituiUserName: string | undefined;\n timestamp: Number | undefined;\n WasMentioned: boolean | undefined;\n}\n\nexport interface InboundAccount {\n accountId: string;\n appId: string;\n appSecret: string;\n dmPolicy: string;\n allowFrom: string[];\n groupPolicy: string;\n groupAllowFrom: string[];\n requireMention: boolean;\n emojiReaction: boolean;\n}\nexport interface InboundHandlerOptions {\n json: any\n account: InboundAccount;\n apiRuntime: any;\n log: any;\n}\n\nfunction getSessionKey(cfg: any, payload: ChatPayload, account: InboundAccount, apiRuntime: any): string {\n const { chatId, chatType } = payload;\n const { accountId } = account;\n // 你自己只需要拼接与定义 peer.id\n // 关于 sessionKey 格式的解释: https://docs.openclaw.ai/channels/channel-routing#sessionkey-%E5%8F%82%E8%80%83%E6%A0%BC%E5%BC%8F\n let id = chatId;\n if(chatType == CHAT_TYPE_CHANNEL) {\n const { channel_id, parent_id } = teamsParseChatId(chatId!);\n id = `${channel_id}`;\n if(parent_id) {\n id += `:thread:${parent_id}`;\n }\n }\n\n // sessionKey 不能自己拼字符串,需要用系统api识别,他会根据 bindings 路由规则处理\n const { sessionKey } = apiRuntime.channel.routing.resolveAgentRoute({\n cfg,\n accountId,\n channel: CHANNEL_ID,\n peer: { kind: chatType, id: id },\n });\n return String(sessionKey).replace(/\\//g, '_');\n}\n\nfunction getMediaUrls({ msg_type, images, voice, video, file }: any): string[] | undefined {\n if (msg_type === 'image' || msg_type === 'mixed') {\n if (images?.length) return images;\n } else if (msg_type === 'voice') {\n if (voice) return [voice];\n } else if (msg_type === 'video') {\n if (video) return [video];\n } else if (msg_type === 'file') {\n if (file?.url) return [file.url];\n }\n return undefined;\n}\n\nasync function dispatchReply(ctx: any, cfg: any, account: InboundAccount, payload: ChatPayload, apiRuntime: any, log: any) {\n const { accountId } = account;\n await apiRuntime.channel.reply.dispatchReplyWithBufferedBlockDispatcher({\n ctx,\n cfg,\n dispatcherOptions: {\n deliver: async (outbound: TuiTuiOutboundDeliverOptions) => {\n // Custom message (e.g. page)\n if (outbound.custom) {\n const { msgtype, page, tousers, togroups } = outbound.custom;\n if (msgtype === 'page' && page) {\n await sendPageMsg(account, payload.chatId, payload.chatType, page, 'tuitui.deliver.page', tousers, togroups);\n return;\n }\n log?.warn?.(`[${CHANNEL_ID}] AccountId: ${accountId}, Unsupported custom message type: ${msgtype}`);\n return;\n }\n\n // Media message\n const mediaUrl = outbound.mediaUrl || outbound.mediaUrls?.[0];\n if (mediaUrl) {\n await sendMediaMsg(account, payload.chatId, payload.chatType, mediaUrl, 'tuitui.deliver.media', [payload.tuituiAccount]);\n return;\n }\n\n // Text message\n const replyText = outbound?.text || outbound?.body;\n if (replyText) {\n // 群消息回复时不再使用 reference_msgid 避免并发时引用错乱,依靠 @ 来提醒用户\n await sendTextMsg(account, payload.chatId, payload.chatType, replyText, 'tuitui.deliver.text', [payload.tuituiAccount]);\n return;\n }\n log?.info?.(`[${CHANNEL_ID}] AccountId: ${accountId}, no_reply_content`);\n },\n\n onReplyStart: () => {\n log?.info?.(`[${CHANNEL_ID}] AccountId: ${accountId}, Agent is typing to ${payload.tuituiAccount}`);\n },\n },\n });\n}\n\n/*** 配对节流映射 - 用于防止短时间内大量重复配对请求消息发出\n * key: `${accountId}-${chatId}`\n * val: timestamp */\nconst pairingThrottleMap = new Map<string, number>();\n// 暂时控制为 2 分钟内同一个用户只能触发一次配对请求\nconst needPairingThrottle = (accountId: string | undefined, chatId: string, throttleMs = 2 * 60 * 1000): boolean => {\n const key = `${accountId}-${chatId}`;\n const now = Date.now();\n const lastTime = pairingThrottleMap.get(key) || 0;\n if (now - lastTime < throttleMs) {\n return true;\n }\n pairingThrottleMap.set(key, now);\n return false;\n}\n\nasync function sendSingleChatPairingMsg(account: any, payload: any, log: any, apiRuntime: any) {\n const { accountId } = account;\n const { chatId, chatType } = payload;\n if (needPairingThrottle(accountId, chatId)) {\n return log?.info?.(`[${CHANNEL_ID}] AccountId: ${accountId}, pairing throttled for sender=${chatId}`);\n }\n try {\n log?.debug?.(`[${CHANNEL_ID}] AccountId: ${accountId}, pairing flow: checking if pairing request exists for sender=${chatId}`);\n const req = await apiRuntime.channel.pairing.upsertPairingRequest({ channel: CHANNEL_ID, accountId, id: chatId });\n log?.debug?.(`[${CHANNEL_ID}] AccountId: ${accountId}, pairing flow: upsertPairingRequest result=${JSON.stringify(req)}`);\n // 只要没配对,会每次和机器人聊,都会返回配对信息。\n const replyText = apiRuntime.channel.pairing.buildPairingReply({ channel: CHANNEL_ID, code: req.code });\n await sendTextMsg(account, chatId, chatType, replyText, 'tuitui.pairing.reply');\n } catch (err) {\n log?.warn?.(`[${CHANNEL_ID}] AccountId: ${accountId}, pairing failed for ${chatId}: ${String(err)}`);\n }\n}\n\n//tuituiAccounts列表中是否存在至少1个允许私聊的用户(私聊白名单、配对、或者open)\nasync function isAllowOneOfAccount(tuituiAccounts: string[], apiRuntime: any, account: InboundAccount) {\n if(!tuituiAccounts) return false;\n const { accountId, allowFrom, dmPolicy } = account;\n if (dmPolicy === 'open') return true;\n\n // 是否包含任意一个元素\n if (tuituiAccounts.some(item => allowFrom.includes(item))) return true;\n\n try {\n let storeAllowFrom = parseAllowFroms(\n await apiRuntime?.channel?.pairing?.readAllowFromStore?.({ channel: CHANNEL_ID, accountId })\n );\n if (tuituiAccounts.some(item => storeAllowFrom.includes(item))) return true;\n } catch {}\n return false; \n}\n\nasync function isAllowAccount(tuituiAccount: string, apiRuntime: any, account: InboundAccount) {\n return await isAllowOneOfAccount([tuituiAccount], apiRuntime, account);\n}\n\nasync function isChannelCoordAuthorized(tuituiAccount: string, apiRuntime: any, account: InboundAccount, team_id:string, chat_id:string) {\n // 协调员身份校验\n if (tuituiAccount != \"bot-FiwwCeDw\" && tuituiAccount != \"bot-sUwUeknd\") return false;\n\n // 当前 thread 中有白名单用户发帖,则协调员继承该权限\n const [members, posts] = await Promise.all([\n teams_get_members(account, team_id),\n getPostChainByChatId(account, chat_id),\n ]);\n if (!members?.length || !posts?.length) return false;\n\n const from_uids = posts.map((p: any) => p.from_uid).filter(Boolean);\n if (!from_uids.length) return false;\n\n //console.log(\"from_uids\", from_uids);\n\n // 将 uid 映射到 user_account\n const from_accounts: string[] = members\n .filter((m: any) => from_uids.includes(m.uid) && m.account)\n .map((m: any) => String(m.account));\n if (!from_accounts.length) return false;\n\n //console.log(\"from_accounts\", from_accounts);\n return await isAllowOneOfAccount(from_accounts, apiRuntime, account);\n}\n\n\n/**\n * 处理单聊(single_chat)、群聊、团队帖子分支,直接修改并校验 payload。\n * 返回 false 表示消息不合法,外层应提前 return;返回 true 表示校验通过,继续执行。\n */\nasync function parse_single_chat(payload: ChatPayload, msgData: any, account: InboundAccount, apiRuntime: any, log: any): Promise<boolean> {\n const { accountId, dmPolicy, allowFrom } = account;\n const chatId = payload.tuituiAccount ? String(payload.tuituiAccount || '').toLowerCase().trim() : '';\n if (dmPolicy === 'disabled') { //['pairing', 'allowlist', 'open', 'disabled'],\n log?.warn?.(`[${CHANNEL_ID}] AccountId: ${accountId}, DM disabled sender=${chatId}`);\n return false;\n }\n\n payload.chatType = CHAT_TYPE_DIRECT;\n payload.chatId = chatId;\n payload.text = parseChatMessageBody(msgData);\n payload.msgId = msgData.msgid;\n log?.debug?.(\n `[${CHANNEL_ID}] AccountId: ${accountId}, inbound single_chat:\n userAccount=${chatId},\n tuituiUid=${payload.tuituiUid},\n tuituiUserName=${payload.tuituiUserName},\n dmPolicy=${dmPolicy},\n allowFrom=${JSON.stringify(allowFrom)}`);\n\n if (!chatId && !payload.tuituiUid) {\n log?.info?.(`[${CHANNEL_ID}] AccountId: ${accountId}, Missing user_account or uid in single_chat event`);\n return false;\n }\n\n if (dmPolicy === 'open') return true;\n\n if(await isAllowAccount(chatId, apiRuntime, account)){\n return true;\n }\n\n if (dmPolicy === 'pairing') {\n sendSingleChatPairingMsg(account, payload, log, apiRuntime);\n log?.info?.(`[${CHANNEL_ID}] AccountId: ${accountId}, pairing required`);\n return false;\n }\n // allowlist\n log?.warn?.(`[${CHANNEL_ID}] AccountId: ${accountId}, Blocked unauthorized sender (allowlist): sender=${chatId} allowFrom=${JSON.stringify(allowFrom)}`);\n return false;\n}\n\nasync function parse_group_chat(payload: ChatPayload, msgData: any, account: InboundAccount, apiRuntime: any, log: any): Promise<boolean> {\n const { accountId, groupPolicy, groupAllowFrom } = account;\n payload.chatType = CHAT_TYPE_GROUP;\n const chatId = msgData.group_id ? String(msgData.group_id).toLowerCase().trim() : '';\n payload.chatId = chatId;\n payload.groupName = msgData.group_name;\n payload.msgId = msgData.msgid;\n payload.text = parseChatMessageBody(msgData);\n payload.WasMentioned = msgData.at_me;\n const { tuituiAccount } = payload;\n log?.debug?.(\n `[${CHANNEL_ID}] AccountId: ${accountId}, inbound group_chat:\n tuituiAccount=${tuituiAccount},\n tuituiUid=${payload.tuituiUid},\n tuituiUserName=${payload.tuituiUserName},\n groupId=${chatId},\n groupPolicy=${groupPolicy},\n groupAllowFrom=${JSON.stringify(groupAllowFrom)},\n at_me=${JSON.stringify(msgData.at_me)},\n at=${JSON.stringify(msgData.at)}`);\n\n if (groupPolicy === 'disabled') {\n log?.info?.(`${CHANNEL_ID} AccountId: ${accountId}, groupPolicy disabled`);\n return false;\n }\n\n if (!tuituiAccount || !chatId) {\n log?.info?.(`[${CHANNEL_ID}] AccountId: ${accountId}, Missing tuituiAccount or chatId in group_chat event`);\n return false;\n }\n\n if (!msgData.at_me && account.requireMention) {\n log?.info?.(`[${CHANNEL_ID}] AccountId: ${accountId}, ignore group message (not mentioned), add to history key: ${chatId}`);\n await addUnmentionedHistory(apiRuntime, accountId, chatId, payload.tuituiUserName, tuituiAccount, payload.text, payload.timestamp);\n return false;\n }\n\n // 私聊白名单对群聊仍然生效,当群里只想特定人@时,可以不配置groupAllowFrom,而是配置 allowFrom\n if(await isAllowAccount(tuituiAccount, apiRuntime, account)){\n return true;\n }\n\n if (!groupAllowFrom.includes(chatId)) {\n if (needPairingThrottle(accountId, chatId)) {\n log?.info?.(`[${CHANNEL_ID}] AccountId: ${accountId}, group pairing throttled for groupId=${chatId}`);\n return false;\n }\n\n const msgTxt=`当前 OpenClaw(AccountId: ${accountId})的群聊策略为白名单模式。\n需由龙虾主人在配置中添加白名单(两种方式二选一即可):\n\n- 允许群中所有人用,在群白名单(Group Allow From)添加当前群ID: ${chatId}\n\n- 不想群所有人用,只想特定人用,在私聊白名单(Allow From)添加当前用户 ${payload.tuituiAccount} ,私聊白名单对群仍然有效`\n\n await sendTextMsg(account, chatId, payload.chatType, msgTxt, 'tuitui.groupPolicy.reply');\n return false;\n }\n\n return true; \n}\n\n\nasync function parse_teams_post(payload: ChatPayload, msgData: any, account: InboundAccount, apiRuntime: any, log: any): Promise<boolean> {\n const { accountId, groupPolicy, groupAllowFrom } = account;\n payload.chatType = CHAT_TYPE_CHANNEL;\n const { team_id, channel_id, parent_id, post_id, content, team_name, channel_name } = msgData;\n const thread_id = (parent_id && parent_id != \"0\")?parent_id: post_id;\n const chatId = teamsBuildChatId(team_id, channel_id, thread_id);\n payload.chatId = chatId;\n payload.msgId = post_id;\n payload.text = content;\n payload.channelName = channel_name;\n payload.replyToId = \"\";\n payload.WasMentioned = msgData.at_me;\n const { tuituiAccount } = payload;\n log?.debug?.(\n `[${CHANNEL_ID}] AccountId: ${accountId}, inbound teams:\n tuituiAccount=${tuituiAccount},\n tuituiUid=${payload.tuituiUid},\n tuituiUserName=${payload.tuituiUserName},\n chatId=${chatId},\n groupPolicy=${groupPolicy},\n groupAllowFrom=${JSON.stringify(groupAllowFrom)},\n at_me=${JSON.stringify(msgData.at_me)},\n at=${JSON.stringify(msgData.at)}`,\n );\n\n if (groupPolicy === 'disabled') {\n log?.info?.(`${CHANNEL_ID} AccountId: ${accountId}, groupPolicy disabled`);\n return false;\n }\n\n if (!tuituiAccount) {\n log?.info?.(`[${CHANNEL_ID}] AccountId: ${accountId}, Missing tuituiAccount or chatId in event`);\n return false;\n }\n\n \n {\n // 频道帖子文件、附件处理。必须放在正文里\n const {images, files} = msgData;\n if (images) {\n payload.text += \"\\n\\n附录上文提到的图片列表\\n\"\n for (const image of images) {\n payload.text += image + \"\\n\";\n }\n }\n if (files) {\n payload.text += \"\\n\\n附录上文提到的文件列表\\n\"\n for (const file of files) {\n payload.text += `[文件] ${file?.name} : ${file?.url} \\n`;\n }\n }\n }\n\n if (!msgData.at_me && account.requireMention) {\n log?.info?.(`[${CHANNEL_ID}] AccountId: ${accountId}, ignore teams post (not mentioned), add to history ${chatId} -> ${payload.text}`);\n await addUnmentionedHistory(apiRuntime, accountId, chatId, payload.tuituiUserName, tuituiAccount, payload.text, payload.timestamp);\n return false;\n }\n\n if(_session_ctx_injected.checkAndRecord(accountId + \"_\" + payload.chatId)) {\n // 注入上下文\n // 解决机器人不知道自己是谁的问题\n if(payload.botName) {\n payload.text += `\\n\\n*** 参考信息: 你在当前session中的名字叫: ${payload.botName} 如果有人@这个名字,就是在命令你 ***\\n`;\n }\n // 公告\n const annnouncement = await teams_get_announcement(account, channel_id, false);\n if(annnouncement) {\n payload.text += \"\\n\\n*** 参考信息: 当前公告内容如下 ***\\n\";\n payload.text += \"```\\n\" + annnouncement + \"\\n```\";\n }\n\n // 成员\n const members = await teams_get_members_text(account, team_id);\n if(members) {\n payload.text += \"\\n\\n*** 参考信息: 当前团队成员清单如下,每行一个成员名。如果需要询问成员、或者发送给成员时,需要用 @名字 的语法;并且@时必须从如下清单中匹配到最接近的,禁止@不存在的成员 ***\\n\";\n payload.text += \"```\\n\" + members + \"\\n```\";\n }\n }\n\n // 私聊白名单对团队仍然生效,限制特定人@时,可以不配置groupAllowFrom,而是配置 allowFrom\n if(await isAllowAccount(tuituiAccount, apiRuntime, account)){\n return true;\n }\n \n if (!groupAllowFrom.includes(String(team_id)) && !groupAllowFrom.includes(String(channel_id)) ) {\n if (!msgData.at_me) {\n // 解决这个case:requireMention=false时,团队里发任意帖子都会回复加白,搞得没法用\n // 要求必须@才触发回复加白\n log?.info?.(`[${CHANNEL_ID}] AccountId: ${accountId}, ignore teams post (not mentioned)`);\n return false;\n }\n\n // 频道中允许协调员@自己(且帖子里有白名单用户发帖)\n if (await isChannelCoordAuthorized(tuituiAccount, apiRuntime, account, team_id, chatId)) {\n return true;\n }\n\n if (needPairingThrottle(accountId, chatId)) {\n log?.info?.(`[${CHANNEL_ID}] AccountId: ${accountId}, teams pairing throttled for teamsChatId=${chatId}`);\n return false;\n }\n\n const msgTxt=`当前 OpenClaw(AccountId: ${accountId})的群聊/团队策略为白名单模式。\n需由龙虾主人在配置中添加白名单(3种方式选一种即可):\n\n- 允许团队中所有人用,在群白名单(Group Allow From)添加当前团队ID: ${team_id}\n- 仅允许当前频道使用,在群白名单(Group Allow From)添加当前频道ID: ${channel_id}\n- 仅允许特定人使用,在私聊白名单(Allow From)添加当前用户: ${payload.tuituiAccount} ,私聊白名单对团队仍然有效`\n\n await sendTextMsg(account, chatId, payload.chatType, msgTxt, 'tuitui.groupPolicy.reply');\n return false;\n }\n\n return true;\n}\n\nconst parseAndVerifyPayload: Record<string, Function> = {\n single_chat: parse_single_chat,\n group_chat: parse_group_chat,\n teams_post_create: parse_teams_post,\n //teams_post_modify: parse_teams_post,\n} as const;\n\n/**\n * 处理长链接消息\n * account: 长连接初始化时,对应的Account配置信息\n * accountId: 长连接启动初始化,对应的配置ID\n */\nexport async function handleInboundMessage({ json, account, apiRuntime, log }: InboundHandlerOptions) {\n // Signature / AppId validation\n const { accountId, appId, appSecret } = account;\n if (appSecret && appId && json.header['X-Tuitui-Robot-Appid'] !== appId) {\n log?.info?.(`[${CHANNEL_ID}] Invalid appId`);\n return;\n }\n\n // Decode message\n const msg = json.body as TuiTuiInboundMessage;\n const msgData = msg.data;\n const { ref } = msgData;\n const payload: ChatPayload = {\n chatType: CHAT_TYPE_DIRECT,\n chatId: undefined, \n botName: json.header['X-Tuitui-Robot-AppName'],\n text: undefined,\n groupName: undefined,\n WasMentioned: undefined,\n channelName: undefined,\n mediaUrls: getMediaUrls(msgData),\n replyToId: ref?.is_me && ref?.msgid ? ref.msgid : undefined,\n tuituiAccount: msg.user_account || \"\",\n tuituiUid: msg.uid || \"\",\n tuituiUserName: msg.user_name || \"\",\n timestamp: msg.timestamp ? parseInt(msg.timestamp, 10)*1000 : undefined\n };\n const wsEvent = json.body.event;\n // 按event类型,标准化并校验基础数据\n const parseAndVerifyPayloadFun = parseAndVerifyPayload[wsEvent] as Function | undefined;\n if (!parseAndVerifyPayloadFun) {\n log?.info?.(`[${CHANNEL_ID}] ignore unknown event ${wsEvent}`);\n return;\n }\n if (!(await parseAndVerifyPayloadFun(payload, msgData, account, apiRuntime, log))) return;\n\n if (!payload.chatId || !payload.msgId) {\n log?.info?.(`[${CHANNEL_ID}] ignore unknown mseeage, missing chatId or msgId`, payload);\n return;\n }\n\n if (account.emojiReaction) {\n // 因为回复较慢,先回复一个表情\n try{\n await tuituiEmojiReaction(account, payload.chatId, payload.chatType, payload.msgId, '收到');\n } catch (err) {\n // 出错不影响后续逻辑\n }\n }\n\n // 路由判断\n const routeSenderFrom = payload.tuituiAccount || payload.tuituiUid || 'unknown';\n\n const cfg = await apiRuntime.config.loadConfig();\n const sessionKey = getSessionKey(cfg, payload, account, apiRuntime);\n log?.info?.(`[${CHANNEL_ID}] AccountId: ${accountId}, dispatching to agent session=${sessionKey}, chatType: ${payload.chatType}, chatId ${payload.chatId}, routeSenderFrom: ${routeSenderFrom}`);\n\n let finalBody = payload.text || ' ';\n if (payload.text && payload.botName) {\n const stripped = payload.text.replace(`@${payload.botName}`, '').trim();\n if (stripped.startsWith('/')) {\n finalBody = stripped;\n }\n }\n\n if(finalBody.startsWith(\"/new\") || finalBody.endsWith(\"/new\")) {\n // 清理agent上下文时,同时清空历史\n popUnmentionedHistories(accountId, payload.chatId);\n }\n\n // 字段意义 参考 openclaw 代码\n // src\\auto-reply\\reply\\inbound-meta.ts\n // buildInboundUserContextPrefix()\n const ctx: any = {\n Body: finalBody,\n From: String(routeSenderFrom),\n To: CHANNEL_ID,\n SessionId: sessionKey,\n SessionKey: sessionKey,\n AccountId: accountId,\n OriginatingChannel: CHANNEL_ID,\n OriginatingTo: payload.chatId,\n ChatType: payload.chatType!,\n Surface: CHANNEL_ID,\n Provider: CHANNEL_ID,\n SenderName: payload.tuituiUserName,\n SenderId: payload.tuituiAccount,\n SenderUsername: payload.tuituiAccount, \n UserAccount: payload.tuituiAccount,\n Timestamp: payload.timestamp,\n CommandAuthorized: true, // 允许 /new 等内置命令\n };\n if (payload.chatType == CHAT_TYPE_GROUP && payload.chatId) {\n ctx.WasMentioned = payload.WasMentioned;\n ctx.GroupSubject = payload.groupName;\n ctx.GroupId = payload.chatId;\n ctx.InboundHistory = popUnmentionedHistories(accountId, payload.chatId);\n }\n if (payload.chatType == CHAT_TYPE_CHANNEL) {\n ctx.WasMentioned = payload.WasMentioned;\n ctx.IsForum = true;\n ctx.GroupSubject = payload.channelName;\n ctx.GroupChannel = payload.chatId;\n ctx.InboundHistory = popUnmentionedHistories(accountId, payload.chatId);\n }\n if (payload.mediaUrls?.length) ctx.MediaUrls = payload.mediaUrls;\n if (payload.replyToId) ctx.ReplyToId = payload.replyToId;\n\n log?.info?.(`[${CHANNEL_ID}] AccountId: ${accountId}, handleInboundMessage dispatchReply ctx: ${JSON.stringify(ctx, null, ' ')}`);\n try {\n await dispatchReply(ctx, cfg, account, payload, apiRuntime, log);\n } catch (err) {\n log?.error?.(`[${CHANNEL_ID}] AccountId: ${accountId}, dispatchReply failed:`, err);\n }\n}\n"]}
|
package/dist/src/tools.js
CHANGED
|
@@ -26,7 +26,7 @@ const tuitui_im_get_messages_factory = (ctx) => {
|
|
|
26
26
|
}),
|
|
27
27
|
execute: async (_toolCallId, params) => {
|
|
28
28
|
console.log(`tuitui_im_get_messages(): agentAccountId: ${ctx.agentAccountId}, sessionKey: ${ctx.sessionKey}`, params);
|
|
29
|
-
const account = resolveAccount(ctx.config, ctx.agentAccountId);
|
|
29
|
+
const account = resolveAccount(ctx.config, ctx.agentAccountId, ctx.agentId);
|
|
30
30
|
if (!account || !account.enabled || !account.appId || !account.appSecret) {
|
|
31
31
|
return tool_errmsg(`invalid tuitui account ${ctx.agentAccountId}`);
|
|
32
32
|
}
|
|
@@ -63,7 +63,7 @@ const tuitui_send_channel_post_factory = (ctx) => {
|
|
|
63
63
|
}),
|
|
64
64
|
execute: async (_toolCallId, params) => {
|
|
65
65
|
console.log(`tuitui_send_channel_post(): agentAccountId: ${ctx.agentAccountId}, sessionKey: ${ctx.sessionKey}`, params);
|
|
66
|
-
const account = resolveAccount(ctx.config, ctx.agentAccountId);
|
|
66
|
+
const account = resolveAccount(ctx.config, ctx.agentAccountId, ctx.agentId);
|
|
67
67
|
if (!account || !account.enabled || !account.appId || !account.appSecret) {
|
|
68
68
|
return tool_errmsg(`invalid tuitui account ${ctx.agentAccountId}`);
|
|
69
69
|
}
|
|
@@ -95,7 +95,7 @@ const tuitui_get_announcement_factory = (ctx) => {
|
|
|
95
95
|
}),
|
|
96
96
|
execute: async (_toolCallId, params) => {
|
|
97
97
|
console.log(`tuitui_get_announcement(): agentAccountId: ${ctx.agentAccountId}, sessionKey: ${ctx.sessionKey}`);
|
|
98
|
-
const account = resolveAccount(ctx.config, ctx.agentAccountId);
|
|
98
|
+
const account = resolveAccount(ctx.config, ctx.agentAccountId, ctx.agentId);
|
|
99
99
|
if (!account || !account.enabled || !account.appId || !account.appSecret) {
|
|
100
100
|
return tool_errmsg(`invalid tuitui account ${ctx.agentAccountId}`);
|
|
101
101
|
}
|
|
@@ -114,7 +114,7 @@ const tuitui_file_space_list_factory = (ctx) => {
|
|
|
114
114
|
}),
|
|
115
115
|
execute: async (_toolCallId, params) => {
|
|
116
116
|
console.log(`tuitui_file_space_list(): agentAccountId: ${ctx.agentAccountId}, sessionKey: ${ctx.sessionKey}`);
|
|
117
|
-
const account = resolveAccount(ctx.config, ctx.agentAccountId);
|
|
117
|
+
const account = resolveAccount(ctx.config, ctx.agentAccountId, ctx.agentId);
|
|
118
118
|
if (!account || !account.enabled || !account.appId || !account.appSecret) {
|
|
119
119
|
return tool_errmsg(`invalid tuitui account ${ctx.agentAccountId}`);
|
|
120
120
|
}
|
|
@@ -133,7 +133,7 @@ const tuitui_file_space_add_factory = (ctx) => {
|
|
|
133
133
|
}),
|
|
134
134
|
execute: async (_toolCallId, params) => {
|
|
135
135
|
console.log(`tuitui_file_space_add(): agentAccountId: ${ctx.agentAccountId}, sessionKey: ${ctx.sessionKey}`, params);
|
|
136
|
-
const account = resolveAccount(ctx.config, ctx.agentAccountId);
|
|
136
|
+
const account = resolveAccount(ctx.config, ctx.agentAccountId, ctx.agentId);
|
|
137
137
|
if (!account || !account.enabled || !account.appId || !account.appSecret) {
|
|
138
138
|
return tool_errmsg(`invalid tuitui account ${ctx.agentAccountId}`);
|
|
139
139
|
}
|
|
@@ -153,7 +153,7 @@ const tuitui_im_send_message_factory = (ctx) => {
|
|
|
153
153
|
}),
|
|
154
154
|
execute: async (_toolCallId, params) => {
|
|
155
155
|
console.log(`tuitui_im_send_message(): agentAccountId: ${ctx.agentAccountId}, sessionKey: ${ctx.sessionKey}`, params);
|
|
156
|
-
const account = resolveAccount(ctx.config, ctx.agentAccountId);
|
|
156
|
+
const account = resolveAccount(ctx.config, ctx.agentAccountId, ctx.agentId);
|
|
157
157
|
if (!account || !account.enabled || !account.appId || !account.appSecret) {
|
|
158
158
|
return tool_errmsg(`invalid tuitui account ${ctx.agentAccountId}`);
|
|
159
159
|
}
|
package/dist/src/tools.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/tools.ts"],"names":[],"mappings":"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","sourcesContent":["import type { OpenClawPluginApi } from \"openclaw/plugin-sdk/core\";\nimport type { OpenClawPluginToolContext } from \"openclaw/plugin-sdk/core\";\nimport { resolveAccount } from \"./accounts\"\nimport { Type } from \"@sinclair/typebox\";\nimport { CHANNEL_ID } from './const';\nimport {sendTextMsg} from \"./outbound\"\nimport { teams_get_announcement } from \"./teams_api\"\nimport {CHAT_TYPE_DIRECT,CHAT_TYPE_GROUP,CHAT_TYPE_CHANNEL,guessChatType, teamsBuildChatId} from \"./chat_base\"\nimport {getChatRecord, getChannelInfoById} from \"./chat_record\"\nimport {file_space_list, file_space_add} from \"./filespace\"\n \nfunction tool_errmsg(str:string) {\n throw new Error(str);\n}\n\nconst tuitui_im_get_messages_factory = (ctx: OpenClawPluginToolContext) => {\n return {\n name: \"tuitui_im_get_messages\",\n label: \"tuitui_im_get_messages\",\n description: \"推推(tuitui) 聊天记录获取,可查询私聊、群聊、频道的聊天记录\\n\\n\",\n parameters: Type.Object({\n chatId: Type.String({ description: \"聊天ID,单聊指tuitui用户的account,群聊是群ID,频道指频道ID\" }),\n chatType: Type.String({ description: `聊天类型。 单聊:${CHAT_TYPE_DIRECT} 群聊:${CHAT_TYPE_GROUP} 频道:${CHAT_TYPE_CHANNEL}`}),\n relativeTime: Type.Optional(Type.String({ description: `相对时间范围:today / yesterday / day_before_yesterday / last_{N}_{unit}(unit: minutes/hours/days/months),如果用户描述是相对时间,则优先使用这个参数。与 startTime/endTime 互斥`})),\n startTime: Type.Optional(Type.String({ description: `起始时间(ISO 8601 格式,如 2026-02-27T00:00:00+08:00),非必填,默认指2000年。与 relativeTime 互斥`})),\n endTime: Type.Optional(Type.String({ description: `结束时间(ISO 8601 格式,如 2026-02-27T00:00:00+08:00),非必填,默认为now。与 relativeTime 互斥`})),\n limit: Type.Optional(Type.Number({ description: `每页条数,1~100,默认 100`})),\n cursor: Type.Optional(Type.String({ description: `游标首次调用填 \"0\",返回结果中has_more为true时代表可以获取下一页,如果你需要下一页,可以传返回结果的cursor代表继续拉取下一页, 带有cursor时,必须要有relativeTime或者startTime参数`})),\n orderAsc: Type.Optional(Type.Boolean({ description: `返回数据是否按时间正序排序,默认 false(按时间逆序,即从最新的开始拉取)`})),\n }),\n execute: async (_toolCallId: any, params: any) => {\n console.log(`tuitui_im_get_messages(): agentAccountId: ${ctx.agentAccountId}, sessionKey: ${ctx.sessionKey}`, params);\n const account = resolveAccount(ctx.config, ctx.agentAccountId);\n if(!account || !account.enabled || !account.appId || !account.appSecret) {\n return tool_errmsg(`invalid tuitui account ${ctx.agentAccountId}`);\n }\n \n const chatType = params?.chatType || \"\";\n const chatId = params?.chatId || \"\";\n if(!chatId || !chatType) {\n return tool_errmsg(`chatType or chatId empty`);\n }\n\n if(chatType == CHAT_TYPE_DIRECT || chatType == CHAT_TYPE_GROUP || chatType == CHAT_TYPE_CHANNEL) {\n return await getChatRecord(account, chatId, chatType, {\n startTime: params?.startTime,\n endTime: params?.endTime,\n relativeTime: params?.relativeTime,\n limit: params?.limit,\n cursor: params?.cursor,\n orderAsc: params?.orderAsc,\n });\n } else {\n return tool_errmsg(`unknown chatType: ${chatType}`);\n }\n },\n };\n};\n\n\nconst tuitui_send_channel_post_factory = (ctx: OpenClawPluginToolContext) => {\n return {\n name: \"tuitui_send_channel_post\",\n label: \"tuitui_send_channel_post\",\n description: \"推推(tuitui) 发送团队频道的帖子,帖子内容是markdown格式\\n\\n\",\n parameters: Type.Object({\n channel_id: Type.String({ description: \"推推频道ID\" }),\n markdown: Type.String({ description: `帖子正文,markdown格式`}),\n parent_id: Type.Optional(Type.String({ description: `如果要回复一个帖子,需要填写这个字段为被回复的帖子ID`})),\n }),\n execute: async (_toolCallId: any, params: any) => {\n console.log(`tuitui_send_channel_post(): agentAccountId: ${ctx.agentAccountId}, sessionKey: ${ctx.sessionKey}`, params);\n const account = resolveAccount(ctx.config, ctx.agentAccountId);\n if(!account || !account.enabled || !account.appId || !account.appSecret) {\n return tool_errmsg(`invalid tuitui account ${ctx.agentAccountId}`);\n }\n\n let chatId = \"\";\n const guessType = guessChatType(params?.channel_id);\n if(guessType == CHAT_TYPE_CHANNEL) {\n // 解决badcase: 发个帖子,内容是个笑话\n // 如果用户没明确说频道ID,大模型在频道调用发帖tool会传sessionKey过来\n chatId = params?.channel_id;\n } else {\n const channel_info = await getChannelInfoById(account, params?.channel_id);\n const team_id = channel_info?.team_id;\n chatId = teamsBuildChatId(team_id, params?.channel_id, params?.parent_id);\n }\n\n const result: Promise<any> = sendTextMsg(account, chatId, CHAT_TYPE_CHANNEL, params?.markdown);\n return result;\n },\n };\n};\n\n\nconst tuitui_get_announcement_factory = (ctx: OpenClawPluginToolContext) => {\n return {\n name: \"tuitui_get_announcement\",\n label: \"tuitui_get_announcement\",\n description: \"获取推推(tuitui) 当前会话的公告信息\\n\\n\",\n parameters: Type.Object({\n // 参数不能为空,对模型兼容有问题,即使不用也要传一个\n reason: Type.String({ description: \"调用本工具的原因\" }),\n }),\n execute: async (_toolCallId: any, params: any) => {\n console.log(`tuitui_get_announcement(): agentAccountId: ${ctx.agentAccountId}, sessionKey: ${ctx.sessionKey}`);\n const account = resolveAccount(ctx.config, ctx.agentAccountId);\n if(!account || !account.enabled || !account.appId || !account.appSecret) {\n return tool_errmsg(`invalid tuitui account ${ctx.agentAccountId}`);\n }\n return await teams_get_announcement(account, ctx.sessionKey);\n },\n };\n};\n\n\n\n\nconst tuitui_file_space_list_factory = (ctx: OpenClawPluginToolContext) => {\n return {\n name: \"tuitui_file_space_list\",\n label: \"tuitui_file_space_list\",\n description: \"推推(tuitui) 在当前Session的共享文件(共享空间)文件列表\\n\\n\",\n parameters: Type.Object({\n // 参数不能为空,对模型兼容有问题,即使不用也要传一个\n reason: Type.String({ description: \"调用本工具的原因\" }),\n }),\n execute: async (_toolCallId: any, params: any) => {\n console.log(`tuitui_file_space_list(): agentAccountId: ${ctx.agentAccountId}, sessionKey: ${ctx.sessionKey}`);\n const account = resolveAccount(ctx.config, ctx.agentAccountId);\n if(!account || !account.enabled || !account.appId || !account.appSecret) {\n return tool_errmsg(`invalid tuitui account ${ctx.agentAccountId}`);\n }\n return await file_space_list(account, ctx.sessionKey||\"\");\n },\n };\n};\n\nconst tuitui_file_space_add_factory = (ctx: OpenClawPluginToolContext) => {\n return {\n name: \"tuitui_file_space_add\",\n label: \"tuitui_file_space_add\",\n description: \"推推(tuitui) 团队频道的共享文件(共享空间)添加文件\\n\\n\",\n parameters: Type.Object({\n cloud_filepath: Type.String({ description: \"云端文件名路径,父目录不存在会自动创建。不含目录代表放根目录示例 1.png ,也支持带目录写法例如 /image/1.png\" }),\n url_or_localpath: Type.String({ description: \"支持两种格式:以http开头的文件url;或者本地全路径文件名\" }),\n }),\n execute: async (_toolCallId: any, params: any) => {\n console.log(`tuitui_file_space_add(): agentAccountId: ${ctx.agentAccountId}, sessionKey: ${ctx.sessionKey}`, params);\n const account = resolveAccount(ctx.config, ctx.agentAccountId);\n if(!account || !account.enabled || !account.appId || !account.appSecret) {\n return tool_errmsg(`invalid tuitui account ${ctx.agentAccountId}`);\n }\n return await file_space_add(account, ctx.sessionKey||\"\", params?.cloud_filepath, params?.url_or_localpath);\n },\n };\n};\n\n\nconst tuitui_im_send_message_factory = (ctx: OpenClawPluginToolContext) => {\n return {\n name: \"tuitui_im_send_message\",\n label: \"tuitui_im_send_message\",\n description: \"推推(tuitui) 发送消息,支持私聊和群聊\",\n parameters: Type.Object({\n chatId: Type.String({ description: \"目标会话 ID。私聊填用户账号(英文),群聊填群ID(数字)\" }),\n content: Type.String({ description: \"消息正文,markdown 格式\" }),\n chatType: Type.Optional(Type.String({ description: `会话类型:${CHAT_TYPE_DIRECT}(私聊)或 ${CHAT_TYPE_GROUP}(群聊),留空则根据 chatId 自动推断` })),\n }),\n execute: async (_toolCallId: any, params: any): Promise<any> => {\n console.log(`tuitui_im_send_message(): agentAccountId: ${ctx.agentAccountId}, sessionKey: ${ctx.sessionKey}`, params);\n const account = resolveAccount(ctx.config, ctx.agentAccountId);\n if (!account || !account.enabled || !account.appId || !account.appSecret) {\n return tool_errmsg(`invalid tuitui account ${ctx.agentAccountId}`);\n }\n const { chatId, content, chatType } = params;\n const resolvedChatType = chatType ?? guessChatType(chatId);\n if (resolvedChatType === CHAT_TYPE_CHANNEL) {\n return tool_errmsg(`tuitui_im_send_message 不支持 channel 类型,请使用 tuitui_send_channel_post`);\n }\n await sendTextMsg(account, chatId, resolvedChatType, content, 'tuitui.im.send_message');\n return { success: true };\n },\n };\n};\n\n\nexport function registerTuituiTools(api: OpenClawPluginApi) {\n if (!api.config) {\n api.logger.debug?.(\"tuitui: Registered tool: No config available\");\n return;\n }\n\n const channels = api.config.channels || {};\n const currChannel = channels[CHANNEL_ID] || {};\n if (!currChannel?.appId && !currChannel?.accounts) {\n // 无推推配置时,不需要注册工具防止污染上下文\n // api.logger.info?.(`tuitui: ignore Registered tools`);\n return\n }\n \n api.registerTool(tuitui_im_get_messages_factory);\n api.registerTool(tuitui_send_channel_post_factory);\n api.registerTool(tuitui_get_announcement_factory);\n api.registerTool(tuitui_file_space_list_factory);\n api.registerTool(tuitui_file_space_add_factory);\n api.registerTool(tuitui_im_send_message_factory);\n api.logger.info?.(`tuitui: Registered tools`);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/tools.ts"],"names":[],"mappings":"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","sourcesContent":["import type { OpenClawPluginApi } from \"openclaw/plugin-sdk/core\";\nimport type { OpenClawPluginToolContext } from \"openclaw/plugin-sdk/core\";\nimport { resolveAccount } from \"./accounts\"\nimport { Type } from \"@sinclair/typebox\";\nimport { CHANNEL_ID } from './const';\nimport {sendTextMsg} from \"./outbound\"\nimport { teams_get_announcement } from \"./teams_api\"\nimport {CHAT_TYPE_DIRECT,CHAT_TYPE_GROUP,CHAT_TYPE_CHANNEL,guessChatType, teamsBuildChatId} from \"./chat_base\"\nimport {getChatRecord, getChannelInfoById} from \"./chat_record\"\nimport {file_space_list, file_space_add} from \"./filespace\"\n \nfunction tool_errmsg(str:string) {\n throw new Error(str);\n}\n\nconst tuitui_im_get_messages_factory = (ctx: OpenClawPluginToolContext) => {\n return {\n name: \"tuitui_im_get_messages\",\n label: \"tuitui_im_get_messages\",\n description: \"推推(tuitui) 聊天记录获取,可查询私聊、群聊、频道的聊天记录\\n\\n\",\n parameters: Type.Object({\n chatId: Type.String({ description: \"聊天ID,单聊指tuitui用户的account,群聊是群ID,频道指频道ID\" }),\n chatType: Type.String({ description: `聊天类型。 单聊:${CHAT_TYPE_DIRECT} 群聊:${CHAT_TYPE_GROUP} 频道:${CHAT_TYPE_CHANNEL}`}),\n relativeTime: Type.Optional(Type.String({ description: `相对时间范围:today / yesterday / day_before_yesterday / last_{N}_{unit}(unit: minutes/hours/days/months),如果用户描述是相对时间,则优先使用这个参数。与 startTime/endTime 互斥`})),\n startTime: Type.Optional(Type.String({ description: `起始时间(ISO 8601 格式,如 2026-02-27T00:00:00+08:00),非必填,默认指2000年。与 relativeTime 互斥`})),\n endTime: Type.Optional(Type.String({ description: `结束时间(ISO 8601 格式,如 2026-02-27T00:00:00+08:00),非必填,默认为now。与 relativeTime 互斥`})),\n limit: Type.Optional(Type.Number({ description: `每页条数,1~100,默认 100`})),\n cursor: Type.Optional(Type.String({ description: `游标首次调用填 \"0\",返回结果中has_more为true时代表可以获取下一页,如果你需要下一页,可以传返回结果的cursor代表继续拉取下一页, 带有cursor时,必须要有relativeTime或者startTime参数`})),\n orderAsc: Type.Optional(Type.Boolean({ description: `返回数据是否按时间正序排序,默认 false(按时间逆序,即从最新的开始拉取)`})),\n }),\n execute: async (_toolCallId: any, params: any) => {\n console.log(`tuitui_im_get_messages(): agentAccountId: ${ctx.agentAccountId}, sessionKey: ${ctx.sessionKey}`, params);\n const account = resolveAccount(ctx.config, ctx.agentAccountId, ctx.agentId);\n if(!account || !account.enabled || !account.appId || !account.appSecret) {\n return tool_errmsg(`invalid tuitui account ${ctx.agentAccountId}`);\n }\n \n const chatType = params?.chatType || \"\";\n const chatId = params?.chatId || \"\";\n if(!chatId || !chatType) {\n return tool_errmsg(`chatType or chatId empty`);\n }\n\n if(chatType == CHAT_TYPE_DIRECT || chatType == CHAT_TYPE_GROUP || chatType == CHAT_TYPE_CHANNEL) {\n return await getChatRecord(account, chatId, chatType, {\n startTime: params?.startTime,\n endTime: params?.endTime,\n relativeTime: params?.relativeTime,\n limit: params?.limit,\n cursor: params?.cursor,\n orderAsc: params?.orderAsc,\n });\n } else {\n return tool_errmsg(`unknown chatType: ${chatType}`);\n }\n },\n };\n};\n\n\nconst tuitui_send_channel_post_factory = (ctx: OpenClawPluginToolContext) => {\n return {\n name: \"tuitui_send_channel_post\",\n label: \"tuitui_send_channel_post\",\n description: \"推推(tuitui) 发送团队频道的帖子,帖子内容是markdown格式\\n\\n\",\n parameters: Type.Object({\n channel_id: Type.String({ description: \"推推频道ID\" }),\n markdown: Type.String({ description: `帖子正文,markdown格式`}),\n parent_id: Type.Optional(Type.String({ description: `如果要回复一个帖子,需要填写这个字段为被回复的帖子ID`})),\n }),\n execute: async (_toolCallId: any, params: any) => {\n console.log(`tuitui_send_channel_post(): agentAccountId: ${ctx.agentAccountId}, sessionKey: ${ctx.sessionKey}`, params);\n const account = resolveAccount(ctx.config, ctx.agentAccountId, ctx.agentId);\n if(!account || !account.enabled || !account.appId || !account.appSecret) {\n return tool_errmsg(`invalid tuitui account ${ctx.agentAccountId}`);\n }\n\n let chatId = \"\";\n const guessType = guessChatType(params?.channel_id);\n if(guessType == CHAT_TYPE_CHANNEL) {\n // 解决badcase: 发个帖子,内容是个笑话\n // 如果用户没明确说频道ID,大模型在频道调用发帖tool会传sessionKey过来\n chatId = params?.channel_id;\n } else {\n const channel_info = await getChannelInfoById(account, params?.channel_id);\n const team_id = channel_info?.team_id;\n chatId = teamsBuildChatId(team_id, params?.channel_id, params?.parent_id);\n }\n\n const result: Promise<any> = sendTextMsg(account, chatId, CHAT_TYPE_CHANNEL, params?.markdown);\n return result;\n },\n };\n};\n\n\nconst tuitui_get_announcement_factory = (ctx: OpenClawPluginToolContext) => {\n return {\n name: \"tuitui_get_announcement\",\n label: \"tuitui_get_announcement\",\n description: \"获取推推(tuitui) 当前会话的公告信息\\n\\n\",\n parameters: Type.Object({\n // 参数不能为空,对模型兼容有问题,即使不用也要传一个\n reason: Type.String({ description: \"调用本工具的原因\" }),\n }),\n execute: async (_toolCallId: any, params: any) => {\n console.log(`tuitui_get_announcement(): agentAccountId: ${ctx.agentAccountId}, sessionKey: ${ctx.sessionKey}`);\n const account = resolveAccount(ctx.config, ctx.agentAccountId, ctx.agentId);\n if(!account || !account.enabled || !account.appId || !account.appSecret) {\n return tool_errmsg(`invalid tuitui account ${ctx.agentAccountId}`);\n }\n return await teams_get_announcement(account, ctx.sessionKey);\n },\n };\n};\n\n\n\n\nconst tuitui_file_space_list_factory = (ctx: OpenClawPluginToolContext) => {\n return {\n name: \"tuitui_file_space_list\",\n label: \"tuitui_file_space_list\",\n description: \"推推(tuitui) 在当前Session的共享文件(共享空间)文件列表\\n\\n\",\n parameters: Type.Object({\n // 参数不能为空,对模型兼容有问题,即使不用也要传一个\n reason: Type.String({ description: \"调用本工具的原因\" }),\n }),\n execute: async (_toolCallId: any, params: any) => {\n console.log(`tuitui_file_space_list(): agentAccountId: ${ctx.agentAccountId}, sessionKey: ${ctx.sessionKey}`);\n const account = resolveAccount(ctx.config, ctx.agentAccountId, ctx.agentId);\n if(!account || !account.enabled || !account.appId || !account.appSecret) {\n return tool_errmsg(`invalid tuitui account ${ctx.agentAccountId}`);\n }\n return await file_space_list(account, ctx.sessionKey||\"\");\n },\n };\n};\n\nconst tuitui_file_space_add_factory = (ctx: OpenClawPluginToolContext) => {\n return {\n name: \"tuitui_file_space_add\",\n label: \"tuitui_file_space_add\",\n description: \"推推(tuitui) 团队频道的共享文件(共享空间)添加文件\\n\\n\",\n parameters: Type.Object({\n cloud_filepath: Type.String({ description: \"云端文件名路径,父目录不存在会自动创建。不含目录代表放根目录示例 1.png ,也支持带目录写法例如 /image/1.png\" }),\n url_or_localpath: Type.String({ description: \"支持两种格式:以http开头的文件url;或者本地全路径文件名\" }),\n }),\n execute: async (_toolCallId: any, params: any) => {\n console.log(`tuitui_file_space_add(): agentAccountId: ${ctx.agentAccountId}, sessionKey: ${ctx.sessionKey}`, params);\n const account = resolveAccount(ctx.config, ctx.agentAccountId, ctx.agentId);\n if(!account || !account.enabled || !account.appId || !account.appSecret) {\n return tool_errmsg(`invalid tuitui account ${ctx.agentAccountId}`);\n }\n return await file_space_add(account, ctx.sessionKey||\"\", params?.cloud_filepath, params?.url_or_localpath);\n },\n };\n};\n\n\nconst tuitui_im_send_message_factory = (ctx: OpenClawPluginToolContext) => {\n return {\n name: \"tuitui_im_send_message\",\n label: \"tuitui_im_send_message\",\n description: \"推推(tuitui) 发送消息,支持私聊和群聊\",\n parameters: Type.Object({\n chatId: Type.String({ description: \"目标会话 ID。私聊填用户账号(英文),群聊填群ID(数字)\" }),\n content: Type.String({ description: \"消息正文,markdown 格式\" }),\n chatType: Type.Optional(Type.String({ description: `会话类型:${CHAT_TYPE_DIRECT}(私聊)或 ${CHAT_TYPE_GROUP}(群聊),留空则根据 chatId 自动推断` })),\n }),\n execute: async (_toolCallId: any, params: any): Promise<any> => {\n console.log(`tuitui_im_send_message(): agentAccountId: ${ctx.agentAccountId}, sessionKey: ${ctx.sessionKey}`, params);\n const account = resolveAccount(ctx.config, ctx.agentAccountId, ctx.agentId);\n if (!account || !account.enabled || !account.appId || !account.appSecret) {\n return tool_errmsg(`invalid tuitui account ${ctx.agentAccountId}`);\n }\n const { chatId, content, chatType } = params;\n const resolvedChatType = chatType ?? guessChatType(chatId);\n if (resolvedChatType === CHAT_TYPE_CHANNEL) {\n return tool_errmsg(`tuitui_im_send_message 不支持 channel 类型,请使用 tuitui_send_channel_post`);\n }\n await sendTextMsg(account, chatId, resolvedChatType, content, 'tuitui.im.send_message');\n return { success: true };\n },\n };\n};\n\n\nexport function registerTuituiTools(api: OpenClawPluginApi) {\n if (!api.config) {\n api.logger.debug?.(\"tuitui: Registered tool: No config available\");\n return;\n }\n\n const channels = api.config.channels || {};\n const currChannel = channels[CHANNEL_ID] || {};\n if (!currChannel?.appId && !currChannel?.accounts) {\n // 无推推配置时,不需要注册工具防止污染上下文\n // api.logger.info?.(`tuitui: ignore Registered tools`);\n return\n }\n \n api.registerTool(tuitui_im_get_messages_factory);\n api.registerTool(tuitui_send_channel_post_factory);\n api.registerTool(tuitui_get_announcement_factory);\n api.registerTool(tuitui_file_space_list_factory);\n api.registerTool(tuitui_file_space_add_factory);\n api.registerTool(tuitui_im_send_message_factory);\n api.logger.info?.(`tuitui: Registered tools`);\n}\n"]}
|