@dingxiang-me/openclaw-wechat 0.4.9
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/CHANGELOG.md +205 -0
- package/LICENSE +21 -0
- package/README.en.md +287 -0
- package/README.md +508 -0
- package/docs/channels/wecom.md +58 -0
- package/openclaw.plugin.json +412 -0
- package/package.json +49 -0
- package/src/core.js +732 -0
- package/src/index.js +3800 -0
package/README.md
ADDED
|
@@ -0,0 +1,508 @@
|
|
|
1
|
+
# OpenClaw-Wechat 企业微信插件
|
|
2
|
+
|
|
3
|
+
[中文 README](./README.md) | [English README](./README.en.md)
|
|
4
|
+
|
|
5
|
+
OpenClaw-Wechat 是一个面向 OpenClaw 的企业微信渠道插件,支持两种接入方式:
|
|
6
|
+
|
|
7
|
+
- `Agent 模式`:企业微信自建应用(XML 回调,经典模式)
|
|
8
|
+
- `Bot 模式`:企业微信智能机器人 API 模式(JSON 回调,原生 stream)
|
|
9
|
+
|
|
10
|
+
适用于“个人微信扫码进入企业微信应用对话”、“企业内员工问答助手”、“多账户多业务线消息分流”等场景。
|
|
11
|
+
|
|
12
|
+
## 目录
|
|
13
|
+
|
|
14
|
+
- [功能概览](#功能概览)
|
|
15
|
+
- [模式对比](#模式对比)
|
|
16
|
+
- [5 分钟极速上手](#5-分钟极速上手)
|
|
17
|
+
- [前置要求](#前置要求)
|
|
18
|
+
- [安装与加载](#安装与加载)
|
|
19
|
+
- [快速开始](#快速开始)
|
|
20
|
+
- [配置参考](#配置参考)
|
|
21
|
+
- [消息能力矩阵](#消息能力矩阵)
|
|
22
|
+
- [命令与会话策略](#命令与会话策略)
|
|
23
|
+
- [环境变量速查](#环境变量速查)
|
|
24
|
+
- [与其他渠道并存建议](#与其他渠道并存建议)
|
|
25
|
+
- [故障排查](#故障排查)
|
|
26
|
+
- [开发与发布](#开发与发布)
|
|
27
|
+
- [FAQ](#faq)
|
|
28
|
+
- [版本与贡献](#版本与贡献)
|
|
29
|
+
|
|
30
|
+
## 5 分钟极速上手
|
|
31
|
+
|
|
32
|
+
适合“先跑起来再细调”的场景。
|
|
33
|
+
|
|
34
|
+
### Step 1. 安装插件
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
git clone https://github.com/dingxiang-me/OpenClaw-Wechat.git
|
|
38
|
+
cd OpenClaw-Wechat
|
|
39
|
+
npm install
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Step 2. 在 OpenClaw 里加载插件
|
|
43
|
+
|
|
44
|
+
在 `~/.openclaw/openclaw.json` 增加:
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"plugins": {
|
|
49
|
+
"enabled": true,
|
|
50
|
+
"allow": ["openclaw-wechat"],
|
|
51
|
+
"load": {
|
|
52
|
+
"paths": ["/path/to/OpenClaw-Wechat"]
|
|
53
|
+
},
|
|
54
|
+
"entries": {
|
|
55
|
+
"openclaw-wechat": {
|
|
56
|
+
"enabled": true
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Step 3. 选择一种模式配置
|
|
64
|
+
|
|
65
|
+
| 模式 | 回调路径 | 企业微信侧类型 | 最少需要的配置 |
|
|
66
|
+
|---|---|---|---|
|
|
67
|
+
| Agent(自建应用) | `/wecom/callback` | 自建应用 API 接收 | `corpId/corpSecret/agentId/callbackToken/callbackAesKey` |
|
|
68
|
+
| Bot(智能机器人) | `/wecom/bot/callback` | 智能机器人 **API 模式** | `bot.enabled/token/encodingAesKey` |
|
|
69
|
+
|
|
70
|
+
### Step 4. 重启并自检
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
openclaw gateway restart
|
|
74
|
+
openclaw gateway status
|
|
75
|
+
npm run wecom:selfcheck -- --all-accounts
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Step 5. 发一条消息验证
|
|
79
|
+
|
|
80
|
+
| 验证项 | 预期结果 |
|
|
81
|
+
|---|---|
|
|
82
|
+
| 文本消息 | 机器人返回文本 |
|
|
83
|
+
| 图片消息(Bot) | 不再提示“图片接收失败”,可识别图像内容 |
|
|
84
|
+
| `openclaw gateway status` | `RPC probe: ok` 且 WeCom 状态正常 |
|
|
85
|
+
|
|
86
|
+
## 功能概览
|
|
87
|
+
|
|
88
|
+
### 核心能力
|
|
89
|
+
|
|
90
|
+
| 能力 | 状态 | 说明 |
|
|
91
|
+
|---|---|---|
|
|
92
|
+
| 企业微信入站消息处理 | ✅ | 文本、图片、语音、链接、文件/视频(Agent) |
|
|
93
|
+
| AI 自动回复 | ✅ | 接入 OpenClaw Runtime,自动路由 Agent |
|
|
94
|
+
| Bot 原生 stream 协议 | ✅ | `msgtype=stream` 刷新与增量回包 |
|
|
95
|
+
| 多账户 | ✅ | `channels.wecom.accounts.<id>` |
|
|
96
|
+
| 发送者授权控制 | ✅ | `allowFrom` + 账户级覆盖 |
|
|
97
|
+
| 命令白名单 | ✅ | `/help` `/status` `/clear` 等 |
|
|
98
|
+
| 群聊触发策略 | ✅ | 支持“仅 @ 触发”或“直接触发” |
|
|
99
|
+
| 文本防抖合并 | ✅ | 窗口期内多条消息合并投递 |
|
|
100
|
+
| 异步补发(超时后) | ✅ | transcript 轮询补发最终回复 |
|
|
101
|
+
| WeCom 出站代理 | ✅ | `outboundProxy` / `WECOM_PROXY` |
|
|
102
|
+
|
|
103
|
+
### 媒体能力
|
|
104
|
+
|
|
105
|
+
| 能力 | 状态 | 说明 |
|
|
106
|
+
|---|---|---|
|
|
107
|
+
| 图片识别(入站) | ✅ | 支持 URL 下载、类型识别、必要时解密后识别 |
|
|
108
|
+
| 图片发送(出站) | ✅ | Agent 模式支持 |
|
|
109
|
+
| 视频/文件发送(出站) | ✅ | 自动判型上传后发送 |
|
|
110
|
+
| 语音转写(本地) | ✅ | 企业微信 Recognition 优先,缺失时回退本地 whisper |
|
|
111
|
+
| Bot 模式媒体回传 | ⚠️ | 当前以文本 stream 为主,媒体不直接回传 |
|
|
112
|
+
|
|
113
|
+
## 模式对比
|
|
114
|
+
|
|
115
|
+
| 维度 | Agent 模式(自建应用) | Bot 模式(智能机器人 API) |
|
|
116
|
+
|---|---|---|
|
|
117
|
+
| 回调数据格式 | XML | JSON |
|
|
118
|
+
| 企业微信创建方式 | 应用管理 -> 自建应用 | 智能机器人 -> **API 模式** |
|
|
119
|
+
| 回调路径默认值 | `/wecom/callback` | `/wecom/bot/callback` |
|
|
120
|
+
| 回复机制 | 主动调用 WeCom 发送 API | 回调响应 `stream` + 轮询刷新 |
|
|
121
|
+
| 流式体验 | 多条消息模拟增量 | 原生 stream 协议 |
|
|
122
|
+
| 出站媒体(图/视频/文件) | 支持 | 当前不作为主路径 |
|
|
123
|
+
| 典型场景 | 标准企业应用、菜单/回调体系 | 对话机器人、连续流式问答 |
|
|
124
|
+
|
|
125
|
+
### 回调路径规划建议
|
|
126
|
+
|
|
127
|
+
| 场景 | 建议 |
|
|
128
|
+
|---|---|
|
|
129
|
+
| 同时开 Agent + Bot | 使用不同路径:`/wecom/callback` 与 `/wecom/bot/callback` |
|
|
130
|
+
| 多账户 Agent | 每个账户独立路径(如 `/wecom/sales/callback`) |
|
|
131
|
+
| 与 Telegram/Feishu 并存 | 不复用任何 webhook path,避免路由冲突 |
|
|
132
|
+
|
|
133
|
+
## 前置要求
|
|
134
|
+
|
|
135
|
+
| 项目 | 说明 |
|
|
136
|
+
|---|---|
|
|
137
|
+
| OpenClaw | 已安装并可正常运行 Gateway |
|
|
138
|
+
| 企业微信管理员权限 | 可创建应用或智能机器人并配置回调 |
|
|
139
|
+
| 公网入口 | 企业微信需回调到可访问 URL(常见用 Cloudflare Tunnel) |
|
|
140
|
+
| Node.js | 与 OpenClaw 运行环境一致 |
|
|
141
|
+
| 本地语音识别(可选) | `whisper-cli` 或 `whisper` |
|
|
142
|
+
| ffmpeg(推荐) | AMR 等格式转码时需要 |
|
|
143
|
+
|
|
144
|
+
## 安装与加载
|
|
145
|
+
|
|
146
|
+
### 方式 A:本地路径加载(推荐)
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
git clone https://github.com/dingxiang-me/OpenClaw-Wechat.git
|
|
150
|
+
cd OpenClaw-Wechat
|
|
151
|
+
npm install
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
在 `~/.openclaw/openclaw.json` 中配置插件加载:
|
|
155
|
+
|
|
156
|
+
```json
|
|
157
|
+
{
|
|
158
|
+
"plugins": {
|
|
159
|
+
"enabled": true,
|
|
160
|
+
"allow": ["openclaw-wechat"],
|
|
161
|
+
"load": {
|
|
162
|
+
"paths": ["/path/to/OpenClaw-Wechat"]
|
|
163
|
+
},
|
|
164
|
+
"entries": {
|
|
165
|
+
"openclaw-wechat": {
|
|
166
|
+
"enabled": true
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### 方式 B:npm 安装(包发布后)
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
openclaw plugins install @dingxiang-me/openclaw-wechat
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## 快速开始
|
|
180
|
+
|
|
181
|
+
### 1) 企业微信侧准备
|
|
182
|
+
|
|
183
|
+
#### Agent 模式(自建应用)
|
|
184
|
+
|
|
185
|
+
1. 创建自建应用,拿到 `AgentId`、`Secret`
|
|
186
|
+
2. 在“我的企业”拿到 `CorpId`
|
|
187
|
+
3. 开启“接收消息”,配置:
|
|
188
|
+
- URL: `https://你的域名/wecom/callback`
|
|
189
|
+
- Token: 自定义随机字符串
|
|
190
|
+
- EncodingAESKey: 企业微信生成
|
|
191
|
+
|
|
192
|
+
#### Bot 模式(智能机器人)
|
|
193
|
+
|
|
194
|
+
1. 创建智能机器人时选择 **API 模式**
|
|
195
|
+
2. 配置回调 URL:`https://你的域名/wecom/bot/callback`
|
|
196
|
+
3. 获取并保存 `token` 与 `encodingAesKey`
|
|
197
|
+
|
|
198
|
+
### 2) OpenClaw 最小配置示例
|
|
199
|
+
|
|
200
|
+
#### Agent 最小可用
|
|
201
|
+
|
|
202
|
+
```json
|
|
203
|
+
{
|
|
204
|
+
"channels": {
|
|
205
|
+
"wecom": {
|
|
206
|
+
"enabled": true,
|
|
207
|
+
"corpId": "wwxxxx",
|
|
208
|
+
"corpSecret": "xxxx",
|
|
209
|
+
"agentId": 1000004,
|
|
210
|
+
"callbackToken": "xxxx",
|
|
211
|
+
"callbackAesKey": "xxxx",
|
|
212
|
+
"webhookPath": "/wecom/callback"
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
#### Bot 最小可用(Bot-only)
|
|
219
|
+
|
|
220
|
+
```json
|
|
221
|
+
{
|
|
222
|
+
"channels": {
|
|
223
|
+
"wecom": {
|
|
224
|
+
"enabled": true,
|
|
225
|
+
"bot": {
|
|
226
|
+
"enabled": true,
|
|
227
|
+
"token": "xxxx",
|
|
228
|
+
"encodingAesKey": "xxxx",
|
|
229
|
+
"webhookPath": "/wecom/bot/callback"
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### 3) 启动与验证
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
openclaw gateway restart
|
|
240
|
+
openclaw gateway status
|
|
241
|
+
openclaw plugins list
|
|
242
|
+
npm run wecom:selfcheck -- --all-accounts
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
`wecom:selfcheck` 帮助:
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
node ./scripts/wecom-selfcheck.mjs --help
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## 配置参考
|
|
252
|
+
|
|
253
|
+
### 主配置键(`channels.wecom`)
|
|
254
|
+
|
|
255
|
+
| 键 | 类型 | 默认 | 说明 |
|
|
256
|
+
|---|---|---|---|
|
|
257
|
+
| `enabled` | boolean | `true` | 是否启用 WeCom 渠道 |
|
|
258
|
+
| `corpId` | string | - | 企业 ID(Agent 模式) |
|
|
259
|
+
| `corpSecret` | string | - | 应用 Secret(敏感) |
|
|
260
|
+
| `agentId` | number/string | - | 应用 AgentId |
|
|
261
|
+
| `callbackToken` | string | - | 回调 Token(敏感) |
|
|
262
|
+
| `callbackAesKey` | string | - | 回调 AES Key(敏感) |
|
|
263
|
+
| `webhookPath` | string | `/wecom/callback` | Agent 回调路径 |
|
|
264
|
+
| `outboundProxy` | string | - | WeCom 出站代理 |
|
|
265
|
+
| `accounts` | object | - | 多账户配置 |
|
|
266
|
+
|
|
267
|
+
### Bot 配置(`channels.wecom.bot`)
|
|
268
|
+
|
|
269
|
+
| 键 | 类型 | 默认 | 说明 |
|
|
270
|
+
|---|---|---|---|
|
|
271
|
+
| `enabled` | boolean | `false` | 启用 Bot 模式 |
|
|
272
|
+
| `token` | string | - | Bot 回调 Token(敏感) |
|
|
273
|
+
| `encodingAesKey` | string | - | Bot 回调 AESKey(43 位,敏感) |
|
|
274
|
+
| `webhookPath` | string | `/wecom/bot/callback` | Bot 回调路径 |
|
|
275
|
+
| `placeholderText` | string | `消息已收到...` | stream 初始占位文案(可设为空字符串) |
|
|
276
|
+
| `streamExpireMs` | integer | `600000` | stream 状态保留时间(30s~1h) |
|
|
277
|
+
|
|
278
|
+
### 授权与指令策略
|
|
279
|
+
|
|
280
|
+
| 模块 | 配置键 | 作用 |
|
|
281
|
+
|---|---|---|
|
|
282
|
+
| 发送者授权 | `allowFrom` / `accounts.<id>.allowFrom` | 限定可对话用户;支持 `*` |
|
|
283
|
+
| 拒绝文案 | `allowFromRejectMessage` | 未授权提示 |
|
|
284
|
+
| 管理员 | `adminUsers` | 绕过命令白名单 |
|
|
285
|
+
| 命令白名单 | `commands.enabled` + `commands.allowlist` | 限制 `/` 指令 |
|
|
286
|
+
| 群聊触发 | `groupChat.enabled` + `requireMention` | 控制群消息触发条件 |
|
|
287
|
+
|
|
288
|
+
### 吞吐与稳定性
|
|
289
|
+
|
|
290
|
+
| 模块 | 配置键 | 说明 |
|
|
291
|
+
|---|---|---|
|
|
292
|
+
| 文本防抖 | `debounce.enabled/windowMs/maxBatch` | 合并短时间多条文本 |
|
|
293
|
+
| Agent 增量回包 | `streaming.enabled/minChars/minIntervalMs` | 多消息模拟流式 |
|
|
294
|
+
| 异步补发 | `WECOM_LATE_REPLY_WATCH_MS/POLL_MS` | dispatch 超时后补发最终回复 |
|
|
295
|
+
|
|
296
|
+
### 语音转写(本地)
|
|
297
|
+
|
|
298
|
+
| 键 | 默认 | 说明 |
|
|
299
|
+
|---|---|---|
|
|
300
|
+
| `voiceTranscription.enabled` | `true` | 开启回退转写 |
|
|
301
|
+
| `provider` | `local-whisper-cli` | `local-whisper-cli` / `local-whisper` |
|
|
302
|
+
| `command` | 自动探测 | 本地命令路径 |
|
|
303
|
+
| `modelPath` | - | whisper-cli 模型路径 |
|
|
304
|
+
| `model` | `base` | whisper 模型名 |
|
|
305
|
+
| `timeoutMs` | `120000` | 单次转写超时 |
|
|
306
|
+
| `maxBytes` | `10485760` | 最大音频大小 |
|
|
307
|
+
| `ffmpegEnabled` | `true` | 不兼容格式自动转码 |
|
|
308
|
+
| `transcodeToWav` | `true` | 优先转为 wav |
|
|
309
|
+
|
|
310
|
+
### 多账户示例
|
|
311
|
+
|
|
312
|
+
```json
|
|
313
|
+
{
|
|
314
|
+
"channels": {
|
|
315
|
+
"wecom": {
|
|
316
|
+
"outboundProxy": "http://127.0.0.1:7890",
|
|
317
|
+
"accounts": {
|
|
318
|
+
"default": {
|
|
319
|
+
"enabled": true,
|
|
320
|
+
"corpId": "ww-default",
|
|
321
|
+
"corpSecret": "secret-default",
|
|
322
|
+
"agentId": 1000004,
|
|
323
|
+
"callbackToken": "token-default",
|
|
324
|
+
"callbackAesKey": "aes-default",
|
|
325
|
+
"webhookPath": "/wecom/callback",
|
|
326
|
+
"allowFrom": ["*"]
|
|
327
|
+
},
|
|
328
|
+
"sales": {
|
|
329
|
+
"enabled": true,
|
|
330
|
+
"corpId": "ww-sales",
|
|
331
|
+
"corpSecret": "secret-sales",
|
|
332
|
+
"agentId": 1000005,
|
|
333
|
+
"callbackToken": "token-sales",
|
|
334
|
+
"callbackAesKey": "aes-sales",
|
|
335
|
+
"webhookPath": "/wecom/sales/callback",
|
|
336
|
+
"outboundProxy": "http://10.0.0.5:8888",
|
|
337
|
+
"allowFrom": ["alice", "wecom:bob"],
|
|
338
|
+
"allowFromRejectMessage": "销售助手未授权,请联系管理员。"
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
## 消息能力矩阵
|
|
347
|
+
|
|
348
|
+
### Agent 模式
|
|
349
|
+
|
|
350
|
+
| 类型 | 入站 | 出站 | 备注 |
|
|
351
|
+
|---|---|---|---|
|
|
352
|
+
| 文本 | ✅ | ✅ | 自动分段 |
|
|
353
|
+
| 图片 | ✅ | ✅ | 入站可识别,出站可发送 |
|
|
354
|
+
| 语音 | ✅ | ❌ | 支持本地转写回退 |
|
|
355
|
+
| 视频 | ✅ | ✅ | 下载并可回包 |
|
|
356
|
+
| 文件 | ✅ | ✅ | 下载并可回包 |
|
|
357
|
+
| 链接 | ✅ | ❌ | 提取标题/描述/URL |
|
|
358
|
+
|
|
359
|
+
### Bot 模式
|
|
360
|
+
|
|
361
|
+
| 类型 | 入站 | 出站 | 备注 |
|
|
362
|
+
|---|---|---|---|
|
|
363
|
+
| 文本 | ✅ | ✅ | 原生 stream |
|
|
364
|
+
| 图片 | ✅ | ⚠️ | 主要用于识别后回文本 |
|
|
365
|
+
| 语音 | ✅ | ✅ | 以文本结果回传 |
|
|
366
|
+
| mixed(图文) | ✅ | ✅ | 聚合后回文本 |
|
|
367
|
+
| 链接/位置 | ✅ | ✅ | 转换为文本上下文 |
|
|
368
|
+
|
|
369
|
+
## 命令与会话策略
|
|
370
|
+
|
|
371
|
+
### 命令
|
|
372
|
+
|
|
373
|
+
| 命令 | 说明 |
|
|
374
|
+
|---|---|
|
|
375
|
+
| `/help` | 查看帮助 |
|
|
376
|
+
| `/status` | 查看运行状态 |
|
|
377
|
+
| `/clear` | 清理会话(兼容映射到 `/reset`) |
|
|
378
|
+
| `/reset` | 重置会话 |
|
|
379
|
+
| `/new` | 新建会话(由上层运行时支持) |
|
|
380
|
+
| `/compact` | 压缩会话(由上层运行时支持) |
|
|
381
|
+
|
|
382
|
+
### 会话策略
|
|
383
|
+
|
|
384
|
+
- 默认一用户一会话:`wecom:<userid>`
|
|
385
|
+
- 群聊可配置“仅 @ 才触发”,避免误触发
|
|
386
|
+
|
|
387
|
+
## 环境变量速查
|
|
388
|
+
|
|
389
|
+
### 核心与回调
|
|
390
|
+
|
|
391
|
+
| 变量 | 必填 | 说明 |
|
|
392
|
+
|---|---|---|
|
|
393
|
+
| `WECOM_CORP_ID` | Agent 必填 | 企业 ID |
|
|
394
|
+
| `WECOM_CORP_SECRET` | Agent 必填 | 应用 Secret |
|
|
395
|
+
| `WECOM_AGENT_ID` | Agent 必填 | AgentId |
|
|
396
|
+
| `WECOM_CALLBACK_TOKEN` | Agent 必填 | 回调 Token |
|
|
397
|
+
| `WECOM_CALLBACK_AES_KEY` | Agent 必填 | 回调 AESKey |
|
|
398
|
+
| `WECOM_WEBHOOK_PATH` | 否 | Agent 回调路径(默认 `/wecom/callback`) |
|
|
399
|
+
|
|
400
|
+
### Bot
|
|
401
|
+
|
|
402
|
+
| 变量 | 必填 | 说明 |
|
|
403
|
+
|---|---|---|
|
|
404
|
+
| `WECOM_BOT_ENABLED` | 否 | 是否启用 Bot 模式 |
|
|
405
|
+
| `WECOM_BOT_TOKEN` | Bot 必填 | Bot Token |
|
|
406
|
+
| `WECOM_BOT_ENCODING_AES_KEY` | Bot 必填 | Bot EncodingAESKey |
|
|
407
|
+
| `WECOM_BOT_WEBHOOK_PATH` | 否 | Bot 回调路径 |
|
|
408
|
+
| `WECOM_BOT_PLACEHOLDER_TEXT` | 否 | stream 占位文案 |
|
|
409
|
+
| `WECOM_BOT_STREAM_EXPIRE_MS` | 否 | stream 保留时长 |
|
|
410
|
+
|
|
411
|
+
### 策略与流控
|
|
412
|
+
|
|
413
|
+
| 变量 | 说明 |
|
|
414
|
+
|---|---|
|
|
415
|
+
| `WECOM_ALLOW_FROM` / `WECOM_<ACCOUNT>_ALLOW_FROM` | 发送者白名单 |
|
|
416
|
+
| `WECOM_ALLOW_FROM_REJECT_MESSAGE` / `WECOM_<ACCOUNT>_ALLOW_FROM_REJECT_MESSAGE` | 未授权提示 |
|
|
417
|
+
| `WECOM_ADMIN_USERS` | 管理员用户列表 |
|
|
418
|
+
| `WECOM_COMMANDS_ENABLED` / `WECOM_COMMANDS_ALLOWLIST` / `WECOM_COMMANDS_REJECT_MESSAGE` | 命令白名单策略 |
|
|
419
|
+
| `WECOM_GROUP_CHAT_ENABLED` / `WECOM_GROUP_CHAT_REQUIRE_MENTION` / `WECOM_GROUP_CHAT_MENTION_PATTERNS` | 群触发策略 |
|
|
420
|
+
| `WECOM_DEBOUNCE_ENABLED` / `WECOM_DEBOUNCE_WINDOW_MS` / `WECOM_DEBOUNCE_MAX_BATCH` | 文本防抖 |
|
|
421
|
+
| `WECOM_STREAMING_ENABLED` / `WECOM_STREAMING_MIN_CHARS` / `WECOM_STREAMING_MIN_INTERVAL_MS` | Agent 增量回包 |
|
|
422
|
+
| `WECOM_LATE_REPLY_WATCH_MS` / `WECOM_LATE_REPLY_POLL_MS` | 异步补发窗口与轮询频率 |
|
|
423
|
+
|
|
424
|
+
### 语音回退转写
|
|
425
|
+
|
|
426
|
+
| 变量 | 说明 |
|
|
427
|
+
|---|---|
|
|
428
|
+
| `WECOM_VOICE_TRANSCRIBE_ENABLED` | 启用本地语音转写回退 |
|
|
429
|
+
| `WECOM_VOICE_TRANSCRIBE_PROVIDER` | `local-whisper-cli` / `local-whisper` |
|
|
430
|
+
| `WECOM_VOICE_TRANSCRIBE_COMMAND` | 转写命令 |
|
|
431
|
+
| `WECOM_VOICE_TRANSCRIBE_MODEL_PATH` | whisper-cli 模型路径 |
|
|
432
|
+
| `WECOM_VOICE_TRANSCRIBE_MODEL` | whisper 模型名 |
|
|
433
|
+
| `WECOM_VOICE_TRANSCRIBE_TIMEOUT_MS` | 转写超时 |
|
|
434
|
+
| `WECOM_VOICE_TRANSCRIBE_MAX_BYTES` | 音频大小上限 |
|
|
435
|
+
| `WECOM_VOICE_TRANSCRIBE_FFMPEG_ENABLED` | 是否允许 ffmpeg 转码 |
|
|
436
|
+
| `WECOM_VOICE_TRANSCRIBE_TRANSCODE_TO_WAV` | 是否优先转 WAV |
|
|
437
|
+
|
|
438
|
+
## 与其他渠道并存建议
|
|
439
|
+
|
|
440
|
+
建议固定以下三点,减少“偶发无回复/冲突”风险:
|
|
441
|
+
|
|
442
|
+
1. 配置 `plugins.allow` 显式白名单(至少包含 `openclaw-wechat`)
|
|
443
|
+
2. 各渠道使用独立 webhook path,不复用
|
|
444
|
+
3. 同一台机器尽量只运行一个 OpenClaw gateway 进程
|
|
445
|
+
|
|
446
|
+
详细说明见:[`docs/troubleshooting/coexistence.md`](./docs/troubleshooting/coexistence.md)
|
|
447
|
+
|
|
448
|
+
## 故障排查
|
|
449
|
+
|
|
450
|
+
### 快速定位表
|
|
451
|
+
|
|
452
|
+
| 现象 | 先看什么 | 常见原因 | 处理建议 |
|
|
453
|
+
|---|---|---|---|
|
|
454
|
+
| 回调验证失败 | `curl https://域名/wecom/callback` | URL 不通、Token/AESKey 不一致 | 先通公网,再核对配置 |
|
|
455
|
+
| 能收到消息但不回复 | `openclaw gateway status` + `openclaw logs --follow` | 模型超时、会话排队、权限策略拦截 | 查看 dispatch/allowFrom/commands 日志 |
|
|
456
|
+
| Bot 图片识别失败 | `wecom(bot): failed to fetch image url` | URL 失效、返回非图像流 | 已支持 octet-stream+解密兜底,先升级到最新版本 |
|
|
457
|
+
| 语音转写失败 | `wecom: voice transcription failed` | 本地命令或模型路径错误 | 检查 `command`、`modelPath`、`ffmpeg` |
|
|
458
|
+
| gettoken 失败 | 企业微信 API 返回码 | CorpId/Secret 错或网络受限 | 检查凭据/配置代理 |
|
|
459
|
+
|
|
460
|
+
### 推荐检查命令
|
|
461
|
+
|
|
462
|
+
```bash
|
|
463
|
+
openclaw gateway status
|
|
464
|
+
openclaw status --deep
|
|
465
|
+
openclaw logs --follow
|
|
466
|
+
npm run wecom:selfcheck -- --all-accounts
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
## 开发与发布
|
|
470
|
+
|
|
471
|
+
### 常用命令
|
|
472
|
+
|
|
473
|
+
| 命令 | 作用 |
|
|
474
|
+
|---|---|
|
|
475
|
+
| `npm test` | 语法与单测 |
|
|
476
|
+
| `npm run wecom:selfcheck -- --all-accounts` | 配置+网络体检 |
|
|
477
|
+
| `npm run wecom:smoke` | 升级后快速回归 |
|
|
478
|
+
| `openclaw gateway restart` | 重启网关 |
|
|
479
|
+
|
|
480
|
+
### 发版建议流程
|
|
481
|
+
|
|
482
|
+
1. 更新 `CHANGELOG.md` 与版本号
|
|
483
|
+
2. 运行 `npm test` 与 `wecom:selfcheck`
|
|
484
|
+
3. 打 tag 并发布 GitHub Release
|
|
485
|
+
4. (可选)发布 npm 包
|
|
486
|
+
|
|
487
|
+
## FAQ
|
|
488
|
+
|
|
489
|
+
### Q1:Bot 模式回调一直失败?
|
|
490
|
+
通常是机器人创建成“标准模式”。请重建为 **API 模式**(JSON 回调)。
|
|
491
|
+
|
|
492
|
+
### Q2:为什么图片偶发识别失败?
|
|
493
|
+
企业微信可能返回非标准 `content-type` 或加密媒体流。插件已增加类型识别与解密兜底;仍失败时请查看日志中的 header/下载错误。
|
|
494
|
+
|
|
495
|
+
### Q3:Telegram 和 WeCom 会互相影响吗?
|
|
496
|
+
理论上独立;实战中若复用 webhook 路径、多进程抢占、或 `plugins.allow` 未收紧,会出现干扰。按“并存建议”配置可大幅降低风险。
|
|
497
|
+
|
|
498
|
+
### Q4:支持个人微信吗?
|
|
499
|
+
支持企业微信场景下的“微信插件入口”(个人微信扫码进入企业应用对话),不等同于“个人微信网页版协议”。
|
|
500
|
+
|
|
501
|
+
## 版本与贡献
|
|
502
|
+
|
|
503
|
+
- 版本记录:[`CHANGELOG.md`](./CHANGELOG.md)
|
|
504
|
+
- 渠道文档:[`docs/channels/wecom.md`](./docs/channels/wecom.md)
|
|
505
|
+
- 问题排查:[`docs/troubleshooting/coexistence.md`](./docs/troubleshooting/coexistence.md)
|
|
506
|
+
- 许可证:MIT
|
|
507
|
+
|
|
508
|
+
欢迎提交 Issue / PR。
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
summary: "OpenClaw-Wechat WeCom channel plugin"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# WeCom (企业微信) (plugin)
|
|
6
|
+
|
|
7
|
+
This channel integrates OpenClaw with WeCom (企业微信) internal apps.
|
|
8
|
+
|
|
9
|
+
## Status
|
|
10
|
+
|
|
11
|
+
- Webhook verification: supported (requires Token + EncodingAESKey)
|
|
12
|
+
- Inbound messages: text/image/voice/video/file/link
|
|
13
|
+
- Outbound: text and image
|
|
14
|
+
- Multi-account: supported (`channels.wecom.accounts`)
|
|
15
|
+
- Voice recognition: WeCom `Recognition` first; local whisper fallback supported (`channels.wecom.voiceTranscription`)
|
|
16
|
+
|
|
17
|
+
## Callback URL
|
|
18
|
+
|
|
19
|
+
Recommended:
|
|
20
|
+
|
|
21
|
+
- `https://<your-domain>/wecom/callback`
|
|
22
|
+
|
|
23
|
+
## Selfcheck
|
|
24
|
+
|
|
25
|
+
Run:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm run wecom:selfcheck -- --account default
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
All accounts:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm run wecom:selfcheck -- --all-accounts
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Upgrade smoke check:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npm run wecom:smoke
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Coexistence (Telegram/Feishu)
|
|
44
|
+
|
|
45
|
+
See troubleshooting guide:
|
|
46
|
+
|
|
47
|
+
- `docs/troubleshooting/coexistence.md`
|
|
48
|
+
|
|
49
|
+
Optional:
|
|
50
|
+
|
|
51
|
+
- `--config ~/.openclaw/openclaw.json`
|
|
52
|
+
- `--skip-network`
|
|
53
|
+
- `--skip-local-webhook`
|
|
54
|
+
- `--json`
|
|
55
|
+
|
|
56
|
+
## Security
|
|
57
|
+
|
|
58
|
+
Store secrets in environment variables or secret files. Do not commit them.
|