openclaw-weixin 3.0.2 → 3.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.
@@ -1,338 +0,0 @@
1
- # 后端 API 协议
2
-
3
- [返回详细指南](./guide.zh_CN.md) | [English](./backend-api.md)
4
-
5
- 本文档覆盖插件用于扫码登录、生命周期通知、消息和媒体的全部微信后端接口。两个扫码
6
- 登录请求始终使用腾讯固定服务;账号登录后 `baseurl` 指定的后端需要实现生命周期、
7
- 消息和媒体接口。
8
-
9
- 二维码创建和登录后的接口使用 `POST`;二维码状态轮询使用 `GET`。所有 API
10
- 请求均携带:
11
-
12
- | Header | 说明 |
13
- |--------|------|
14
- | `iLink-App-Id` | 插件应用 ID |
15
- | `iLink-App-ClientVersion` | 编码为无符号整数的插件版本 |
16
- | `SKRouteTag` | 可选的配置路由标签 |
17
-
18
- `POST` 请求还会携带 `Content-Type: application/json`、
19
- `AuthorizationType: ilink_bot_token` 和随机 uint32 的 base64 编码
20
- `X-WECHAT-UIN`。登录后的鉴权请求还会携带
21
- `Authorization: Bearer <bot-token>`;二维码状态 `GET` 请求不携带这些 `POST`
22
- 专用请求头。
23
-
24
- 登录后的 `POST` 请求体包含 `base_info`,二维码创建请求则不包含。下方消息示例
25
- 为简洁起见将其省略。
26
-
27
- ```json
28
- {
29
- "base_info": {
30
- "channel_version": "<插件版本>",
31
- "bot_agent": "OpenClaw"
32
- }
33
- }
34
- ```
35
-
36
- `bot_agent` 仅用于观测,其格式和配置方式见
37
- [详细指南](./guide.zh_CN.md#自定义-botagent可选)。
38
-
39
- ## 接口列表
40
-
41
- | 方法 | 路径 | 说明 |
42
- |------|------|------|
43
- | `POST` | `/ilink/bot/get_bot_qrcode?bot_type=3` | 创建扫码登录会话 |
44
- | `GET` | `/ilink/bot/get_qrcode_status?qrcode=<opaque-id>` | 轮询扫码状态;可选传入 `verify_code` |
45
- | `POST` | `/ilink/bot/msg/notifystart` | 通知后端 channel 已启动 |
46
- | `POST` | `/ilink/bot/msg/notifystop` | 通知后端 channel 已停止 |
47
- | `POST` | `/ilink/bot/getupdates` | 长轮询获取新消息 |
48
- | `POST` | `/ilink/bot/sendmessage` | 发送消息(文本/图片/视频/文件) |
49
- | `POST` | `/ilink/bot/getuploadurl` | 获取 CDN 上传预签名参数 |
50
- | `POST` | `/ilink/bot/getconfig` | 获取账号配置(typing ticket 等) |
51
- | `POST` | `/ilink/bot/sendtyping` | 发送或取消输入状态 |
52
-
53
- 前两行描述固定的扫码登录服务,不会发送到账号登录后的 `baseurl`。
54
-
55
- ## 扫码登录与生命周期
56
-
57
- 创建扫码会话:
58
-
59
- ```http
60
- POST /ilink/bot/get_bot_qrcode?bot_type=3
61
- Content-Type: application/json
62
- ```
63
-
64
- ```json
65
- {
66
- "local_token_list": []
67
- }
68
- ```
69
-
70
- 响应包含不透明的 `qrcode` 标识,以及用于生成二维码的 URL
71
- `qrcode_img_content`。随后轮询
72
- `GET /ilink/bot/get_qrcode_status?qrcode=<opaque-id>`,直到进入终止状态。遇到
73
- 验证挑战时,可通过 `verify_code` 查询参数提交验证码。
74
-
75
- | 字段 | 类型 | 说明 |
76
- |------|------|------|
77
- | `status` | `string` | `wait`、`scaned`、`need_verifycode`、`verify_code_blocked`、`expired`、`scaned_but_redirect`、`binded_redirect` 或 `confirmed` |
78
- | `bot_token` | `string?` | 确认后返回的 bot 凭据 |
79
- | `ilink_bot_id` | `string?` | 确认后必需的账号 ID |
80
- | `baseurl` | `string?` | 账号 API 基础 URL |
81
- | `ilink_user_id` | `string?` | 扫码用户 ID |
82
- | `redirect_host` | `string?` | `scaned_but_redirect` 返回的新轮询主机 |
83
-
84
- 鉴权完成后,channel 启动时调用 `/ilink/bot/msg/notifystart`,停止时调用
85
- `/ilink/bot/msg/notifystop`。两者均接收标准 `base_info` 请求体,并返回
86
- 以下结构:
87
-
88
- ```json
89
- {
90
- "ret": 0,
91
- "errmsg": ""
92
- }
93
- ```
94
-
95
- 二维码标识、验证码、bot token、账号 ID、用户 ID 和 context token 均属敏感
96
- 信息,不要在日志或示例中写入真实值。
97
-
98
- ## getUpdates
99
-
100
- 长轮询接口。服务端在有新消息或超时后返回。
101
-
102
- **请求体:**
103
-
104
- ```json
105
- {
106
- "get_updates_buf": ""
107
- }
108
- ```
109
-
110
- | 字段 | 类型 | 说明 |
111
- |------|------|------|
112
- | `get_updates_buf` | `string` | 上次响应返回的同步游标,首次请求传空字符串 |
113
-
114
- **响应体:**
115
-
116
- ```json
117
- {
118
- "ret": 0,
119
- "msgs": [],
120
- "get_updates_buf": "<新游标>",
121
- "longpolling_timeout_ms": 35000
122
- }
123
- ```
124
-
125
- | 字段 | 类型 | 说明 |
126
- |------|------|------|
127
- | `ret` | `number` | 返回码,`0` = 成功 |
128
- | `errcode` | `number?` | 错误码(如 `-14` = token 失效) |
129
- | `errmsg` | `string?` | 错误描述 |
130
- | `msgs` | `WeixinMessage[]` | 消息列表(结构见下方) |
131
- | `get_updates_buf` | `string` | 新的同步游标,下次请求时回传 |
132
- | `longpolling_timeout_ms` | `number?` | 服务端建议的下次长轮询超时(ms) |
133
-
134
- ## sendMessage
135
-
136
- 发送一条消息给用户。
137
-
138
- **请求体:**
139
-
140
- ```json
141
- {
142
- "msg": {
143
- "to_user_id": "<目标用户 ID>",
144
- "context_token": "<会话上下文令牌>",
145
- "item_list": [
146
- {
147
- "type": 1,
148
- "text_item": { "text": "你好" }
149
- }
150
- ]
151
- }
152
- }
153
- ```
154
-
155
- **响应体:**
156
-
157
- ```json
158
- {
159
- "ret": 0,
160
- "errmsg": ""
161
- }
162
- ```
163
-
164
- ## getUploadUrl
165
-
166
- 获取 CDN 上传预签名参数。上传文件前需先调用此接口获取 `upload_param` 和
167
- `thumb_upload_param`。
168
-
169
- **请求体:**
170
-
171
- ```json
172
- {
173
- "filekey": "<文件标识>",
174
- "media_type": 1,
175
- "to_user_id": "<目标用户 ID>",
176
- "rawsize": 12345,
177
- "rawfilemd5": "<明文 MD5>",
178
- "filesize": 12352,
179
- "no_need_thumb": true,
180
- "aeskey": "<32 位十六进制 AES 密钥>"
181
- }
182
- ```
183
-
184
- | 字段 | 类型 | 说明 |
185
- |------|------|------|
186
- | `filekey` | `string` | 本次上传的文件标识 |
187
- | `media_type` | `number` | `1` = IMAGE、`2` = VIDEO、`3` = FILE、`4` = VOICE |
188
- | `to_user_id` | `string` | 目标用户 ID |
189
- | `rawsize` | `number` | 原文件明文大小 |
190
- | `rawfilemd5` | `string` | 原文件明文 MD5 |
191
- | `filesize` | `number` | AES-128-ECB 加密后的密文大小 |
192
- | `no_need_thumb` | `boolean?` | 设为 `true` 时不请求缩略图上传参数 |
193
- | `aeskey` | `string?` | 32 位十六进制 AES-128 密钥 |
194
- | `thumb_rawsize` | `number?` | 请求缩略图时的明文大小 |
195
- | `thumb_rawfilemd5` | `string?` | 请求缩略图时的明文 MD5 |
196
- | `thumb_filesize` | `number?` | 请求缩略图时的密文大小 |
197
-
198
- **响应体:**
199
-
200
- ```json
201
- {
202
- "upload_param": "<原图上传加密参数>",
203
- "upload_full_url": "https://cdn.example.test/upload",
204
- "thumb_upload_param": "<可选的缩略图上传参数>"
205
- }
206
- ```
207
-
208
- | 字段 | 类型 | 说明 |
209
- |------|------|------|
210
- | `upload_param` | `string?` | 用于构造 CDN 上传 URL 的参数 |
211
- | `upload_full_url` | `string?` | 完整 CDN 上传 URL;优先于 `upload_param` |
212
- | `thumb_upload_param` | `string?` | 可选的缩略图上传参数 |
213
-
214
- ## getConfig
215
-
216
- 获取账号配置,包括 typing ticket。
217
-
218
- **请求体:**
219
-
220
- ```json
221
- {
222
- "ilink_user_id": "<用户 ID>",
223
- "context_token": "<可选,会话上下文令牌>"
224
- }
225
- ```
226
-
227
- **响应体:**
228
-
229
- ```json
230
- {
231
- "ret": 0,
232
- "errmsg": "",
233
- "typing_ticket": "<base64 编码的 typing ticket>"
234
- }
235
- ```
236
-
237
- ## sendTyping
238
-
239
- 发送或取消输入状态指示。
240
-
241
- **请求体:**
242
-
243
- ```json
244
- {
245
- "ilink_user_id": "<用户 ID>",
246
- "typing_ticket": "<从 getConfig 获取>",
247
- "status": 1
248
- }
249
- ```
250
-
251
- | 字段 | 类型 | 说明 |
252
- |------|------|------|
253
- | `status` | `number` | `1` = 正在输入,`2` = 取消输入 |
254
-
255
- **响应体:**
256
-
257
- ```json
258
- {
259
- "ret": 0,
260
- "errmsg": ""
261
- }
262
- ```
263
-
264
- ## 消息结构
265
-
266
- ### WeixinMessage
267
-
268
- | 字段 | 类型 | 说明 |
269
- |------|------|------|
270
- | `seq` | `number?` | 消息序列号 |
271
- | `message_id` | `number?` | 消息唯一 ID |
272
- | `from_user_id` | `string?` | 发送者 ID |
273
- | `to_user_id` | `string?` | 接收者 ID |
274
- | `client_id` | `string?` | 客户端生成的消息 ID |
275
- | `create_time_ms` | `number?` | 创建时间戳(ms) |
276
- | `update_time_ms` | `number?` | 更新时间戳(ms) |
277
- | `delete_time_ms` | `number?` | 删除时间戳(ms) |
278
- | `session_id` | `string?` | 会话 ID |
279
- | `group_id` | `string?` | 群组 ID |
280
- | `message_type` | `number?` | `1` = USER, `2` = BOT |
281
- | `message_state` | `number?` | `0` = NEW, `1` = GENERATING, `2` = FINISH |
282
- | `item_list` | `MessageItem[]?` | 消息内容列表 |
283
- | `context_token` | `string?` | 会话上下文令牌,回复时需回传 |
284
- | `run_id` | `string?` | 生成回复对应的 OpenClaw run ID |
285
-
286
- ### MessageItem
287
-
288
- | 字段 | 类型 | 说明 |
289
- |------|------|------|
290
- | `type` | `number` | `1` TEXT、`2` IMAGE、`3` VOICE、`4` FILE、`5` VIDEO、`11` TOOL_CALL_START、`12` TOOL_CALL_RESULT |
291
- | `create_time_ms` | `number?` | 条目创建时间戳 |
292
- | `update_time_ms` | `number?` | 条目更新时间戳 |
293
- | `is_completed` | `boolean?` | 进度条目是否完成 |
294
- | `msg_id` | `string?` | 条目消息 ID |
295
- | `text_item` | `{ text: string }?` | 文本内容 |
296
- | `image_item` | `ImageItem?` | 图片(含 CDN 引用和 AES 密钥) |
297
- | `voice_item` | `VoiceItem?` | 语音(SILK 编码) |
298
- | `file_item` | `FileItem?` | 文件附件 |
299
- | `video_item` | `VideoItem?` | 视频 |
300
- | `ref_msg` | `RefMessage?` | 引用消息 |
301
- | `tool_call_start_item` | `{ tool_name?: string; tool_call_id?: string }?` | 工具调用信息 |
302
- | `tool_call_result_item` | `{ tool_name?: string; tool_call_id?: string; status?: string }?` | 工具完成信息 |
303
-
304
- ### 嵌套条目结构
305
-
306
- | 结构 | 字段 |
307
- |------|------|
308
- | `RefMessage` | `message_item?: MessageItem`、`title?: string` |
309
- | `ImageItem` | `media?: CDNMedia`、`thumb_media?: CDNMedia`、`aeskey?: string`、`url?: string`、`mid_size?: number`、`thumb_size?: number`、`thumb_height?: number`、`thumb_width?: number`、`hd_size?: number` |
310
- | `VoiceItem` | `media?: CDNMedia`、`encode_type?: number`、`bits_per_sample?: number`、`sample_rate?: number`、`playtime?: number`、`text?: string` |
311
- | `FileItem` | `media?: CDNMedia`、`file_name?: string`、`md5?: string`、`len?: string` |
312
- | `VideoItem` | `media?: CDNMedia`、`video_size?: number`、`play_length?: number`、`video_md5?: string`、`thumb_media?: CDNMedia`、`thumb_size?: number`、`thumb_height?: number`、`thumb_width?: number` |
313
- | `ToolCallStartItem` | `tool_name?: string`、`tool_call_id?: string` |
314
- | `ToolCallResultItem` | `tool_name?: string`、`tool_call_id?: string`、`status?: string` |
315
-
316
- ### CDN 媒体引用 (CDNMedia)
317
-
318
- 所有媒体类型(图片/语音/文件/视频)通过 CDN 传输,使用 AES-128-ECB 加密:
319
-
320
- | 字段 | 类型 | 说明 |
321
- |------|------|------|
322
- | `encrypt_query_param` | `string?` | CDN 下载/上传的加密参数 |
323
- | `aes_key` | `string?` | base64 编码的 AES-128 密钥 |
324
- | `encrypt_type` | `number?` | 加密元数据模式 |
325
- | `full_url` | `string?` | 后端返回的完整下载 URL |
326
-
327
- ## CDN 上传流程
328
-
329
- 1. 计算文件明文大小、MD5,以及 AES-128-ECB 加密后的密文大小
330
- 2. 如需缩略图(图片/视频),同样计算缩略图的明文和密文参数
331
- 3. 调用 `getUploadUrl` 获取 `upload_full_url` 或 `upload_param`(以及可选的
332
- `thumb_upload_param`)
333
- 4. 使用 AES-128-ECB 加密文件内容,以 `application/octet-stream` 通过 `POST`
334
- 上传到 CDN URL
335
- 5. 需要缩略图时,同理加密并上传
336
- 6. 从 CDN 响应读取 `x-encrypted-param`,作为 `CDNMedia` 引用中的
337
- `encrypt_query_param`
338
- 7. 将引用放入 `MessageItem` 后发送
@@ -1,99 +0,0 @@
1
- # 详细指南
2
-
3
- [返回 README](../README.md) | [English](./guide.md)
4
-
5
- ## 安装说明
6
-
7
- ### 包名与状态兼容性
8
-
9
- npm 包、插件 ID 和 channel ID 均为 `openclaw-weixin`。README 中的
10
- [安装命令](../README.md#安装或替换)会保留
11
- `channels.openclaw-weixin`、`plugins.entries.openclaw-weixin` 和
12
- `~/.openclaw/openclaw-weixin/` 状态路径。
13
-
14
- `--force` 表示确认信任此 npm 来源,并允许 OpenClaw 替换内部 ID 相同的插件。
15
- OpenClaw 会自动轮换配置备份;此次替换无需复制整个状态目录。
16
-
17
- ### 安装限制
18
-
19
- - 此社区 npm 包需通过 CLI 安装;OpenClaw Control UI 不能安装任意 npm、git
20
- 或本地路径来源的插件。
21
- - Nix 模式(`OPENCLAW_NIX_MODE=1`)会禁止插件安装、更新、卸载、启用和停用
22
- 命令;请改动 Nix 配置源后重新构建。
23
- - OpenClaw 安装插件依赖时会禁用生命周期脚本,因此本包直接携带编译后的
24
- `dist/index.js`,无需在用户机器上构建。
25
-
26
- ## 自定义 BotAgent(可选)
27
-
28
- 登录后的每条鉴权请求会带一个自我声明的 `bot_agent` 字段——类似 HTTP
29
- `User-Agent`——用于后台日志归因和监控聚合。**默认值为 `OpenClaw`**。声明自己的
30
- 应用名能让你的流量在后台日志中更容易识别。
31
-
32
- 在 `openclaw.json` 中加一行即可:
33
-
34
- ```json
35
- {
36
- "channels": {
37
- "openclaw-weixin": {
38
- "botAgent": "MyBot/1.2.0"
39
- }
40
- }
41
- }
42
- ```
43
-
44
- **格式规范**(UA 风格):
45
-
46
- - 一个或多个 `Name/Version` token,空格分隔
47
- - 每个 token 可选地跟一个 ` (comment)`
48
- - 仅允许 ASCII 字符;总长 ≤ 256 字节
49
- - 不合规的 token 在清洗时静默丢弃;如果最终为空,回退到 `OpenClaw`
50
-
51
- 可直接使用的示例:
52
-
53
- - `MyBot/1.2.0`
54
- - `MyBot/1.2.0 (region=cn;env=prod)`
55
- - `MyBot/1.2.0 LangChain/0.3.5`
56
- - `MyBot/1.2.0-rc.1+build.5`
57
-
58
- **注意**:`bot_agent` 仅用于观测,**不参与鉴权或路由**。当前本插件实例下所有
59
- 已注册的 agent 共享同一个 `botAgent` 声明;如有需要按 agent 单独标识的场景,
60
- 可在后续版本扩展配置。
61
-
62
- ## 卸载
63
-
64
- > [!WARNING]
65
- > 替换腾讯版时不要卸载,请使用 README 中的
66
- > [安装命令](../README.md#安装或替换)原位替换。
67
-
68
- 如果以后可能重装,请先备份 `~/.openclaw/openclaw.json`:新版 OpenClaw
69
- 卸载时会删除插件条目及其拥有的 `channels.openclaw-weixin` 配置。
70
-
71
- ```bash
72
- openclaw plugins uninstall openclaw-weixin
73
- ```
74
-
75
- ## 故障排查
76
-
77
- ### "requires OpenClaw >=2026.6.1" 报错
78
-
79
- 你的 OpenClaw 版本太旧,不兼容当前插件版本。检查版本:
80
-
81
- ```bash
82
- openclaw --version
83
- ```
84
-
85
- 请先升级 OpenClaw。社区包不发布旧宿主兼容版本线。
86
-
87
- ### Channel 显示 "OK" 但未连接
88
-
89
- 启用插件,重载或重启实际承载 OpenClaw 的运行单元,然后再次探测:
90
-
91
- ```bash
92
- openclaw plugins enable openclaw-weixin
93
- openclaw channels status --probe
94
- ```
95
-
96
- ## 开发者文档
97
-
98
- - [后端 API 协议](./backend-api.zh_CN.md)
99
- - [架构说明](./architecture.md)