@wecom/wecom-openclaw-plugin 2026.3.31-beta.0 → 2026.4.1-beta.1
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/README.md +4 -251
- package/dist/cjs/index.js +45 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/src/channel.js +339 -0
- package/dist/cjs/src/channel.js.map +1 -0
- package/dist/cjs/src/const.js +137 -0
- package/dist/cjs/src/const.js.map +1 -0
- package/dist/cjs/src/dm-policy.js +89 -0
- package/dist/cjs/src/dm-policy.js.map +1 -0
- package/dist/cjs/src/group-policy.js +133 -0
- package/dist/cjs/src/group-policy.js.map +1 -0
- package/dist/cjs/src/mcp/interceptors/biz-error.js +70 -0
- package/dist/cjs/src/mcp/interceptors/biz-error.js.map +1 -0
- package/dist/cjs/src/mcp/interceptors/index.js +73 -0
- package/dist/cjs/src/mcp/interceptors/index.js.map +1 -0
- package/dist/cjs/src/mcp/interceptors/msg-media.js +159 -0
- package/dist/cjs/src/mcp/interceptors/msg-media.js.map +1 -0
- package/dist/cjs/src/mcp/interceptors/smartpage-create.js +157 -0
- package/dist/cjs/src/mcp/interceptors/smartpage-create.js.map +1 -0
- package/dist/cjs/src/mcp/interceptors/smartpage-export.js +93 -0
- package/dist/cjs/src/mcp/interceptors/smartpage-export.js.map +1 -0
- package/dist/cjs/src/mcp/schema.js +104 -0
- package/dist/cjs/src/mcp/schema.js.map +1 -0
- package/dist/cjs/src/mcp/tool.js +208 -0
- package/dist/cjs/src/mcp/tool.js.map +1 -0
- package/dist/cjs/src/mcp/transport.js +417 -0
- package/dist/cjs/src/mcp/transport.js.map +1 -0
- package/dist/cjs/src/media-handler.js +129 -0
- package/dist/cjs/src/media-handler.js.map +1 -0
- package/dist/cjs/src/media-uploader.js +284 -0
- package/dist/cjs/src/media-uploader.js.map +1 -0
- package/dist/cjs/src/message-parser.js +134 -0
- package/dist/cjs/src/message-parser.js.map +1 -0
- package/dist/cjs/src/message-sender.js +89 -0
- package/dist/cjs/src/message-sender.js.map +1 -0
- package/dist/cjs/src/monitor.js +991 -0
- package/dist/cjs/src/monitor.js.map +1 -0
- package/dist/cjs/src/onboarding.js +182 -0
- package/dist/cjs/src/onboarding.js.map +1 -0
- package/dist/cjs/src/openclaw-compat.js +400 -0
- package/dist/cjs/src/openclaw-compat.js.map +1 -0
- package/dist/cjs/src/reqid-store.js +88 -0
- package/dist/cjs/src/reqid-store.js.map +1 -0
- package/dist/cjs/src/runtime.js +16 -0
- package/dist/cjs/src/runtime.js.map +1 -0
- package/dist/cjs/src/state-dir-resolve.js +35 -0
- package/dist/cjs/src/state-dir-resolve.js.map +1 -0
- package/dist/cjs/src/state-manager.js +158 -0
- package/dist/cjs/src/state-manager.js.map +1 -0
- package/dist/cjs/src/template-card-parser.js +641 -0
- package/dist/cjs/src/template-card-parser.js.map +1 -0
- package/dist/cjs/src/timeout.js +42 -0
- package/dist/cjs/src/timeout.js.map +1 -0
- package/dist/cjs/src/utils.js +60 -0
- package/dist/cjs/src/utils.js.map +1 -0
- package/dist/cjs/src/version.js +26 -0
- package/dist/cjs/src/version.js.map +1 -0
- package/dist/esm/index.js +41 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/src/channel.js +337 -0
- package/dist/esm/src/channel.js.map +1 -0
- package/dist/{src → esm/src}/const.js +30 -77
- package/dist/esm/src/const.js.map +1 -0
- package/dist/{src → esm/src}/dm-policy.js +9 -6
- package/dist/esm/src/dm-policy.js.map +1 -0
- package/dist/{src → esm/src}/group-policy.js +7 -3
- package/dist/esm/src/group-policy.js.map +1 -0
- package/dist/{src → esm/src}/mcp/interceptors/biz-error.js +6 -2
- package/dist/esm/src/mcp/interceptors/biz-error.js.map +1 -0
- package/dist/{src → esm/src}/mcp/interceptors/index.js +10 -6
- package/dist/esm/src/mcp/interceptors/index.js.map +1 -0
- package/dist/{src → esm/src}/mcp/interceptors/msg-media.js +10 -6
- package/dist/esm/src/mcp/interceptors/msg-media.js.map +1 -0
- package/dist/{src → esm/src}/mcp/interceptors/smartpage-create.js +6 -2
- package/dist/esm/src/mcp/interceptors/smartpage-create.js.map +1 -0
- package/dist/{src → esm/src}/mcp/interceptors/smartpage-export.js +6 -2
- package/dist/esm/src/mcp/interceptors/smartpage-export.js.map +1 -0
- package/dist/{src → esm/src}/mcp/schema.js +4 -1
- package/dist/esm/src/mcp/schema.js.map +1 -0
- package/dist/{src → esm/src}/mcp/tool.js +8 -4
- package/dist/esm/src/mcp/tool.js.map +1 -0
- package/dist/{src → esm/src}/mcp/transport.js +16 -15
- package/dist/esm/src/mcp/transport.js.map +1 -0
- package/dist/{src → esm/src}/media-handler.js +10 -6
- package/dist/esm/src/media-handler.js.map +1 -0
- package/dist/{src → esm/src}/media-uploader.js +10 -64
- package/dist/esm/src/media-uploader.js.map +1 -0
- package/dist/{src → esm/src}/message-parser.js +4 -1
- package/dist/esm/src/message-parser.js.map +1 -0
- package/dist/{src → esm/src}/message-sender.js +11 -46
- package/dist/esm/src/message-sender.js.map +1 -0
- package/dist/{src → esm/src}/monitor.js +282 -151
- package/dist/esm/src/monitor.js.map +1 -0
- package/dist/{src → esm/src}/onboarding.js +26 -22
- package/dist/esm/src/onboarding.js.map +1 -0
- package/dist/{src → esm/src}/openclaw-compat.js +27 -143
- package/dist/esm/src/openclaw-compat.js.map +1 -0
- package/dist/{src → esm/src}/reqid-store.js +7 -4
- package/dist/esm/src/reqid-store.js.map +1 -0
- package/dist/{src → esm/src}/runtime.js +5 -2
- package/dist/esm/src/runtime.js.map +1 -0
- package/dist/esm/src/state-dir-resolve.js +13 -0
- package/dist/esm/src/state-dir-resolve.js.map +1 -0
- package/dist/{src → esm/src}/state-manager.js +16 -84
- package/dist/esm/src/state-manager.js.map +1 -0
- package/dist/{src → esm/src}/template-card-parser.js +8 -17
- package/dist/esm/src/template-card-parser.js.map +1 -0
- package/dist/{src → esm/src}/timeout.js +5 -2
- package/dist/esm/src/timeout.js.map +1 -0
- package/dist/{src → esm/src}/utils.js +10 -24
- package/dist/esm/src/utils.js.map +1 -0
- package/dist/esm/src/version.js +23 -0
- package/dist/esm/src/version.js.map +1 -0
- package/dist/esm/types/index.d.ts +9 -0
- package/dist/{src → esm/types/src}/const.d.ts +0 -46
- package/dist/{src → esm/types/src}/interface.d.ts +2 -0
- package/dist/{src → esm/types/src}/message-sender.d.ts +0 -18
- package/dist/{src → esm/types/src}/openclaw-compat.d.ts +0 -49
- package/dist/esm/types/src/state-dir-resolve.d.ts +2 -0
- package/dist/{src → esm/types/src}/utils.d.ts +0 -39
- package/dist/esm/types/src/version.d.ts +2 -0
- package/dist/index.d.ts +4 -2
- package/package.json +7 -15
- package/dist/index.js +0 -113
- package/dist/src/accounts.d.ts +0 -57
- package/dist/src/accounts.js +0 -222
- package/dist/src/agent/api-client.d.ts +0 -94
- package/dist/src/agent/api-client.js +0 -292
- package/dist/src/agent/handler.d.ts +0 -63
- package/dist/src/agent/handler.js +0 -532
- package/dist/src/agent/index.d.ts +0 -5
- package/dist/src/agent/index.js +0 -5
- package/dist/src/agent/webhook.d.ts +0 -23
- package/dist/src/agent/webhook.js +0 -226
- package/dist/src/agent/xml.d.ts +0 -21
- package/dist/src/agent/xml.js +0 -41
- package/dist/src/channel.js +0 -564
- package/dist/src/chat-queue.d.ts +0 -31
- package/dist/src/chat-queue.js +0 -45
- package/dist/src/http.d.ts +0 -26
- package/dist/src/http.js +0 -93
- package/dist/src/interface.js +0 -4
- package/dist/src/mcp/index.js +0 -6
- package/dist/src/mcp/interceptors/types.js +0 -7
- package/dist/src/shared/command-auth.d.ts +0 -23
- package/dist/src/shared/command-auth.js +0 -73
- package/dist/src/shared/xml-parser.d.ts +0 -46
- package/dist/src/shared/xml-parser.js +0 -210
- package/dist/src/target.d.ts +0 -35
- package/dist/src/target.js +0 -67
- package/dist/src/template-card-manager.d.ts +0 -55
- package/dist/src/template-card-manager.js +0 -205
- package/dist/src/types/account.d.ts +0 -29
- package/dist/src/types/account.js +0 -4
- package/dist/src/types/config.d.ts +0 -80
- package/dist/src/types/config.js +0 -7
- package/dist/src/types/constants.d.ts +0 -42
- package/dist/src/types/constants.js +0 -42
- package/dist/src/types/index.d.ts +0 -7
- package/dist/src/types/index.js +0 -5
- package/dist/src/types/message.d.ts +0 -238
- package/dist/src/types/message.js +0 -5
- package/dist/src/version.d.ts +0 -2
- package/dist/src/version.js +0 -24
- package/dist/src/webhook/command-auth.d.ts +0 -47
- package/dist/src/webhook/command-auth.js +0 -96
- package/dist/src/webhook/gateway.d.ts +0 -36
- package/dist/src/webhook/gateway.js +0 -227
- package/dist/src/webhook/handler.d.ts +0 -18
- package/dist/src/webhook/handler.js +0 -420
- package/dist/src/webhook/helpers.d.ts +0 -156
- package/dist/src/webhook/helpers.js +0 -833
- package/dist/src/webhook/http.d.ts +0 -26
- package/dist/src/webhook/http.js +0 -94
- package/dist/src/webhook/index.d.ts +0 -11
- package/dist/src/webhook/index.js +0 -14
- package/dist/src/webhook/media.d.ts +0 -29
- package/dist/src/webhook/media.js +0 -88
- package/dist/src/webhook/monitor.d.ts +0 -59
- package/dist/src/webhook/monitor.js +0 -1147
- package/dist/src/webhook/state.d.ts +0 -220
- package/dist/src/webhook/state.js +0 -491
- package/dist/src/webhook/target.d.ts +0 -41
- package/dist/src/webhook/target.js +0 -132
- package/dist/src/webhook/types.d.ts +0 -347
- package/dist/src/webhook/types.js +0 -33
- /package/dist/{src → esm/types/src}/channel.d.ts +0 -0
- /package/dist/{src → esm/types/src}/dm-policy.d.ts +0 -0
- /package/dist/{src → esm/types/src}/group-policy.d.ts +0 -0
- /package/dist/{src → esm/types/src}/mcp/index.d.ts +0 -0
- /package/dist/{src → esm/types/src}/mcp/interceptors/biz-error.d.ts +0 -0
- /package/dist/{src → esm/types/src}/mcp/interceptors/index.d.ts +0 -0
- /package/dist/{src → esm/types/src}/mcp/interceptors/msg-media.d.ts +0 -0
- /package/dist/{src → esm/types/src}/mcp/interceptors/smartpage-create.d.ts +0 -0
- /package/dist/{src → esm/types/src}/mcp/interceptors/smartpage-export.d.ts +0 -0
- /package/dist/{src → esm/types/src}/mcp/interceptors/types.d.ts +0 -0
- /package/dist/{src → esm/types/src}/mcp/schema.d.ts +0 -0
- /package/dist/{src → esm/types/src}/mcp/tool.d.ts +0 -0
- /package/dist/{src → esm/types/src}/mcp/transport.d.ts +0 -0
- /package/dist/{src → esm/types/src}/media-handler.d.ts +0 -0
- /package/dist/{src → esm/types/src}/media-uploader.d.ts +0 -0
- /package/dist/{src → esm/types/src}/message-parser.d.ts +0 -0
- /package/dist/{src → esm/types/src}/monitor.d.ts +0 -0
- /package/dist/{src → esm/types/src}/onboarding.d.ts +0 -0
- /package/dist/{src → esm/types/src}/reqid-store.d.ts +0 -0
- /package/dist/{src → esm/types/src}/runtime.d.ts +0 -0
- /package/dist/{src → esm/types/src}/state-manager.d.ts +0 -0
- /package/dist/{src → esm/types/src}/template-card-parser.d.ts +0 -0
- /package/dist/{src → esm/types/src}/timeout.d.ts +0 -0
|
@@ -1,18 +1,19 @@
|
|
|
1
|
+
import { DEFAULT_ACCOUNT_ID } from './openclaw-compat.js';
|
|
2
|
+
import { CHANNEL_ID } from './const.js';
|
|
3
|
+
|
|
1
4
|
/**
|
|
2
5
|
* 企业微信公共工具函数
|
|
3
6
|
*/
|
|
4
|
-
|
|
5
|
-
import { CHANNEL_ID } from "./const.js";
|
|
6
|
-
export const DefaultWsUrl = "wss://openws.work.weixin.qq.com";
|
|
7
|
+
const DefaultWsUrl = "wss://openws.work.weixin.qq.com";
|
|
7
8
|
/**
|
|
8
9
|
* 解析企业微信账户配置
|
|
9
10
|
*/
|
|
10
|
-
|
|
11
|
+
function resolveWeComAccount(cfg) {
|
|
11
12
|
const wecomConfig = (cfg.channels?.[CHANNEL_ID] ?? {});
|
|
12
13
|
return {
|
|
13
14
|
accountId: DEFAULT_ACCOUNT_ID,
|
|
14
15
|
name: wecomConfig.name ?? "企业微信",
|
|
15
|
-
enabled: wecomConfig.enabled
|
|
16
|
+
enabled: wecomConfig.enabled ?? false,
|
|
16
17
|
websocketUrl: wecomConfig.websocketUrl || DefaultWsUrl,
|
|
17
18
|
botId: wecomConfig.botId ?? "",
|
|
18
19
|
secret: wecomConfig.secret ?? "",
|
|
@@ -23,7 +24,7 @@ export function resolveWeComAccount(cfg) {
|
|
|
23
24
|
/**
|
|
24
25
|
* 设置企业微信账户配置
|
|
25
26
|
*/
|
|
26
|
-
|
|
27
|
+
function setWeComAccount(cfg, account) {
|
|
27
28
|
const existing = (cfg.channels?.[CHANNEL_ID] ?? {});
|
|
28
29
|
const merged = {
|
|
29
30
|
enabled: account.enabled ?? existing?.enabled ?? true,
|
|
@@ -50,21 +51,6 @@ export function setWeComAccount(cfg, account) {
|
|
|
50
51
|
},
|
|
51
52
|
};
|
|
52
53
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
* 优先级:
|
|
57
|
-
* 1. config.channels.wecom.network.egressProxyUrl
|
|
58
|
-
* 2. 环境变量:OPENCLAW_WECOM_EGRESS_PROXY_URL → WECOM_EGRESS_PROXY_URL → HTTPS_PROXY → ALL_PROXY → HTTP_PROXY
|
|
59
|
-
*/
|
|
60
|
-
export function resolveWecomEgressProxyUrl(cfg) {
|
|
61
|
-
const wecom = (cfg.channels?.[CHANNEL_ID] ?? {});
|
|
62
|
-
const proxyUrl = wecom.network?.egressProxyUrl ??
|
|
63
|
-
process.env.OPENCLAW_WECOM_EGRESS_PROXY_URL ??
|
|
64
|
-
process.env.WECOM_EGRESS_PROXY_URL ??
|
|
65
|
-
process.env.HTTPS_PROXY ??
|
|
66
|
-
process.env.ALL_PROXY ??
|
|
67
|
-
process.env.HTTP_PROXY ??
|
|
68
|
-
"";
|
|
69
|
-
return proxyUrl.trim() || undefined;
|
|
70
|
-
}
|
|
54
|
+
|
|
55
|
+
export { DefaultWsUrl, resolveWeComAccount, setWeComAccount };
|
|
56
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sources":["../../../../../src/utils.ts"],"sourcesContent":["/**\n * 企业微信公共工具函数\n */\n\nimport type { OpenClawConfig } from \"openclaw/plugin-sdk/core\";\nimport { DEFAULT_ACCOUNT_ID } from \"./openclaw-compat.js\";\nimport { CHANNEL_ID } from \"./const.js\";\n\n// ============================================================================\n// 配置类型定义\n// ============================================================================\n\n/**\n * 企业微信群组配置\n */\nexport interface WeComGroupConfig {\n /** 群组内发送者白名单(仅列表中的成员消息会被处理) */\n allowFrom?: Array<string | number>;\n}\n\n/**\n * 企业微信配置类型\n */\nexport interface WeComConfig {\n enabled?: boolean;\n websocketUrl?: string;\n botId?: string;\n secret?: string;\n name?: string;\n allowFrom?: Array<string | number>;\n dmPolicy?: \"open\" | \"allowlist\" | \"pairing\" | \"disabled\";\n /** 群组访问策略:\"open\" = 允许所有群组(默认),\"allowlist\" = 仅允许 groupAllowFrom 中的群组,\"disabled\" = 禁用群组消息 */\n groupPolicy?: \"open\" | \"allowlist\" | \"disabled\";\n /** 群组白名单(仅 groupPolicy=\"allowlist\" 时生效) */\n groupAllowFrom?: Array<string | number>;\n /** 每个群组的详细配置(如群组内发送者白名单) */\n groups?: Record<string, WeComGroupConfig>;\n /** 是否发送\"思考中\"消息,默认为 true */\n sendThinkingMessage?: boolean;\n /** 额外允许访问的本地媒体路径白名单(支持 ~ 表示 home 目录),如 [\"~/Downloads\", \"~/Documents\"] */\n mediaLocalRoots?: string[];\n}\n\nexport const DefaultWsUrl = \"wss://openws.work.weixin.qq.com\";\n\nexport interface ResolvedWeComAccount {\n accountId: string;\n name: string;\n enabled: boolean;\n websocketUrl: string;\n botId: string;\n secret: string;\n /** 是否发送\"思考中\"消息,默认为 true */\n sendThinkingMessage: boolean;\n config: WeComConfig;\n}\n\n/**\n * 解析企业微信账户配置\n */\nexport function resolveWeComAccount(cfg: OpenClawConfig): ResolvedWeComAccount {\n const wecomConfig = (cfg.channels?.[CHANNEL_ID] ?? {}) as WeComConfig;\n\n return {\n accountId: DEFAULT_ACCOUNT_ID,\n name: wecomConfig.name ?? \"企业微信\",\n enabled: wecomConfig.enabled ?? false,\n websocketUrl: wecomConfig.websocketUrl || DefaultWsUrl,\n botId: wecomConfig.botId ?? \"\",\n secret: wecomConfig.secret ?? \"\",\n sendThinkingMessage: wecomConfig.sendThinkingMessage ?? true,\n config: wecomConfig,\n };\n}\n\n/**\n * 设置企业微信账户配置\n */\nexport function setWeComAccount(\n cfg: OpenClawConfig,\n account: Partial<WeComConfig>,\n): OpenClawConfig {\n const existing = (cfg.channels?.[CHANNEL_ID] ?? {}) as WeComConfig;\n const merged: WeComConfig = {\n enabled: account.enabled ?? existing?.enabled ?? true,\n botId: account.botId ?? existing?.botId ?? \"\",\n secret: account.secret ?? existing?.secret ?? \"\",\n allowFrom: account.allowFrom ?? existing?.allowFrom,\n dmPolicy: account.dmPolicy ?? existing?.dmPolicy,\n // 以下字段仅在已有配置值或显式传入时才写入,onboarding 时不主动生成\n ...(account.websocketUrl || existing?.websocketUrl\n ? { websocketUrl: account.websocketUrl ?? existing?.websocketUrl }\n : {}),\n ...(account.name || existing?.name\n ? { name: account.name ?? existing?.name }\n : {}),\n ...(account.sendThinkingMessage !== undefined || existing?.sendThinkingMessage !== undefined\n ? { sendThinkingMessage: account.sendThinkingMessage ?? existing?.sendThinkingMessage }\n : {}),\n };\n\nreturn {\n ...cfg,\n channels: {\n ...cfg.channels,\n [CHANNEL_ID]: merged,\n },\n };\n}\n"],"names":[],"mappings":";;;AAAA;;AAEG;AAyCI,MAAM,YAAY,GAAG;AAc5B;;AAEG;AACG,SAAU,mBAAmB,CAAC,GAAmB,EAAA;AACrD,IAAA,MAAM,WAAW,IAAI,GAAG,CAAC,QAAQ,GAAG,UAAU,CAAC,IAAI,EAAE,CAAgB;IAErE,OAAO;AACL,QAAA,SAAS,EAAE,kBAAkB;AAC7B,QAAA,IAAI,EAAE,WAAW,CAAC,IAAI,IAAI,MAAM;AAChC,QAAA,OAAO,EAAE,WAAW,CAAC,OAAO,IAAI,KAAK;AACrC,QAAA,YAAY,EAAE,WAAW,CAAC,YAAY,IAAI,YAAY;AACtD,QAAA,KAAK,EAAE,WAAW,CAAC,KAAK,IAAI,EAAE;AAC9B,QAAA,MAAM,EAAE,WAAW,CAAC,MAAM,IAAI,EAAE;AAChC,QAAA,mBAAmB,EAAE,WAAW,CAAC,mBAAmB,IAAI,IAAI;AAC5D,QAAA,MAAM,EAAE,WAAW;KACpB;AACH;AAEA;;AAEG;AACG,SAAU,eAAe,CAC7B,GAAmB,EACnB,OAA6B,EAAA;AAE7B,IAAA,MAAM,QAAQ,IAAI,GAAG,CAAC,QAAQ,GAAG,UAAU,CAAC,IAAI,EAAE,CAAgB;AAClE,IAAA,MAAM,MAAM,GAAgB;QAC1B,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,QAAQ,EAAE,OAAO,IAAI,IAAI;QACrD,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,QAAQ,EAAE,KAAK,IAAI,EAAE;QAC7C,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,QAAQ,EAAE,MAAM,IAAI,EAAE;AAChD,QAAA,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,QAAQ,EAAE,SAAS;AACnD,QAAA,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,QAAQ,EAAE,QAAQ;;AAEhD,QAAA,IAAI,OAAO,CAAC,YAAY,IAAI,QAAQ,EAAE;cAClC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,QAAQ,EAAE,YAAY;cAC9D,EAAE,CAAC;AACP,QAAA,IAAI,OAAO,CAAC,IAAI,IAAI,QAAQ,EAAE;cAC1B,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,QAAQ,EAAE,IAAI;cACtC,EAAE,CAAC;QACP,IAAI,OAAO,CAAC,mBAAmB,KAAK,SAAS,IAAI,QAAQ,EAAE,mBAAmB,KAAK;cAC/E,EAAE,mBAAmB,EAAE,OAAO,CAAC,mBAAmB,IAAI,QAAQ,EAAE,mBAAmB;cACnF,EAAE,CAAC;KACR;IAEH,OAAO;AACH,QAAA,GAAG,GAAG;AACN,QAAA,QAAQ,EAAE;YACR,GAAG,GAAG,CAAC,QAAQ;YACf,CAAC,UAAU,GAAG,MAAM;AACrB,SAAA;KACF;AACH;;;;"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, resolve } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
|
|
5
|
+
/** 从 package.json 中读取版本号,兼容打包产物和直接运行 .ts 两种场景 */
|
|
6
|
+
const getVersion = () => {
|
|
7
|
+
try {
|
|
8
|
+
// ESM 环境使用 import.meta.url,CJS 环境使用全局 __dirname
|
|
9
|
+
const currentDir = dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
// 直接运行 .ts 时在 src/ 下,打包后在 dist/ 下,都向上一级找 package.json
|
|
11
|
+
const pkgPath = resolve(currentDir, "..", "package.json");
|
|
12
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
13
|
+
return pkg.version ?? "";
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return "";
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
/** 插件版本号,来源于 package.json */
|
|
20
|
+
const PLUGIN_VERSION = getVersion();
|
|
21
|
+
|
|
22
|
+
export { PLUGIN_VERSION };
|
|
23
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sources":["../../../../../src/version.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { resolve, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\n/** 从 package.json 中读取版本号,兼容打包产物和直接运行 .ts 两种场景 */\nconst getVersion = (): string => {\n try {\n // ESM 环境使用 import.meta.url,CJS 环境使用全局 __dirname\n const currentDir = dirname(fileURLToPath(import.meta.url));\n\n // 直接运行 .ts 时在 src/ 下,打包后在 dist/ 下,都向上一级找 package.json\n const pkgPath = resolve(currentDir, \"..\", \"package.json\");\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\"));\n return pkg.version ?? \"\";\n } catch {\n return \"\";\n }\n};\n\n/** 插件版本号,来源于 package.json */\nexport const PLUGIN_VERSION: string = getVersion();\n"],"names":[],"mappings":";;;;AAIA;AACA,MAAM,UAAU,GAAG,MAAa;AAC9B,IAAA,IAAI;;AAEF,QAAA,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;;QAG1D,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,EAAE,IAAI,EAAE,cAAc,CAAC;AACzD,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AACtD,QAAA,OAAO,GAAG,CAAC,OAAO,IAAI,EAAE;IAC1B;AAAE,IAAA,MAAM;AACN,QAAA,OAAO,EAAE;IACX;AACF,CAAC;AAED;AACO,MAAM,cAAc,GAAW,UAAU;;;;"}
|
|
@@ -70,51 +70,5 @@ export declare const EVENT_ENTER_CHECK_UPDATE = "event.enter_check_update";
|
|
|
70
70
|
export declare const CMD_ENTER_EVENT_REPLY = "ww_ai_robot_enter_event";
|
|
71
71
|
/** WSClient scene 参数:企微 OpenClaw 场景 */
|
|
72
72
|
export declare const SCENE_WECOM_OPENCLAW = 1;
|
|
73
|
-
/**
|
|
74
|
-
* WeCom 双模式常量定义
|
|
75
|
-
*/
|
|
76
|
-
/** 固定 Webhook 路径 */
|
|
77
|
-
export declare const WEBHOOK_PATHS: {
|
|
78
|
-
/** Bot 模式历史兼容路径(不再维护) */
|
|
79
|
-
readonly BOT: "/wecom";
|
|
80
|
-
/** Bot 模式历史备用兼容路径(不再维护) */
|
|
81
|
-
readonly BOT_ALT: "/wecom/bot";
|
|
82
|
-
/** Agent 模式历史兼容路径(不再维护) */
|
|
83
|
-
readonly AGENT: "/wecom/agent";
|
|
84
|
-
/** Bot 模式推荐路径前缀 */
|
|
85
|
-
readonly BOT_PLUGIN: "/plugins/wecom/bot";
|
|
86
|
-
/** Agent 模式推荐路径前缀 */
|
|
87
|
-
readonly AGENT_PLUGIN: "/plugins/wecom/agent";
|
|
88
|
-
};
|
|
89
|
-
/** 企业微信 API 端点 */
|
|
90
|
-
export declare const API_ENDPOINTS: {
|
|
91
|
-
readonly GET_TOKEN: "https://qyapi.weixin.qq.com/cgi-bin/gettoken";
|
|
92
|
-
readonly SEND_MESSAGE: "https://qyapi.weixin.qq.com/cgi-bin/message/send";
|
|
93
|
-
readonly SEND_APPCHAT: "https://qyapi.weixin.qq.com/cgi-bin/appchat/send";
|
|
94
|
-
readonly UPLOAD_MEDIA: "https://qyapi.weixin.qq.com/cgi-bin/media/upload";
|
|
95
|
-
readonly DOWNLOAD_MEDIA: "https://qyapi.weixin.qq.com/cgi-bin/media/get";
|
|
96
|
-
};
|
|
97
|
-
/** 各类限制常量 */
|
|
98
|
-
export declare const LIMITS: {
|
|
99
|
-
/** 文本消息最大字节数 */
|
|
100
|
-
readonly TEXT_MAX_BYTES: 2048;
|
|
101
|
-
/** Token 刷新缓冲时间 (提前刷新) */
|
|
102
|
-
readonly TOKEN_REFRESH_BUFFER_MS: 60000;
|
|
103
|
-
/** HTTP 请求超时 */
|
|
104
|
-
readonly REQUEST_TIMEOUT_MS: 15000;
|
|
105
|
-
/** 最大请求体大小 */
|
|
106
|
-
readonly MAX_REQUEST_BODY_SIZE: number;
|
|
107
|
-
};
|
|
108
|
-
/** AES 加密常量 */
|
|
109
|
-
export declare const CRYPTO: {
|
|
110
|
-
/** PKCS#7 块大小 */
|
|
111
|
-
readonly PKCS7_BLOCK_SIZE: 32;
|
|
112
|
-
/** AES Key 长度 */
|
|
113
|
-
readonly AES_KEY_LENGTH: 32;
|
|
114
|
-
};
|
|
115
73
|
/** 合法的模板卡片 card_type 列表 */
|
|
116
74
|
export declare const VALID_CARD_TYPES: string[];
|
|
117
|
-
/** 模板卡片缓存条目 TTL(毫秒):24小时 */
|
|
118
|
-
export declare const TEMPLATE_CARD_CACHE_TTL_MS: number;
|
|
119
|
-
/** 模板卡片缓存最大条目数 */
|
|
120
|
-
export declare const TEMPLATE_CARD_CACHE_MAX_SIZE = 300;
|
|
@@ -29,6 +29,8 @@ export interface MessageState {
|
|
|
29
29
|
hasMediaFailed?: boolean;
|
|
30
30
|
/** 媒体发送失败时的纯文本错误摘要(用于替换 thinking 流展示给用户) */
|
|
31
31
|
mediaErrorSummary?: string;
|
|
32
|
+
/** deliver 回调是否被调用过(用于区分"核心无回复"和"核心回复了空内容") */
|
|
33
|
+
deliverCalled?: boolean;
|
|
32
34
|
/** 流式回复是否已过期(errcode 846608,>6分钟),需降级为主动发送 */
|
|
33
35
|
streamExpired?: boolean;
|
|
34
36
|
/** 是否已成功发送过模板卡片 */
|
|
@@ -32,21 +32,3 @@ export declare function sendWeComReply(params: {
|
|
|
32
32
|
/** 指定 streamId,用于流式回复时保持相同的 streamId */
|
|
33
33
|
streamId?: string;
|
|
34
34
|
}): Promise<string>;
|
|
35
|
-
/**
|
|
36
|
-
* 非阻塞流式文本回复
|
|
37
|
-
*
|
|
38
|
-
* 基于 SDK 的 replyStreamNonBlocking 方法:
|
|
39
|
-
* - 如果上一条同 reqId 的消息尚未收到 ack,则跳过本次发送(返回 'skipped'),
|
|
40
|
-
* 避免流式中间帧排队积压导致延迟。
|
|
41
|
-
* - finish=true 的最终帧不受此限制,始终保证发送。
|
|
42
|
-
*
|
|
43
|
-
* @returns 'skipped' 表示被跳过,否则返回 streamId
|
|
44
|
-
*/
|
|
45
|
-
export declare function sendWeComReplyNonBlocking(params: {
|
|
46
|
-
wsClient: WSClient;
|
|
47
|
-
frame: WsFrame;
|
|
48
|
-
text: string;
|
|
49
|
-
runtime: RuntimeEnv;
|
|
50
|
-
streamId: string;
|
|
51
|
-
finish?: boolean;
|
|
52
|
-
}): Promise<string | 'skipped'>;
|
|
@@ -51,8 +51,6 @@ export declare function loadOutboundMediaFromUrl(mediaUrl: string, options?: Out
|
|
|
51
51
|
* SDK 引用在模块加载时异步探测并缓存,调用时同步读取缓存。
|
|
52
52
|
*/
|
|
53
53
|
export declare function addWildcardAllowFrom(allowFrom: string[]): string[];
|
|
54
|
-
/** 通过框架 PluginRuntime 获取 openclaw 状态目录(避免直接访问环境变量) */
|
|
55
|
-
export declare function resolveStateDir(): string;
|
|
56
54
|
/**
|
|
57
55
|
* 获取默认媒体本地路径白名单(兼容入口)
|
|
58
56
|
*
|
|
@@ -96,50 +94,3 @@ export declare function buildAccountScopedDmSecurityPolicy(params: {
|
|
|
96
94
|
* @returns 配对审批提示字符串
|
|
97
95
|
*/
|
|
98
96
|
export declare function formatPairingApproveHint(channelId: string): string;
|
|
99
|
-
/**
|
|
100
|
-
* 与 openclaw plugin-sdk/channel-policy 中 ChannelSecurityDmPolicy 兼容的类型。
|
|
101
|
-
* 低版本 SDK 未导出该方法时,使用此 fallback。
|
|
102
|
-
*/
|
|
103
|
-
export type ChannelSecurityDmPolicyCompat = {
|
|
104
|
-
policy: string;
|
|
105
|
-
allowFrom?: Array<string | number> | null;
|
|
106
|
-
policyPath?: string;
|
|
107
|
-
allowFromPath: string;
|
|
108
|
-
approveHint: string;
|
|
109
|
-
normalizeEntry?: (raw: string) => string;
|
|
110
|
-
};
|
|
111
|
-
declare global {
|
|
112
|
-
namespace openclaw.plugin.sdk {
|
|
113
|
-
interface ChannelSecurityDmPolicy {
|
|
114
|
-
policy: string;
|
|
115
|
-
allowFrom?: Array<string | number> | null;
|
|
116
|
-
policyPath?: string;
|
|
117
|
-
allowFromPath: string;
|
|
118
|
-
approveHint: string;
|
|
119
|
-
normalizeEntry?: (raw: string) => string;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
export type BuildAccountScopedDmSecurityPolicyParams = {
|
|
124
|
-
cfg: {
|
|
125
|
-
channels?: Record<string, unknown>;
|
|
126
|
-
};
|
|
127
|
-
channelKey: string;
|
|
128
|
-
accountId?: string | null;
|
|
129
|
-
fallbackAccountId?: string | null;
|
|
130
|
-
policy?: string | null;
|
|
131
|
-
allowFrom?: Array<string | number> | null;
|
|
132
|
-
defaultPolicy?: string;
|
|
133
|
-
allowFromPathSuffix?: string;
|
|
134
|
-
policyPathSuffix?: string;
|
|
135
|
-
approveChannelId?: string;
|
|
136
|
-
approveHint?: string;
|
|
137
|
-
normalizeEntry?: (raw: string) => string;
|
|
138
|
-
};
|
|
139
|
-
/**
|
|
140
|
-
* 构建多账号作用域的 DM 安全策略(兼容入口)
|
|
141
|
-
*
|
|
142
|
-
* 优先使用 SDK 版本(openclaw/plugin-sdk/channel-policy),
|
|
143
|
-
* 不可用时使用 fallback 实现。
|
|
144
|
-
*/
|
|
145
|
-
export declare function buildAccountScopedDmSecurityPolicyCompat(params: BuildAccountScopedDmSecurityPolicyParams): Promise<ChannelSecurityDmPolicyCompat>;
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
* 企业微信公共工具函数
|
|
3
3
|
*/
|
|
4
4
|
import type { OpenClawConfig } from "openclaw/plugin-sdk/core";
|
|
5
|
-
import type { ResolvedAgentAccount } from "./types/account.js";
|
|
6
|
-
import type { WecomAgentConfig, WecomNetworkConfig, WecomMediaConfig } from "./types/config.js";
|
|
7
5
|
/**
|
|
8
6
|
* 企业微信群组配置
|
|
9
7
|
*/
|
|
@@ -32,30 +30,7 @@ export interface WeComConfig {
|
|
|
32
30
|
sendThinkingMessage?: boolean;
|
|
33
31
|
/** 额外允许访问的本地媒体路径白名单(支持 ~ 表示 home 目录),如 ["~/Downloads", "~/Documents"] */
|
|
34
32
|
mediaLocalRoots?: string[];
|
|
35
|
-
/** Agent 模式配置(自建应用) */
|
|
36
|
-
agent?: WecomAgentConfig;
|
|
37
|
-
/** 网络配置 */
|
|
38
|
-
network?: WecomNetworkConfig;
|
|
39
|
-
/** 媒体处理配置 */
|
|
40
|
-
media?: WecomMediaConfig;
|
|
41
|
-
/** 连接模式:webhook | websocket(默认 websocket) */
|
|
42
|
-
connectionMode?: "webhook" | "websocket";
|
|
43
|
-
/** Webhook 验证 token */
|
|
44
|
-
token?: string;
|
|
45
|
-
/** AES 加密密钥(43 字符 Base64) */
|
|
46
|
-
encodingAESKey?: string;
|
|
47
|
-
/** 接收方 ID */
|
|
48
|
-
receiveId?: string;
|
|
49
|
-
/** enter_chat 欢迎消息 */
|
|
50
|
-
welcomeText?: string;
|
|
51
|
-
/** 流式占位符提示内容 */
|
|
52
|
-
streamPlaceholderContent?: string;
|
|
53
33
|
}
|
|
54
|
-
/**
|
|
55
|
-
* 单个企业微信账号的配置类型(用于 accounts 字段下的每个账号)。
|
|
56
|
-
* 与 WeComConfig 字段完全一致,账号级字段会覆盖顶层同名字段。
|
|
57
|
-
*/
|
|
58
|
-
export type WeComAccountConfig = Partial<WeComConfig>;
|
|
59
34
|
export declare const DefaultWsUrl = "wss://openws.work.weixin.qq.com";
|
|
60
35
|
export interface ResolvedWeComAccount {
|
|
61
36
|
accountId: string;
|
|
@@ -67,12 +42,6 @@ export interface ResolvedWeComAccount {
|
|
|
67
42
|
/** 是否发送"思考中"消息,默认为 true */
|
|
68
43
|
sendThinkingMessage: boolean;
|
|
69
44
|
config: WeComConfig;
|
|
70
|
-
/** Agent 模式能力(自建应用) */
|
|
71
|
-
agent?: ResolvedAgentAccount;
|
|
72
|
-
/** Webhook 模式配置 */
|
|
73
|
-
token?: string;
|
|
74
|
-
encodingAESKey?: string;
|
|
75
|
-
receiveId?: string;
|
|
76
45
|
}
|
|
77
46
|
/**
|
|
78
47
|
* 解析企业微信账户配置
|
|
@@ -82,11 +51,3 @@ export declare function resolveWeComAccount(cfg: OpenClawConfig): ResolvedWeComA
|
|
|
82
51
|
* 设置企业微信账户配置
|
|
83
52
|
*/
|
|
84
53
|
export declare function setWeComAccount(cfg: OpenClawConfig, account: Partial<WeComConfig>): OpenClawConfig;
|
|
85
|
-
/**
|
|
86
|
-
* 解析出口代理 URL(对齐原版 resolveWecomEgressProxyUrl)
|
|
87
|
-
*
|
|
88
|
-
* 优先级:
|
|
89
|
-
* 1. config.channels.wecom.network.egressProxyUrl
|
|
90
|
-
* 2. 环境变量:OPENCLAW_WECOM_EGRESS_PROXY_URL → WECOM_EGRESS_PROXY_URL → HTTPS_PROXY → ALL_PROXY → HTTP_PROXY
|
|
91
|
-
*/
|
|
92
|
-
export declare function resolveWecomEgressProxyUrl(cfg: OpenClawConfig): string | undefined;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { OpenClawPluginApi } from 'openclaw/plugin-sdk/core';
|
|
2
|
+
|
|
2
3
|
declare const plugin: {
|
|
3
4
|
id: string;
|
|
4
5
|
name: string;
|
|
@@ -6,4 +7,5 @@ declare const plugin: {
|
|
|
6
7
|
configSchema: Record<string, unknown>;
|
|
7
8
|
register(api: OpenClawPluginApi): void;
|
|
8
9
|
};
|
|
9
|
-
|
|
10
|
+
|
|
11
|
+
export { plugin as default };
|
package/package.json
CHANGED
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wecom/wecom-openclaw-plugin",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.4.1-beta.1",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"main": "dist/index.js",
|
|
5
|
+
"main": "dist/cjs/index.js",
|
|
6
|
+
"module": "dist/esm/index.js",
|
|
6
7
|
"types": "dist/index.d.ts",
|
|
7
|
-
"exports": {
|
|
8
|
-
".": {
|
|
9
|
-
"types": "./dist/index.d.ts",
|
|
10
|
-
"import": "./dist/index.js"
|
|
11
|
-
}
|
|
12
|
-
},
|
|
13
8
|
"files": [
|
|
14
9
|
"dist",
|
|
15
10
|
"skills",
|
|
@@ -17,8 +12,8 @@
|
|
|
17
12
|
"README.md"
|
|
18
13
|
],
|
|
19
14
|
"scripts": {
|
|
20
|
-
"build": "
|
|
21
|
-
"dev": "
|
|
15
|
+
"build": "rollup -c",
|
|
16
|
+
"dev": "rollup -c -w",
|
|
22
17
|
"clean": "rm -rf dist",
|
|
23
18
|
"prebuild": "npm run clean",
|
|
24
19
|
"release": "node scripts/publish-all.mjs",
|
|
@@ -42,7 +37,7 @@
|
|
|
42
37
|
"description": "OpenClaw WeCom (企业微信) channel plugin (official by Tencent WeCom team)",
|
|
43
38
|
"openclaw": {
|
|
44
39
|
"extensions": [
|
|
45
|
-
"./dist/index.js"
|
|
40
|
+
"./dist/index.esm.js"
|
|
46
41
|
],
|
|
47
42
|
"channel": {
|
|
48
43
|
"id": "wecom",
|
|
@@ -61,10 +56,7 @@
|
|
|
61
56
|
}
|
|
62
57
|
},
|
|
63
58
|
"dependencies": {
|
|
64
|
-
"@wecom/aibot-node-sdk": "1.0.5-beta.1",
|
|
65
|
-
"fast-xml-parser": "^5.5.9",
|
|
66
59
|
"file-type": "^21.3.0",
|
|
67
|
-
"
|
|
68
|
-
"zod": "^4.3.6"
|
|
60
|
+
"@wecom/aibot-node-sdk": "^1.0.4"
|
|
69
61
|
}
|
|
70
62
|
}
|
package/dist/index.js
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import { emptyPluginConfigSchema } from "./src/openclaw-compat.js";
|
|
2
|
-
import { wecomPlugin } from "./src/channel.js";
|
|
3
|
-
import { createWeComMcpTool } from "./src/mcp/index.js";
|
|
4
|
-
import { setWeComRuntime } from "./src/runtime.js";
|
|
5
|
-
import { CHANNEL_ID, WEBHOOK_PATHS } from "./src/const.js";
|
|
6
|
-
import { handleWecomAgentWebhookRequest } from "./src/agent/webhook.js";
|
|
7
|
-
import { handleWecomWebhookRequest } from "./src/webhook/index.js";
|
|
8
|
-
// ============================================================================
|
|
9
|
-
// 需要自动注入 tools.alsoAllow 的工具名列表
|
|
10
|
-
// ============================================================================
|
|
11
|
-
const REQUIRED_ALSO_ALLOW_TOOLS = ["wecom_mcp"];
|
|
12
|
-
/**
|
|
13
|
-
* 确保 tools.alsoAllow 中包含插件所需的工具名。
|
|
14
|
-
*
|
|
15
|
-
* 逻辑:
|
|
16
|
-
* 1. 读取当前配置
|
|
17
|
-
* 2. 检查 tools.alsoAllow 中是否已包含所需工具
|
|
18
|
-
* 3. 如有缺失,合并写入配置文件
|
|
19
|
-
*
|
|
20
|
-
* 幂等操作——重复调用不会产生副作用。
|
|
21
|
-
* 若 tools.allow 已显式设置(与 alsoAllow 互斥),则跳过注入并打印提示。
|
|
22
|
-
*/
|
|
23
|
-
async function ensureToolsAlsoAllow(api) {
|
|
24
|
-
try {
|
|
25
|
-
const cfg = api.runtime.config.loadConfig();
|
|
26
|
-
const tools = cfg.tools ?? {};
|
|
27
|
-
// 如果用户显式配置了 tools.allow(全量白名单),则 alsoAllow 与之互斥,
|
|
28
|
-
// 此时不应自动追加 alsoAllow,避免产生校验冲突
|
|
29
|
-
if (tools.allow && tools.allow.length > 0) {
|
|
30
|
-
const missing = REQUIRED_ALSO_ALLOW_TOOLS.filter((t) => !tools.allow.includes(t));
|
|
31
|
-
if (missing.length > 0) {
|
|
32
|
-
console.warn(`[wecom] tools.allow 已显式设置,无法自动注入 alsoAllow。` +
|
|
33
|
-
`请手动将 ${JSON.stringify(missing)} 加入 tools.allow。`);
|
|
34
|
-
}
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
const existing = tools.alsoAllow ?? [];
|
|
38
|
-
const missing = REQUIRED_ALSO_ALLOW_TOOLS.filter((t) => !existing.includes(t));
|
|
39
|
-
if (missing.length === 0) {
|
|
40
|
-
// 所有工具已在白名单中,无需操作
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
const merged = [...existing, ...missing];
|
|
44
|
-
const nextConfig = {
|
|
45
|
-
...cfg,
|
|
46
|
-
tools: {
|
|
47
|
-
...tools,
|
|
48
|
-
alsoAllow: merged,
|
|
49
|
-
},
|
|
50
|
-
};
|
|
51
|
-
await api.runtime.config.writeConfigFile(nextConfig);
|
|
52
|
-
console.log(`[wecom] 已自动将 ${JSON.stringify(missing)} 加入 tools.alsoAllow`);
|
|
53
|
-
}
|
|
54
|
-
catch (err) {
|
|
55
|
-
// 配置写入失败不应阻断 Gateway 启动
|
|
56
|
-
console.error(`[wecom] 自动注入 tools.alsoAllow 失败:`, err instanceof Error ? err.message : String(err));
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
const plugin = {
|
|
60
|
-
id: "wecom-openclaw-plugin",
|
|
61
|
-
name: "企业微信",
|
|
62
|
-
description: "企业微信 OpenClaw 插件",
|
|
63
|
-
configSchema: emptyPluginConfigSchema(),
|
|
64
|
-
register(api) {
|
|
65
|
-
setWeComRuntime(api.runtime);
|
|
66
|
-
api.registerChannel({ plugin: wecomPlugin });
|
|
67
|
-
// 注册 wecom_mcp:通过 HTTP 直接调用企业微信 MCP Server
|
|
68
|
-
api.registerTool(createWeComMcpTool(), { name: "wecom_mcp" });
|
|
69
|
-
// 注册 Agent 模式 HTTP 路由(prefix match 覆盖带 accountId 的子路径)
|
|
70
|
-
api.registerHttpRoute({
|
|
71
|
-
path: WEBHOOK_PATHS.AGENT_PLUGIN,
|
|
72
|
-
handler: handleWecomAgentWebhookRequest,
|
|
73
|
-
auth: "plugin",
|
|
74
|
-
match: "prefix",
|
|
75
|
-
});
|
|
76
|
-
api.registerHttpRoute({
|
|
77
|
-
path: WEBHOOK_PATHS.AGENT,
|
|
78
|
-
handler: handleWecomAgentWebhookRequest,
|
|
79
|
-
auth: "plugin",
|
|
80
|
-
match: "prefix",
|
|
81
|
-
});
|
|
82
|
-
// ── 注册 bot Webhook HTTP 路由 ────────────────────────────────────────
|
|
83
|
-
// 前缀匹配模式,同时覆盖 /plugins/wecom 和 /wecom 路径
|
|
84
|
-
const webhookRoutes = [WEBHOOK_PATHS.BOT_PLUGIN, WEBHOOK_PATHS.BOT_ALT, WEBHOOK_PATHS.BOT];
|
|
85
|
-
for (const routePath of webhookRoutes) {
|
|
86
|
-
api.registerHttpRoute({
|
|
87
|
-
path: routePath,
|
|
88
|
-
handler: handleWecomWebhookRequest,
|
|
89
|
-
auth: "plugin",
|
|
90
|
-
match: "prefix",
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
// ── Gateway 启动时自动确保 tools.alsoAllow 包含 wecom_mcp ──────────
|
|
94
|
-
// 在 gateway_start 阶段检测并写入,保证插件安装/更新后首次启动即生效
|
|
95
|
-
// api.on("gateway_start", async () => {
|
|
96
|
-
// await ensureToolsAlsoAllow(api);
|
|
97
|
-
// });
|
|
98
|
-
// 注入媒体发送指令和文件大小限制提示词(仅对企业微信 channel 生效)
|
|
99
|
-
api.on("before_prompt_build", (_event, ctx) => {
|
|
100
|
-
// 只在企业微信 channel 的会话中注入,避免影响其他 channel 插件
|
|
101
|
-
if (ctx?.channelId !== CHANNEL_ID) {
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
return {
|
|
105
|
-
appendSystemContext: [
|
|
106
|
-
"重要:涉及发送图片/视频/语音/文件给用户时,请务必使用 `MEDIA:` 指令。详见 wecom-send-media 这个 skill(技能)。",
|
|
107
|
-
"重要:当需要向用户发送结构化卡片消息(如通知、投票、按钮选择等)时,请在回复中直接输出 JSON 代码块(```json ... ```),其中 card_type 字段标明卡片类型。详见 wecom-send-template-card 技能。"
|
|
108
|
-
].join("\n"),
|
|
109
|
-
};
|
|
110
|
-
});
|
|
111
|
-
},
|
|
112
|
-
};
|
|
113
|
-
export default plugin;
|
package/dist/src/accounts.d.ts
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import type { OpenClawConfig } from "openclaw/plugin-sdk";
|
|
2
|
-
import type { WeComConfig, WeComAccountConfig, ResolvedWeComAccount } from "./utils.js";
|
|
3
|
-
/**
|
|
4
|
-
* 企业微信多账号配置结构(扩展 WeComConfig)
|
|
5
|
-
*/
|
|
6
|
-
export interface WeComMultiAccountConfig extends WeComConfig {
|
|
7
|
-
/** 默认账号 ID */
|
|
8
|
-
defaultAccount?: string;
|
|
9
|
-
/** 多账号配置 */
|
|
10
|
-
accounts?: Record<string, WeComAccountConfig>;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* 判断是否为多账号模式(即配置中存在 accounts 字段)。
|
|
14
|
-
* 用于区分单账号/多账号模式的分支判断,替代 `accountId === DEFAULT_ACCOUNT_ID` 的不可靠判断。
|
|
15
|
-
*/
|
|
16
|
-
export declare function hasMultiAccounts(cfg: OpenClawConfig): boolean;
|
|
17
|
-
/**
|
|
18
|
-
* 列出所有企业微信账号 ID。
|
|
19
|
-
* 如果没有 accounts 字段,返回 [DEFAULT_ACCOUNT_ID] 以向后兼容。
|
|
20
|
-
*/
|
|
21
|
-
export declare function listWeComAccountIds(cfg: OpenClawConfig): string[];
|
|
22
|
-
/**
|
|
23
|
-
* 解析默认账号 ID。
|
|
24
|
-
*
|
|
25
|
-
* 优先级:
|
|
26
|
-
* 1. 显式设置的 defaultAccount
|
|
27
|
-
* 2. 包含 DEFAULT_ACCOUNT_ID 的账号列表
|
|
28
|
-
* 3. 字母序第一个账号
|
|
29
|
-
*/
|
|
30
|
-
export declare function resolveDefaultWeComAccountId(cfg: OpenClawConfig): string;
|
|
31
|
-
/**
|
|
32
|
-
* 解析单个企业微信账号的完整配置。
|
|
33
|
-
*
|
|
34
|
-
* 支持:
|
|
35
|
-
* - 显式指定 accountId → 使用该 accountId
|
|
36
|
-
* - 未指定 → 使用默认账号
|
|
37
|
-
* - 单账号模式(无 accounts 字段) → 直接读取顶层配置
|
|
38
|
-
*/
|
|
39
|
-
export declare function resolveWeComAccountMulti(params: {
|
|
40
|
-
cfg: OpenClawConfig;
|
|
41
|
-
accountId?: string | null;
|
|
42
|
-
}): ResolvedWeComAccount;
|
|
43
|
-
/**
|
|
44
|
-
* 列出所有已启用且已配置凭据的账号。
|
|
45
|
-
*/
|
|
46
|
-
export declare function listEnabledWeComAccounts(cfg: OpenClawConfig): ResolvedWeComAccount[];
|
|
47
|
-
/**
|
|
48
|
-
* 写入企业微信账户配置(自动区分单账号/多账号模式)。
|
|
49
|
-
*
|
|
50
|
-
* - 单账号模式(无 accounts 字段):写入顶层 channels.wecom
|
|
51
|
-
* - 多账号模式:写入 channels.wecom.accounts[accountId]
|
|
52
|
-
*
|
|
53
|
-
* @param cfg 当前全局配置
|
|
54
|
-
* @param updates 要写入的部分配置字段
|
|
55
|
-
* @param accountId 目标账号 ID(默认写入默认账号)
|
|
56
|
-
*/
|
|
57
|
-
export declare function setWeComAccountMulti(cfg: OpenClawConfig, updates: Partial<WeComConfig>, accountId?: string): OpenClawConfig;
|