openclaw-plugin-wecom 1.0.0 → 1.0.2
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 +192 -104
- package/README_ZH.md +172 -84
- package/index.js +1 -0
- package/logger.js +21 -3
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,148 +1,131 @@
|
|
|
1
1
|
# OpenClaw WeCom (Enterprise WeChat) AI Bot Plugin
|
|
2
2
|
|
|
3
|
-
[
|
|
3
|
+
[English](https://github.com/sunnoy/openclaw-plugin-wecom/blob/main/README.md) | [简体中文](https://github.com/sunnoy/openclaw-plugin-wecom/blob/main/README_ZH.md)
|
|
4
4
|
|
|
5
|
-
`openclaw-plugin-wecom` is
|
|
5
|
+
`openclaw-plugin-wecom` is an Enterprise WeChat (WeCom) integration plugin developed for the [OpenClaw](https://github.com/openclaw/openclaw) framework. It enables seamless AI capabilities in Enterprise WeChat with advanced features.
|
|
6
6
|
|
|
7
7
|
## ✨ Key Features
|
|
8
8
|
|
|
9
|
-
- 🌊 **Streaming Output**:
|
|
10
|
-
- 🤖 **Dynamic Agent Management**: Automatically creates
|
|
11
|
-
- 👥 **Group Chat Integration**:
|
|
12
|
-
- 🛠️ **Command
|
|
13
|
-
- 🔒 **Security**:
|
|
14
|
-
- ⚡ **Async Processing**:
|
|
9
|
+
- 🌊 **Streaming Output**: Built on WeCom's latest AI bot streaming mechanism for smooth typewriter-style responses.
|
|
10
|
+
- 🤖 **Dynamic Agent Management**: Automatically creates isolated agents per direct message user or group chat, with independent workspaces and conversation contexts.
|
|
11
|
+
- 👥 **Deep Group Chat Integration**: Supports group message parsing with @mention triggering.
|
|
12
|
+
- 🛠️ **Command Enhancement**: Built-in commands (e.g., `/new` for new sessions, `/status` for status) with allowlist configuration.
|
|
13
|
+
- 🔒 **Security & Authentication**: Full support for WeCom message encryption/decryption, URL verification, and sender validation.
|
|
14
|
+
- ⚡ **High-Performance Async Processing**: Asynchronous message architecture ensures responsive gateway even during long AI inference.
|
|
15
15
|
|
|
16
|
-
##
|
|
16
|
+
## 📋 Prerequisites
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
- [OpenClaw](https://github.com/openclaw/openclaw) installed (version 2026.1.30+)
|
|
19
|
+
- Enterprise WeChat admin access to create intelligent robot applications
|
|
20
|
+
- Server address accessible from Enterprise WeChat (HTTP/HTTPS)
|
|
19
21
|
|
|
20
|
-
|
|
22
|
+
## 🚀 Installation
|
|
21
23
|
|
|
22
|
-
|
|
23
|
-
# 1. Clone the repository
|
|
24
|
-
git clone https://github.com/sunnoy/openclaw-plugin-wecom.git
|
|
25
|
-
cd openclaw-plugin-wecom/deploy
|
|
26
|
-
|
|
27
|
-
# 2. Copy environment configuration
|
|
28
|
-
cp .env.example .env
|
|
29
|
-
|
|
30
|
-
# 3. Edit .env file with your settings
|
|
31
|
-
vim .env
|
|
32
|
-
|
|
33
|
-
# 4. Run deployment script
|
|
34
|
-
./deploy.sh
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
The deployment script automatically:
|
|
38
|
-
- Creates data directories and sets permissions
|
|
39
|
-
- Generates configuration files
|
|
40
|
-
- Starts Docker containers
|
|
41
|
-
- Installs the WeCom plugin
|
|
42
|
-
- Configures and restarts services
|
|
43
|
-
|
|
44
|
-
#### 🌟 Deployment Highlights
|
|
45
|
-
|
|
46
|
-
**Custom Data Directory & Agent Workspace Paths**
|
|
47
|
-
|
|
48
|
-
The core advantage of this deployment is unified data storage in a custom path, effectively utilizing data disks:
|
|
49
|
-
|
|
50
|
-
```bash
|
|
51
|
-
# .env configuration example
|
|
52
|
-
OPENCLAW_DATA_DIR=/data/openclaw # Custom data directory
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
- **OpenClaw State Directory**: `/data/openclaw/`
|
|
56
|
-
- **Dynamic Agent Workspace**: `/data/openclaw/.openclaw/`
|
|
57
|
-
- **Plugin Directory**: `/data/openclaw/extensions/`
|
|
58
|
-
- **Canvas Data**: `/data/openclaw/canvas/`
|
|
59
|
-
|
|
60
|
-
Benefits:
|
|
61
|
-
- ✅ All Agent workspace data stored on data disk, avoiding system disk usage
|
|
62
|
-
- ✅ Independent Agent files for each user/group managed under unified path
|
|
63
|
-
- ✅ Easy backup, migration, and expansion
|
|
64
|
-
- ✅ Enterprise-ready deployment with independently mountable data disks
|
|
65
|
-
|
|
66
|
-
### Option 2: Manual Plugin Installation
|
|
67
|
-
|
|
68
|
-
Install in an existing OpenClaw environment:
|
|
24
|
+
### Method 1: Using OpenClaw CLI (Recommended)
|
|
69
25
|
|
|
70
26
|
```bash
|
|
71
27
|
openclaw plugins install openclaw-plugin-wecom
|
|
72
28
|
```
|
|
73
29
|
|
|
74
|
-
|
|
30
|
+
### Method 2: Using npm
|
|
75
31
|
|
|
76
32
|
```bash
|
|
77
33
|
npm install openclaw-plugin-wecom
|
|
78
34
|
```
|
|
79
35
|
|
|
80
|
-
|
|
36
|
+
## ⚙️ Configuration
|
|
37
|
+
|
|
38
|
+
Add to your OpenClaw configuration file (`~/.openclaw/openclaw.json`):
|
|
81
39
|
|
|
82
40
|
```json
|
|
83
41
|
{
|
|
84
42
|
"plugins": {
|
|
43
|
+
"deny": ["wecom"],
|
|
85
44
|
"entries": {
|
|
86
|
-
"wecom": {
|
|
45
|
+
"openclaw-plugin-wecom": {
|
|
46
|
+
"enabled": true
|
|
47
|
+
}
|
|
87
48
|
}
|
|
88
49
|
},
|
|
89
50
|
"channels": {
|
|
90
51
|
"wecom": {
|
|
91
52
|
"enabled": true,
|
|
92
53
|
"token": "Your Token",
|
|
93
|
-
"encodingAesKey": "Your EncodingAESKey"
|
|
54
|
+
"encodingAesKey": "Your EncodingAESKey",
|
|
55
|
+
"commands": {
|
|
56
|
+
"enabled": true,
|
|
57
|
+
"allowlist": ["/new", "/status", "/help", "/compact"]
|
|
58
|
+
}
|
|
94
59
|
}
|
|
95
60
|
}
|
|
96
61
|
}
|
|
97
62
|
```
|
|
98
63
|
|
|
99
|
-
###
|
|
64
|
+
### Configuration Options
|
|
100
65
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
66
|
+
| Option | Type | Required | Description |
|
|
67
|
+
|--------|------|----------|-------------|
|
|
68
|
+
| `plugins.deny` | array | Recommended | Add `["wecom"]` to prevent OpenClaw from auto-enabling built-in channel |
|
|
69
|
+
| `plugins.entries.openclaw-plugin-wecom.enabled` | boolean | Yes | Enable the plugin |
|
|
70
|
+
| `channels.wecom.token` | string | Yes | WeCom bot Token |
|
|
71
|
+
| `channels.wecom.encodingAesKey` | string | Yes | WeCom message encryption key (43 chars) |
|
|
72
|
+
| `channels.wecom.commands.allowlist` | array | No | Command allowlist |
|
|
104
73
|
|
|
105
|
-
##
|
|
74
|
+
## 🔌 Enterprise WeChat Configuration
|
|
106
75
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
│ └── openclaw.json.template # Full configuration template
|
|
115
|
-
├── Dockerfile # OpenClaw image build file
|
|
116
|
-
├── local.sh # Local image build script
|
|
117
|
-
├── index.js # Plugin entry point
|
|
118
|
-
├── webhook.js # WeCom HTTP communication
|
|
119
|
-
├── dynamic-agent.js # Dynamic Agent routing
|
|
120
|
-
├── stream-manager.js # Streaming response management
|
|
121
|
-
├── crypto.js # WeCom encryption
|
|
122
|
-
└── client.js # Client logic
|
|
123
|
-
```
|
|
76
|
+
1. Log in to [Enterprise WeChat Admin Console](https://work.weixin.qq.com/)
|
|
77
|
+
2. Navigate to "Application Management" → "Applications" → "Create Application" → Select "Intelligent Robot"
|
|
78
|
+
3. Configure "Receive Messages":
|
|
79
|
+
- **URL**: `https://your-domain.com/webhooks/wecom`
|
|
80
|
+
- **Token**: Match `channels.wecom.token`
|
|
81
|
+
- **EncodingAESKey**: Match `channels.wecom.encodingAesKey`
|
|
82
|
+
4. Save and enable message receiving
|
|
124
83
|
|
|
125
84
|
## 🤖 Dynamic Agent Routing
|
|
126
85
|
|
|
127
|
-
The plugin implements per-user/per-group isolation:
|
|
86
|
+
The plugin implements per-user/per-group agent isolation:
|
|
128
87
|
|
|
129
|
-
|
|
130
|
-
- DM: `wecom-dm-<userId>`
|
|
131
|
-
- Group: `wecom-group-<chatId>`
|
|
132
|
-
2. OpenClaw automatically creates/reuses the corresponding Agent workspace.
|
|
88
|
+
### How It Works
|
|
133
89
|
|
|
134
|
-
|
|
90
|
+
1. When a WeCom message arrives, the plugin generates a deterministic `agentId`:
|
|
91
|
+
- **Direct Messages**: `wecom-dm-<userId>`
|
|
92
|
+
- **Group Chats**: `wecom-group-<chatId>`
|
|
93
|
+
2. OpenClaw automatically creates/reuses the corresponding agent workspace
|
|
94
|
+
3. Each user/group has independent conversation history and context
|
|
95
|
+
|
|
96
|
+
### Advanced Configuration
|
|
135
97
|
|
|
136
|
-
|
|
98
|
+
Configure under `channels.wecom`:
|
|
99
|
+
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"channels": {
|
|
103
|
+
"wecom": {
|
|
104
|
+
"dynamicAgents": {
|
|
105
|
+
"enabled": true
|
|
106
|
+
},
|
|
107
|
+
"dm": {
|
|
108
|
+
"createAgentOnFirstMessage": true
|
|
109
|
+
},
|
|
110
|
+
"groupChat": {
|
|
111
|
+
"enabled": true,
|
|
112
|
+
"requireMention": true
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
```
|
|
137
118
|
|
|
138
119
|
| Option | Type | Default | Description |
|
|
139
120
|
|--------|------|---------|-------------|
|
|
140
|
-
| `dynamicAgents.enabled` | boolean | `true` | Enable dynamic
|
|
141
|
-
| `dm.createAgentOnFirstMessage` | boolean | `true` | Use dynamic
|
|
142
|
-
| `groupChat.enabled` | boolean | `true` | Enable group chat
|
|
121
|
+
| `dynamicAgents.enabled` | boolean | `true` | Enable dynamic agents |
|
|
122
|
+
| `dm.createAgentOnFirstMessage` | boolean | `true` | Use dynamic agents for DMs |
|
|
123
|
+
| `groupChat.enabled` | boolean | `true` | Enable group chat processing |
|
|
143
124
|
| `groupChat.requireMention` | boolean | `true` | Require @mention in groups |
|
|
144
125
|
|
|
145
|
-
|
|
126
|
+
### Disable Dynamic Agents
|
|
127
|
+
|
|
128
|
+
To route all messages to the default agent:
|
|
146
129
|
|
|
147
130
|
```json
|
|
148
131
|
{
|
|
@@ -154,11 +137,9 @@ To route all messages to the default Agent:
|
|
|
154
137
|
}
|
|
155
138
|
```
|
|
156
139
|
|
|
157
|
-
## 🛠️ Command
|
|
158
|
-
|
|
159
|
-
To prevent regular users from executing sensitive Gateway management commands via WeCom messages, this plugin supports a **command whitelist** mechanism. Only commands in the whitelist will be executed; others are ignored.
|
|
140
|
+
## 🛠️ Command Allowlist
|
|
160
141
|
|
|
161
|
-
|
|
142
|
+
Prevent regular users from executing sensitive Gateway management commands through WeCom messages.
|
|
162
143
|
|
|
163
144
|
```json
|
|
164
145
|
{
|
|
@@ -173,19 +154,126 @@ To prevent regular users from executing sensitive Gateway management commands vi
|
|
|
173
154
|
}
|
|
174
155
|
```
|
|
175
156
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
|
179
|
-
|
|
157
|
+
### Recommended Allowlist Commands
|
|
158
|
+
|
|
159
|
+
| Command | Description | Safety Level |
|
|
160
|
+
|---------|-------------|--------------|
|
|
161
|
+
| `/new` | Reset conversation, start new session | ✅ User-level |
|
|
162
|
+
| `/compact` | Compress current session context | ✅ User-level |
|
|
180
163
|
| `/help` | Show help information | ✅ User-level |
|
|
181
164
|
| `/status` | Show Agent status | ✅ User-level |
|
|
182
165
|
|
|
183
|
-
> ⚠️ **Security Note**: Do not add `/gateway`, `/plugins`, or other management commands to the
|
|
166
|
+
> ⚠️ **Security Note**: Do not add `/gateway`, `/plugins`, or other management commands to the allowlist to prevent regular users from gaining Gateway instance admin privileges.
|
|
167
|
+
|
|
168
|
+
## ❓ FAQ
|
|
169
|
+
|
|
170
|
+
### Q: What plugin ID should I use in the configuration file?
|
|
171
|
+
|
|
172
|
+
**A:** Use the **complete plugin ID** in `plugins.entries`:
|
|
173
|
+
|
|
174
|
+
```json
|
|
175
|
+
{
|
|
176
|
+
"plugins": {
|
|
177
|
+
"entries": {
|
|
178
|
+
"openclaw-plugin-wecom": { "enabled": true } // ✅ Correct
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**Do not** use the channel id:
|
|
185
|
+
```json
|
|
186
|
+
{
|
|
187
|
+
"plugins": {
|
|
188
|
+
"entries": {
|
|
189
|
+
"wecom": { "enabled": true } // ❌ Incorrect
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Q: Why does `openclaw doctor` keep reporting "wecom configured, not enabled yet"?
|
|
196
|
+
|
|
197
|
+
**A:** Add `"deny": ["wecom"]` to your `plugins` configuration:
|
|
198
|
+
|
|
199
|
+
```json
|
|
200
|
+
{
|
|
201
|
+
"plugins": {
|
|
202
|
+
"deny": ["wecom"],
|
|
203
|
+
"entries": {
|
|
204
|
+
"openclaw-plugin-wecom": {
|
|
205
|
+
"enabled": true
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
**Reason:** OpenClaw tries to auto-enable built-in channel configurations with the id `wecom`. Adding `deny` prevents this auto-enablement, ensuring only the `openclaw-plugin-wecom` plugin is used.
|
|
213
|
+
|
|
214
|
+
### Q: How to configure auth token for public-facing OpenClaw with WeCom callbacks?
|
|
215
|
+
|
|
216
|
+
**A:** WeCom bot **does not need** OpenClaw's Gateway Auth Token.
|
|
217
|
+
|
|
218
|
+
- **Gateway Auth Token** (`gateway.auth.token`) is used for:
|
|
219
|
+
- WebUI access authentication
|
|
220
|
+
- WebSocket connection authentication
|
|
221
|
+
- CLI remote connection authentication
|
|
222
|
+
|
|
223
|
+
- **WeCom Webhook** (`/webhooks/wecom`) authentication:
|
|
224
|
+
- Uses WeCom's own signature verification (Token + EncodingAESKey)
|
|
225
|
+
- Does not require Gateway Auth Token
|
|
226
|
+
- OpenClaw plugin system automatically handles webhook routing
|
|
227
|
+
|
|
228
|
+
**Deployment suggestions:**
|
|
229
|
+
1. If using a reverse proxy (e.g., Nginx), configure authentication exemption for `/webhooks/wecom` path
|
|
230
|
+
2. Or expose the webhook endpoint on a separate port without Gateway Auth
|
|
231
|
+
|
|
232
|
+
### Q: How to fix EncodingAESKey length validation failure?
|
|
233
|
+
|
|
234
|
+
**A:** Common causes and solutions:
|
|
235
|
+
|
|
236
|
+
1. **Check configuration key name**: Ensure correct key name `encodingAesKey` (case-sensitive)
|
|
237
|
+
```json
|
|
238
|
+
{
|
|
239
|
+
"channels": {
|
|
240
|
+
"wecom": {
|
|
241
|
+
"encodingAesKey": "..." // ✅ Correct
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
2. **Check key length**: EncodingAESKey must be exactly 43 characters
|
|
248
|
+
```bash
|
|
249
|
+
# Check length
|
|
250
|
+
echo -n "your-key" | wc -c
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
3. **Check for extra spaces/newlines**: Ensure no leading/trailing whitespace in the key string
|
|
254
|
+
|
|
255
|
+
## 📂 Project Structure
|
|
256
|
+
|
|
257
|
+
```
|
|
258
|
+
openclaw-plugin-wecom/
|
|
259
|
+
├── index.js # Plugin entry point
|
|
260
|
+
├── webhook.js # WeCom HTTP communication handler
|
|
261
|
+
├── dynamic-agent.js # Dynamic agent routing logic
|
|
262
|
+
├── stream-manager.js # Streaming response manager
|
|
263
|
+
├── crypto.js # WeCom encryption algorithms
|
|
264
|
+
├── client.js # Client logic
|
|
265
|
+
├── logger.js # Logging module
|
|
266
|
+
├── utils.js # Utility functions
|
|
267
|
+
├── package.json # npm package config
|
|
268
|
+
└── openclaw.plugin.json # OpenClaw plugin manifest
|
|
269
|
+
```
|
|
184
270
|
|
|
185
271
|
## 🤝 Contributing
|
|
186
272
|
|
|
187
273
|
We welcome contributions! Please submit Issues or Pull Requests for bugs or feature suggestions.
|
|
188
274
|
|
|
275
|
+
See [CONTRIBUTING.md](./CONTRIBUTING.md) for details.
|
|
276
|
+
|
|
189
277
|
## 📄 License
|
|
190
278
|
|
|
191
279
|
This project is licensed under the [ISC License](./LICENSE).
|
package/README_ZH.md
CHANGED
|
@@ -13,128 +13,109 @@
|
|
|
13
13
|
- 🔒 **安全与认证**: 完整支持企业微信消息加解密、URL 验证及发送者身份校验。
|
|
14
14
|
- ⚡ **高性能异步处理**: 采用异步消息处理架构,确保即使在长耗时 AI 推理过程中,企业微信网关也能保持高响应性。
|
|
15
15
|
|
|
16
|
-
##
|
|
16
|
+
## 📋 前置要求
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
- 已安装 [OpenClaw](https://github.com/openclaw/openclaw) (版本 2026.1.30+)
|
|
19
|
+
- 企业微信管理后台权限,可创建智能机器人应用
|
|
20
|
+
- 可从企业微信访问的服务器地址(HTTP/HTTPS)
|
|
19
21
|
|
|
20
|
-
|
|
22
|
+
## 🚀 安装
|
|
21
23
|
|
|
22
|
-
|
|
23
|
-
# 1. 克隆仓库
|
|
24
|
-
git clone https://github.com/sunnoy/openclaw-plugin-wecom.git
|
|
25
|
-
cd openclaw-plugin-wecom/deploy
|
|
26
|
-
|
|
27
|
-
# 2. 复制环境变量配置
|
|
28
|
-
cp .env.example .env
|
|
29
|
-
|
|
30
|
-
# 3. 编辑 .env 文件,填写实际配置
|
|
31
|
-
vim .env
|
|
32
|
-
|
|
33
|
-
# 4. 运行部署脚本
|
|
34
|
-
./deploy.sh
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
部署脚本会自动执行:
|
|
38
|
-
- 创建数据目录和设置权限
|
|
39
|
-
- 生成配置文件
|
|
40
|
-
- 启动 Docker 容器
|
|
41
|
-
- 安装企业微信插件
|
|
42
|
-
- 配置并重启服务
|
|
43
|
-
|
|
44
|
-
#### 🌟 部署亮点
|
|
45
|
-
|
|
46
|
-
**自定义数据目录 & Agent Workspace 路径**
|
|
47
|
-
|
|
48
|
-
本部署方案的核心优势是将所有数据统一存储到自定义路径,有效利用数据盘:
|
|
49
|
-
|
|
50
|
-
```bash
|
|
51
|
-
# .env 配置示例
|
|
52
|
-
OPENCLAW_DATA_DIR=/data/openclaw # 自定义数据目录
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
- **OpenClaw 状态目录**:`/data/openclaw/`
|
|
56
|
-
- **动态 Agent Workspace**:`/data/openclaw/.openclaw/`
|
|
57
|
-
- **插件目录**:`/data/openclaw/extensions/`
|
|
58
|
-
- **Canvas 数据**:`/data/openclaw/canvas/`
|
|
59
|
-
|
|
60
|
-
这意味着:
|
|
61
|
-
- ✅ 所有 Agent 工作区数据存储在数据盘,避免占用系统盘空间
|
|
62
|
-
- ✅ 每个用户/群聊的独立 Agent 文件都在统一路径下管理
|
|
63
|
-
- ✅ 方便备份、迁移和扩容
|
|
64
|
-
- ✅ 适合企业级部署,数据盘可独立挂载和扩展
|
|
65
|
-
|
|
66
|
-
### 方式二:手动安装插件
|
|
67
|
-
|
|
68
|
-
在已有的 OpenClaw 环境中安装:
|
|
24
|
+
### 方式一:使用 OpenClaw CLI(推荐)
|
|
69
25
|
|
|
70
26
|
```bash
|
|
71
27
|
openclaw plugins install openclaw-plugin-wecom
|
|
72
28
|
```
|
|
73
29
|
|
|
74
|
-
|
|
30
|
+
### 方式二:使用 npm
|
|
75
31
|
|
|
76
32
|
```bash
|
|
77
33
|
npm install openclaw-plugin-wecom
|
|
78
34
|
```
|
|
79
35
|
|
|
80
|
-
|
|
36
|
+
## ⚙️ 配置
|
|
37
|
+
|
|
38
|
+
在 OpenClaw 配置文件(`~/.openclaw/openclaw.json`)中添加:
|
|
81
39
|
|
|
82
40
|
```json
|
|
83
41
|
{
|
|
84
42
|
"plugins": {
|
|
43
|
+
"deny": ["wecom"],
|
|
85
44
|
"entries": {
|
|
86
|
-
"wecom": {
|
|
45
|
+
"openclaw-plugin-wecom": {
|
|
46
|
+
"enabled": true
|
|
47
|
+
}
|
|
87
48
|
}
|
|
88
49
|
},
|
|
89
50
|
"channels": {
|
|
90
51
|
"wecom": {
|
|
91
52
|
"enabled": true,
|
|
92
53
|
"token": "你的 Token",
|
|
93
|
-
"encodingAesKey": "你的 EncodingAESKey"
|
|
54
|
+
"encodingAesKey": "你的 EncodingAESKey",
|
|
55
|
+
"commands": {
|
|
56
|
+
"enabled": true,
|
|
57
|
+
"allowlist": ["/new", "/status", "/help", "/compact"]
|
|
58
|
+
}
|
|
94
59
|
}
|
|
95
60
|
}
|
|
96
61
|
}
|
|
97
62
|
```
|
|
98
63
|
|
|
99
|
-
###
|
|
64
|
+
### 配置说明
|
|
100
65
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
66
|
+
| 配置项 | 类型 | 必填 | 说明 |
|
|
67
|
+
|--------|------|------|------|
|
|
68
|
+
| `plugins.deny` | array | 推荐 | 添加 `["wecom"]` 防止 OpenClaw 自动启用内置 channel |
|
|
69
|
+
| `plugins.entries.openclaw-plugin-wecom.enabled` | boolean | 是 | 启用插件 |
|
|
70
|
+
| `channels.wecom.token` | string | 是 | 企业微信机器人 Token |
|
|
71
|
+
| `channels.wecom.encodingAesKey` | string | 是 | 企业微信消息加密密钥(43 位) |
|
|
72
|
+
| `channels.wecom.commands.allowlist` | array | 否 | 允许的指令白名单 |
|
|
104
73
|
|
|
105
|
-
##
|
|
74
|
+
## 🔌 企业微信后台配置
|
|
106
75
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
│ └── openclaw.json.template # 完整配置模板
|
|
115
|
-
├── Dockerfile # OpenClaw 镜像构建文件
|
|
116
|
-
├── local.sh # 本地镜像构建脚本
|
|
117
|
-
├── index.js # 插件入口
|
|
118
|
-
├── webhook.js # 企业微信 HTTP 通信处理
|
|
119
|
-
├── dynamic-agent.js # 动态 Agent 分配逻辑
|
|
120
|
-
├── stream-manager.js # 流式回复管理
|
|
121
|
-
├── crypto.js # 企业微信加密算法
|
|
122
|
-
└── client.js # 客户端逻辑
|
|
123
|
-
```
|
|
76
|
+
1. 登录[企业微信管理后台](https://work.weixin.qq.com/)
|
|
77
|
+
2. 进入"应用管理" → "应用" → "创建应用" → 选择"智能机器人"
|
|
78
|
+
3. 在"接收消息配置"中设置:
|
|
79
|
+
- **URL**: `https://your-domain.com/webhooks/wecom`
|
|
80
|
+
- **Token**: 与 `channels.wecom.token` 一致
|
|
81
|
+
- **EncodingAESKey**: 与 `channels.wecom.encodingAesKey` 一致
|
|
82
|
+
4. 保存配置并启用消息接收
|
|
124
83
|
|
|
125
84
|
## 🤖 动态 Agent 路由
|
|
126
85
|
|
|
127
|
-
|
|
86
|
+
本插件实现"按人/按群隔离"的 Agent 管理:
|
|
87
|
+
|
|
88
|
+
### 工作原理
|
|
128
89
|
|
|
129
90
|
1. 企业微信消息到达后,插件生成确定性的 `agentId`:
|
|
130
|
-
-
|
|
131
|
-
-
|
|
132
|
-
2. OpenClaw 自动创建/复用对应的 Agent
|
|
91
|
+
- **私聊**: `wecom-dm-<userId>`
|
|
92
|
+
- **群聊**: `wecom-group-<chatId>`
|
|
93
|
+
2. OpenClaw 自动创建/复用对应的 Agent 工作区
|
|
94
|
+
3. 每个用户/群聊拥有独立的对话历史和上下文
|
|
133
95
|
|
|
134
|
-
###
|
|
96
|
+
### 高级配置
|
|
135
97
|
|
|
136
98
|
配置在 `channels.wecom` 下:
|
|
137
99
|
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"channels": {
|
|
103
|
+
"wecom": {
|
|
104
|
+
"dynamicAgents": {
|
|
105
|
+
"enabled": true
|
|
106
|
+
},
|
|
107
|
+
"dm": {
|
|
108
|
+
"createAgentOnFirstMessage": true
|
|
109
|
+
},
|
|
110
|
+
"groupChat": {
|
|
111
|
+
"enabled": true,
|
|
112
|
+
"requireMention": true
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
138
119
|
| 配置项 | 类型 | 默认值 | 说明 |
|
|
139
120
|
|--------|------|--------|------|
|
|
140
121
|
| `dynamicAgents.enabled` | boolean | `true` | 是否启用动态 Agent |
|
|
@@ -142,6 +123,8 @@ OpenClaw 会通过解析 `SessionKey` 来决定本次消息由哪个 Agent 处
|
|
|
142
123
|
| `groupChat.enabled` | boolean | `true` | 启用群聊处理 |
|
|
143
124
|
| `groupChat.requireMention` | boolean | `true` | 群聊必须 @ 提及才响应 |
|
|
144
125
|
|
|
126
|
+
### 禁用动态 Agent
|
|
127
|
+
|
|
145
128
|
如果需要所有消息进入默认 Agent:
|
|
146
129
|
|
|
147
130
|
```json
|
|
@@ -156,9 +139,7 @@ OpenClaw 会通过解析 `SessionKey` 来决定本次消息由哪个 Agent 处
|
|
|
156
139
|
|
|
157
140
|
## 🛠️ 指令白名单
|
|
158
141
|
|
|
159
|
-
为防止普通用户通过企业微信消息执行敏感的 Gateway
|
|
160
|
-
|
|
161
|
-
> 💡 **提示**:此配置已包含在 `deploy/openclaw.json.template` 中,部署时会自动生效。
|
|
142
|
+
为防止普通用户通过企业微信消息执行敏感的 Gateway 管理指令,本插件支持**指令白名单**机制。
|
|
162
143
|
|
|
163
144
|
```json
|
|
164
145
|
{
|
|
@@ -173,6 +154,8 @@ OpenClaw 会通过解析 `SessionKey` 来决定本次消息由哪个 Agent 处
|
|
|
173
154
|
}
|
|
174
155
|
```
|
|
175
156
|
|
|
157
|
+
### 推荐白名单指令
|
|
158
|
+
|
|
176
159
|
| 指令 | 说明 | 安全级别 |
|
|
177
160
|
|------|------|----------|
|
|
178
161
|
| `/new` | 重置当前对话,开启全新会话 | ✅ 用户级 |
|
|
@@ -182,10 +165,115 @@ OpenClaw 会通过解析 `SessionKey` 来决定本次消息由哪个 Agent 处
|
|
|
182
165
|
|
|
183
166
|
> ⚠️ **安全提示**:不要将 `/gateway`、`/plugins` 等管理指令添加到白名单,避免普通用户获得 Gateway 实例的管理权限。
|
|
184
167
|
|
|
168
|
+
## ❓ 常见问题 (FAQ)
|
|
169
|
+
|
|
170
|
+
### Q: 配置文件中的插件 ID 应该使用什么?
|
|
171
|
+
|
|
172
|
+
**A:** 在 `plugins.entries` 中,应该使用**完整的插件 ID**:
|
|
173
|
+
|
|
174
|
+
```json
|
|
175
|
+
{
|
|
176
|
+
"plugins": {
|
|
177
|
+
"entries": {
|
|
178
|
+
"openclaw-plugin-wecom": { "enabled": true } // ✅ 正确
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**不要**使用 channel id:
|
|
185
|
+
```json
|
|
186
|
+
{
|
|
187
|
+
"plugins": {
|
|
188
|
+
"entries": {
|
|
189
|
+
"wecom": { "enabled": true } // ❌ 错误
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Q: 为什么 `openclaw doctor` 一直报错 "wecom configured, not enabled yet"?
|
|
196
|
+
|
|
197
|
+
**A:** 需要在 `plugins` 配置中添加 `"deny": ["wecom"]`:
|
|
198
|
+
|
|
199
|
+
```json
|
|
200
|
+
{
|
|
201
|
+
"plugins": {
|
|
202
|
+
"deny": ["wecom"],
|
|
203
|
+
"entries": {
|
|
204
|
+
"openclaw-plugin-wecom": {
|
|
205
|
+
"enabled": true
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
**原因:** OpenClaw 会尝试自动启用 channel id 为 `wecom` 的内置插件配置,添加 `deny` 可以防止这种自动启用,确保只使用 `openclaw-plugin-wecom` 插件。
|
|
213
|
+
|
|
214
|
+
### Q: OpenClaw 开放公网需要 auth token,企业微信回调如何配置?
|
|
215
|
+
|
|
216
|
+
**A:** 企业微信机器人**不需要**配置 OpenClaw 的 Gateway Auth Token。
|
|
217
|
+
|
|
218
|
+
- **Gateway Auth Token** (`gateway.auth.token`) 主要用于:
|
|
219
|
+
- WebUI 访问认证
|
|
220
|
+
- WebSocket 连接认证
|
|
221
|
+
- CLI 远程连接认证
|
|
222
|
+
|
|
223
|
+
- **企业微信 Webhook** (`/webhooks/wecom`) 的认证机制:
|
|
224
|
+
- 使用企业微信自己的签名验证(Token + EncodingAESKey)
|
|
225
|
+
- 不需要 Gateway Auth Token
|
|
226
|
+
- OpenClaw 插件系统会自动处理 webhook 路由
|
|
227
|
+
|
|
228
|
+
**部署建议:**
|
|
229
|
+
1. 如果使用反向代理(如 Nginx),可以为 `/webhooks/wecom` 路径配置豁免认证
|
|
230
|
+
2. 或者将 webhook 端点暴露在独立端口,不经过 Gateway Auth
|
|
231
|
+
|
|
232
|
+
### Q: EncodingAESKey 长度验证失败怎么办?
|
|
233
|
+
|
|
234
|
+
**A:** 常见原因和解决方法:
|
|
235
|
+
|
|
236
|
+
1. **检查配置键名**:确保使用正确的键名 `encodingAesKey`(注意大小写)
|
|
237
|
+
```json
|
|
238
|
+
{
|
|
239
|
+
"channels": {
|
|
240
|
+
"wecom": {
|
|
241
|
+
"encodingAesKey": "..." // ✅ 正确
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
2. **检查密钥长度**:EncodingAESKey 必须是 43 位字符
|
|
248
|
+
```bash
|
|
249
|
+
# 检查长度
|
|
250
|
+
echo -n "你的密钥" | wc -c
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
3. **检查是否有多余空格/换行**:确保密钥字符串前后没有空格或换行符
|
|
254
|
+
|
|
255
|
+
## 📂 项目结构
|
|
256
|
+
|
|
257
|
+
```
|
|
258
|
+
openclaw-plugin-wecom/
|
|
259
|
+
├── index.js # 插件入口
|
|
260
|
+
├── webhook.js # 企业微信 HTTP 通信处理
|
|
261
|
+
├── dynamic-agent.js # 动态 Agent 分配逻辑
|
|
262
|
+
├── stream-manager.js # 流式回复管理
|
|
263
|
+
├── crypto.js # 企业微信加密算法
|
|
264
|
+
├── client.js # 客户端逻辑
|
|
265
|
+
├── logger.js # 日志模块
|
|
266
|
+
├── utils.js # 工具函数
|
|
267
|
+
├── package.json # npm 包配置
|
|
268
|
+
└── openclaw.plugin.json # OpenClaw 插件清单
|
|
269
|
+
```
|
|
270
|
+
|
|
185
271
|
## 🤝 贡献规范
|
|
186
272
|
|
|
187
273
|
我们非常欢迎开发者参与贡献!如果你发现了 Bug 或有更好的功能建议,请提交 Issue 或 Pull Request。
|
|
188
274
|
|
|
275
|
+
详见 [CONTRIBUTING.md](./CONTRIBUTING.md)
|
|
276
|
+
|
|
189
277
|
## 📄 开源协议
|
|
190
278
|
|
|
191
279
|
本项目采用 [ISC License](./LICENSE) 协议。
|
package/index.js
CHANGED
|
@@ -807,6 +807,7 @@ async function deliverWecomReply({ payload, account, responseUrl, senderId, stre
|
|
|
807
807
|
// =============================================================================
|
|
808
808
|
|
|
809
809
|
const plugin = {
|
|
810
|
+
// Plugin id should match `openclaw.plugin.json` id (and config.plugins.entries key).
|
|
810
811
|
id: "openclaw-plugin-wecom",
|
|
811
812
|
name: "Enterprise WeChat",
|
|
812
813
|
description: "Enterprise WeChat AI Bot channel plugin for OpenClaw",
|
package/logger.js
CHANGED
|
@@ -1,12 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Structured logging for WeCom plugin
|
|
3
3
|
*/
|
|
4
|
+
const LEVELS = {
|
|
5
|
+
debug: 10,
|
|
6
|
+
info: 20,
|
|
7
|
+
warn: 30,
|
|
8
|
+
error: 40,
|
|
9
|
+
silent: 100,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
function getEnvLogLevel() {
|
|
13
|
+
const raw = (process.env.WECOM_LOG_LEVEL || process.env.LOG_LEVEL || "info").toLowerCase();
|
|
14
|
+
return Object.prototype.hasOwnProperty.call(LEVELS, raw) ? raw : "info";
|
|
15
|
+
}
|
|
16
|
+
|
|
4
17
|
export class Logger {
|
|
5
18
|
prefix;
|
|
6
|
-
|
|
19
|
+
level;
|
|
20
|
+
constructor(prefix = "[wecom]", level = getEnvLogLevel()) {
|
|
7
21
|
this.prefix = prefix;
|
|
22
|
+
this.level = level;
|
|
8
23
|
}
|
|
9
24
|
log(level, message, context) {
|
|
25
|
+
if (LEVELS[level] < LEVELS[this.level]) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
10
28
|
const timestamp = new Date().toISOString();
|
|
11
29
|
const contextStr = context ? ` ${JSON.stringify(context)}` : "";
|
|
12
30
|
const logMessage = `${timestamp} ${level.toUpperCase()} ${this.prefix} ${message}${contextStr}`;
|
|
@@ -38,9 +56,9 @@ export class Logger {
|
|
|
38
56
|
this.log("error", message, context);
|
|
39
57
|
}
|
|
40
58
|
child(subPrefix) {
|
|
41
|
-
return new Logger(`${this.prefix}:${subPrefix}
|
|
59
|
+
return new Logger(`${this.prefix}:${subPrefix}`, this.level);
|
|
42
60
|
}
|
|
43
61
|
}
|
|
44
62
|
// Default logger instance
|
|
45
63
|
export const logger = new Logger();
|
|
46
|
-
//# sourceMappingURL=logger.js.map
|
|
64
|
+
//# sourceMappingURL=logger.js.map
|
package/openclaw.plugin.json
CHANGED