@max1874/openclaw-wecom 0.1.0
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 +110 -0
- package/docs/CONFIG.md +362 -0
- package/docs/SETUP.md +162 -0
- package/index.ts +43 -0
- package/openclaw.plugin.json +17 -0
- package/package.json +73 -0
- package/src/accounts.ts +42 -0
- package/src/bot.ts +377 -0
- package/src/channel.ts +208 -0
- package/src/config-schema.ts +77 -0
- package/src/media.ts +149 -0
- package/src/monitor.ts +75 -0
- package/src/outbound.ts +75 -0
- package/src/policy.ts +111 -0
- package/src/probe.ts +32 -0
- package/src/reply-dispatcher.ts +91 -0
- package/src/runtime.ts +14 -0
- package/src/send.ts +250 -0
- package/src/targets.ts +66 -0
- package/src/types.ts +257 -0
- package/src/webhook.ts +171 -0
package/README.md
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# OpenClaw WeChat/WeCom Plugin
|
|
2
|
+
|
|
3
|
+
通过 Stride 服务与微信/企业微信对接的 OpenClaw 渠道插件。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 配置
|
|
12
|
+
|
|
13
|
+
在 `openclaw.yaml` 或环境变量中配置:
|
|
14
|
+
|
|
15
|
+
```yaml
|
|
16
|
+
channels:
|
|
17
|
+
wecom:
|
|
18
|
+
enabled: true
|
|
19
|
+
token: "your-stride-token" # Stride API token
|
|
20
|
+
chatId: "your-default-chat-id" # 默认 chatId
|
|
21
|
+
webhookPath: "/webhooks/wechat" # Webhook 路径
|
|
22
|
+
webhookPort: 3000 # Webhook 端口
|
|
23
|
+
|
|
24
|
+
# 私聊策略
|
|
25
|
+
dmPolicy: "allowlist" # "open" | "allowlist"
|
|
26
|
+
allowFrom:
|
|
27
|
+
- "7881303019076556" # 允许的用户 ID
|
|
28
|
+
- "username" # 或用户名
|
|
29
|
+
|
|
30
|
+
# 群聊策略
|
|
31
|
+
groupPolicy: "allowlist" # "open" | "allowlist" | "disabled"
|
|
32
|
+
groupAllowFrom:
|
|
33
|
+
- "R:10917132666297873" # 允许的群 ID
|
|
34
|
+
requireMention: true # 群聊是否需要 @
|
|
35
|
+
|
|
36
|
+
# 单群配置 (可选)
|
|
37
|
+
groups:
|
|
38
|
+
"R:10917132666297873":
|
|
39
|
+
requireMention: false
|
|
40
|
+
allowFrom:
|
|
41
|
+
- "*" # 允许所有群成员
|
|
42
|
+
|
|
43
|
+
# 消息配置
|
|
44
|
+
textChunkLimit: 4000 # 单条消息字符限制
|
|
45
|
+
mediaMaxMb: 30 # 媒体文件大小限制 (MB)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
环境变量支持:
|
|
49
|
+
- `WECOM_TOKEN` 或 `STRIDE_TOKEN`: API token
|
|
50
|
+
- `WECOM_CHAT_ID` 或 `STRIDE_CHAT_ID`: 默认 chatId
|
|
51
|
+
|
|
52
|
+
## Webhook 端点
|
|
53
|
+
|
|
54
|
+
启动后,插件会监听以下 Webhook 端点:
|
|
55
|
+
|
|
56
|
+
| 路径 | 说明 |
|
|
57
|
+
|------|------|
|
|
58
|
+
| `/webhooks/wechat/events/message` | 消息事件 |
|
|
59
|
+
| `/webhooks/wechat/events/room/joined` | 群成员加入 |
|
|
60
|
+
| `/webhooks/wechat/events/chatroom/loaded` | 群信息加载 |
|
|
61
|
+
| `/webhooks/wechat/events/chatroom/joined` | 入群完成 |
|
|
62
|
+
| `/health` | 健康检查 |
|
|
63
|
+
|
|
64
|
+
## 消息类型
|
|
65
|
+
|
|
66
|
+
### 支持接收的消息类型
|
|
67
|
+
|
|
68
|
+
| type | 类型 | 说明 |
|
|
69
|
+
|------|------|------|
|
|
70
|
+
| 1 | 文件 | 下载并保存本地 |
|
|
71
|
+
| 2 | 语音 | 使用 Stride 转写的文本 |
|
|
72
|
+
| 4 | 聊天记录 | 合并转发的消息 |
|
|
73
|
+
| 6 | 图片 | 下载并保存本地 |
|
|
74
|
+
| 7 | 文字 | 主要消息类型 |
|
|
75
|
+
| 12 | 链接 | 提取标题和 URL |
|
|
76
|
+
|
|
77
|
+
### 支持发送的消息类型
|
|
78
|
+
|
|
79
|
+
| messageType | 类型 | 说明 |
|
|
80
|
+
|-------------|------|------|
|
|
81
|
+
| 0 | 文字 | 主要发送类型 |
|
|
82
|
+
| 1 | 图片 | 需要可访问的 URL |
|
|
83
|
+
| 2 | 链接 | 卡片式链接 |
|
|
84
|
+
| 3 | 文件 | 需要可访问的 URL |
|
|
85
|
+
|
|
86
|
+
## 与飞书插件的差异
|
|
87
|
+
|
|
88
|
+
| 特性 | 飞书插件 | 微信插件 |
|
|
89
|
+
|------|---------|----------|
|
|
90
|
+
| 连接方式 | WebSocket | Webhook 回调 |
|
|
91
|
+
| SDK | 官方 SDK | HTTP REST API |
|
|
92
|
+
| ID 类型 | open_id / chat_id | contactId / chatId / roomId |
|
|
93
|
+
| 媒体处理 | 需要上传下载 | URL 直接可用 |
|
|
94
|
+
| Card 消息 | 支持 | 不支持 |
|
|
95
|
+
| 消息编辑 | 支持 | 不支持 |
|
|
96
|
+
| Typing 指示器 | 反应替代 | 不支持 |
|
|
97
|
+
|
|
98
|
+
## 开发
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
# 类型检查
|
|
102
|
+
npx tsc --noEmit
|
|
103
|
+
|
|
104
|
+
# 运行测试
|
|
105
|
+
npm test
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## 许可
|
|
109
|
+
|
|
110
|
+
MIT
|
package/docs/CONFIG.md
ADDED
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
# OpenClaw WeChat/WeCom 配置指南
|
|
2
|
+
|
|
3
|
+
## 快速开始
|
|
4
|
+
|
|
5
|
+
### 1. 获取 Stride 凭证
|
|
6
|
+
|
|
7
|
+
从 Stride 服务获取:
|
|
8
|
+
- **token**: API 访问令牌
|
|
9
|
+
- **chatId**: 默认聊天 ID(可选,用于主动发送消息)
|
|
10
|
+
|
|
11
|
+
### 2. 最小配置
|
|
12
|
+
|
|
13
|
+
```yaml
|
|
14
|
+
# openclaw.yaml
|
|
15
|
+
channels:
|
|
16
|
+
wecom:
|
|
17
|
+
enabled: true
|
|
18
|
+
token: "693b9eba76962211776ef462"
|
|
19
|
+
webhookPort: 3000
|
|
20
|
+
allowFrom:
|
|
21
|
+
- "*" # 允许所有人私聊
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### 3. 配置 Webhook 回调
|
|
25
|
+
|
|
26
|
+
将 Stride 的回调地址配置为:
|
|
27
|
+
```
|
|
28
|
+
http://your-server:3000/webhooks/wechat/events/message
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
如果使用 ngrok/cloudflare tunnel:
|
|
32
|
+
```bash
|
|
33
|
+
ngrok http 3000
|
|
34
|
+
# 然后使用 https://xxx.ngrok.io/webhooks/wechat/events/message
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## 完整配置参考
|
|
40
|
+
|
|
41
|
+
```yaml
|
|
42
|
+
channels:
|
|
43
|
+
wecom:
|
|
44
|
+
# ========== 基础配置 ==========
|
|
45
|
+
enabled: true # 是否启用
|
|
46
|
+
token: "your-stride-token" # Stride API token (必需)
|
|
47
|
+
chatId: "697dea419d6d3a463be7b4df" # 默认 chatId (可选)
|
|
48
|
+
|
|
49
|
+
# ========== Webhook 配置 ==========
|
|
50
|
+
webhookPath: "/webhooks/wechat" # Webhook 路径前缀
|
|
51
|
+
webhookPort: 3000 # 监听端口
|
|
52
|
+
|
|
53
|
+
# ========== 私聊策略 ==========
|
|
54
|
+
dmPolicy: "allowlist" # "open" | "allowlist"
|
|
55
|
+
allowFrom: # 私聊白名单
|
|
56
|
+
- "7881303019076556" # 用户 contactId
|
|
57
|
+
- "lin" # 或用户名 (contactName)
|
|
58
|
+
- "*" # 通配符,允许所有人
|
|
59
|
+
|
|
60
|
+
# ========== 群聊策略 ==========
|
|
61
|
+
groupPolicy: "allowlist" # "open" | "allowlist" | "disabled"
|
|
62
|
+
groupAllowFrom: # 群聊白名单 (群 ID 或发送者)
|
|
63
|
+
- "R:10917132666297873" # roomId
|
|
64
|
+
- "697dea419d6d3a463be7b4df" # chatId
|
|
65
|
+
requireMention: true # 群聊是否需要 @机器人
|
|
66
|
+
|
|
67
|
+
# ========== 单群配置 (可选) ==========
|
|
68
|
+
groups:
|
|
69
|
+
"R:10917132666297873": # 群 ID
|
|
70
|
+
enabled: true # 是否启用
|
|
71
|
+
requireMention: false # 覆盖全局设置
|
|
72
|
+
allowFrom: # 该群的发送者白名单
|
|
73
|
+
- "*" # 允许所有群成员
|
|
74
|
+
systemPrompt: "你是群助手" # 该群专用的系统提示词
|
|
75
|
+
tools: # 工具策略
|
|
76
|
+
allow: ["web_search"]
|
|
77
|
+
deny: ["file_write"]
|
|
78
|
+
|
|
79
|
+
# ========== 私聊配置 (可选) ==========
|
|
80
|
+
dms:
|
|
81
|
+
"7881303019076556": # 用户 contactId
|
|
82
|
+
enabled: true
|
|
83
|
+
systemPrompt: "你是私人助理"
|
|
84
|
+
|
|
85
|
+
# ========== 消息配置 ==========
|
|
86
|
+
textChunkLimit: 4000 # 单条消息字符限制
|
|
87
|
+
chunkMode: "length" # "length" | "newline"
|
|
88
|
+
renderMode: "auto" # "auto" | "raw"
|
|
89
|
+
|
|
90
|
+
# ========== 历史记录 ==========
|
|
91
|
+
historyLimit: 10 # 群聊历史记录条数
|
|
92
|
+
dmHistoryLimit: 5 # 私聊历史记录条数
|
|
93
|
+
|
|
94
|
+
# ========== 媒体配置 ==========
|
|
95
|
+
mediaMaxMb: 30 # 媒体文件大小限制 (MB)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## 策略配置详解
|
|
101
|
+
|
|
102
|
+
### 私聊策略 (dmPolicy)
|
|
103
|
+
|
|
104
|
+
| 值 | 说明 |
|
|
105
|
+
|---|------|
|
|
106
|
+
| `open` | 允许所有人私聊,需要 `allowFrom: ["*"]` |
|
|
107
|
+
| `allowlist` | 只允许白名单用户私聊 |
|
|
108
|
+
|
|
109
|
+
```yaml
|
|
110
|
+
# 示例:开放私聊
|
|
111
|
+
dmPolicy: "open"
|
|
112
|
+
allowFrom:
|
|
113
|
+
- "*"
|
|
114
|
+
|
|
115
|
+
# 示例:仅允许特定用户
|
|
116
|
+
dmPolicy: "allowlist"
|
|
117
|
+
allowFrom:
|
|
118
|
+
- "7881303019076556"
|
|
119
|
+
- "lin"
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### 群聊策略 (groupPolicy)
|
|
123
|
+
|
|
124
|
+
| 值 | 说明 |
|
|
125
|
+
|---|------|
|
|
126
|
+
| `open` | 允许所有群(需 @机器人) |
|
|
127
|
+
| `allowlist` | 只响应白名单群/用户 |
|
|
128
|
+
| `disabled` | 禁用群聊功能 |
|
|
129
|
+
|
|
130
|
+
```yaml
|
|
131
|
+
# 示例:开放所有群
|
|
132
|
+
groupPolicy: "open"
|
|
133
|
+
requireMention: true # 必须 @机器人
|
|
134
|
+
|
|
135
|
+
# 示例:仅特定群
|
|
136
|
+
groupPolicy: "allowlist"
|
|
137
|
+
groupAllowFrom:
|
|
138
|
+
- "R:10917132666297873"
|
|
139
|
+
|
|
140
|
+
# 示例:禁用群聊
|
|
141
|
+
groupPolicy: "disabled"
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### 白名单匹配规则
|
|
145
|
+
|
|
146
|
+
白名单支持三种匹配方式:
|
|
147
|
+
|
|
148
|
+
1. **通配符**: `"*"` 匹配所有
|
|
149
|
+
2. **ID 匹配**: contactId / roomId / chatId
|
|
150
|
+
3. **名称匹配**: contactName (大小写不敏感)
|
|
151
|
+
|
|
152
|
+
```yaml
|
|
153
|
+
allowFrom:
|
|
154
|
+
- "*" # 通配符
|
|
155
|
+
- "7881303019076556" # contactId
|
|
156
|
+
- "lin" # contactName
|
|
157
|
+
- "R:10917132666297873" # roomId
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## 单群配置
|
|
163
|
+
|
|
164
|
+
为特定群设置独立策略:
|
|
165
|
+
|
|
166
|
+
```yaml
|
|
167
|
+
groups:
|
|
168
|
+
# 测试群 - 宽松策略
|
|
169
|
+
"R:10917132666297873":
|
|
170
|
+
requireMention: false # 不需要 @
|
|
171
|
+
allowFrom: ["*"] # 允许所有人
|
|
172
|
+
systemPrompt: |
|
|
173
|
+
你是测试群的助手。
|
|
174
|
+
请用简洁的方式回答问题。
|
|
175
|
+
|
|
176
|
+
# 工作群 - 严格策略
|
|
177
|
+
"R:20917132666297874":
|
|
178
|
+
requireMention: true
|
|
179
|
+
allowFrom:
|
|
180
|
+
- "7881303019076556" # 只允许管理员
|
|
181
|
+
tools:
|
|
182
|
+
allow: ["web_search"]
|
|
183
|
+
deny: ["*"] # 禁用其他工具
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## 环境变量
|
|
189
|
+
|
|
190
|
+
支持通过环境变量配置敏感信息:
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
# Stride 凭证
|
|
194
|
+
export WECOM_TOKEN="693b9eba76962211776ef462"
|
|
195
|
+
export WECOM_CHAT_ID="697dea419d6d3a463be7b4df"
|
|
196
|
+
|
|
197
|
+
# 或使用 STRIDE_ 前缀
|
|
198
|
+
export STRIDE_TOKEN="693b9eba76962211776ef462"
|
|
199
|
+
export STRIDE_CHAT_ID="697dea419d6d3a463be7b4df"
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
配置文件中可以省略这些值:
|
|
203
|
+
|
|
204
|
+
```yaml
|
|
205
|
+
channels:
|
|
206
|
+
wecom:
|
|
207
|
+
enabled: true
|
|
208
|
+
# token 和 chatId 从环境变量读取
|
|
209
|
+
webhookPort: 3000
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## ID 格式说明
|
|
215
|
+
|
|
216
|
+
微信插件使用以下 ID 格式:
|
|
217
|
+
|
|
218
|
+
| ID 类型 | 格式 | 示例 |
|
|
219
|
+
|--------|------|------|
|
|
220
|
+
| chatId | 24位十六进制 | `697dea419d6d3a463be7b4df` |
|
|
221
|
+
| contactId | 数字字符串 | `7881303019076556` |
|
|
222
|
+
| roomId | R:数字 | `R:10917132666297873` |
|
|
223
|
+
|
|
224
|
+
在配置中引用:
|
|
225
|
+
|
|
226
|
+
```yaml
|
|
227
|
+
# 直接使用
|
|
228
|
+
allowFrom:
|
|
229
|
+
- "7881303019076556"
|
|
230
|
+
- "R:10917132666297873"
|
|
231
|
+
|
|
232
|
+
# 或带前缀 (可选)
|
|
233
|
+
allowFrom:
|
|
234
|
+
- "user:7881303019076556"
|
|
235
|
+
- "room:R:10917132666297873"
|
|
236
|
+
- "chat:697dea419d6d3a463be7b4df"
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## 常见配置场景
|
|
242
|
+
|
|
243
|
+
### 场景 1: 个人助手
|
|
244
|
+
|
|
245
|
+
只允许自己使用,禁用群聊:
|
|
246
|
+
|
|
247
|
+
```yaml
|
|
248
|
+
channels:
|
|
249
|
+
wecom:
|
|
250
|
+
enabled: true
|
|
251
|
+
token: "your-token"
|
|
252
|
+
webhookPort: 3000
|
|
253
|
+
dmPolicy: "allowlist"
|
|
254
|
+
allowFrom:
|
|
255
|
+
- "your-contact-id"
|
|
256
|
+
groupPolicy: "disabled"
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### 场景 2: 团队机器人
|
|
260
|
+
|
|
261
|
+
只在特定群响应,需要 @:
|
|
262
|
+
|
|
263
|
+
```yaml
|
|
264
|
+
channels:
|
|
265
|
+
wecom:
|
|
266
|
+
enabled: true
|
|
267
|
+
token: "your-token"
|
|
268
|
+
webhookPort: 3000
|
|
269
|
+
dmPolicy: "allowlist"
|
|
270
|
+
allowFrom: [] # 禁用私聊
|
|
271
|
+
groupPolicy: "allowlist"
|
|
272
|
+
groupAllowFrom:
|
|
273
|
+
- "R:team-room-id"
|
|
274
|
+
requireMention: true
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### 场景 3: 客服机器人
|
|
278
|
+
|
|
279
|
+
开放所有人私聊:
|
|
280
|
+
|
|
281
|
+
```yaml
|
|
282
|
+
channels:
|
|
283
|
+
wecom:
|
|
284
|
+
enabled: true
|
|
285
|
+
token: "your-token"
|
|
286
|
+
webhookPort: 3000
|
|
287
|
+
dmPolicy: "open"
|
|
288
|
+
allowFrom:
|
|
289
|
+
- "*"
|
|
290
|
+
groupPolicy: "disabled"
|
|
291
|
+
textChunkLimit: 2000 # 较短的回复
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### 场景 4: 多群差异化配置
|
|
295
|
+
|
|
296
|
+
不同群使用不同策略:
|
|
297
|
+
|
|
298
|
+
```yaml
|
|
299
|
+
channels:
|
|
300
|
+
wecom:
|
|
301
|
+
enabled: true
|
|
302
|
+
token: "your-token"
|
|
303
|
+
webhookPort: 3000
|
|
304
|
+
groupPolicy: "allowlist"
|
|
305
|
+
groupAllowFrom:
|
|
306
|
+
- "R:group1"
|
|
307
|
+
- "R:group2"
|
|
308
|
+
requireMention: true # 默认需要 @
|
|
309
|
+
|
|
310
|
+
groups:
|
|
311
|
+
"R:group1":
|
|
312
|
+
requireMention: false # 这个群不需要 @
|
|
313
|
+
systemPrompt: "你是技术支持"
|
|
314
|
+
|
|
315
|
+
"R:group2":
|
|
316
|
+
allowFrom:
|
|
317
|
+
- "admin-id" # 只有管理员能触发
|
|
318
|
+
systemPrompt: "你是项目助手"
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## 调试与排查
|
|
324
|
+
|
|
325
|
+
### 查看 Webhook 日志
|
|
326
|
+
|
|
327
|
+
插件启动时会打印:
|
|
328
|
+
```
|
|
329
|
+
wecom: starting webhook server...
|
|
330
|
+
wecom webhook: server listening on port 3000
|
|
331
|
+
wecom webhook: message endpoint: http://localhost:3000/webhooks/wechat/events/message
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
收到消息时:
|
|
335
|
+
```
|
|
336
|
+
wecom webhook: POST /webhooks/wechat/events/message
|
|
337
|
+
wecom: received text from lin (7881303019076556) in 697dea419d6d3a463be7b4df (dm)
|
|
338
|
+
wecom: dispatching to agent (session=wecom:7881303019076556)
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### 健康检查
|
|
342
|
+
|
|
343
|
+
```bash
|
|
344
|
+
curl http://localhost:3000/health
|
|
345
|
+
# {"status":"ok","channel":"wecom"}
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### 常见问题
|
|
349
|
+
|
|
350
|
+
**Q: 消息收不到?**
|
|
351
|
+
- 检查 Stride 回调地址是否正确
|
|
352
|
+
- 确认端口是否开放
|
|
353
|
+
- 查看 webhook 日志是否有请求
|
|
354
|
+
|
|
355
|
+
**Q: 机器人不回复?**
|
|
356
|
+
- 检查 `allowFrom` 白名单
|
|
357
|
+
- 群聊检查 `requireMention` 和 `mentionSelf`
|
|
358
|
+
- 查看日志中的策略检查结果
|
|
359
|
+
|
|
360
|
+
**Q: 消息被截断?**
|
|
361
|
+
- 调整 `textChunkLimit` 参数
|
|
362
|
+
- 微信单条消息限制约 4000 字符
|
package/docs/SETUP.md
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# OpenClaw WeChat/WeCom 配置指南
|
|
2
|
+
|
|
3
|
+
## 快速配置
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
# 启用插件
|
|
7
|
+
openclaw config set channels.wecom.enabled true
|
|
8
|
+
|
|
9
|
+
# Stride 凭证
|
|
10
|
+
openclaw config set channels.wecom.token "693b9eba76962211776ef462"
|
|
11
|
+
openclaw config set channels.wecom.chatId "697dea419d6d3a463be7b4df"
|
|
12
|
+
|
|
13
|
+
# Webhook 配置
|
|
14
|
+
openclaw config set channels.wecom.webhookPort 3000
|
|
15
|
+
openclaw config set channels.wecom.webhookPath "/webhooks/wechat"
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## 策略配置
|
|
19
|
+
|
|
20
|
+
### 私聊策略
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# 私聊策略: "open" | "allowlist"
|
|
24
|
+
openclaw config set channels.wecom.dmPolicy "allowlist"
|
|
25
|
+
|
|
26
|
+
# 私聊白名单 (contactId 或 contactName)
|
|
27
|
+
openclaw config set channels.wecom.allowFrom '["7881303019076556", "lin"]'
|
|
28
|
+
|
|
29
|
+
# 开放所有人私聊
|
|
30
|
+
openclaw config set channels.wecom.dmPolicy "open"
|
|
31
|
+
openclaw config set channels.wecom.allowFrom '["*"]'
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### 群聊策略
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# 群聊策略: "open" | "allowlist" | "disabled"
|
|
38
|
+
openclaw config set channels.wecom.groupPolicy "allowlist"
|
|
39
|
+
|
|
40
|
+
# 群聊白名单 (roomId 或 chatId)
|
|
41
|
+
openclaw config set channels.wecom.groupAllowFrom '["R:10917132666297873"]'
|
|
42
|
+
|
|
43
|
+
# 是否需要 @机器人
|
|
44
|
+
openclaw config set channels.wecom.requireMention true
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## 消息配置
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# 单条消息字符限制 (默认 4000)
|
|
51
|
+
openclaw config set channels.wecom.textChunkLimit 4000
|
|
52
|
+
|
|
53
|
+
# 分块模式: "length" | "newline"
|
|
54
|
+
openclaw config set channels.wecom.chunkMode "length"
|
|
55
|
+
|
|
56
|
+
# 渲染模式: "auto" | "raw"
|
|
57
|
+
openclaw config set channels.wecom.renderMode "auto"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## 历史记录
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# 群聊历史记录条数
|
|
64
|
+
openclaw config set channels.wecom.historyLimit 10
|
|
65
|
+
|
|
66
|
+
# 私聊历史记录条数
|
|
67
|
+
openclaw config set channels.wecom.dmHistoryLimit 5
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## 媒体配置
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# 媒体文件大小限制 (MB)
|
|
74
|
+
openclaw config set channels.wecom.mediaMaxMb 30
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## 单群配置
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# 特定群不需要 @
|
|
81
|
+
openclaw config set channels.wecom.groups.R:10917132666297873.requireMention false
|
|
82
|
+
|
|
83
|
+
# 特定群允许所有人
|
|
84
|
+
openclaw config set channels.wecom.groups.R:10917132666297873.allowFrom '["*"]'
|
|
85
|
+
|
|
86
|
+
# 特定群的系统提示词
|
|
87
|
+
openclaw config set channels.wecom.groups.R:10917132666297873.systemPrompt "你是测试群的助手"
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## 完整示例
|
|
91
|
+
|
|
92
|
+
### 个人助手配置
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
openclaw config set channels.wecom.enabled true
|
|
96
|
+
openclaw config set channels.wecom.token "your-stride-token"
|
|
97
|
+
openclaw config set channels.wecom.webhookPort 3000
|
|
98
|
+
openclaw config set channels.wecom.dmPolicy "allowlist"
|
|
99
|
+
openclaw config set channels.wecom.allowFrom '["your-contact-id"]'
|
|
100
|
+
openclaw config set channels.wecom.groupPolicy "disabled"
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 团队机器人配置
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
openclaw config set channels.wecom.enabled true
|
|
107
|
+
openclaw config set channels.wecom.token "your-stride-token"
|
|
108
|
+
openclaw config set channels.wecom.webhookPort 3000
|
|
109
|
+
openclaw config set channels.wecom.dmPolicy "allowlist"
|
|
110
|
+
openclaw config set channels.wecom.allowFrom '[]'
|
|
111
|
+
openclaw config set channels.wecom.groupPolicy "allowlist"
|
|
112
|
+
openclaw config set channels.wecom.groupAllowFrom '["R:team-room-id"]'
|
|
113
|
+
openclaw config set channels.wecom.requireMention true
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### 开放客服配置
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
openclaw config set channels.wecom.enabled true
|
|
120
|
+
openclaw config set channels.wecom.token "your-stride-token"
|
|
121
|
+
openclaw config set channels.wecom.webhookPort 3000
|
|
122
|
+
openclaw config set channels.wecom.dmPolicy "open"
|
|
123
|
+
openclaw config set channels.wecom.allowFrom '["*"]'
|
|
124
|
+
openclaw config set channels.wecom.groupPolicy "disabled"
|
|
125
|
+
openclaw config set channels.wecom.textChunkLimit 2000
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## 查看配置
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
# 查看所有 wecom 配置
|
|
132
|
+
openclaw config get channels.wecom
|
|
133
|
+
|
|
134
|
+
# 查看特定配置
|
|
135
|
+
openclaw config get channels.wecom.token
|
|
136
|
+
openclaw config get channels.wecom.webhookPort
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## 环境变量 (可选)
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
export WECOM_TOKEN="your-stride-token"
|
|
143
|
+
export WECOM_CHAT_ID="your-default-chat-id"
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Stride 回调配置
|
|
147
|
+
|
|
148
|
+
启动后,配置 Stride 回调地址为:
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
http://your-server:3000/webhooks/wechat/events/message
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
使用 tunnel 时:
|
|
155
|
+
```bash
|
|
156
|
+
# ngrok
|
|
157
|
+
ngrok http 3000
|
|
158
|
+
# 使用 https://xxx.ngrok.io/webhooks/wechat/events/message
|
|
159
|
+
|
|
160
|
+
# cloudflared
|
|
161
|
+
cloudflared tunnel --url http://localhost:3000
|
|
162
|
+
```
|
package/index.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { ClawdbotPluginApi } from "openclaw/plugin-sdk";
|
|
2
|
+
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk";
|
|
3
|
+
import { wecomPlugin } from "./src/channel.js";
|
|
4
|
+
import { setWecomRuntime } from "./src/runtime.js";
|
|
5
|
+
|
|
6
|
+
// Re-export main components
|
|
7
|
+
export { monitorWecomProvider, stopWecomMonitor } from "./src/monitor.js";
|
|
8
|
+
export {
|
|
9
|
+
sendMessageWecom,
|
|
10
|
+
sendImageWecom,
|
|
11
|
+
sendFileWecom,
|
|
12
|
+
sendLinkWecom,
|
|
13
|
+
} from "./src/send.js";
|
|
14
|
+
export { probeWecom } from "./src/probe.js";
|
|
15
|
+
export { wecomPlugin } from "./src/channel.js";
|
|
16
|
+
export { handleWecomMessage, parseWecomMessageEvent } from "./src/bot.js";
|
|
17
|
+
export { startWebhookServer, stopWebhookServer } from "./src/webhook.js";
|
|
18
|
+
|
|
19
|
+
// Re-export types
|
|
20
|
+
export type {
|
|
21
|
+
WecomConfig,
|
|
22
|
+
WecomGroupConfig,
|
|
23
|
+
ResolvedWecomAccount,
|
|
24
|
+
WecomWebhookEvent,
|
|
25
|
+
WecomMessageContext,
|
|
26
|
+
WecomSendResult,
|
|
27
|
+
WecomProbeResult,
|
|
28
|
+
InboundMessageType,
|
|
29
|
+
OutboundMessageType,
|
|
30
|
+
} from "./src/types.js";
|
|
31
|
+
|
|
32
|
+
const plugin = {
|
|
33
|
+
id: "wecom",
|
|
34
|
+
name: "WeChat",
|
|
35
|
+
description: "WeChat/WeCom channel plugin via Stride",
|
|
36
|
+
configSchema: emptyPluginConfigSchema(),
|
|
37
|
+
register(api: ClawdbotPluginApi) {
|
|
38
|
+
setWecomRuntime(api.runtime);
|
|
39
|
+
api.registerChannel({ plugin: wecomPlugin });
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export default plugin;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://openclaw.dev/schemas/plugin.json",
|
|
3
|
+
"id": "wecom",
|
|
4
|
+
"name": "WeChat/WeCom",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"description": "WeChat/WeCom channel plugin via Stride",
|
|
7
|
+
"author": "OpenClaw",
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"channel": {
|
|
10
|
+
"id": "wecom",
|
|
11
|
+
"label": "WeChat",
|
|
12
|
+
"selectionLabel": "WeChat/WeCom (微信/企业微信)",
|
|
13
|
+
"blurb": "WeChat/WeCom messaging via Stride.",
|
|
14
|
+
"aliases": ["wechat", "stride"]
|
|
15
|
+
},
|
|
16
|
+
"extensions": ["./index.ts"]
|
|
17
|
+
}
|