ylib-wecom-openclaw-plugin 2026.4.29-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.
Files changed (180) hide show
  1. package/README.md +596 -0
  2. package/dist/index.d.ts +10 -0
  3. package/dist/index.js +99 -0
  4. package/dist/src/accounts.d.ts +57 -0
  5. package/dist/src/accounts.js +247 -0
  6. package/dist/src/agent/api-client.d.ts +95 -0
  7. package/dist/src/agent/api-client.js +425 -0
  8. package/dist/src/agent/handler.d.ts +64 -0
  9. package/dist/src/agent/handler.js +731 -0
  10. package/dist/src/agent/index.d.ts +5 -0
  11. package/dist/src/agent/index.js +21 -0
  12. package/dist/src/agent/webhook.d.ts +25 -0
  13. package/dist/src/agent/webhook.js +294 -0
  14. package/dist/src/agent/xml.d.ts +21 -0
  15. package/dist/src/agent/xml.js +43 -0
  16. package/dist/src/channel.d.ts +5 -0
  17. package/dist/src/channel.js +815 -0
  18. package/dist/src/chat-queue.d.ts +31 -0
  19. package/dist/src/chat-queue.js +53 -0
  20. package/dist/src/config-schema.d.ts +587 -0
  21. package/dist/src/config-schema.js +146 -0
  22. package/dist/src/const.d.ts +128 -0
  23. package/dist/src/const.js +168 -0
  24. package/dist/src/dm-policy.d.ts +29 -0
  25. package/dist/src/dm-policy.js +146 -0
  26. package/dist/src/dynamic-agent.d.ts +37 -0
  27. package/dist/src/dynamic-agent.js +67 -0
  28. package/dist/src/dynamic-routing.d.ts +65 -0
  29. package/dist/src/dynamic-routing.js +62 -0
  30. package/dist/src/endpoint-dispatch.d.ts +54 -0
  31. package/dist/src/endpoint-dispatch.js +967 -0
  32. package/dist/src/endpoint-event-adapter.d.ts +15 -0
  33. package/dist/src/endpoint-event-adapter.js +427 -0
  34. package/dist/src/group-policy.d.ts +30 -0
  35. package/dist/src/group-policy.js +126 -0
  36. package/dist/src/http.d.ts +27 -0
  37. package/dist/src/http.js +168 -0
  38. package/dist/src/im-runtime-telemetry.d.ts +25 -0
  39. package/dist/src/im-runtime-telemetry.js +68 -0
  40. package/dist/src/interface.d.ts +192 -0
  41. package/dist/src/interface.js +5 -0
  42. package/dist/src/markdown-chunk.d.ts +1 -0
  43. package/dist/src/markdown-chunk.js +396 -0
  44. package/dist/src/mcp/index.d.ts +6 -0
  45. package/dist/src/mcp/index.js +28 -0
  46. package/dist/src/mcp/interceptors/biz-error.d.ts +11 -0
  47. package/dist/src/mcp/interceptors/biz-error.js +73 -0
  48. package/dist/src/mcp/interceptors/doc-auth-error.d.ts +10 -0
  49. package/dist/src/mcp/interceptors/doc-auth-error.js +235 -0
  50. package/dist/src/mcp/interceptors/index.d.ts +35 -0
  51. package/dist/src/mcp/interceptors/index.js +143 -0
  52. package/dist/src/mcp/interceptors/msg-media.d.ts +11 -0
  53. package/dist/src/mcp/interceptors/msg-media.js +201 -0
  54. package/dist/src/mcp/interceptors/smartpage-create.d.ts +30 -0
  55. package/dist/src/mcp/interceptors/smartpage-create.js +252 -0
  56. package/dist/src/mcp/interceptors/smartpage-export.d.ts +17 -0
  57. package/dist/src/mcp/interceptors/smartpage-export.js +135 -0
  58. package/dist/src/mcp/interceptors/smartsheet-upload.d.ts +22 -0
  59. package/dist/src/mcp/interceptors/smartsheet-upload.js +388 -0
  60. package/dist/src/mcp/interceptors/types.d.ts +64 -0
  61. package/dist/src/mcp/interceptors/types.js +8 -0
  62. package/dist/src/mcp/schema.d.ts +11 -0
  63. package/dist/src/mcp/schema.js +115 -0
  64. package/dist/src/mcp/tool.d.ts +63 -0
  65. package/dist/src/mcp/tool.js +318 -0
  66. package/dist/src/mcp/transport.d.ts +94 -0
  67. package/dist/src/mcp/transport.js +702 -0
  68. package/dist/src/media-handler.d.ts +55 -0
  69. package/dist/src/media-handler.js +306 -0
  70. package/dist/src/media-uploader.d.ts +142 -0
  71. package/dist/src/media-uploader.js +446 -0
  72. package/dist/src/message-parser.d.ts +104 -0
  73. package/dist/src/message-parser.js +232 -0
  74. package/dist/src/message-sender.d.ts +54 -0
  75. package/dist/src/message-sender.js +210 -0
  76. package/dist/src/monitor.d.ts +69 -0
  77. package/dist/src/monitor.js +1846 -0
  78. package/dist/src/onboarding.d.ts +8 -0
  79. package/dist/src/onboarding.js +248 -0
  80. package/dist/src/openclaw-compat.d.ts +148 -0
  81. package/dist/src/openclaw-compat.js +839 -0
  82. package/dist/src/proactive-markdown-send.d.ts +14 -0
  83. package/dist/src/proactive-markdown-send.js +205 -0
  84. package/dist/src/reqid-store.d.ts +23 -0
  85. package/dist/src/reqid-store.js +136 -0
  86. package/dist/src/runtime.d.ts +2 -0
  87. package/dist/src/runtime.js +7 -0
  88. package/dist/src/shared/command-auth.d.ts +23 -0
  89. package/dist/src/shared/command-auth.js +112 -0
  90. package/dist/src/shared/xml-parser.d.ts +46 -0
  91. package/dist/src/shared/xml-parser.js +228 -0
  92. package/dist/src/state-dir-resolve.d.ts +2 -0
  93. package/dist/src/state-dir-resolve.js +33 -0
  94. package/dist/src/state-manager.d.ts +115 -0
  95. package/dist/src/state-manager.js +413 -0
  96. package/dist/src/target.d.ts +35 -0
  97. package/dist/src/target.js +71 -0
  98. package/dist/src/template-card-manager.d.ts +55 -0
  99. package/dist/src/template-card-manager.js +316 -0
  100. package/dist/src/template-card-parser.d.ts +37 -0
  101. package/dist/src/template-card-parser.js +672 -0
  102. package/dist/src/timeout.d.ts +20 -0
  103. package/dist/src/timeout.js +57 -0
  104. package/dist/src/types/account.d.ts +29 -0
  105. package/dist/src/types/account.js +5 -0
  106. package/dist/src/types/config.d.ts +98 -0
  107. package/dist/src/types/config.js +8 -0
  108. package/dist/src/types/constants.d.ts +42 -0
  109. package/dist/src/types/constants.js +45 -0
  110. package/dist/src/types/index.d.ts +7 -0
  111. package/dist/src/types/index.js +17 -0
  112. package/dist/src/types/message.d.ts +238 -0
  113. package/dist/src/types/message.js +6 -0
  114. package/dist/src/utils.d.ts +148 -0
  115. package/dist/src/utils.js +92 -0
  116. package/dist/src/version.d.ts +2 -0
  117. package/dist/src/version.js +28 -0
  118. package/dist/src/webhook/command-auth.d.ts +47 -0
  119. package/dist/src/webhook/command-auth.js +137 -0
  120. package/dist/src/webhook/gateway.d.ts +36 -0
  121. package/dist/src/webhook/gateway.js +297 -0
  122. package/dist/src/webhook/handler.d.ts +19 -0
  123. package/dist/src/webhook/handler.js +481 -0
  124. package/dist/src/webhook/helpers.d.ts +157 -0
  125. package/dist/src/webhook/helpers.js +936 -0
  126. package/dist/src/webhook/http.d.ts +27 -0
  127. package/dist/src/webhook/http.js +168 -0
  128. package/dist/src/webhook/index.d.ts +11 -0
  129. package/dist/src/webhook/index.js +43 -0
  130. package/dist/src/webhook/media.d.ts +30 -0
  131. package/dist/src/webhook/media.js +152 -0
  132. package/dist/src/webhook/monitor.d.ts +59 -0
  133. package/dist/src/webhook/monitor.js +1672 -0
  134. package/dist/src/webhook/state.d.ts +220 -0
  135. package/dist/src/webhook/state.js +568 -0
  136. package/dist/src/webhook/target.d.ts +41 -0
  137. package/dist/src/webhook/target.js +165 -0
  138. package/dist/src/webhook/types.d.ts +348 -0
  139. package/dist/src/webhook/types.js +36 -0
  140. package/dist/src/webhook/video-frame.d.ts +13 -0
  141. package/dist/src/webhook/video-frame.js +108 -0
  142. package/openclaw.plugin.json +19 -0
  143. package/package.json +96 -0
  144. package/schema.json +534 -0
  145. package/scripts/generate-schema.mjs +33 -0
  146. package/skills/wecom-contact/SKILL.md +162 -0
  147. package/skills/wecom-doc/SKILL.md +162 -0
  148. package/skills/wecom-doc/references/create-doc.md +56 -0
  149. package/skills/wecom-doc/references/edit-doc-content.md +68 -0
  150. package/skills/wecom-doc/references/get-doc-content.md +88 -0
  151. package/skills/wecom-doc/references/smartpage-create.md +125 -0
  152. package/skills/wecom-doc/references/smartpage-export.md +160 -0
  153. package/skills/wecom-meeting/SKILL.md +441 -0
  154. package/skills/wecom-meeting/references/example-full.md +30 -0
  155. package/skills/wecom-meeting/references/example-reminder.md +46 -0
  156. package/skills/wecom-meeting/references/example-security.md +22 -0
  157. package/skills/wecom-meeting/references/response-get-meeting-info.md +148 -0
  158. package/skills/wecom-msg/SKILL.md +157 -0
  159. package/skills/wecom-msg/references/api-get-messages.md +93 -0
  160. package/skills/wecom-msg/references/api-get-msg-chat-list.md +58 -0
  161. package/skills/wecom-msg/references/api-get-msg-media.md +44 -0
  162. package/skills/wecom-msg/references/api-send-message.md +39 -0
  163. package/skills/wecom-preflight/SKILL.md +141 -0
  164. package/skills/wecom-schedule/SKILL.md +161 -0
  165. package/skills/wecom-schedule/references/api-check-availability.md +56 -0
  166. package/skills/wecom-schedule/references/api-create-schedule.md +38 -0
  167. package/skills/wecom-schedule/references/api-get-schedule-detail.md +81 -0
  168. package/skills/wecom-schedule/references/api-update-schedule.md +32 -0
  169. package/skills/wecom-schedule/references/ref-reminders.md +24 -0
  170. package/skills/wecom-send-media/SKILL.md +68 -0
  171. package/skills/wecom-send-template-card/SKILL.md +157 -0
  172. package/skills/wecom-send-template-card/references/api-template-card-types.md +358 -0
  173. package/skills/wecom-smartsheet/SKILL.md +164 -0
  174. package/skills/wecom-smartsheet/references/smartsheet-cell-value-formats.md +163 -0
  175. package/skills/wecom-smartsheet/references/smartsheet-field-types.md +44 -0
  176. package/skills/wecom-smartsheet/references/smartsheet-get-records.md +96 -0
  177. package/skills/wecom-smartsheet/references/webhook-examples.md +185 -0
  178. package/skills/wecom-smartsheet/references/webhook-fallback.md +184 -0
  179. package/skills/wecom-todo/SKILL.md +392 -0
  180. package/skills/wecom-todo/examples/workflows.md +163 -0
