ylib-wecom-openclaw-plugin 2026.4.29
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 +596 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +99 -0
- package/dist/src/accounts.d.ts +57 -0
- package/dist/src/accounts.js +247 -0
- package/dist/src/agent/api-client.d.ts +95 -0
- package/dist/src/agent/api-client.js +425 -0
- package/dist/src/agent/handler.d.ts +64 -0
- package/dist/src/agent/handler.js +731 -0
- package/dist/src/agent/index.d.ts +5 -0
- package/dist/src/agent/index.js +21 -0
- package/dist/src/agent/webhook.d.ts +25 -0
- package/dist/src/agent/webhook.js +294 -0
- package/dist/src/agent/xml.d.ts +21 -0
- package/dist/src/agent/xml.js +43 -0
- package/dist/src/channel.d.ts +5 -0
- package/dist/src/channel.js +815 -0
- package/dist/src/chat-queue.d.ts +31 -0
- package/dist/src/chat-queue.js +53 -0
- package/dist/src/config-schema.d.ts +587 -0
- package/dist/src/config-schema.js +146 -0
- package/dist/src/const.d.ts +128 -0
- package/dist/src/const.js +168 -0
- package/dist/src/dm-policy.d.ts +29 -0
- package/dist/src/dm-policy.js +146 -0
- package/dist/src/dynamic-agent.d.ts +37 -0
- package/dist/src/dynamic-agent.js +67 -0
- package/dist/src/dynamic-routing.d.ts +65 -0
- package/dist/src/dynamic-routing.js +62 -0
- package/dist/src/endpoint-dispatch.d.ts +54 -0
- package/dist/src/endpoint-dispatch.js +967 -0
- package/dist/src/endpoint-event-adapter.d.ts +15 -0
- package/dist/src/endpoint-event-adapter.js +427 -0
- package/dist/src/group-policy.d.ts +30 -0
- package/dist/src/group-policy.js +126 -0
- package/dist/src/http.d.ts +27 -0
- package/dist/src/http.js +168 -0
- package/dist/src/im-runtime-telemetry.d.ts +25 -0
- package/dist/src/im-runtime-telemetry.js +68 -0
- package/dist/src/interface.d.ts +192 -0
- package/dist/src/interface.js +5 -0
- package/dist/src/markdown-chunk.d.ts +1 -0
- package/dist/src/markdown-chunk.js +396 -0
- package/dist/src/mcp/index.d.ts +6 -0
- package/dist/src/mcp/index.js +28 -0
- package/dist/src/mcp/interceptors/biz-error.d.ts +11 -0
- package/dist/src/mcp/interceptors/biz-error.js +73 -0
- package/dist/src/mcp/interceptors/doc-auth-error.d.ts +10 -0
- package/dist/src/mcp/interceptors/doc-auth-error.js +235 -0
- package/dist/src/mcp/interceptors/index.d.ts +35 -0
- package/dist/src/mcp/interceptors/index.js +143 -0
- package/dist/src/mcp/interceptors/msg-media.d.ts +11 -0
- package/dist/src/mcp/interceptors/msg-media.js +201 -0
- package/dist/src/mcp/interceptors/smartpage-create.d.ts +30 -0
- package/dist/src/mcp/interceptors/smartpage-create.js +252 -0
- package/dist/src/mcp/interceptors/smartpage-export.d.ts +17 -0
- package/dist/src/mcp/interceptors/smartpage-export.js +135 -0
- package/dist/src/mcp/interceptors/smartsheet-upload.d.ts +22 -0
- package/dist/src/mcp/interceptors/smartsheet-upload.js +388 -0
- package/dist/src/mcp/interceptors/types.d.ts +64 -0
- package/dist/src/mcp/interceptors/types.js +8 -0
- package/dist/src/mcp/schema.d.ts +11 -0
- package/dist/src/mcp/schema.js +115 -0
- package/dist/src/mcp/tool.d.ts +63 -0
- package/dist/src/mcp/tool.js +318 -0
- package/dist/src/mcp/transport.d.ts +94 -0
- package/dist/src/mcp/transport.js +702 -0
- package/dist/src/media-handler.d.ts +55 -0
- package/dist/src/media-handler.js +306 -0
- package/dist/src/media-uploader.d.ts +142 -0
- package/dist/src/media-uploader.js +446 -0
- package/dist/src/message-parser.d.ts +104 -0
- package/dist/src/message-parser.js +232 -0
- package/dist/src/message-sender.d.ts +54 -0
- package/dist/src/message-sender.js +210 -0
- package/dist/src/monitor.d.ts +69 -0
- package/dist/src/monitor.js +1846 -0
- package/dist/src/onboarding.d.ts +8 -0
- package/dist/src/onboarding.js +248 -0
- package/dist/src/openclaw-compat.d.ts +148 -0
- package/dist/src/openclaw-compat.js +839 -0
- package/dist/src/proactive-markdown-send.d.ts +14 -0
- package/dist/src/proactive-markdown-send.js +205 -0
- package/dist/src/reqid-store.d.ts +23 -0
- package/dist/src/reqid-store.js +136 -0
- package/dist/src/runtime.d.ts +2 -0
- package/dist/src/runtime.js +7 -0
- package/dist/src/shared/command-auth.d.ts +23 -0
- package/dist/src/shared/command-auth.js +112 -0
- package/dist/src/shared/xml-parser.d.ts +46 -0
- package/dist/src/shared/xml-parser.js +228 -0
- package/dist/src/state-dir-resolve.d.ts +2 -0
- package/dist/src/state-dir-resolve.js +33 -0
- package/dist/src/state-manager.d.ts +115 -0
- package/dist/src/state-manager.js +413 -0
- package/dist/src/target.d.ts +35 -0
- package/dist/src/target.js +71 -0
- package/dist/src/template-card-manager.d.ts +55 -0
- package/dist/src/template-card-manager.js +316 -0
- package/dist/src/template-card-parser.d.ts +37 -0
- package/dist/src/template-card-parser.js +672 -0
- package/dist/src/timeout.d.ts +20 -0
- package/dist/src/timeout.js +57 -0
- package/dist/src/types/account.d.ts +29 -0
- package/dist/src/types/account.js +5 -0
- package/dist/src/types/config.d.ts +98 -0
- package/dist/src/types/config.js +8 -0
- package/dist/src/types/constants.d.ts +42 -0
- package/dist/src/types/constants.js +45 -0
- package/dist/src/types/index.d.ts +7 -0
- package/dist/src/types/index.js +17 -0
- package/dist/src/types/message.d.ts +238 -0
- package/dist/src/types/message.js +6 -0
- package/dist/src/utils.d.ts +148 -0
- package/dist/src/utils.js +92 -0
- package/dist/src/version.d.ts +2 -0
- package/dist/src/version.js +28 -0
- package/dist/src/webhook/command-auth.d.ts +47 -0
- package/dist/src/webhook/command-auth.js +137 -0
- package/dist/src/webhook/gateway.d.ts +36 -0
- package/dist/src/webhook/gateway.js +297 -0
- package/dist/src/webhook/handler.d.ts +19 -0
- package/dist/src/webhook/handler.js +481 -0
- package/dist/src/webhook/helpers.d.ts +157 -0
- package/dist/src/webhook/helpers.js +936 -0
- package/dist/src/webhook/http.d.ts +27 -0
- package/dist/src/webhook/http.js +168 -0
- package/dist/src/webhook/index.d.ts +11 -0
- package/dist/src/webhook/index.js +43 -0
- package/dist/src/webhook/media.d.ts +30 -0
- package/dist/src/webhook/media.js +152 -0
- package/dist/src/webhook/monitor.d.ts +59 -0
- package/dist/src/webhook/monitor.js +1672 -0
- package/dist/src/webhook/state.d.ts +220 -0
- package/dist/src/webhook/state.js +568 -0
- package/dist/src/webhook/target.d.ts +41 -0
- package/dist/src/webhook/target.js +165 -0
- package/dist/src/webhook/types.d.ts +348 -0
- package/dist/src/webhook/types.js +36 -0
- package/dist/src/webhook/video-frame.d.ts +13 -0
- package/dist/src/webhook/video-frame.js +108 -0
- package/openclaw.plugin.json +19 -0
- package/package.json +96 -0
- package/schema.json +534 -0
- package/scripts/generate-schema.mjs +33 -0
- package/skills/wecom-contact/SKILL.md +162 -0
- package/skills/wecom-doc/SKILL.md +162 -0
- package/skills/wecom-doc/references/create-doc.md +56 -0
- package/skills/wecom-doc/references/edit-doc-content.md +68 -0
- package/skills/wecom-doc/references/get-doc-content.md +88 -0
- package/skills/wecom-doc/references/smartpage-create.md +125 -0
- package/skills/wecom-doc/references/smartpage-export.md +160 -0
- package/skills/wecom-meeting/SKILL.md +441 -0
- package/skills/wecom-meeting/references/example-full.md +30 -0
- package/skills/wecom-meeting/references/example-reminder.md +46 -0
- package/skills/wecom-meeting/references/example-security.md +22 -0
- package/skills/wecom-meeting/references/response-get-meeting-info.md +148 -0
- package/skills/wecom-msg/SKILL.md +157 -0
- package/skills/wecom-msg/references/api-get-messages.md +93 -0
- package/skills/wecom-msg/references/api-get-msg-chat-list.md +58 -0
- package/skills/wecom-msg/references/api-get-msg-media.md +44 -0
- package/skills/wecom-msg/references/api-send-message.md +39 -0
- package/skills/wecom-preflight/SKILL.md +141 -0
- package/skills/wecom-schedule/SKILL.md +161 -0
- package/skills/wecom-schedule/references/api-check-availability.md +56 -0
- package/skills/wecom-schedule/references/api-create-schedule.md +38 -0
- package/skills/wecom-schedule/references/api-get-schedule-detail.md +81 -0
- package/skills/wecom-schedule/references/api-update-schedule.md +32 -0
- package/skills/wecom-schedule/references/ref-reminders.md +24 -0
- package/skills/wecom-send-media/SKILL.md +68 -0
- package/skills/wecom-send-template-card/SKILL.md +157 -0
- package/skills/wecom-send-template-card/references/api-template-card-types.md +358 -0
- package/skills/wecom-smartsheet/SKILL.md +164 -0
- package/skills/wecom-smartsheet/references/smartsheet-cell-value-formats.md +163 -0
- package/skills/wecom-smartsheet/references/smartsheet-field-types.md +44 -0
- package/skills/wecom-smartsheet/references/smartsheet-get-records.md +96 -0
- package/skills/wecom-smartsheet/references/webhook-examples.md +185 -0
- package/skills/wecom-smartsheet/references/webhook-fallback.md +184 -0
- package/skills/wecom-todo/SKILL.md +392 -0
- package/skills/wecom-todo/examples/workflows.md +163 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
exports.__esModule = true;
|
|
3
|
+
exports.WeComConfigSchema = void 0;
|
|
4
|
+
var zod_1 = require("zod");
|
|
5
|
+
var wecomAgentSchema = zod_1.z
|
|
6
|
+
.object({
|
|
7
|
+
corpId: zod_1.z.string().optional(),
|
|
8
|
+
corpSecret: zod_1.z.string().optional(),
|
|
9
|
+
agentId: zod_1.z.union([zod_1.z.string(), zod_1.z.number()]).optional(),
|
|
10
|
+
token: zod_1.z.string().optional(),
|
|
11
|
+
encodingAESKey: zod_1.z.string().optional()
|
|
12
|
+
})
|
|
13
|
+
.passthrough();
|
|
14
|
+
var wecomNetworkSchema = zod_1.z
|
|
15
|
+
.object({
|
|
16
|
+
egressProxyUrl: zod_1.z.string().optional()
|
|
17
|
+
})
|
|
18
|
+
.passthrough();
|
|
19
|
+
var wecomMediaSchema = zod_1.z
|
|
20
|
+
.object({
|
|
21
|
+
maxFileSizeMB: zod_1.z.number().optional(),
|
|
22
|
+
allowedMimeTypes: zod_1.z.array(zod_1.z.string()).optional()
|
|
23
|
+
})
|
|
24
|
+
.passthrough();
|
|
25
|
+
var wecomDynamicAgentsSchema = zod_1.z
|
|
26
|
+
.object({
|
|
27
|
+
enabled: zod_1.z.boolean().optional(),
|
|
28
|
+
mappings: zod_1.z.record(zod_1.z.string(), zod_1.z.any()).optional()
|
|
29
|
+
})
|
|
30
|
+
.passthrough();
|
|
31
|
+
var wecomAccountSchema = zod_1.z.object({
|
|
32
|
+
// -------------------------------------------------------------------------
|
|
33
|
+
// 基础账号信息
|
|
34
|
+
// -------------------------------------------------------------------------
|
|
35
|
+
/** 账号显示名称(仅用于展示和日志)。 */
|
|
36
|
+
name: zod_1.z.string().optional(),
|
|
37
|
+
/** 是否启用该账号。 */
|
|
38
|
+
enabled: zod_1.z.boolean().optional(),
|
|
39
|
+
/** Bot WebSocket 地址。 */
|
|
40
|
+
websocketUrl: zod_1.z.string().optional(),
|
|
41
|
+
/** Bot 模式凭证:botId。 */
|
|
42
|
+
botId: zod_1.z.string().optional(),
|
|
43
|
+
/** Bot 模式凭证:secret。 */
|
|
44
|
+
secret: zod_1.z.string().optional(),
|
|
45
|
+
// -------------------------------------------------------------------------
|
|
46
|
+
// Bot 连接模式字段(固定 WebSocket)
|
|
47
|
+
// -------------------------------------------------------------------------
|
|
48
|
+
/** 连接模式:固定 `websocket`(只读,不可编辑)。 */
|
|
49
|
+
connectionMode: zod_1.z["enum"](["websocket"])
|
|
50
|
+
.optional()["default"]("websocket")
|
|
51
|
+
.meta({ readOnly: true, description: "企业微信仅支持 websocket(固定值,不可修改)" }),
|
|
52
|
+
/** Bot Webhook token。 */
|
|
53
|
+
token: zod_1.z.string().optional(),
|
|
54
|
+
/** Bot Webhook AES Key。 */
|
|
55
|
+
encodingAESKey: zod_1.z.string().optional(),
|
|
56
|
+
/** Bot Webhook receiveId。 */
|
|
57
|
+
receiveId: zod_1.z.string().optional(),
|
|
58
|
+
/** enter_chat 欢迎语。 */
|
|
59
|
+
welcomeText: zod_1.z.string().optional(),
|
|
60
|
+
/** 流式首帧占位文案。 */
|
|
61
|
+
streamPlaceholderContent: zod_1.z.string().optional(),
|
|
62
|
+
// -------------------------------------------------------------------------
|
|
63
|
+
// Python Endpoint / Gateway 字段
|
|
64
|
+
// -------------------------------------------------------------------------
|
|
65
|
+
/** Python/Gateway 基础地址。 */
|
|
66
|
+
gatewayBaseUrl: zod_1.z.string().optional(),
|
|
67
|
+
/** Gateway 鉴权令牌。 */
|
|
68
|
+
gatewayToken: zod_1.z.string().optional(),
|
|
69
|
+
/** 媒体上传基址。 */
|
|
70
|
+
uploadHost: zod_1.z.string().optional(),
|
|
71
|
+
/** endpoint 调用模型名(默认 `main`)。 */
|
|
72
|
+
modelName: zod_1.z.string().optional()["default"]("main"),
|
|
73
|
+
/** endpoint 调用 agentId(默认 `main`)。 */
|
|
74
|
+
agentId: zod_1.z.string().optional()["default"]("main"),
|
|
75
|
+
// -------------------------------------------------------------------------
|
|
76
|
+
// 运行时注入只读字段(前端不可编辑)
|
|
77
|
+
// -------------------------------------------------------------------------
|
|
78
|
+
/** 作用域类型(由后端运行时注入)。 */
|
|
79
|
+
scopeType: zod_1.z.string().optional()["default"]("workspace").meta({ readOnly: true }),
|
|
80
|
+
/** Workspace ID(由后端运行时注入)。 */
|
|
81
|
+
workspaceId: zod_1.z.string().optional()["default"]("").meta({ readOnly: true }),
|
|
82
|
+
/** 项目 ID(历史兼容字段,由后端运行时注入)。 */
|
|
83
|
+
projectId: zod_1.z.string().optional()["default"]("").meta({ readOnly: true }),
|
|
84
|
+
/** 作用域类型 snake/camel 兼容字段(只读)。 */
|
|
85
|
+
scope_kind: zod_1.z.string().optional().meta({ readOnly: true }),
|
|
86
|
+
/** 作用域类型 snake/camel 兼容字段(只读)。 */
|
|
87
|
+
scopeKind: zod_1.z.string().optional().meta({ readOnly: true }),
|
|
88
|
+
/** 作用域类型 snake/camel 兼容字段(只读)。 */
|
|
89
|
+
scope_type: zod_1.z.string().optional().meta({ readOnly: true }),
|
|
90
|
+
/** Workspace ID snake_case 兼容字段(只读)。 */
|
|
91
|
+
workspace_id: zod_1.z.string().optional().meta({ readOnly: true }),
|
|
92
|
+
/** 项目 ID snake_case 兼容字段(只读)。 */
|
|
93
|
+
project_id: zod_1.z.string().optional().meta({ readOnly: true }),
|
|
94
|
+
/** 历史 type 字段(只读)。 */
|
|
95
|
+
type: zod_1.z.string().optional().meta({ readOnly: true }),
|
|
96
|
+
/** 是否按会话类型拆分 session(固定 true,不可修改)。 */
|
|
97
|
+
separateSessionByConversation: zod_1.z
|
|
98
|
+
.boolean()
|
|
99
|
+
.optional()["default"](true)
|
|
100
|
+
.meta({ readOnly: true, description: "是否按单聊/群聊区分 session(固定值,不可修改)" }),
|
|
101
|
+
/** 群聊会话粒度(固定 `group_sender`,不可修改)。 */
|
|
102
|
+
groupSessionScope: zod_1.z["enum"](["group_sender"])
|
|
103
|
+
.optional()["default"]("group_sender")
|
|
104
|
+
.meta({ readOnly: true, description: "群组按人隔离会话模式(固定值,不可修改)" }),
|
|
105
|
+
// -------------------------------------------------------------------------
|
|
106
|
+
// 访问控制与消息策略
|
|
107
|
+
// -------------------------------------------------------------------------
|
|
108
|
+
/** 私聊白名单。 */
|
|
109
|
+
allowFrom: zod_1.z.array(zod_1.z.union([zod_1.z.string(), zod_1.z.number()])).optional(),
|
|
110
|
+
/** 私聊访问策略。 */
|
|
111
|
+
dmPolicy: zod_1.z["enum"](["open", "allowlist", "pairing", "disabled"]).optional(),
|
|
112
|
+
/** 群访问策略。 */
|
|
113
|
+
groupPolicy: zod_1.z["enum"](["open", "allowlist", "disabled"]).optional(),
|
|
114
|
+
/** 群白名单(仅 groupPolicy=allowlist 生效)。 */
|
|
115
|
+
groupAllowFrom: zod_1.z.array(zod_1.z.union([zod_1.z.string(), zod_1.z.number()])).optional(),
|
|
116
|
+
/** 分群配置(每个群可独立 sender 白名单等)。 */
|
|
117
|
+
groups: zod_1.z.record(zod_1.z.string(), zod_1.z.any()).optional(),
|
|
118
|
+
/** 是否发送“思考中”占位。 */
|
|
119
|
+
sendThinkingMessage: zod_1.z.boolean().optional(),
|
|
120
|
+
/**
|
|
121
|
+
* 默认关闭以保持历史输出;开启后普通 content、sub-agent 过程文本和资源过程产物不展示,
|
|
122
|
+
* 但 error 与主流程确认兜底仍会展示,避免失败信息丢失或确认流程卡住。
|
|
123
|
+
*/
|
|
124
|
+
showFinalAnswerOnly: zod_1.z.boolean().optional()["default"](false),
|
|
125
|
+
/** 本地媒体可访问根目录白名单。 */
|
|
126
|
+
mediaLocalRoots: zod_1.z.array(zod_1.z.string()).optional(),
|
|
127
|
+
// -------------------------------------------------------------------------
|
|
128
|
+
// 子模块配置
|
|
129
|
+
// -------------------------------------------------------------------------
|
|
130
|
+
/** Agent 模式子配置(自建应用)。 */
|
|
131
|
+
agent: wecomAgentSchema.optional(),
|
|
132
|
+
/** 网络子配置。 */
|
|
133
|
+
network: wecomNetworkSchema.optional(),
|
|
134
|
+
/** 媒体子配置。 */
|
|
135
|
+
media: wecomMediaSchema.optional(),
|
|
136
|
+
/** 动态 Agent 子配置。 */
|
|
137
|
+
dynamicAgents: wecomDynamicAgentsSchema.optional()
|
|
138
|
+
});
|
|
139
|
+
exports.WeComConfigSchema = wecomAccountSchema.extend({
|
|
140
|
+
/** 多账号默认账号 ID。 */
|
|
141
|
+
defaultAccount: zod_1.z.string().optional(),
|
|
142
|
+
/** 多账号配置映射(accountId -> accountConfig)。 */
|
|
143
|
+
accounts: zod_1.z.record(zod_1.z.string(), wecomAccountSchema).optional(),
|
|
144
|
+
/** 配置快照更新时间(管理端写入)。 */
|
|
145
|
+
channelConfigUpdatedAt: zod_1.z.string().optional()
|
|
146
|
+
});
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 企业微信渠道常量定义
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* 企业微信渠道 ID
|
|
6
|
+
*/
|
|
7
|
+
export declare const CHANNEL_ID: "wecom";
|
|
8
|
+
/**
|
|
9
|
+
* 企业微信 WebSocket 命令枚举
|
|
10
|
+
*/
|
|
11
|
+
export declare enum WeComCommand {
|
|
12
|
+
/** 认证订阅 */
|
|
13
|
+
SUBSCRIBE = "aibot_subscribe",
|
|
14
|
+
/** 心跳 */
|
|
15
|
+
PING = "ping",
|
|
16
|
+
/** 企业微信推送消息 */
|
|
17
|
+
AIBOT_CALLBACK = "aibot_callback",
|
|
18
|
+
/** clawdbot 响应消息 */
|
|
19
|
+
AIBOT_RESPONSE = "aibot_response"
|
|
20
|
+
}
|
|
21
|
+
/** 图片下载超时时间(毫秒) */
|
|
22
|
+
export declare const IMAGE_DOWNLOAD_TIMEOUT_MS = 30000;
|
|
23
|
+
/** 文件下载超时时间(毫秒) */
|
|
24
|
+
export declare const FILE_DOWNLOAD_TIMEOUT_MS = 60000;
|
|
25
|
+
/** 消息发送超时时间(毫秒) */
|
|
26
|
+
export declare const REPLY_SEND_TIMEOUT_MS = 15000;
|
|
27
|
+
/** 企业微信流式消息服务端约 10 分钟过期;本地提前降级为主动发送,避免触发 846608。 */
|
|
28
|
+
export declare const STREAM_REPLY_LOCAL_TTL_MS: number;
|
|
29
|
+
/** 消息处理总超时时间(毫秒) */
|
|
30
|
+
export declare const MESSAGE_PROCESS_TIMEOUT_MS: number;
|
|
31
|
+
/** WebSocket 心跳间隔(毫秒) */
|
|
32
|
+
export declare const WS_HEARTBEAT_INTERVAL_MS = 30000;
|
|
33
|
+
/** WebSocket 连接断开时的最大重连次数 */
|
|
34
|
+
export declare const WS_MAX_RECONNECT_ATTEMPTS = 10;
|
|
35
|
+
/** WebSocket 认证失败时的最大重试次数 */
|
|
36
|
+
export declare const WS_MAX_AUTH_FAILURE_ATTEMPTS = 5;
|
|
37
|
+
/** messageStates Map 条目的最大 TTL(毫秒),防止内存泄漏 */
|
|
38
|
+
export declare const MESSAGE_STATE_TTL_MS: number;
|
|
39
|
+
/** messageStates Map 清理间隔(毫秒) */
|
|
40
|
+
export declare const MESSAGE_STATE_CLEANUP_INTERVAL_MS = 60000;
|
|
41
|
+
/** messageStates Map 最大条目数 */
|
|
42
|
+
export declare const MESSAGE_STATE_MAX_SIZE = 500;
|
|
43
|
+
/** WebSocket 全局实例键 */
|
|
44
|
+
export declare const GLOBAL_WS_CLIENT_KEY: "__wecom_openclaw_ws_client_instances";
|
|
45
|
+
/** "思考中"流式消息占位内容 */
|
|
46
|
+
export declare const THINKING_MESSAGE = "<think></think>";
|
|
47
|
+
/** 仅包含图片时的消息占位符 */
|
|
48
|
+
export declare const MEDIA_IMAGE_PLACEHOLDER = "<media:image>";
|
|
49
|
+
/** 仅包含文件时的消息占位符 */
|
|
50
|
+
export declare const MEDIA_DOCUMENT_PLACEHOLDER = "<media:document>";
|
|
51
|
+
/** 获取 MCP 配置的 WebSocket 命令 */
|
|
52
|
+
export declare const MCP_GET_CONFIG_CMD = "aibot_get_mcp_config";
|
|
53
|
+
/** 发送业务消息的 WebSocket 命令(如文档授权卡片) */
|
|
54
|
+
export declare const AIBOT_SEND_BIZ_MSG_CMD = "aibot_send_biz_msg";
|
|
55
|
+
/** 业务消息超时时间(毫秒) */
|
|
56
|
+
export declare const BIZ_MSG_SEND_TIMEOUT_MS = 10000;
|
|
57
|
+
/** MCP 配置拉取超时时间(毫秒) */
|
|
58
|
+
export declare const MCP_CONFIG_FETCH_TIMEOUT_MS = 15000;
|
|
59
|
+
/** 默认媒体大小上限(MB) */
|
|
60
|
+
export declare const DEFAULT_MEDIA_MAX_MB = 5;
|
|
61
|
+
/** 文本分块大小上限 */
|
|
62
|
+
export declare const TEXT_CHUNK_LIMIT = 4000;
|
|
63
|
+
/** 图片大小上限(字节):10MB */
|
|
64
|
+
export declare const IMAGE_MAX_BYTES: number;
|
|
65
|
+
/** 视频大小上限(字节):10MB */
|
|
66
|
+
export declare const VIDEO_MAX_BYTES: number;
|
|
67
|
+
/** 语音大小上限(字节):2MB */
|
|
68
|
+
export declare const VOICE_MAX_BYTES: number;
|
|
69
|
+
/** 文件大小上限(字节):20MB */
|
|
70
|
+
export declare const FILE_MAX_BYTES: number;
|
|
71
|
+
/** 文件绝对上限(字节):超过此值无法发送,等于 FILE_MAX_BYTES */
|
|
72
|
+
export declare const ABSOLUTE_MAX_BYTES: number;
|
|
73
|
+
/** 上传分片大小(字节,Base64 编码前):512KB */
|
|
74
|
+
export declare const UPLOAD_CHUNK_SIZE: number;
|
|
75
|
+
/** 版本检查事件名称(SDK 事件监听用) */
|
|
76
|
+
export declare const EVENT_ENTER_CHECK_UPDATE = "event.enter_check_update";
|
|
77
|
+
/** 版本检查事件回复命令名称 */
|
|
78
|
+
export declare const CMD_ENTER_EVENT_REPLY = "ww_ai_robot_enter_event";
|
|
79
|
+
/** WSClient scene 参数:企微 OpenClaw 场景 */
|
|
80
|
+
export declare const SCENE_WECOM_OPENCLAW = 1;
|
|
81
|
+
/**
|
|
82
|
+
* WeCom 双模式常量定义
|
|
83
|
+
*/
|
|
84
|
+
/** 固定 Webhook 路径 */
|
|
85
|
+
export declare const WEBHOOK_PATHS: {
|
|
86
|
+
/** Bot 模式历史兼容路径(不再维护) */
|
|
87
|
+
readonly BOT: "/wecom";
|
|
88
|
+
/** Bot 模式历史备用兼容路径(不再维护) */
|
|
89
|
+
readonly BOT_ALT: "/wecom/bot";
|
|
90
|
+
/** Agent 模式历史兼容路径(不再维护) */
|
|
91
|
+
readonly AGENT: "/wecom/agent";
|
|
92
|
+
/** Bot 模式推荐路径前缀 */
|
|
93
|
+
readonly BOT_PLUGIN: "/plugins/wecom/bot";
|
|
94
|
+
/** Agent 模式推荐路径前缀 */
|
|
95
|
+
readonly AGENT_PLUGIN: "/plugins/wecom/agent";
|
|
96
|
+
};
|
|
97
|
+
/** 企业微信 API 端点 */
|
|
98
|
+
export declare const API_ENDPOINTS: {
|
|
99
|
+
readonly GET_TOKEN: "https://qyapi.weixin.qq.com/cgi-bin/gettoken";
|
|
100
|
+
readonly SEND_MESSAGE: "https://qyapi.weixin.qq.com/cgi-bin/message/send";
|
|
101
|
+
readonly SEND_APPCHAT: "https://qyapi.weixin.qq.com/cgi-bin/appchat/send";
|
|
102
|
+
readonly UPLOAD_MEDIA: "https://qyapi.weixin.qq.com/cgi-bin/media/upload";
|
|
103
|
+
readonly DOWNLOAD_MEDIA: "https://qyapi.weixin.qq.com/cgi-bin/media/get";
|
|
104
|
+
};
|
|
105
|
+
/** 各类限制常量 */
|
|
106
|
+
export declare const LIMITS: {
|
|
107
|
+
/** 文本消息最大字节数 */
|
|
108
|
+
readonly TEXT_MAX_BYTES: 2048;
|
|
109
|
+
/** Token 刷新缓冲时间 (提前刷新) */
|
|
110
|
+
readonly TOKEN_REFRESH_BUFFER_MS: 60000;
|
|
111
|
+
/** HTTP 请求超时 */
|
|
112
|
+
readonly REQUEST_TIMEOUT_MS: 15000;
|
|
113
|
+
/** 最大请求体大小 */
|
|
114
|
+
readonly MAX_REQUEST_BODY_SIZE: number;
|
|
115
|
+
};
|
|
116
|
+
/** AES 加密常量 */
|
|
117
|
+
export declare const CRYPTO: {
|
|
118
|
+
/** PKCS#7 块大小 */
|
|
119
|
+
readonly PKCS7_BLOCK_SIZE: 32;
|
|
120
|
+
/** AES Key 长度 */
|
|
121
|
+
readonly AES_KEY_LENGTH: 32;
|
|
122
|
+
};
|
|
123
|
+
/** 合法的模板卡片 card_type 列表 */
|
|
124
|
+
export declare const VALID_CARD_TYPES: string[];
|
|
125
|
+
/** 模板卡片缓存条目 TTL(毫秒):24小时 */
|
|
126
|
+
export declare const TEMPLATE_CARD_CACHE_TTL_MS: number;
|
|
127
|
+
/** 模板卡片缓存最大条目数 */
|
|
128
|
+
export declare const TEMPLATE_CARD_CACHE_MAX_SIZE = 300;
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 企业微信渠道常量定义
|
|
4
|
+
*/
|
|
5
|
+
exports.__esModule = true;
|
|
6
|
+
exports.TEMPLATE_CARD_CACHE_MAX_SIZE = exports.TEMPLATE_CARD_CACHE_TTL_MS = exports.VALID_CARD_TYPES = exports.CRYPTO = exports.LIMITS = exports.API_ENDPOINTS = exports.WEBHOOK_PATHS = exports.SCENE_WECOM_OPENCLAW = exports.CMD_ENTER_EVENT_REPLY = exports.EVENT_ENTER_CHECK_UPDATE = exports.UPLOAD_CHUNK_SIZE = exports.ABSOLUTE_MAX_BYTES = exports.FILE_MAX_BYTES = exports.VOICE_MAX_BYTES = exports.VIDEO_MAX_BYTES = exports.IMAGE_MAX_BYTES = exports.TEXT_CHUNK_LIMIT = exports.DEFAULT_MEDIA_MAX_MB = exports.MCP_CONFIG_FETCH_TIMEOUT_MS = exports.BIZ_MSG_SEND_TIMEOUT_MS = exports.AIBOT_SEND_BIZ_MSG_CMD = exports.MCP_GET_CONFIG_CMD = exports.MEDIA_DOCUMENT_PLACEHOLDER = exports.MEDIA_IMAGE_PLACEHOLDER = exports.THINKING_MESSAGE = exports.GLOBAL_WS_CLIENT_KEY = exports.MESSAGE_STATE_MAX_SIZE = exports.MESSAGE_STATE_CLEANUP_INTERVAL_MS = exports.MESSAGE_STATE_TTL_MS = exports.WS_MAX_AUTH_FAILURE_ATTEMPTS = exports.WS_MAX_RECONNECT_ATTEMPTS = exports.WS_HEARTBEAT_INTERVAL_MS = exports.MESSAGE_PROCESS_TIMEOUT_MS = exports.STREAM_REPLY_LOCAL_TTL_MS = exports.REPLY_SEND_TIMEOUT_MS = exports.FILE_DOWNLOAD_TIMEOUT_MS = exports.IMAGE_DOWNLOAD_TIMEOUT_MS = exports.WeComCommand = exports.CHANNEL_ID = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* 企业微信渠道 ID
|
|
9
|
+
*/
|
|
10
|
+
exports.CHANNEL_ID = "wecom";
|
|
11
|
+
/**
|
|
12
|
+
* 企业微信 WebSocket 命令枚举
|
|
13
|
+
*/
|
|
14
|
+
var WeComCommand;
|
|
15
|
+
(function (WeComCommand) {
|
|
16
|
+
/** 认证订阅 */
|
|
17
|
+
WeComCommand["SUBSCRIBE"] = "aibot_subscribe";
|
|
18
|
+
/** 心跳 */
|
|
19
|
+
WeComCommand["PING"] = "ping";
|
|
20
|
+
/** 企业微信推送消息 */
|
|
21
|
+
WeComCommand["AIBOT_CALLBACK"] = "aibot_callback";
|
|
22
|
+
/** clawdbot 响应消息 */
|
|
23
|
+
WeComCommand["AIBOT_RESPONSE"] = "aibot_response";
|
|
24
|
+
})(WeComCommand = exports.WeComCommand || (exports.WeComCommand = {}));
|
|
25
|
+
// ============================================================================
|
|
26
|
+
// 超时和重试配置
|
|
27
|
+
// ============================================================================
|
|
28
|
+
/** 图片下载超时时间(毫秒) */
|
|
29
|
+
exports.IMAGE_DOWNLOAD_TIMEOUT_MS = 30000;
|
|
30
|
+
/** 文件下载超时时间(毫秒) */
|
|
31
|
+
exports.FILE_DOWNLOAD_TIMEOUT_MS = 60000;
|
|
32
|
+
/** 消息发送超时时间(毫秒) */
|
|
33
|
+
exports.REPLY_SEND_TIMEOUT_MS = 15000;
|
|
34
|
+
/** 企业微信流式消息服务端约 10 分钟过期;本地提前降级为主动发送,避免触发 846608。 */
|
|
35
|
+
exports.STREAM_REPLY_LOCAL_TTL_MS = Math.max(60000, Number(process.env.WECOM_STREAM_REPLY_LOCAL_TTL_MS || "570000") || 570000);
|
|
36
|
+
/** 消息处理总超时时间(毫秒) */
|
|
37
|
+
exports.MESSAGE_PROCESS_TIMEOUT_MS = 6 * 60 * 1000;
|
|
38
|
+
/** WebSocket 心跳间隔(毫秒) */
|
|
39
|
+
exports.WS_HEARTBEAT_INTERVAL_MS = 30000;
|
|
40
|
+
/** WebSocket 连接断开时的最大重连次数 */
|
|
41
|
+
exports.WS_MAX_RECONNECT_ATTEMPTS = 10;
|
|
42
|
+
/** WebSocket 认证失败时的最大重试次数 */
|
|
43
|
+
exports.WS_MAX_AUTH_FAILURE_ATTEMPTS = 5;
|
|
44
|
+
// ============================================================================
|
|
45
|
+
// 消息状态管理配置
|
|
46
|
+
// ============================================================================
|
|
47
|
+
/** messageStates Map 条目的最大 TTL(毫秒),防止内存泄漏 */
|
|
48
|
+
exports.MESSAGE_STATE_TTL_MS = 10 * 60 * 1000;
|
|
49
|
+
/** messageStates Map 清理间隔(毫秒) */
|
|
50
|
+
exports.MESSAGE_STATE_CLEANUP_INTERVAL_MS = 60000;
|
|
51
|
+
/** messageStates Map 最大条目数 */
|
|
52
|
+
exports.MESSAGE_STATE_MAX_SIZE = 500;
|
|
53
|
+
/** WebSocket 全局实例键 */
|
|
54
|
+
exports.GLOBAL_WS_CLIENT_KEY = "__wecom_openclaw_ws_client_instances";
|
|
55
|
+
// ============================================================================
|
|
56
|
+
// 消息模板
|
|
57
|
+
// ============================================================================
|
|
58
|
+
/** "思考中"流式消息占位内容 */
|
|
59
|
+
exports.THINKING_MESSAGE = "<think></think>";
|
|
60
|
+
/** 仅包含图片时的消息占位符 */
|
|
61
|
+
exports.MEDIA_IMAGE_PLACEHOLDER = "<media:image>";
|
|
62
|
+
/** 仅包含文件时的消息占位符 */
|
|
63
|
+
exports.MEDIA_DOCUMENT_PLACEHOLDER = "<media:document>";
|
|
64
|
+
// ============================================================================
|
|
65
|
+
// 默认值
|
|
66
|
+
// ============================================================================
|
|
67
|
+
// ============================================================================
|
|
68
|
+
// MCP 配置
|
|
69
|
+
// ============================================================================
|
|
70
|
+
/** 获取 MCP 配置的 WebSocket 命令 */
|
|
71
|
+
exports.MCP_GET_CONFIG_CMD = "aibot_get_mcp_config";
|
|
72
|
+
/** 发送业务消息的 WebSocket 命令(如文档授权卡片) */
|
|
73
|
+
exports.AIBOT_SEND_BIZ_MSG_CMD = "aibot_send_biz_msg";
|
|
74
|
+
/** 业务消息超时时间(毫秒) */
|
|
75
|
+
exports.BIZ_MSG_SEND_TIMEOUT_MS = 10000;
|
|
76
|
+
/** MCP 配置拉取超时时间(毫秒) */
|
|
77
|
+
exports.MCP_CONFIG_FETCH_TIMEOUT_MS = 15000;
|
|
78
|
+
// ============================================================================
|
|
79
|
+
// 默认值
|
|
80
|
+
// ============================================================================
|
|
81
|
+
/** 默认媒体大小上限(MB) */
|
|
82
|
+
exports.DEFAULT_MEDIA_MAX_MB = 5;
|
|
83
|
+
/** 文本分块大小上限 */
|
|
84
|
+
exports.TEXT_CHUNK_LIMIT = 4000;
|
|
85
|
+
// ============================================================================
|
|
86
|
+
// 媒体上传相关常量
|
|
87
|
+
// ============================================================================
|
|
88
|
+
/** 图片大小上限(字节):10MB */
|
|
89
|
+
exports.IMAGE_MAX_BYTES = 10 * 1024 * 1024;
|
|
90
|
+
/** 视频大小上限(字节):10MB */
|
|
91
|
+
exports.VIDEO_MAX_BYTES = 10 * 1024 * 1024;
|
|
92
|
+
/** 语音大小上限(字节):2MB */
|
|
93
|
+
exports.VOICE_MAX_BYTES = 2 * 1024 * 1024;
|
|
94
|
+
/** 文件大小上限(字节):20MB */
|
|
95
|
+
exports.FILE_MAX_BYTES = 20 * 1024 * 1024;
|
|
96
|
+
/** 文件绝对上限(字节):超过此值无法发送,等于 FILE_MAX_BYTES */
|
|
97
|
+
exports.ABSOLUTE_MAX_BYTES = exports.FILE_MAX_BYTES;
|
|
98
|
+
/** 上传分片大小(字节,Base64 编码前):512KB */
|
|
99
|
+
exports.UPLOAD_CHUNK_SIZE = 512 * 1024;
|
|
100
|
+
// ============================================================================
|
|
101
|
+
// 事件/命令名称常量
|
|
102
|
+
// ============================================================================
|
|
103
|
+
/** 版本检查事件名称(SDK 事件监听用) */
|
|
104
|
+
exports.EVENT_ENTER_CHECK_UPDATE = "event.enter_check_update";
|
|
105
|
+
/** 版本检查事件回复命令名称 */
|
|
106
|
+
exports.CMD_ENTER_EVENT_REPLY = "ww_ai_robot_enter_event";
|
|
107
|
+
// ============================================================================
|
|
108
|
+
// SDK 连接配置
|
|
109
|
+
// ============================================================================
|
|
110
|
+
/** WSClient scene 参数:企微 OpenClaw 场景 */
|
|
111
|
+
exports.SCENE_WECOM_OPENCLAW = 1;
|
|
112
|
+
/**
|
|
113
|
+
* WeCom 双模式常量定义
|
|
114
|
+
*/
|
|
115
|
+
/** 固定 Webhook 路径 */
|
|
116
|
+
exports.WEBHOOK_PATHS = {
|
|
117
|
+
/** Bot 模式历史兼容路径(不再维护) */
|
|
118
|
+
BOT: "/wecom",
|
|
119
|
+
/** Bot 模式历史备用兼容路径(不再维护) */
|
|
120
|
+
BOT_ALT: "/wecom/bot",
|
|
121
|
+
/** Agent 模式历史兼容路径(不再维护) */
|
|
122
|
+
AGENT: "/wecom/agent",
|
|
123
|
+
/** Bot 模式推荐路径前缀 */
|
|
124
|
+
BOT_PLUGIN: "/plugins/wecom/bot",
|
|
125
|
+
/** Agent 模式推荐路径前缀 */
|
|
126
|
+
AGENT_PLUGIN: "/plugins/wecom/agent"
|
|
127
|
+
};
|
|
128
|
+
/** 企业微信 API 端点 */
|
|
129
|
+
exports.API_ENDPOINTS = {
|
|
130
|
+
GET_TOKEN: "https://qyapi.weixin.qq.com/cgi-bin/gettoken",
|
|
131
|
+
SEND_MESSAGE: "https://qyapi.weixin.qq.com/cgi-bin/message/send",
|
|
132
|
+
SEND_APPCHAT: "https://qyapi.weixin.qq.com/cgi-bin/appchat/send",
|
|
133
|
+
UPLOAD_MEDIA: "https://qyapi.weixin.qq.com/cgi-bin/media/upload",
|
|
134
|
+
DOWNLOAD_MEDIA: "https://qyapi.weixin.qq.com/cgi-bin/media/get"
|
|
135
|
+
};
|
|
136
|
+
/** 各类限制常量 */
|
|
137
|
+
exports.LIMITS = {
|
|
138
|
+
/** 文本消息最大字节数 */
|
|
139
|
+
TEXT_MAX_BYTES: 2048,
|
|
140
|
+
/** Token 刷新缓冲时间 (提前刷新) */
|
|
141
|
+
TOKEN_REFRESH_BUFFER_MS: 60000,
|
|
142
|
+
/** HTTP 请求超时 */
|
|
143
|
+
REQUEST_TIMEOUT_MS: 15000,
|
|
144
|
+
/** 最大请求体大小 */
|
|
145
|
+
MAX_REQUEST_BODY_SIZE: 1024 * 1024
|
|
146
|
+
};
|
|
147
|
+
/** AES 加密常量 */
|
|
148
|
+
exports.CRYPTO = {
|
|
149
|
+
/** PKCS#7 块大小 */
|
|
150
|
+
PKCS7_BLOCK_SIZE: 32,
|
|
151
|
+
/** AES Key 长度 */
|
|
152
|
+
AES_KEY_LENGTH: 32
|
|
153
|
+
};
|
|
154
|
+
// ============================================================================
|
|
155
|
+
// 模板卡片配置
|
|
156
|
+
// ============================================================================
|
|
157
|
+
/** 合法的模板卡片 card_type 列表 */
|
|
158
|
+
exports.VALID_CARD_TYPES = [
|
|
159
|
+
"text_notice",
|
|
160
|
+
"news_notice",
|
|
161
|
+
"button_interaction",
|
|
162
|
+
"vote_interaction",
|
|
163
|
+
"multiple_interaction",
|
|
164
|
+
];
|
|
165
|
+
/** 模板卡片缓存条目 TTL(毫秒):24小时 */
|
|
166
|
+
exports.TEMPLATE_CARD_CACHE_TTL_MS = 24 * 60 * 60 * 1000;
|
|
167
|
+
/** 模板卡片缓存最大条目数 */
|
|
168
|
+
exports.TEMPLATE_CARD_CACHE_MAX_SIZE = 300;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 企业微信 DM(私聊)访问控制模块
|
|
3
|
+
*
|
|
4
|
+
* 负责私聊策略检查、配对流程
|
|
5
|
+
*/
|
|
6
|
+
import type { RuntimeEnv } from "ylib-openclaw/plugin-sdk";
|
|
7
|
+
import type { WSClient, WsFrame } from "@wecom/aibot-node-sdk";
|
|
8
|
+
import type { ResolvedWeComAccount } from "./utils.js";
|
|
9
|
+
/**
|
|
10
|
+
* DM Policy 检查结果
|
|
11
|
+
*/
|
|
12
|
+
export interface DmPolicyCheckResult {
|
|
13
|
+
/** 是否允许继续处理消息 */
|
|
14
|
+
allowed: boolean;
|
|
15
|
+
/** 是否已发送配对消息(仅在 pairing 模式下) */
|
|
16
|
+
pairingSent?: boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* 检查 DM Policy 访问控制
|
|
20
|
+
* @returns 检查结果,包含是否允许继续处理
|
|
21
|
+
*/
|
|
22
|
+
export declare function checkDmPolicy(params: {
|
|
23
|
+
senderId: string;
|
|
24
|
+
isGroup: boolean;
|
|
25
|
+
account: ResolvedWeComAccount;
|
|
26
|
+
wsClient: WSClient;
|
|
27
|
+
frame: WsFrame;
|
|
28
|
+
runtime: RuntimeEnv;
|
|
29
|
+
}): Promise<DmPolicyCheckResult>;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 企业微信 DM(私聊)访问控制模块
|
|
4
|
+
*
|
|
5
|
+
* 负责私聊策略检查、配对流程
|
|
6
|
+
*/
|
|
7
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
8
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
9
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
10
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
11
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
12
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
13
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
17
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
18
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
19
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
20
|
+
function step(op) {
|
|
21
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
22
|
+
while (_) try {
|
|
23
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
24
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
25
|
+
switch (op[0]) {
|
|
26
|
+
case 0: case 1: t = op; break;
|
|
27
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
28
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
29
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
30
|
+
default:
|
|
31
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
32
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
33
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
34
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
35
|
+
if (t[2]) _.ops.pop();
|
|
36
|
+
_.trys.pop(); continue;
|
|
37
|
+
}
|
|
38
|
+
op = body.call(thisArg, _);
|
|
39
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
40
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
var __spreadArrays = (this && this.__spreadArrays) || function () {
|
|
44
|
+
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
|
|
45
|
+
for (var r = Array(s), k = 0, i = 0; i < il; i++)
|
|
46
|
+
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
|
|
47
|
+
r[k] = a[j];
|
|
48
|
+
return r;
|
|
49
|
+
};
|
|
50
|
+
exports.__esModule = true;
|
|
51
|
+
exports.checkDmPolicy = void 0;
|
|
52
|
+
var runtime_js_1 = require("./runtime.js");
|
|
53
|
+
var const_js_1 = require("./const.js");
|
|
54
|
+
var message_sender_js_1 = require("./message-sender.js");
|
|
55
|
+
var group_policy_js_1 = require("./group-policy.js");
|
|
56
|
+
// ============================================================================
|
|
57
|
+
// 公开 API
|
|
58
|
+
// ============================================================================
|
|
59
|
+
/**
|
|
60
|
+
* 检查 DM Policy 访问控制
|
|
61
|
+
* @returns 检查结果,包含是否允许继续处理
|
|
62
|
+
*/
|
|
63
|
+
function checkDmPolicy(params) {
|
|
64
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
65
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
66
|
+
var senderId, isGroup, account, wsClient, frame, runtime, core, dmPolicy, configAllowFrom, oldStoreAllowFrom, newStoreAllowFrom, storeAllowFrom, effectiveAllowFrom, senderAllowedResult, _h, code, created, err_1;
|
|
67
|
+
return __generator(this, function (_j) {
|
|
68
|
+
switch (_j.label) {
|
|
69
|
+
case 0:
|
|
70
|
+
senderId = params.senderId, isGroup = params.isGroup, account = params.account, wsClient = params.wsClient, frame = params.frame, runtime = params.runtime;
|
|
71
|
+
core = runtime_js_1.getWeComRuntime();
|
|
72
|
+
// 群聊消息不检查 DM Policy
|
|
73
|
+
if (isGroup) {
|
|
74
|
+
return [2 /*return*/, { allowed: true }];
|
|
75
|
+
}
|
|
76
|
+
dmPolicy = (_a = account.config.dmPolicy) !== null && _a !== void 0 ? _a : "open";
|
|
77
|
+
configAllowFrom = ((_b = account.config.allowFrom) !== null && _b !== void 0 ? _b : []).map(function (v) { return String(v); });
|
|
78
|
+
// 如果 dmPolicy 是 disabled,直接拒绝
|
|
79
|
+
if (dmPolicy === "disabled") {
|
|
80
|
+
(_c = runtime.log) === null || _c === void 0 ? void 0 : _c.call(runtime, "[WeCom] Blocked DM from " + senderId + " (dmPolicy=disabled)");
|
|
81
|
+
return [2 /*return*/, { allowed: false }];
|
|
82
|
+
}
|
|
83
|
+
// 如果是 open 模式,允许所有人
|
|
84
|
+
if (dmPolicy === "open") {
|
|
85
|
+
return [2 /*return*/, { allowed: true }];
|
|
86
|
+
}
|
|
87
|
+
return [4 /*yield*/, core.channel.pairing.readAllowFromStore('wecom', undefined, account.accountId)["catch"](function () { return []; })];
|
|
88
|
+
case 1:
|
|
89
|
+
oldStoreAllowFrom = _j.sent();
|
|
90
|
+
return [4 /*yield*/, core.channel.pairing
|
|
91
|
+
.readAllowFromStore({ channel: const_js_1.CHANNEL_ID, accountId: account.accountId })["catch"](function () { return []; })];
|
|
92
|
+
case 2:
|
|
93
|
+
newStoreAllowFrom = _j.sent();
|
|
94
|
+
storeAllowFrom = __spreadArrays(oldStoreAllowFrom, newStoreAllowFrom);
|
|
95
|
+
effectiveAllowFrom = __spreadArrays(configAllowFrom, storeAllowFrom);
|
|
96
|
+
senderAllowedResult = group_policy_js_1.isSenderAllowed(senderId, effectiveAllowFrom);
|
|
97
|
+
if (senderAllowedResult) {
|
|
98
|
+
return [2 /*return*/, { allowed: true }];
|
|
99
|
+
}
|
|
100
|
+
if (!(dmPolicy === "pairing")) return [3 /*break*/, 10];
|
|
101
|
+
return [4 /*yield*/, core.channel.pairing.upsertPairingRequest({
|
|
102
|
+
channel: const_js_1.CHANNEL_ID,
|
|
103
|
+
id: senderId,
|
|
104
|
+
accountId: account.accountId,
|
|
105
|
+
meta: { name: senderId }
|
|
106
|
+
})];
|
|
107
|
+
case 3:
|
|
108
|
+
_h = _j.sent(), code = _h.code, created = _h.created;
|
|
109
|
+
if (!created) return [3 /*break*/, 8];
|
|
110
|
+
(_d = runtime.log) === null || _d === void 0 ? void 0 : _d.call(runtime, "[WeCom] Pairing request created for sender=" + senderId);
|
|
111
|
+
_j.label = 4;
|
|
112
|
+
case 4:
|
|
113
|
+
_j.trys.push([4, 6, , 7]);
|
|
114
|
+
return [4 /*yield*/, message_sender_js_1.sendWeComReply({
|
|
115
|
+
wsClient: wsClient,
|
|
116
|
+
frame: frame,
|
|
117
|
+
text: core.channel.pairing.buildPairingReply({
|
|
118
|
+
channel: const_js_1.CHANNEL_ID,
|
|
119
|
+
idLine: "\u60A8\u7684\u4F01\u4E1A\u5FAE\u4FE1\u7528\u6237ID: " + senderId,
|
|
120
|
+
code: code
|
|
121
|
+
}),
|
|
122
|
+
runtime: runtime,
|
|
123
|
+
finish: true,
|
|
124
|
+
accountId: account.accountId
|
|
125
|
+
})];
|
|
126
|
+
case 5:
|
|
127
|
+
_j.sent();
|
|
128
|
+
return [3 /*break*/, 7];
|
|
129
|
+
case 6:
|
|
130
|
+
err_1 = _j.sent();
|
|
131
|
+
(_e = runtime.error) === null || _e === void 0 ? void 0 : _e.call(runtime, "[WeCom] Failed to send pairing reply to " + senderId + ": " + String(err_1));
|
|
132
|
+
return [3 /*break*/, 7];
|
|
133
|
+
case 7: return [3 /*break*/, 9];
|
|
134
|
+
case 8:
|
|
135
|
+
(_f = runtime.log) === null || _f === void 0 ? void 0 : _f.call(runtime, "[WeCom] Pairing request already exists for sender=" + senderId);
|
|
136
|
+
_j.label = 9;
|
|
137
|
+
case 9: return [2 /*return*/, { allowed: false, pairingSent: created }];
|
|
138
|
+
case 10:
|
|
139
|
+
// allowlist 模式:直接拒绝未授权用户
|
|
140
|
+
(_g = runtime.log) === null || _g === void 0 ? void 0 : _g.call(runtime, "[WeCom] Blocked unauthorized sender " + senderId + " (dmPolicy=" + dmPolicy + ")");
|
|
141
|
+
return [2 /*return*/, { allowed: false }];
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
exports.checkDmPolicy = checkDmPolicy;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* **动态 Agent 路由模块**
|
|
3
|
+
*
|
|
4
|
+
* 为每个用户/群组自动生成独立的 Agent ID,实现会话隔离。
|
|
5
|
+
* 参考: openclaw-plugin-wecom/dynamic-agent.js
|
|
6
|
+
*/
|
|
7
|
+
import type { OpenClawConfig } from "ylib-openclaw/plugin-sdk";
|
|
8
|
+
export interface DynamicAgentConfig {
|
|
9
|
+
enabled: boolean;
|
|
10
|
+
dmCreateAgent: boolean;
|
|
11
|
+
groupEnabled: boolean;
|
|
12
|
+
adminUsers: string[];
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* **getDynamicAgentConfig (读取动态 Agent 配置)**
|
|
16
|
+
*
|
|
17
|
+
* 从全局配置中读取动态 Agent 配置,提供默认值。
|
|
18
|
+
*/
|
|
19
|
+
export declare function getDynamicAgentConfig(config: OpenClawConfig): DynamicAgentConfig;
|
|
20
|
+
/**
|
|
21
|
+
* **generateAgentId (生成动态 Agent ID)**
|
|
22
|
+
*
|
|
23
|
+
* 根据账号 + 聊天类型 + 对端 ID 生成确定性的 Agent ID,避免多账号串会话。
|
|
24
|
+
* 格式: wecom-{accountId}-{type}-{sanitizedPeerId}
|
|
25
|
+
*/
|
|
26
|
+
export declare function generateAgentId(chatType: "dm" | "group", peerId: string, accountId?: string): string;
|
|
27
|
+
/**
|
|
28
|
+
* **shouldUseDynamicAgent (检查是否使用动态 Agent)**
|
|
29
|
+
*
|
|
30
|
+
* 根据配置和发送者信息判断是否应使用动态 Agent。
|
|
31
|
+
* 管理员(adminUsers)始终绕过动态路由,使用主 Agent。
|
|
32
|
+
*/
|
|
33
|
+
export declare function shouldUseDynamicAgent(params: {
|
|
34
|
+
chatType: "dm" | "group";
|
|
35
|
+
senderId: string;
|
|
36
|
+
config: OpenClawConfig;
|
|
37
|
+
}): boolean;
|