@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/CHANGELOG.md
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [0.4.9] - 2026-03-02
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- 新增企业微信 AI 机器人 Bot 模式(JSON 回调)配置:`channels.wecom.bot.*` / `WECOM_BOT_*`
|
|
9
|
+
- 新增 Bot 模式原生 stream 路由:支持 `msgtype=stream` 刷新请求与增量内容回包
|
|
10
|
+
- 新增 Bot 流式会话状态管理与过期清理
|
|
11
|
+
- 新增核心测试覆盖 Bot 模式配置解析与环境变量回退
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
- 文档明确区分两种模式:
|
|
15
|
+
- Bot 模式:原生 stream(推荐)
|
|
16
|
+
- Agent 模式:多消息增量回包(非原生 stream)
|
|
17
|
+
- `register` 启动逻辑支持 Bot-only 场景(无需自建应用账号也可加载路由)
|
|
18
|
+
|
|
19
|
+
## [0.4.8] - 2026-03-02
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
- 新增 WeCom 可配置流式回复:`channels.wecom.streaming.*` / `WECOM_STREAMING_*`
|
|
23
|
+
- 新增流式参数:最小增量字符数(`minChars`)与最短发送间隔(`minIntervalMs`)
|
|
24
|
+
- 新增核心测试覆盖流式配置解析与边界收敛
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
- WeCom 回复链路接入 block 增量发送(以多条文本消息模拟流式,适配企业微信不可编辑消息限制)
|
|
28
|
+
- `/status` 命令新增流式回复状态展示
|
|
29
|
+
- 文档与示例同步新增流式配置(`README.md`、`.env.example`、`openclaw.plugin.json`)
|
|
30
|
+
|
|
31
|
+
## [0.4.7] - 2026-03-02
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
- 新增 WeCom 超时后异步补发链路:dispatch 超时/排队时自动轮询 transcript 并在拿到 final 后回推企业微信
|
|
35
|
+
- 新增异步补发调优参数:`WECOM_LATE_REPLY_WATCH_MS`、`WECOM_LATE_REPLY_POLL_MS`
|
|
36
|
+
|
|
37
|
+
### Changed
|
|
38
|
+
- `dispatch timed out` 不再立即返回失败文案,优先切换到“处理中 + 异步补发”流程
|
|
39
|
+
- 新增超时后晚到 dispatcher 回包抑制,避免与异步补发并发造成重复回复
|
|
40
|
+
|
|
41
|
+
### Fixed
|
|
42
|
+
- 修复会话排队或长耗时场景下,用户只收到“处理中/超时”而收不到最终回复的问题
|
|
43
|
+
|
|
44
|
+
## [0.4.6] - 2026-03-01
|
|
45
|
+
|
|
46
|
+
### Added
|
|
47
|
+
- 新增发送者授权策略:`channels.wecom.allowFrom`、`channels.wecom.accounts.<id>.allowFrom`
|
|
48
|
+
- 新增发送者未授权拒绝文案:`allowFromRejectMessage`、`WECOM_ALLOW_FROM_REJECT_MESSAGE`
|
|
49
|
+
- 新增核心测试覆盖 `allowFrom` 解析、账户级覆盖与授权判定
|
|
50
|
+
|
|
51
|
+
### Changed
|
|
52
|
+
- 群聊 mention 触发匹配从简单 `includes` 升级为边界感知匹配,降低邮箱文本误触发
|
|
53
|
+
- 群聊 mention 清理逻辑增强:移除 `@提及` 时不再误删 email 片段
|
|
54
|
+
- `/status` 增加发送者授权策略状态展示
|
|
55
|
+
|
|
56
|
+
### Fixed
|
|
57
|
+
- 修复账户级 `allowFrom` 无法覆盖全局配置的问题
|
|
58
|
+
- 修复 `requireMention=true` 场景中 `test@example.com` 被误判为 mention 的问题
|
|
59
|
+
|
|
60
|
+
## [0.4.5] - 2026-03-01
|
|
61
|
+
|
|
62
|
+
### Added
|
|
63
|
+
- 新增命令白名单策略:`channels.wecom.commands.*` 与 `WECOM_COMMANDS_*`
|
|
64
|
+
- 新增管理员绕过配置:`channels.wecom.adminUsers` 与 `WECOM_ADMIN_USERS`
|
|
65
|
+
- 新增群聊触发策略:`channels.wecom.groupChat.*` 与 `WECOM_GROUP_CHAT_*`
|
|
66
|
+
- 新增文本防抖合并:`channels.wecom.debounce.*` 与 `WECOM_DEBOUNCE_*`
|
|
67
|
+
- 新增核心测试覆盖命令解析、策略配置和防抖配置边界
|
|
68
|
+
|
|
69
|
+
### Changed
|
|
70
|
+
- 文本入站链路接入防抖调度;命令消息优先直通,自动冲刷队列
|
|
71
|
+
- `/status` 增加命令白名单、群聊触发、防抖状态展示
|
|
72
|
+
- 版本升级为 `0.4.5`
|
|
73
|
+
|
|
74
|
+
### Fixed
|
|
75
|
+
- 修复新策略已实现但未接入主处理链路的问题(文本仍走旧路径)
|
|
76
|
+
- 修复群聊场景下命令判定偏差(支持先去除 mention 再识别 `/` 指令)
|
|
77
|
+
|
|
78
|
+
## [0.4.4] - 2026-03-01
|
|
79
|
+
|
|
80
|
+
### Added
|
|
81
|
+
- 新增 WeCom API 出站代理支持:`channels.wecom.outboundProxy`、`channels.wecom.accounts.<id>.outboundProxy`
|
|
82
|
+
- 新增环境变量代理支持:`WECOM_PROXY` 与 `WECOM_<ACCOUNT>_PROXY`
|
|
83
|
+
- 新增代理配置解析测试,覆盖账户级/渠道级/环境变量优先级
|
|
84
|
+
- 新增媒体回包自动判型:`deliverReply` 支持 `image/video/file`,并可基于 URL 后缀推断
|
|
85
|
+
|
|
86
|
+
### Changed
|
|
87
|
+
- 所有 WeCom API 调用链路(`gettoken`、消息发送、媒体下载/上传)统一接入代理能力
|
|
88
|
+
- `/status` 命令新增代理状态提示(已启用/未启用)
|
|
89
|
+
- 版本升级为 `0.4.4`
|
|
90
|
+
|
|
91
|
+
## [0.4.3] - 2026-03-01
|
|
92
|
+
|
|
93
|
+
### Added
|
|
94
|
+
- 新增语音转写回退链路:当企业微信回调未提供 `Recognition` 时,插件会自动下载语音并调用本地 `whisper-cli/whisper`
|
|
95
|
+
- 新增 AMR/非兼容格式自动转码:支持用 `ffmpeg` 转为 `wav` 后再转写
|
|
96
|
+
- 新增本地转写配置项:`channels.wecom.voiceTranscription.*`(provider/command/modelPath 等)
|
|
97
|
+
- 新增语音相关核心测试:配置解析与音频格式判断
|
|
98
|
+
|
|
99
|
+
### Changed
|
|
100
|
+
- `/status` 命令新增语音转写状态展示(模型、启用状态)
|
|
101
|
+
- 语音失败时改为主动回包错误原因,避免“无响应”体感
|
|
102
|
+
- 版本升级为 `0.4.3`
|
|
103
|
+
|
|
104
|
+
### Fixed
|
|
105
|
+
- 修复本地语音转写临时文件过早清理问题:避免 `whisper-cli` 偶发读取不到输入文件(code 2)
|
|
106
|
+
|
|
107
|
+
## [0.4.1] - 2026-02-28
|
|
108
|
+
|
|
109
|
+
### Changed
|
|
110
|
+
- 插件元数据全面对齐 OpenClaw:`package.json`、`openclaw.plugin.json`、运行时版本统一为 `0.4.1`
|
|
111
|
+
- `/status` 命令支持按当前账户显示,避免多账户场景下状态误报
|
|
112
|
+
- callback 验签不再输出敏感 token 信息,日志仅保留账户与路由信息
|
|
113
|
+
|
|
114
|
+
### Added
|
|
115
|
+
- 多账户 webhook 路由:按 `webhookPath` 分组注册,并按签名动态匹配账户
|
|
116
|
+
- 多账户同路径支持:同一路径下可通过不同 callback token/AES key 区分账户
|
|
117
|
+
- 临时文件延迟清理机制:媒体文件保留 30 分钟后自动删除,兼容排队执行场景
|
|
118
|
+
- `wecom:selfcheck` 自检脚本:校验配置、AES Key、`gettoken` 连通性与本地 webhook 健康
|
|
119
|
+
- `wecom:selfcheck --all-accounts` 批量体检:一次检查全部已发现账户并支持 JSON 报告
|
|
120
|
+
- `wecom:smoke` 回归脚本:串联语法检查、全账户体检、网关健康与状态摘要
|
|
121
|
+
- `tests/wecom-core.test.mjs`:覆盖会话 key、去重、签名匹配、分段逻辑等核心回归
|
|
122
|
+
- 并存排查文档:`docs/troubleshooting/coexistence.md`
|
|
123
|
+
|
|
124
|
+
### Fixed
|
|
125
|
+
- 修复旧实现只注册单一路由、导致 `channels.wecom.accounts` 实际不可用的问题
|
|
126
|
+
- 修复 `pairing required/no deliverable reply` 场景下可能过早删除媒体临时文件的问题
|
|
127
|
+
- AES key 增加长度校验,错误配置将明确报错(避免静默异常)
|
|
128
|
+
- 修复部分场景下仅产生 block 回复导致用户“看起来无回复”的问题:现在会回退发送累计 block 文本
|
|
129
|
+
- 修复长文本分段时的 `trim` 内容损失问题(保留原始空白与换行)
|
|
130
|
+
|
|
131
|
+
## [0.3.2] - 2026-01-29
|
|
132
|
+
|
|
133
|
+
### Added
|
|
134
|
+
|
|
135
|
+
#### 媒体消息扩展
|
|
136
|
+
- **视频消息接收**:支持接收用户发送的视频,自动下载保存到临时目录
|
|
137
|
+
- **视频消息发送**:新增 `sendWecomVideo()` 函数,支持发送视频到企业微信
|
|
138
|
+
- **文件消息接收**:支持接收用户发送的文件/文档,自动识别可读类型(.txt, .md, .json, .pdf 等)
|
|
139
|
+
- **文件消息发送**:新增 `sendWecomFile()` 函数,支持发送文件到企业微信
|
|
140
|
+
- **链接分享消息**:支持接收用户分享的链接,提取标题、描述和 URL
|
|
141
|
+
|
|
142
|
+
#### Chat UI 集成
|
|
143
|
+
- **消息同步到 Transcript**:用户消息和 AI 回复写入 session transcript 文件
|
|
144
|
+
- **实时广播**:通过 gateway broadcast 实时推送消息到 Chat UI
|
|
145
|
+
- **Gateway 方法**:新增 `wecom.init` 和 `wecom.broadcast` 方法
|
|
146
|
+
|
|
147
|
+
### Changed
|
|
148
|
+
- `processInboundMessage()` 函数签名扩展,支持更多消息类型参数
|
|
149
|
+
- HTTP 路由处理器新增 video、file、link 类型消息分发
|
|
150
|
+
|
|
151
|
+
## [0.3.1] - 2026-01-28
|
|
152
|
+
|
|
153
|
+
### Fixed
|
|
154
|
+
- **消息分段按字节计算**:企业微信限制 2048 字节(非字符),中文占 3 字节,修复长消息被截断问题
|
|
155
|
+
- **新增 getByteLength() 函数**:精确计算 UTF-8 字节长度
|
|
156
|
+
- **二分查找分割点**:使用二分查找算法精确定位字节分割位置
|
|
157
|
+
|
|
158
|
+
### Added
|
|
159
|
+
- **处理状态提示**:收到消息后立即发送"⏳ 收到您的消息,正在处理中,请稍候...",缓解用户等待焦虑
|
|
160
|
+
- **详细调试日志**:记录分段数量、字节长度等信息便于排查问题
|
|
161
|
+
|
|
162
|
+
## [0.3.0] - 2026-01-28
|
|
163
|
+
|
|
164
|
+
### Added
|
|
165
|
+
|
|
166
|
+
#### 阶段一:核心稳定性
|
|
167
|
+
- **Token 并发安全**:使用 Promise 锁防止多个请求同时刷新 access_token
|
|
168
|
+
- **消息自动分段**:超过 2048 字符的消息自动在自然断点处分割发送
|
|
169
|
+
- **XML 安全加固**:禁用实体处理防止 XXE 攻击,添加 1MB 请求体限制
|
|
170
|
+
- **错误处理完善**:记录完整堆栈日志,二次发送失败不再吞没异常
|
|
171
|
+
|
|
172
|
+
#### 阶段二:媒体功能
|
|
173
|
+
- **图片上传**:新增 `uploadWecomMedia()` 函数上传临时素材
|
|
174
|
+
- **图片发送**:新增 `sendWecomImage()` 函数发送图片消息
|
|
175
|
+
- **图片 Vision**:下载用户图片保存到临时文件,AI 可读取分析
|
|
176
|
+
- **deliverReply 媒体支持**:支持 `mediaUrl` 和 `mediaType` 参数
|
|
177
|
+
|
|
178
|
+
#### 阶段三:用户体验
|
|
179
|
+
- **命令系统**:支持 `/help`、`/status`、`/clear` 命令
|
|
180
|
+
- **Markdown 转换**:AI 回复中的 Markdown 自动转换为可读纯文本格式
|
|
181
|
+
- **API 限流**:RateLimiter 类限制并发(最多 3 个)和频率(200ms 间隔)
|
|
182
|
+
|
|
183
|
+
#### 阶段四:高级功能
|
|
184
|
+
- **多账户支持**:Token 缓存按账户隔离,支持 `WECOM_<ACCOUNT>_*` 格式配置
|
|
185
|
+
- **语音转文字**:支持企业微信自带语音识别(Recognition 字段)
|
|
186
|
+
- **群聊支持**:capabilities 支持 group 类型,群聊会话 ID 格式 `wecom:group:<chatId>`
|
|
187
|
+
|
|
188
|
+
### Changed
|
|
189
|
+
- `capabilities.media.outbound` 改为 `true`
|
|
190
|
+
- `capabilities.markdown` 改为 `true`
|
|
191
|
+
- `capabilities.chatTypes` 改为 `["direct", "group"]`
|
|
192
|
+
- 插件版本升级至 0.3.0
|
|
193
|
+
|
|
194
|
+
### Fixed
|
|
195
|
+
- 修正 capabilities 声明与实际实现不符的问题
|
|
196
|
+
- 修复长消息可能导致发送失败的问题
|
|
197
|
+
|
|
198
|
+
## [0.1.0] - 2026-01-27
|
|
199
|
+
|
|
200
|
+
### Added
|
|
201
|
+
- 初始版本
|
|
202
|
+
- 基础文本消息收发
|
|
203
|
+
- 消息加解密和签名验证
|
|
204
|
+
- access_token 缓存
|
|
205
|
+
- 图片消息接收(仅传 URL)
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 勾勾
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.en.md
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
# OpenClaw-Wechat (WeCom Plugin)
|
|
2
|
+
|
|
3
|
+
[中文 README](./README.md) | [English README](./README.en.md)
|
|
4
|
+
|
|
5
|
+
OpenClaw-Wechat is an OpenClaw channel plugin for Enterprise WeChat (WeCom), with two integration modes:
|
|
6
|
+
|
|
7
|
+
- `Agent mode`: WeCom custom app callback (XML)
|
|
8
|
+
- `Bot mode`: WeCom intelligent bot API callback (JSON + native stream)
|
|
9
|
+
|
|
10
|
+
## Table of Contents
|
|
11
|
+
|
|
12
|
+
- [Highlights](#highlights)
|
|
13
|
+
- [Mode Comparison](#mode-comparison)
|
|
14
|
+
- [5-Minute Quick Start](#5-minute-quick-start)
|
|
15
|
+
- [Requirements](#requirements)
|
|
16
|
+
- [Install and Load](#install-and-load)
|
|
17
|
+
- [Configuration Reference](#configuration-reference)
|
|
18
|
+
- [Capability Matrix](#capability-matrix)
|
|
19
|
+
- [Commands and Session Policy](#commands-and-session-policy)
|
|
20
|
+
- [Environment Variables](#environment-variables)
|
|
21
|
+
- [Coexistence with Other Channels](#coexistence-with-other-channels)
|
|
22
|
+
- [Troubleshooting](#troubleshooting)
|
|
23
|
+
- [Development](#development)
|
|
24
|
+
- [FAQ](#faq)
|
|
25
|
+
|
|
26
|
+
## Highlights
|
|
27
|
+
|
|
28
|
+
| Feature | Status | Notes |
|
|
29
|
+
|---|---|---|
|
|
30
|
+
| WeCom inbound message handling | ✅ | text/image/voice/link/file/video (Agent) |
|
|
31
|
+
| AI auto-reply via OpenClaw runtime | ✅ | routed by session key |
|
|
32
|
+
| Native WeCom Bot stream protocol | ✅ | `msgtype=stream` refresh flow |
|
|
33
|
+
| Multi-account support | ✅ | `channels.wecom.accounts.<id>` |
|
|
34
|
+
| Sender allowlist and admin bypass | ✅ | `allowFrom` + `adminUsers` |
|
|
35
|
+
| Command allowlist | ✅ | `/help`, `/status`, `/clear`, etc. |
|
|
36
|
+
| Group trigger policy | ✅ | mention-required or direct-trigger |
|
|
37
|
+
| Debounce and late-reply fallback | ✅ | better stability under queue/timeout |
|
|
38
|
+
| Outbound proxy for WeCom APIs | ✅ | `outboundProxy` / `WECOM_PROXY` |
|
|
39
|
+
|
|
40
|
+
## Mode Comparison
|
|
41
|
+
|
|
42
|
+
| Dimension | Agent Mode (Custom App) | Bot Mode (Intelligent Bot API) |
|
|
43
|
+
|---|---|---|
|
|
44
|
+
| Callback payload | XML | JSON |
|
|
45
|
+
| WeCom setup entry | Custom App | Intelligent Bot (**API mode**) |
|
|
46
|
+
| Default callback path | `/wecom/callback` | `/wecom/bot/callback` |
|
|
47
|
+
| Reply mechanism | WeCom send APIs | stream response + refresh polling |
|
|
48
|
+
| Streaming UX | simulated via multiple messages | native stream protocol |
|
|
49
|
+
| Outbound media | full support | currently text-first stream path |
|
|
50
|
+
|
|
51
|
+
## 5-Minute Quick Start
|
|
52
|
+
|
|
53
|
+
### 1) Install plugin
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
git clone https://github.com/dingxiang-me/OpenClaw-Wechat.git
|
|
57
|
+
cd OpenClaw-Wechat
|
|
58
|
+
npm install
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### 2) Load plugin in OpenClaw
|
|
62
|
+
|
|
63
|
+
Add to `~/.openclaw/openclaw.json`:
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"plugins": {
|
|
68
|
+
"enabled": true,
|
|
69
|
+
"allow": ["openclaw-wechat"],
|
|
70
|
+
"load": {
|
|
71
|
+
"paths": ["/path/to/OpenClaw-Wechat"]
|
|
72
|
+
},
|
|
73
|
+
"entries": {
|
|
74
|
+
"openclaw-wechat": {
|
|
75
|
+
"enabled": true
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### 3) Configure one mode
|
|
83
|
+
|
|
84
|
+
| Mode | Required keys |
|
|
85
|
+
|---|---|
|
|
86
|
+
| Agent | `corpId`, `corpSecret`, `agentId`, `callbackToken`, `callbackAesKey` |
|
|
87
|
+
| Bot | `bot.enabled=true`, `bot.token`, `bot.encodingAesKey` |
|
|
88
|
+
|
|
89
|
+
### 4) Restart and verify
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
openclaw gateway restart
|
|
93
|
+
openclaw gateway status
|
|
94
|
+
npm run wecom:selfcheck -- --all-accounts
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Requirements
|
|
98
|
+
|
|
99
|
+
| Item | Description |
|
|
100
|
+
|---|---|
|
|
101
|
+
| OpenClaw | installed and gateway is runnable |
|
|
102
|
+
| WeCom admin permission | to create app/bot and configure callback |
|
|
103
|
+
| Public callback endpoint | accessible from WeCom |
|
|
104
|
+
| Node.js | compatible with OpenClaw runtime |
|
|
105
|
+
| Local STT (optional) | `whisper-cli` or `whisper` |
|
|
106
|
+
| ffmpeg (recommended) | for voice transcoding fallback |
|
|
107
|
+
|
|
108
|
+
## Install and Load
|
|
109
|
+
|
|
110
|
+
### Local path loading (recommended)
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
git clone https://github.com/dingxiang-me/OpenClaw-Wechat.git
|
|
114
|
+
cd OpenClaw-Wechat
|
|
115
|
+
npm install
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Configure plugin load path in `~/.openclaw/openclaw.json`.
|
|
119
|
+
|
|
120
|
+
### npm installation
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
openclaw plugins install @dingxiang-me/openclaw-wechat
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Configuration Reference
|
|
127
|
+
|
|
128
|
+
### Root channel config (`channels.wecom`)
|
|
129
|
+
|
|
130
|
+
| Key | Type | Default | Notes |
|
|
131
|
+
|---|---|---|---|
|
|
132
|
+
| `enabled` | boolean | `true` | enable WeCom channel |
|
|
133
|
+
| `corpId` | string | - | Agent mode |
|
|
134
|
+
| `corpSecret` | string | - | sensitive |
|
|
135
|
+
| `agentId` | number/string | - | Agent mode |
|
|
136
|
+
| `callbackToken` | string | - | sensitive |
|
|
137
|
+
| `callbackAesKey` | string | - | sensitive |
|
|
138
|
+
| `webhookPath` | string | `/wecom/callback` | Agent callback path |
|
|
139
|
+
| `outboundProxy` | string | - | WeCom API proxy |
|
|
140
|
+
| `accounts` | object | - | multi-account map |
|
|
141
|
+
|
|
142
|
+
### Bot config (`channels.wecom.bot`)
|
|
143
|
+
|
|
144
|
+
| Key | Type | Default | Notes |
|
|
145
|
+
|---|---|---|---|
|
|
146
|
+
| `enabled` | boolean | `false` | enable Bot mode |
|
|
147
|
+
| `token` | string | - | sensitive |
|
|
148
|
+
| `encodingAesKey` | string | - | sensitive, 43 chars |
|
|
149
|
+
| `webhookPath` | string | `/wecom/bot/callback` | Bot callback path |
|
|
150
|
+
| `placeholderText` | string | processing text | stream initial placeholder |
|
|
151
|
+
| `streamExpireMs` | integer | `600000` | 30s ~ 1h |
|
|
152
|
+
|
|
153
|
+
### Policy config
|
|
154
|
+
|
|
155
|
+
| Area | Keys |
|
|
156
|
+
|---|---|
|
|
157
|
+
| Sender ACL | `allowFrom`, `allowFromRejectMessage` |
|
|
158
|
+
| Command ACL | `commands.enabled`, `commands.allowlist`, `commands.rejectMessage` |
|
|
159
|
+
| Admin bypass | `adminUsers` |
|
|
160
|
+
| Group trigger | `groupChat.enabled`, `groupChat.requireMention`, `groupChat.mentionPatterns` |
|
|
161
|
+
| Debounce | `debounce.enabled`, `debounce.windowMs`, `debounce.maxBatch` |
|
|
162
|
+
| Agent streaming | `streaming.enabled`, `streaming.minChars`, `streaming.minIntervalMs` |
|
|
163
|
+
|
|
164
|
+
## Capability Matrix
|
|
165
|
+
|
|
166
|
+
### Agent mode
|
|
167
|
+
|
|
168
|
+
| Message type | Inbound | Outbound |
|
|
169
|
+
|---|---|---|
|
|
170
|
+
| Text | ✅ | ✅ |
|
|
171
|
+
| Image | ✅ | ✅ |
|
|
172
|
+
| Voice | ✅ | ❌ (transcript as text) |
|
|
173
|
+
| Video | ✅ | ✅ |
|
|
174
|
+
| File | ✅ | ✅ |
|
|
175
|
+
| Link | ✅ | ❌ |
|
|
176
|
+
|
|
177
|
+
### Bot mode
|
|
178
|
+
|
|
179
|
+
| Message type | Inbound | Outbound | Notes |
|
|
180
|
+
|---|---|---|---|
|
|
181
|
+
| Text | ✅ | ✅ | native stream |
|
|
182
|
+
| Image | ✅ | ⚠️ | image understanding + text reply |
|
|
183
|
+
| Voice | ✅ | ✅ | transcript-driven text reply |
|
|
184
|
+
| Mixed | ✅ | ✅ | aggregated context |
|
|
185
|
+
| Link/Location | ✅ | ✅ | normalized to text context |
|
|
186
|
+
|
|
187
|
+
## Commands and Session Policy
|
|
188
|
+
|
|
189
|
+
| Command | Description |
|
|
190
|
+
|---|---|
|
|
191
|
+
| `/help` | show help |
|
|
192
|
+
| `/status` | show runtime status |
|
|
193
|
+
| `/clear` | clear session (mapped to `/reset`) |
|
|
194
|
+
| `/reset` | reset conversation |
|
|
195
|
+
| `/new` | new session (runtime-supported) |
|
|
196
|
+
| `/compact` | compact session (runtime-supported) |
|
|
197
|
+
|
|
198
|
+
Session key policy: default is one-user-one-session (`wecom:<userid>`).
|
|
199
|
+
|
|
200
|
+
## Environment Variables
|
|
201
|
+
|
|
202
|
+
### Core
|
|
203
|
+
|
|
204
|
+
| Variable | Purpose |
|
|
205
|
+
|---|---|
|
|
206
|
+
| `WECOM_CORP_ID`, `WECOM_CORP_SECRET`, `WECOM_AGENT_ID` | Agent app credentials |
|
|
207
|
+
| `WECOM_CALLBACK_TOKEN`, `WECOM_CALLBACK_AES_KEY` | Agent callback security |
|
|
208
|
+
| `WECOM_WEBHOOK_PATH` | Agent callback path |
|
|
209
|
+
|
|
210
|
+
### Bot
|
|
211
|
+
|
|
212
|
+
| Variable | Purpose |
|
|
213
|
+
|---|---|
|
|
214
|
+
| `WECOM_BOT_ENABLED` | enable Bot mode |
|
|
215
|
+
| `WECOM_BOT_TOKEN` | Bot callback token |
|
|
216
|
+
| `WECOM_BOT_ENCODING_AES_KEY` | Bot AES key |
|
|
217
|
+
| `WECOM_BOT_WEBHOOK_PATH` | Bot callback path |
|
|
218
|
+
| `WECOM_BOT_PLACEHOLDER_TEXT` | stream placeholder text |
|
|
219
|
+
| `WECOM_BOT_STREAM_EXPIRE_MS` | stream cache TTL |
|
|
220
|
+
|
|
221
|
+
### Stability and policy
|
|
222
|
+
|
|
223
|
+
| Variable group | Purpose |
|
|
224
|
+
|---|---|
|
|
225
|
+
| `WECOM_ALLOW_FROM*` | sender authorization |
|
|
226
|
+
| `WECOM_COMMANDS_*` | command ACL |
|
|
227
|
+
| `WECOM_GROUP_CHAT_*` | group trigger policy |
|
|
228
|
+
| `WECOM_DEBOUNCE_*` | text debounce |
|
|
229
|
+
| `WECOM_STREAMING_*` | Agent incremental output |
|
|
230
|
+
| `WECOM_LATE_REPLY_*` | async late reply fallback |
|
|
231
|
+
| `WECOM_PROXY`, `WECOM_<ACCOUNT>_PROXY` | outbound proxy |
|
|
232
|
+
|
|
233
|
+
### Local voice transcription fallback
|
|
234
|
+
|
|
235
|
+
| Variable group | Purpose |
|
|
236
|
+
|---|---|
|
|
237
|
+
| `WECOM_VOICE_TRANSCRIBE_*` | local whisper/whisper-cli settings |
|
|
238
|
+
|
|
239
|
+
## Coexistence with Other Channels
|
|
240
|
+
|
|
241
|
+
Recommended hardening for Telegram/Feishu/WeCom together:
|
|
242
|
+
|
|
243
|
+
1. Use explicit `plugins.allow` whitelist.
|
|
244
|
+
2. Keep webhook paths isolated per channel/account.
|
|
245
|
+
3. Prefer one OpenClaw gateway process per machine.
|
|
246
|
+
|
|
247
|
+
See [`docs/troubleshooting/coexistence.md`](./docs/troubleshooting/coexistence.md).
|
|
248
|
+
|
|
249
|
+
## Troubleshooting
|
|
250
|
+
|
|
251
|
+
| Symptom | Check first | Typical root cause |
|
|
252
|
+
|---|---|---|
|
|
253
|
+
| Callback verification failed | callback URL reachability | URL/Token/AES mismatch |
|
|
254
|
+
| Inbound received but no reply | gateway logs + dispatch status | timeout, queueing, policy block |
|
|
255
|
+
| Bot image parse failed | `wecom(bot): failed to fetch image url` | expired URL/non-image stream |
|
|
256
|
+
| Voice transcription failed | local command/model path | whisper/ffmpeg environment issue |
|
|
257
|
+
| gettoken failed | WeCom API result | wrong credentials or network/proxy |
|
|
258
|
+
|
|
259
|
+
Useful commands:
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
openclaw gateway status
|
|
263
|
+
openclaw status --deep
|
|
264
|
+
openclaw logs --follow
|
|
265
|
+
npm run wecom:selfcheck -- --all-accounts
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## Development
|
|
269
|
+
|
|
270
|
+
| Command | Purpose |
|
|
271
|
+
|---|---|
|
|
272
|
+
| `npm test` | syntax + tests |
|
|
273
|
+
| `npm run wecom:selfcheck -- --all-accounts` | config/network self-check |
|
|
274
|
+
| `npm run wecom:smoke` | smoke test after upgrades |
|
|
275
|
+
| `openclaw gateway restart` | restart runtime |
|
|
276
|
+
|
|
277
|
+
## FAQ
|
|
278
|
+
|
|
279
|
+
### Why does Bot callback fail with parsing errors?
|
|
280
|
+
Most likely the bot was created in non-API mode. Re-create as **API mode**.
|
|
281
|
+
|
|
282
|
+
### Why can image recognition fail intermittently?
|
|
283
|
+
WeCom image URLs can return non-standard content type or encrypted media stream. The plugin now includes content sniffing and decrypt fallback.
|
|
284
|
+
|
|
285
|
+
### Can Telegram and WeCom affect each other?
|
|
286
|
+
They are logically independent, but can conflict via shared webhook paths, multi-process gateway races, or loose plugin loading policy.
|
|
287
|
+
|