package/README.md ADDED
@@ -0,0 +1,596 @@
1
+ > 💡 **快速上手指引 & 交流群**
2
+ >
3
+ > 📖 [点击查看完整接入指引文档](https://doc.weixin.qq.com/doc/w3_AFYA1wY6ACoCNRxfnyGRJQaSa6jjJ?scode=AJEAIQdfAAo0RJmzxLAFYA1wY6ACo) — 包含配置步骤、产品介绍、常见问题解答等。
4
+ >
5
+ > 💬 扫码加入企业微信交流群:
6
+ >
7
+ > <img src="https://wwcdn.weixin.qq.com/node/wework/images/202603241759.3fb01c32cc.png" alt="扫码入群交流" width="200" />
8
+
9
+ # 特别说明
10
+ > ****2026.3.22 版本 OpenClaw 兼容说明****
11
+ >
12
+ > 如果你的 OpenClaw 是 2026.3.22 及以上的版本,请升级插件到 2026.3.24 及以上版本。
13
+ >
14
+ > 如果你的 OpenClaw 是 2026.3.22 以下的版本,请保持插件版本在 2026.3.20 版本。
15
+ >
16
+ > 你可以使用以下命令快速安装: `npx -y @wecom/wecom-openclaw-cli install --force`
17
+
18
+ # 🤖 WeCom OpenClaw Plugin
19
+
20
+ **WeCom channel plugin for [OpenClaw](https://github.com/openclaw)** — by the Tencent WeCom team.
21
+
22
+ > A channel plugin powered by WeCom. Supports **Bot mode** (WebSocket long-polling or HTTP webhook with JSON callbacks) and **Agent mode** (HTTP webhook with XML encrypted callbacks). Direct messages, group chats, streaming replies, and proactive messaging.
23
+
24
+ ---
25
+
26
+ 📖 [WeCom AI Bot Official Documentation](https://open.work.weixin.qq.com/help?doc_id=21657)
27
+
28
+
29
+ ## ✨ Features
30
+
31
+ - 🔗 **Dual-mode**: Bot (WebSocket / Webhook) and Agent (HTTP webhook) can run independently or together
32
+ - 💬 Supports both direct messages (DM) and group chat
33
+ - 📤 Proactive messaging to specific users, groups, departments, or tags
34
+ - 🖼️ Receives and processes image, voice, video, file, and **mixed (图文混排)** messages with automatic downloading
35
+ - 🗣️ Voice-to-text: automatically extracts transcribed text from voice messages
36
+ - 💬 Quote message support: processes quoted text, image, voice, and file messages
37
+ - ⏳ Streaming replies with "thinking" placeholder messages (Bot mode)
38
+ - 🔐 Agent mode: AES-256-CBC encrypted XML callbacks with SHA1 signature verification
39
+ - 📝 Markdown formatting support for replies
40
+ - 🃏 Template card messages (text_notice, news_notice, button_interaction, vote_interaction, multiple_interaction) with **event callback handling**
41
+ - 🔒 Built-in access control: DM Policy (pairing / open / allowlist / disabled) and Group Policy (open / allowlist / disabled)
42
+ - 🔑 Command authorization: per-account command permission control with access group support
43
+ - 👥 Multi-account support: run multiple WeCom accounts with independent bot/agent configs
44
+ - 🧩 MCP tool integration (`wecom_mcp`) with interceptor pipeline (biz-error, media, smartpage-create, smartpage-export)
45
+ - 🎯 **15 built-in Skills**: contact lookup, doc management, todo, meeting, schedule, messaging, smartsheet, template cards, and more
46
+ - 🔀 Dynamic Agent routing: auto-create isolated agents per user/group
47
+ - 📁 Local file sending with configurable media path allowlist (`mediaLocalRoots`)
48
+ - 📊 Smart media size limits with auto-downgrade (image 10MB → file, video 10MB → file, voice 2MB/AMR-only → file, max 20MB)
49
+ - 🔄 **Bot-first, Agent-fallback** outbound delivery: auto fallback to Agent HTTP API when Bot WS is unavailable
50
+ - ⚡ Auto heartbeat keep-alive and reconnection (up to 10 reconnect attempts, 5 auth failure retries)
51
+ - 🛡️ Anti-kick protection: suppresses auto-restart on server-side disconnection to prevent mutual kicking loops
52
+ - 🧙 Interactive CLI setup wizard
53
+
54
+ ---
55
+
56
+ ## 🚀 Getting Started
57
+
58
+ ### Requirements
59
+
60
+ - OpenClaw `>= 2026.3.28`
61
+
62
+ ### Quick Install
63
+
64
+ Use the CLI tool to automatically install the plugin and complete bot configuration in one step:
65
+
66
+ ```shell
67
+ # Automatically install the channel plugin and quickly complete configuration; also works for updates
68
+ npx -y @wecom/wecom-openclaw-cli install
69
+ ```
70
+
71
+ More Options
72
+ ```shell
73
+ # If installation fails, try force install
74
+ npx -y @wecom/wecom-openclaw-cli install --force
75
+
76
+ # Use --help to learn more about the tool
77
+ npx -y @wecom/wecom-openclaw-cli --help
78
+ ```
79
+
80
+ ### Manual Install
81
+
82
+ ```shell
83
+ openclaw plugins install @wecom/wecom-openclaw-plugin
84
+ ```
85
+
86
+ ### Configuration
87
+
88
+ #### Option 1: Interactive Setup
89
+
90
+ ```shell
91
+ openclaw channels add
92
+ ```
93
+
94
+ Follow the prompts to enter your WeCom bot's **Bot ID** and **Secret**.
95
+
96
+ #### Option 2: CLI Quick Setup
97
+
98
+ ```shell
99
+ openclaw config set channels.wecom.botId <YOUR_BOT_ID>
100
+ openclaw config set channels.wecom.secret <YOUR_BOT_SECRET>
101
+ openclaw config set channels.wecom.enabled true
102
+ openclaw gateway restart
103
+ ```
104
+
105
+ ### Mode Overview
106
+
107
+ The plugin supports two connection modes that can be used independently or together:
108
+
109
+ | Mode | Connection | Message Format | Use Case |
110
+ |------|-----------|---------------|----------|
111
+ | **Bot** (智能体) | WebSocket (default) or HTTP webhook | JSON | Quick setup, streaming replies |
112
+ | **Agent** (自建应用) | HTTP webhook callbacks | XML | Enterprise apps, API-driven messaging |
113
+
114
+ > **Note**: Bot mode supports two connection methods via `connectionMode`:
115
+ > - `websocket` (default) — WebSocket long-polling, requires `botId` + `secret`
116
+ > - `webhook` — HTTP callback, requires `token` + `encodingAESKey`
117
+
118
+ ### Bot Mode Configuration
119
+
120
+ #### Core Settings
121
+
122
+ | Config Path | Description | Options | Default |
123
+ |---|---|---|---|
124
+ | `channels.wecom.enabled` | Enable the channel | `true` / `false` | `false` |
125
+ | `channels.wecom.connectionMode` | Bot connection mode | `websocket` / `webhook` | `websocket` |
126
+ | `channels.wecom.name` | Account display name | — | `企业微信` |
127
+
128
+ #### WebSocket Mode (default)
129
+
130
+ | Config Path | Description | Options | Default |
131
+ |---|---|---|---|
132
+ | `channels.wecom.botId` | WeCom bot ID | — | — |
133
+ | `channels.wecom.secret` | WeCom bot secret | — | — |
134
+ | `channels.wecom.websocketUrl` | WebSocket endpoint | — | `wss://openws.work.weixin.qq.com` |
135
+ | `channels.wecom.sendThinkingMessage` | Send "thinking" placeholder | `true` / `false` | `true` |
136
+
137
+ #### Webhook Mode (`connectionMode: "webhook"`)
138
+
139
+ | Config Path | Description | Options | Default |
140
+ |---|---|---|---|
141
+ | `channels.wecom.token` | Webhook verification token | — | — |
142
+ | `channels.wecom.encodingAESKey` | AES encryption key (43 chars Base64) | — | — |
143
+ | `channels.wecom.receiveId` | Receiver ID (for decryption verification) | — | — |
144
+ | `channels.wecom.welcomeText` | Welcome message on enter_chat event | — | — |
145
+ | `channels.wecom.streamPlaceholderContent` | Stream placeholder content | — | — |
146
+
147
+ #### Access Control
148
+
149
+ | Config Path | Description | Options | Default |
150
+ |---|---|---|---|
151
+ | `channels.wecom.dmPolicy` | DM access policy | `pairing` / `open` / `allowlist` / `disabled` | `open` |
152
+ | `channels.wecom.allowFrom` | DM allowlist (user IDs) | — | `[]` |
153
+ | `channels.wecom.groupPolicy` | Group chat access policy | `open` / `allowlist` / `disabled` | `open` |
154
+ | `channels.wecom.groupAllowFrom` | Group allowlist (group IDs) | — | `[]` |
155
+ | `channels.wecom.groups` | Per-group config (e.g. sender allowlist) | — | `{}` |
156
+
157
+ #### Media Settings
158
+
159
+ | Config Path | Description | Default |
160
+ |---|---|---|
161
+ | `channels.wecom.mediaLocalRoots` | Extra local paths allowed for media sending (supports `~`) | `[]` |
162
+ | `channels.wecom.media.maxBytes` | Max media file size in bytes | `20971520` (20MB) |
163
+ | `channels.wecom.media.tempDir` | Temp directory for media processing | — |
164
+ | `channels.wecom.media.retentionHours` | Media file retention hours | — |
165
+ | `channels.wecom.media.cleanupOnStart` | Clean temp media on startup | — |
166
+
167
+ **Media Size Limits & Auto-Downgrade:**
168
+
169
+ | Media Type | Max Size | Downgrade Behavior |
170
+ |---|---|---|
171
+ | Image | 10 MB | Exceeds → sent as file |
172
+ | Video | 10 MB | Exceeds → sent as file |
173
+ | Voice | 2 MB (AMR only) | Non-AMR format or exceeds → sent as file |
174
+ | File | 20 MB | Exceeds → rejected (cannot send) |
175
+
176
+ #### Network Settings
177
+
178
+ | Config Path | Description | Default |
179
+ |---|---|---|
180
+ | `channels.wecom.network.timeoutMs` | HTTP request timeout (ms) | — |
181
+ | `channels.wecom.network.retries` | Number of retries | — |
182
+ | `channels.wecom.network.retryDelayMs` | Delay between retries (ms) | — |
183
+ | `channels.wecom.network.egressProxyUrl` | Egress proxy URL for trusted IP scenarios | — |
184
+
185
+ > **Egress Proxy Priority**: `channels.wecom.network.egressProxyUrl` > `OPENCLAW_WECOM_EGRESS_PROXY_URL` > `WECOM_EGRESS_PROXY_URL` > `HTTPS_PROXY` > `ALL_PROXY` > `HTTP_PROXY`
186
+
187
+ ### Agent Mode Configuration
188
+
189
+ Agent mode uses HTTP webhook callbacks with XML encrypted messages. You need to configure the callback URL in the WeCom admin console under "API Receive" settings.
190
+
191
+ #### Prerequisites
192
+
193
+ 1. Create a self-built app in [WeCom Admin Console](https://work.weixin.qq.com/wework_admin/frame#apps)
194
+ 2. Note down the **CorpID**, **CorpSecret** (from app settings), and **AgentId**
195
+ 3. In the app settings, go to "API Receive" (API接收):
196
+ - Note down the **Token** and **EncodingAESKey** (auto-generated or custom)
197
+ - **Do NOT click save yet** — WeCom will verify the callback URL immediately when you save
198
+
199
+ #### Setup Steps
200
+
201
+ > **Important**: You must configure the Gateway **before** saving the callback URL in WeCom admin console. WeCom sends a verification request (GET with `echostr`) immediately when you save, and the Gateway needs the `token` and `encodingAESKey` to decrypt and respond correctly.
202
+
203
+ **Step 1: Configure Gateway**
204
+
205
+ ```shell
206
+ openclaw config set channels.wecom.agent.corpId <YOUR_CORP_ID>
207
+ openclaw config set channels.wecom.agent.corpSecret <YOUR_CORP_SECRET>
208
+ openclaw config set channels.wecom.agent.agentId <YOUR_AGENT_ID>
209
+ openclaw config set channels.wecom.agent.token <YOUR_CALLBACK_TOKEN>
210
+ openclaw config set channels.wecom.agent.encodingAESKey <YOUR_ENCODING_AES_KEY>
211
+ openclaw config set channels.wecom.enabled true
212
+ openclaw gateway restart
213
+ ```
214
+
215
+ **Step 2: Save callback URL in WeCom admin console**
216
+
217
+ Go back to the "API Receive" settings and enter the callback URL:
218
+ - **URL**: `https://<your-gateway-host>/plugins/wecom/agent/<accountId>` (e.g. `/plugins/wecom/agent/default`); single-account mode can also use `/plugins/wecom/agent`
219
+
220
+ Now click save — the verification should pass.
221
+
222
+ #### JSON Configuration
223
+
224
+ ```json
225
+ {
226
+ "channels": {
227
+ "wecom": {
228
+ "enabled": true,
229
+ "agent": {
230
+ "corpId": "ww1234567890abcdef",
231
+ "corpSecret": "your-corp-secret",
232
+ "agentId": 1000002,
233
+ "token": "your-callback-token",
234
+ "encodingAESKey": "your-encoding-aes-key-43-chars"
235
+ }
236
+ }
237
+ }
238
+ }
239
+ ```
240
+
241
+ #### Agent Config Reference
242
+
243
+ | Config Path | Description | Required |
244
+ |---|---|---|
245
+ | `channels.wecom.agent.corpId` | Enterprise Corp ID | Yes |
246
+ | `channels.wecom.agent.corpSecret` | App secret | Yes |
247
+ | `channels.wecom.agent.agentId` | App agent ID | No (needed for proactive messaging) |
248
+ | `channels.wecom.agent.token` | Callback verification token | Yes |
249
+ | `channels.wecom.agent.encodingAESKey` | Callback encryption key (43 chars) | Yes |
250
+ | `channels.wecom.agent.welcomeText` | Welcome message | No |
251
+ | `channels.wecom.agent.dmPolicy` | DM access policy (overrides top-level) | No |
252
+ | `channels.wecom.agent.allowFrom` | DM allowlist (overrides top-level) | No |
253
+
254
+ #### Webhook Paths
255
+
256
+ **Agent Mode:**
257
+
258
+ | Path | Description |
259
+ |---|---|
260
+ | `/plugins/wecom/agent/<accountId>` | 推荐路径(例如 `/plugins/wecom/agent/default`) |
261
+ | `/plugins/wecom/agent/default` | 多账号模式下自动路由到默认账号(即使默认账号 ID 不是 `default`) |
262
+ | `/plugins/wecom/agent` | 兼容路径(单账号 / 多账号签名匹配) |
263
+ | `/wecom/agent` | Legacy 兼容路径 |
264
+
265
+ **Bot Webhook Mode** (`connectionMode: "webhook"`):
266
+
267
+ | Path | Description |
268
+ |---|---|
269
+ | `/plugins/wecom/bot` | Recommended path (single account) |
270
+ | `/plugins/wecom/bot/<accountId>` | Multi-account path |
271
+ | `/wecom/bot` | Legacy compatible path |
272
+ | `/wecom` | Legacy compatible path |
273
+
274
+ ### Outbound Delivery (Bot WS → Agent HTTP Fallback)
275
+
276
+ The plugin uses a **Bot-first, Agent-fallback** strategy for outbound message delivery:
277
+
278
+ 1. **Bot WebSocket available** → send via WS (supports markdown, streaming)
279
+ 2. **Bot WS unavailable** → automatically fallback to **Agent HTTP API** (`cgi-bin/message/send`)
280
+
281
+ This means:
282
+ - **Agent-only accounts** (no Bot configured) can still send proactive messages, cron deliveries, and broadcasts
283
+ - **Target formats** like `party:1`, `tag:Ops`, `user:zhangsan` are fully supported in both paths
284
+ - **Media fallback**: when Bot WS is unavailable, media files are downloaded, uploaded to WeCom via Agent API, then sent; if upload fails, falls back to text + URL
285
+ - No manual switching needed — the plugin handles fallback transparently
286
+
287
+ ### Using Both Modes Together
288
+
289
+ Bot and Agent can run simultaneously on the same account. Bot handles WebSocket streaming; Agent handles HTTP webhook callbacks with API-driven replies.
290
+
291
+ ```json
292
+ {
293
+ "channels": {
294
+ "wecom": {
295
+ "enabled": true,
296
+ "botId": "your-bot-id",
297
+ "secret": "your-bot-secret",
298
+ "agent": {
299
+ "corpId": "ww1234567890abcdef",
300
+ "corpSecret": "your-corp-secret",
301
+ "agentId": 1000002,
302
+ "token": "your-callback-token",
303
+ "encodingAESKey": "your-encoding-aes-key-43-chars"
304
+ }
305
+ }
306
+ }
307
+ }
308
+ ```
309
+
310
+ ### Multi-Account Configuration
311
+
312
+ Use `accounts` to configure multiple WeCom accounts, each with optional bot and/or agent sub-configs. Account-level fields override top-level fields of the same name.
313
+
314
+ ```json
315
+ {
316
+ "channels": {
317
+ "wecom": {
318
+ "enabled": true,
319
+ "defaultAccount": "main",
320
+ "dmPolicy": "open",
321
+ "accounts": {
322
+ "main": {
323
+ "botId": "bot-id-1",
324
+ "secret": "secret-1",
325
+ "agent": {
326
+ "corpId": "ww1234567890abcdef",
327
+ "corpSecret": "secret-a",
328
+ "agentId": 1000002,
329
+ "token": "token-a",
330
+ "encodingAESKey": "aes-key-a"
331
+ }
332
+ },
333
+ "support": {
334
+ "dmPolicy": "allowlist",
335
+ "allowFrom": ["admin1"],
336
+ "agent": {
337
+ "corpId": "ww1234567890abcdef",
338
+ "corpSecret": "secret-b",
339
+ "agentId": 1000003,
340
+ "token": "token-b",
341
+ "encodingAESKey": "aes-key-b"
342
+ }
343
+ }
344
+ }
345
+ }
346
+ }
347
+ }
348
+ ```
349
+
350
+ > **Note**: In multi-account mode, accounts without explicit `bindings` will not fall back to the default agent. Configure bindings for each account:
351
+ > ```json
352
+ > {
353
+ > "bindings": [
354
+ > { "agentId": "your-agent", "match": { "channel": "wecom", "accountId": "main" } }
355
+ > ]
356
+ > }
357
+ > ```
358
+
359
+ ### Dynamic Agent Configuration
360
+
361
+ Dynamic Agent routing automatically creates isolated agents per user or group, enabling session isolation.
362
+
363
+ ```json
364
+ {
365
+ "channels": {
366
+ "wecom": {
367
+ "dynamicAgents": {
368
+ "enabled": true,
369
+ "dmCreateAgent": true,
370
+ "groupEnabled": true,
371
+ "adminUsers": ["admin_user_id"]
372
+ }
373
+ }
374
+ }
375
+ }
376
+ ```
377
+
378
+ | Config Path | Description | Default |
379
+ |---|---|---|
380
+ | `channels.wecom.dynamicAgents.enabled` | Enable dynamic agent routing | `false` |
381
+ | `channels.wecom.dynamicAgents.dmCreateAgent` | Create isolated agent per DM user | `true` |
382
+ | `channels.wecom.dynamicAgents.groupEnabled` | Enable dynamic agent for group chats | `true` |
383
+ | `channels.wecom.dynamicAgents.adminUsers` | Admin users (bypass dynamic routing, use main agent) | `[]` |
384
+
385
+ ---
386
+
387
+ ## 🔒 Access Control
388
+
389
+ ### DM (Direct Message) Access
390
+
391
+ **Default**: `dmPolicy: "open"` — all users can send direct messages without approval.
392
+
393
+ #### Approve Pairing
394
+
395
+ ```shell
396
+ openclaw pairing list wecom # View pending pairing requests
397
+ openclaw pairing approve wecom <CODE> # Approve a pairing request
398
+ ```
399
+
400
+ #### Allowlist Mode
401
+
402
+ Configure allowed user IDs via `channels.wecom.allowFrom`:
403
+
404
+ ```json
405
+ {
406
+ "channels": {
407
+ "wecom": {
408
+ "dmPolicy": "allowlist",
409
+ "allowFrom": ["user_id_1", "user_id_2"]
410
+ }
411
+ }
412
+ }
413
+ ```
414
+
415
+ #### Open Mode
416
+
417
+ Set `dmPolicy: "open"` to allow all users to send direct messages without approval.
418
+
419
+ #### Disabled Mode
420
+
421
+ Set `dmPolicy: "disabled"` to completely block all direct messages.
422
+
423
+ ### Group Access
424
+
425
+ #### Group Policy (`channels.wecom.groupPolicy`)
426
+
427
+ - `"open"` — Allow messages from all groups (default)
428
+ - `"allowlist"` — Only allow groups listed in `groupAllowFrom`
429
+ - `"disabled"` — Disable all group messages
430
+
431
+ ### Group Configuration Examples
432
+
433
+ #### Allow All Groups (Default Behavior)
434
+
435
+ ```json
436
+ {
437
+ "channels": {
438
+ "wecom": {
439
+ "groupPolicy": "open"
440
+ }
441
+ }
442
+ }
443
+ ```
444
+
445
+ #### Allow Only Specific Groups
446
+
447
+ ```json
448
+ {
449
+ "channels": {
450
+ "wecom": {
451
+ "groupPolicy": "allowlist",
452
+ "groupAllowFrom": ["group_id_1", "group_id_2"]
453
+ }
454
+ }
455
+ }
456
+ ```
457
+
458
+ #### Allow Only Specific Senders Within a Group (Sender Allowlist)
459
+
460
+ In addition to the group allowlist, you can restrict which members within a group are allowed to interact with the bot. Only messages from users listed in `groups.<chatId>.allowFrom` will be processed; messages from other members will be silently ignored. This is a sender-level allowlist that applies to **all messages**.
461
+
462
+ ```json
463
+ {
464
+ "channels": {
465
+ "wecom": {
466
+ "groupPolicy": "allowlist",
467
+ "groupAllowFrom": ["group_id_1"],
468
+ "groups": {
469
+ "group_id_1": {
470
+ "allowFrom": ["user_id_1", "user_id_2"]
471
+ }
472
+ }
473
+ }
474
+ }
475
+ }
476
+ ```
477
+
478
+ ---
479
+
480
+ ## ⏰ Cronjob (Scheduled Tasks)
481
+
482
+ The plugin supports scheduled message delivery via OpenClaw's built-in Cron service. Cron jobs run through the **Agent outbound** channel, so Agent mode must be configured.
483
+
484
+ ### Target Formats
485
+
486
+ The `delivery.to` field supports the following target formats:
487
+
488
+ | Format | Target | Example |
489
+ |--------|--------|--------|
490
+ | `party:<id>` | Department (all members) | `party:1` (root dept = all employees) |
491
+ | `dept:<id>` | Department (alias for party) | `dept:5` |
492
+ | `tag:<id>` | Tag group | `tag:Ops` |
493
+ | `user:<id>` | Specific user | `user:zhangsan` |
494
+ | `group:<id>` | External group chat | `group:wr123abc` |
495
+ | `chat:<id>` | Group chat (alias for group) | `chat:wc456def` |
496
+ | Pure number | Auto-detected as department | `1` → `party:1` |
497
+ | `wr...` / `wc...` | Auto-detected as group chat | `wr123` → `chatid` |
498
+ | Other string | Auto-detected as user | `zhangsan` → `touser` |
499
+
500
+ > **Namespace prefixes** (`wecom:`, `qywx:`, `wework:`, `wechatwork:`, `wecom-agent:`) are automatically stripped before parsing.
501
+
502
+ ### Method 1: CLI (Recommended — takes effect immediately)
503
+
504
+ ```shell
505
+ openclaw cron add \
506
+ --name "daily-report" \
507
+ --agent main \
508
+ --cron "0 9 * * 1-5" \
509
+ --tz "Asia/Shanghai" \
510
+ --message "Good morning! Here is your daily briefing." \
511
+ --announce \
512
+ --channel wecom \
513
+ --to "party:1"
514
+ ```
515
+
516
+ > **Note**: `--announce` enables delivery mode (broadcasts the AI response to the target chat). Use `--no-deliver` to keep output internal. The deprecated `--deliver` flag is an alias for `--announce`.
517
+
518
+ Common CLI commands:
519
+
520
+ ```shell
521
+ openclaw cron list # List all cron jobs
522
+ openclaw cron show <id> # Show job details
523
+ openclaw cron enable <id> # Enable a job
524
+ openclaw cron disable <id> # Disable a job
525
+ openclaw cron remove <id> # Remove a job
526
+ openclaw cron run <id> # Manually trigger a job
527
+ openclaw cron runs --id <id> # View run history
528
+ openclaw cron edit <id> --message "New prompt" # Edit a job
529
+ ```
530
+
531
+ ### Method 2: Edit `jobs.json` (requires gateway restart)
532
+
533
+ File path: `~/.openclaw/cron/jobs.json`
534
+
535
+ ```json
536
+ {
537
+ "version": 1,
538
+ "jobs": [
539
+ {
540
+ "id": "daily-report",
541
+ "name": "Daily Report",
542
+ "agentId": "main",
543
+ "enabled": true,
544
+ "schedule": { "kind": "cron", "expr": "0 9 * * 1-5", "tz": "Asia/Shanghai" },
545
+ "sessionTarget": "isolated",
546
+ "wakeMode": "now",
547
+ "payload": {
548
+ "kind": "agentTurn",
549
+ "message": "Generate today's briefing and send it."
550
+ },
551
+ "delivery": {
552
+ "mode": "announce",
553
+ "channel": "wecom",
554
+ "to": "party:1",
555
+ "accountId": "main"
556
+ },
557
+ "state": {}
558
+ }
559
+ ]
560
+ }
561
+ ```
562
+
563
+ After editing, restart the gateway:
564
+
565
+ ```shell
566
+ openclaw gateway restart
567
+ ```
568
+
569
+ ### Method 3: Create via chat (takes effect immediately)
570
+
571
+ You can ask the AI agent directly in a WeCom conversation:
572
+
573
+ > "Create a scheduled task: send a daily briefing to the entire company at 9am every weekday"
574
+
575
+ The agent will call the Cron API to create the job — no restart needed.
576
+
577
+ ### Notes
578
+
579
+ - Cron jobs use the **Agent outbound** path — Agent mode (`corpId` / `corpSecret` / `agentId`) must be configured.
580
+ - The server IP must be in the WeCom trusted IP allowlist, or configure `egressProxyUrl` for a fixed egress proxy.
581
+ - Jobs created via CLI or chat API take effect immediately. Manual edits to `jobs.json` require `openclaw gateway restart`.
582
+ - For multi-account setups, set `delivery.accountId` to the target account (e.g. `"main"`, `"support"`).
583
+
584
+ ---
585
+
586
+ ## 📦 Update
587
+
588
+ ```shell
589
+ openclaw plugins update wecom-openclaw-plugin
590
+ ```
591
+
592
+ ---
593
+
594
+ ## 📄 License
595
+
596
+ MIT
@@ -0,0 +1,10 @@
1
+ export { wecomPlugin } from "./src/channel.js";
2
+ declare const plugin: {
3
+ id: string;
4
+ name: string;
5
+ description: string;
6
+ configSchema: any;
7
+ wecomPlugin: any;
8
+ register(api: any): void;
9
+ };
10
+ export default plugin;