@dadb/weixin-standalone-api 0.1.0 → 0.1.1
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 +125 -216
- package/package.json +1 -2
- package/README.zh-CN.md +0 -309
package/README.md
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
# weixin-standalone-api
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## 中文文档
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
- inbound message polling + local event queue
|
|
7
|
-
- send text and image APIs
|
|
8
|
-
- account and worker management APIs
|
|
5
|
+
独立的微信机器人 API 服务(不依赖 OpenClaw 运行时)。
|
|
9
6
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
### 功能
|
|
8
|
+
- 手机微信扫码登录
|
|
9
|
+
- 入站消息轮询 + 本地事件队列
|
|
10
|
+
- 文本/图片发送接口
|
|
11
|
+
- 账号与 worker 管理接口
|
|
13
12
|
|
|
13
|
+
### 运行要求
|
|
14
14
|
- Node.js `>=22`
|
|
15
|
-
-
|
|
15
|
+
- 可访问的微信 iLink bot 后端
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
### 安装
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
npm i -g weixin-standalone-api
|
|
20
|
+
npm i -g @dadb/weixin-standalone-api
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
或:
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
|
-
npm i weixin-standalone-api
|
|
26
|
+
npm i @dadb/weixin-standalone-api
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
### 启动
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
32
|
WEIXIN_STANDALONE_TOKEN='replace_me' \
|
|
@@ -35,322 +35,231 @@ WEIXIN_STANDALONE_PORT='8788' \
|
|
|
35
35
|
weixin-standalone-api
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
### 环境变量
|
|
39
|
+
- `WEIXIN_STANDALONE_TOKEN`:API 访问令牌,空则不鉴权
|
|
40
|
+
- `WEIXIN_STANDALONE_HOST`:默认 `127.0.0.1`
|
|
41
|
+
- `WEIXIN_STANDALONE_PORT`:默认 `8788`
|
|
42
|
+
- `WEIXIN_STANDALONE_STATE_DIR`:默认 `./.weixin-standalone`
|
|
43
|
+
- `WEIXIN_BASE_URL`:默认 `https://ilinkai.weixin.qq.com`
|
|
44
|
+
- `WEIXIN_CDN_BASE_URL`:默认 `https://novac2c.cdn.weixin.qq.com/c2c`
|
|
45
|
+
- `WEIXIN_BOT_TYPE`:默认 `"3"`
|
|
39
46
|
|
|
40
|
-
|
|
41
|
-
- `WEIXIN_STANDALONE_HOST`: default `127.0.0.1`
|
|
42
|
-
- `WEIXIN_STANDALONE_PORT`: default `8788`
|
|
43
|
-
- `WEIXIN_STANDALONE_STATE_DIR`: default `./.weixin-standalone`
|
|
44
|
-
- `WEIXIN_BASE_URL`: default `https://ilinkai.weixin.qq.com`
|
|
45
|
-
- `WEIXIN_CDN_BASE_URL`: default `https://novac2c.cdn.weixin.qq.com/c2c`
|
|
46
|
-
- `WEIXIN_BOT_TYPE`: default `"3"`
|
|
47
|
+
### 鉴权
|
|
47
48
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
When `WEIXIN_STANDALONE_TOKEN` is set, all APIs except `/healthz` require:
|
|
49
|
+
设置了 `WEIXIN_STANDALONE_TOKEN` 后,除 `/healthz` 外都要带:
|
|
51
50
|
|
|
52
51
|
```http
|
|
53
52
|
Authorization: Bearer <WEIXIN_STANDALONE_TOKEN>
|
|
54
53
|
```
|
|
55
54
|
|
|
56
|
-
|
|
55
|
+
### 返回格式
|
|
57
56
|
|
|
58
|
-
|
|
57
|
+
成功:
|
|
59
58
|
|
|
60
59
|
```json
|
|
61
|
-
{
|
|
62
|
-
"requestId": "uuid",
|
|
63
|
-
"data": {}
|
|
64
|
-
}
|
|
60
|
+
{ "requestId": "uuid", "data": {} }
|
|
65
61
|
```
|
|
66
62
|
|
|
67
|
-
|
|
63
|
+
失败:
|
|
68
64
|
|
|
69
65
|
```json
|
|
70
|
-
{
|
|
71
|
-
"requestId": "uuid",
|
|
72
|
-
"error": "error message"
|
|
73
|
-
}
|
|
66
|
+
{ "requestId": "uuid", "error": "错误信息" }
|
|
74
67
|
```
|
|
75
68
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
### 1) Health
|
|
69
|
+
### API 说明
|
|
79
70
|
|
|
80
71
|
`GET /healthz`
|
|
81
72
|
|
|
82
|
-
Response:
|
|
83
|
-
|
|
84
|
-
```json
|
|
85
|
-
{ "ok": true, "requestId": "..." }
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### 2) QR Login Start
|
|
89
|
-
|
|
90
73
|
`POST /v1/login/qr/start`
|
|
91
74
|
|
|
92
|
-
|
|
93
|
-
|
|
75
|
+
请求体:
|
|
94
76
|
```json
|
|
95
|
-
{
|
|
96
|
-
"accountId": "optional",
|
|
97
|
-
"botType": "optional",
|
|
98
|
-
"baseUrl": "optional"
|
|
99
|
-
}
|
|
77
|
+
{ "accountId": "可选", "botType": "可选", "baseUrl": "可选" }
|
|
100
78
|
```
|
|
101
79
|
|
|
102
|
-
|
|
103
|
-
|
|
80
|
+
返回:
|
|
104
81
|
```json
|
|
105
|
-
{
|
|
106
|
-
"requestId": "...",
|
|
107
|
-
"data": {
|
|
108
|
-
"sessionKey": "...",
|
|
109
|
-
"qrcodeUrl": "..."
|
|
110
|
-
}
|
|
111
|
-
}
|
|
82
|
+
{ "requestId": "...", "data": { "sessionKey": "...", "qrcodeUrl": "..." } }
|
|
112
83
|
```
|
|
113
84
|
|
|
114
|
-
### 3) QR Login Wait
|
|
115
|
-
|
|
116
85
|
`POST /v1/login/qr/wait`
|
|
117
86
|
|
|
118
|
-
|
|
119
|
-
|
|
87
|
+
请求体:
|
|
120
88
|
```json
|
|
121
|
-
{
|
|
122
|
-
"sessionKey": "...",
|
|
123
|
-
"timeoutMs": 480000
|
|
124
|
-
}
|
|
89
|
+
{ "sessionKey": "...", "timeoutMs": 480000 }
|
|
125
90
|
```
|
|
126
91
|
|
|
127
|
-
|
|
128
|
-
|
|
92
|
+
返回:
|
|
129
93
|
```json
|
|
130
|
-
{
|
|
131
|
-
"requestId": "...",
|
|
132
|
-
"data": {
|
|
133
|
-
"connected": true,
|
|
134
|
-
"accountId": "xxx-im-bot",
|
|
135
|
-
"userId": "xxx@im.wechat"
|
|
136
|
-
}
|
|
137
|
-
}
|
|
94
|
+
{ "requestId": "...", "data": { "connected": true, "accountId": "xxx-im-bot", "userId": "xxx@im.wechat" } }
|
|
138
95
|
```
|
|
139
96
|
|
|
140
|
-
### 4) List Accounts
|
|
141
|
-
|
|
142
97
|
`GET /v1/accounts`
|
|
143
98
|
|
|
144
|
-
Response:
|
|
145
|
-
|
|
146
|
-
```json
|
|
147
|
-
{
|
|
148
|
-
"requestId": "...",
|
|
149
|
-
"data": [
|
|
150
|
-
{
|
|
151
|
-
"accountId": "xxx-im-bot",
|
|
152
|
-
"baseUrl": "https://...",
|
|
153
|
-
"userId": "xxx@im.wechat",
|
|
154
|
-
"enabled": true,
|
|
155
|
-
"createdAt": 1234567890,
|
|
156
|
-
"updatedAt": 1234567890,
|
|
157
|
-
"worker": {
|
|
158
|
-
"running": true,
|
|
159
|
-
"lastError": null,
|
|
160
|
-
"lastEventAt": 1234567890,
|
|
161
|
-
"startedAt": 1234567890
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
]
|
|
165
|
-
}
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
### 5) Start Worker
|
|
169
|
-
|
|
170
99
|
`POST /v1/workers/start`
|
|
171
100
|
|
|
172
|
-
|
|
173
|
-
|
|
101
|
+
请求体:
|
|
174
102
|
```json
|
|
175
103
|
{ "accountId": "xxx-im-bot" }
|
|
176
104
|
```
|
|
177
105
|
|
|
178
|
-
### 6) Stop Worker
|
|
179
|
-
|
|
180
106
|
`POST /v1/workers/stop`
|
|
181
107
|
|
|
182
|
-
|
|
183
|
-
|
|
108
|
+
请求体:
|
|
184
109
|
```json
|
|
185
110
|
{ "accountId": "xxx-im-bot" }
|
|
186
111
|
```
|
|
187
112
|
|
|
188
|
-
### 7) Send Text
|
|
189
|
-
|
|
190
113
|
`POST /v1/messages/text`
|
|
191
114
|
|
|
192
|
-
|
|
193
|
-
|
|
115
|
+
请求体:
|
|
194
116
|
```json
|
|
195
117
|
{
|
|
196
118
|
"accountId": "xxx-im-bot",
|
|
197
119
|
"to": "target@im.wechat",
|
|
198
120
|
"text": "hello",
|
|
199
|
-
"contextToken": "
|
|
121
|
+
"contextToken": "可选"
|
|
200
122
|
}
|
|
201
123
|
```
|
|
202
124
|
|
|
203
|
-
|
|
204
|
-
- `contextToken` is required by upstream. If omitted, server will try cached token for `(accountId,to)`.
|
|
205
|
-
|
|
206
|
-
### 8) Send Image
|
|
125
|
+
说明:`contextToken` 是上游会话关键字段;不传则尝试命中缓存 `(accountId,to)`。
|
|
207
126
|
|
|
208
127
|
`POST /v1/messages/image`
|
|
209
128
|
|
|
210
|
-
|
|
211
|
-
|
|
129
|
+
请求体(本地文件):
|
|
212
130
|
```json
|
|
213
131
|
{
|
|
214
132
|
"accountId": "xxx-im-bot",
|
|
215
133
|
"to": "target@im.wechat",
|
|
216
134
|
"filePath": "/tmp/a.jpg",
|
|
217
|
-
"text": "
|
|
218
|
-
"contextToken": "
|
|
135
|
+
"text": "可选",
|
|
136
|
+
"contextToken": "可选"
|
|
219
137
|
}
|
|
220
138
|
```
|
|
221
139
|
|
|
222
|
-
|
|
223
|
-
|
|
140
|
+
请求体(远程 URL):
|
|
224
141
|
```json
|
|
225
142
|
{
|
|
226
143
|
"accountId": "xxx-im-bot",
|
|
227
144
|
"to": "target@im.wechat",
|
|
228
145
|
"imageUrl": "https://example.com/a.jpg",
|
|
229
|
-
"text": "
|
|
230
|
-
"contextToken": "
|
|
146
|
+
"text": "可选",
|
|
147
|
+
"contextToken": "可选"
|
|
231
148
|
}
|
|
232
149
|
```
|
|
233
150
|
|
|
234
|
-
|
|
235
|
-
- Exactly one of `filePath` or `imageUrl`
|
|
236
|
-
- `imageUrl` must be `https`
|
|
237
|
-
- Max image size: 20 MB
|
|
238
|
-
|
|
239
|
-
### 9) Pull Events
|
|
151
|
+
约束:`filePath`/`imageUrl` 二选一;`imageUrl` 必须 https;最大 20MB。
|
|
240
152
|
|
|
241
153
|
`GET /v1/events?accountId=xxx-im-bot&limit=100&cursor=<eventId>`
|
|
242
154
|
|
|
243
|
-
|
|
244
|
-
- `accountId` required
|
|
245
|
-
- `limit` optional (1..500, default 100)
|
|
246
|
-
- `cursor` optional
|
|
247
|
-
|
|
248
|
-
Response:
|
|
249
|
-
|
|
250
|
-
```json
|
|
251
|
-
{
|
|
252
|
-
"requestId": "...",
|
|
253
|
-
"data": {
|
|
254
|
-
"items": [
|
|
255
|
-
{
|
|
256
|
-
"id": "...",
|
|
257
|
-
"accountId": "xxx-im-bot",
|
|
258
|
-
"from": "user@im.wechat",
|
|
259
|
-
"to": "bot@im.bot",
|
|
260
|
-
"text": "hello",
|
|
261
|
-
"contextToken": "...",
|
|
262
|
-
"raw": {},
|
|
263
|
-
"createdAt": 1234567890,
|
|
264
|
-
"ackedAt": null
|
|
265
|
-
}
|
|
266
|
-
],
|
|
267
|
-
"nextCursor": "..."
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
### 10) Ack Events
|
|
155
|
+
参数:`accountId` 必填,`limit` 可选(1..500,默认 100),`cursor` 可选。
|
|
273
156
|
|
|
274
157
|
`POST /v1/events/ack`
|
|
275
158
|
|
|
276
|
-
|
|
277
|
-
|
|
159
|
+
请求体:
|
|
278
160
|
```json
|
|
279
|
-
{
|
|
280
|
-
"accountId": "xxx-im-bot",
|
|
281
|
-
"ids": ["event-id-1", "event-id-2"]
|
|
282
|
-
}
|
|
161
|
+
{ "accountId": "xxx-im-bot", "ids": ["event-id-1", "event-id-2"] }
|
|
283
162
|
```
|
|
284
163
|
|
|
285
|
-
|
|
286
|
-
|
|
164
|
+
返回:
|
|
287
165
|
```json
|
|
288
|
-
{
|
|
289
|
-
"requestId": "...",
|
|
290
|
-
"data": { "acked": 2 }
|
|
291
|
-
}
|
|
166
|
+
{ "requestId": "...", "data": { "acked": 2 } }
|
|
292
167
|
```
|
|
293
168
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
8. Ack consumed events via `/v1/events/ack`
|
|
169
|
+
### 最小联调流程
|
|
170
|
+
1. 启动服务
|
|
171
|
+
2. 调 `/v1/login/qr/start`
|
|
172
|
+
3. 手机微信扫码
|
|
173
|
+
4. 调 `/v1/login/qr/wait` 直到 `connected=true`
|
|
174
|
+
5. 调 `/v1/accounts` 看账号和 worker
|
|
175
|
+
6. 调 `/v1/events` 拉入站消息
|
|
176
|
+
7. 用事件里的 `contextToken` 调 `/v1/messages/text` 或 `/v1/messages/image`
|
|
177
|
+
8. 调 `/v1/events/ack` 确认消费
|
|
304
178
|
|
|
305
|
-
|
|
179
|
+
### 开发与发布
|
|
306
180
|
|
|
307
181
|
```bash
|
|
308
182
|
npm install
|
|
309
183
|
npm run dev
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
Build:
|
|
313
|
-
|
|
314
|
-
```bash
|
|
184
|
+
npm run typecheck
|
|
315
185
|
npm run build
|
|
316
|
-
npm run
|
|
186
|
+
npm run version:bump
|
|
187
|
+
npm publish
|
|
317
188
|
```
|
|
318
189
|
|
|
319
|
-
|
|
190
|
+
---
|
|
320
191
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
192
|
+
## English
|
|
193
|
+
|
|
194
|
+
Standalone Weixin bot API server without OpenClaw runtime dependency.
|
|
324
195
|
|
|
325
|
-
|
|
196
|
+
### Features
|
|
197
|
+
- QR login via mobile Weixin app
|
|
198
|
+
- inbound polling + local event queue
|
|
199
|
+
- send text/image APIs
|
|
200
|
+
- account and worker management
|
|
326
201
|
|
|
327
|
-
|
|
202
|
+
### Install
|
|
328
203
|
|
|
329
204
|
```bash
|
|
330
|
-
npm
|
|
205
|
+
npm i -g @dadb/weixin-standalone-api
|
|
331
206
|
```
|
|
332
207
|
|
|
333
|
-
|
|
208
|
+
### Run
|
|
334
209
|
|
|
335
210
|
```bash
|
|
336
|
-
|
|
211
|
+
WEIXIN_STANDALONE_TOKEN='replace_me' \
|
|
212
|
+
WEIXIN_STANDALONE_HOST='127.0.0.1' \
|
|
213
|
+
WEIXIN_STANDALONE_PORT='8788' \
|
|
214
|
+
weixin-standalone-api
|
|
337
215
|
```
|
|
338
216
|
|
|
339
|
-
|
|
217
|
+
### Environment Variables
|
|
218
|
+
- `WEIXIN_STANDALONE_TOKEN`: bearer auth token, optional
|
|
219
|
+
- `WEIXIN_STANDALONE_HOST`: default `127.0.0.1`
|
|
220
|
+
- `WEIXIN_STANDALONE_PORT`: default `8788`
|
|
221
|
+
- `WEIXIN_STANDALONE_STATE_DIR`: default `./.weixin-standalone`
|
|
222
|
+
- `WEIXIN_BASE_URL`: default `https://ilinkai.weixin.qq.com`
|
|
223
|
+
- `WEIXIN_CDN_BASE_URL`: default `https://novac2c.cdn.weixin.qq.com/c2c`
|
|
224
|
+
- `WEIXIN_BOT_TYPE`: default `"3"`
|
|
340
225
|
|
|
341
|
-
|
|
342
|
-
|
|
226
|
+
### Auth
|
|
227
|
+
When token is set, all endpoints except `/healthz` require:
|
|
228
|
+
|
|
229
|
+
```http
|
|
230
|
+
Authorization: Bearer <WEIXIN_STANDALONE_TOKEN>
|
|
343
231
|
```
|
|
344
232
|
|
|
345
|
-
|
|
233
|
+
### Response
|
|
234
|
+
Success:
|
|
346
235
|
|
|
347
|
-
```
|
|
348
|
-
|
|
236
|
+
```json
|
|
237
|
+
{ "requestId": "uuid", "data": {} }
|
|
349
238
|
```
|
|
350
239
|
|
|
351
|
-
|
|
240
|
+
Error:
|
|
352
241
|
|
|
353
|
-
```
|
|
354
|
-
|
|
355
|
-
npm publish
|
|
242
|
+
```json
|
|
243
|
+
{ "requestId": "uuid", "error": "message" }
|
|
356
244
|
```
|
|
245
|
+
|
|
246
|
+
### Endpoints
|
|
247
|
+
- `GET /healthz`
|
|
248
|
+
- `POST /v1/login/qr/start`
|
|
249
|
+
- `POST /v1/login/qr/wait`
|
|
250
|
+
- `GET /v1/accounts`
|
|
251
|
+
- `POST /v1/workers/start`
|
|
252
|
+
- `POST /v1/workers/stop`
|
|
253
|
+
- `POST /v1/messages/text`
|
|
254
|
+
- `POST /v1/messages/image`
|
|
255
|
+
- `GET /v1/events`
|
|
256
|
+
- `POST /v1/events/ack`
|
|
257
|
+
|
|
258
|
+
### Minimal Flow
|
|
259
|
+
1. Start server
|
|
260
|
+
2. Call `/v1/login/qr/start`
|
|
261
|
+
3. Scan QR with mobile Weixin app
|
|
262
|
+
4. Poll `/v1/login/qr/wait` until `connected=true`
|
|
263
|
+
5. Pull inbound events from `/v1/events`
|
|
264
|
+
6. Reply with `/v1/messages/text` or `/v1/messages/image`
|
|
265
|
+
7. Ack via `/v1/events/ack`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dadb/weixin-standalone-api",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Standalone Weixin bot API server with QR login, inbound polling, and send message/image endpoints",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "dadb",
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
"bin/",
|
|
13
13
|
"dist/",
|
|
14
14
|
"README.md",
|
|
15
|
-
"README.zh-CN.md",
|
|
16
15
|
"LICENSE"
|
|
17
16
|
],
|
|
18
17
|
"scripts": {
|
package/README.zh-CN.md
DELETED
|
@@ -1,309 +0,0 @@
|
|
|
1
|
-
# weixin-standalone-api
|
|
2
|
-
|
|
3
|
-
独立的微信机器人 API 服务(不依赖 OpenClaw 运行时)。
|
|
4
|
-
|
|
5
|
-
- 手机微信扫码登录
|
|
6
|
-
- 入站消息轮询 + 本地事件队列
|
|
7
|
-
- 文本/图片发送接口
|
|
8
|
-
- 账号与 worker 管理接口
|
|
9
|
-
|
|
10
|
-
英文文档: [README.md](./README.md)
|
|
11
|
-
|
|
12
|
-
## 运行要求
|
|
13
|
-
|
|
14
|
-
- Node.js `>=22`
|
|
15
|
-
- 可访问的微信 iLink bot 后端
|
|
16
|
-
|
|
17
|
-
## 安装
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
npm i -g weixin-standalone-api
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
或:
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
npm i weixin-standalone-api
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## 启动
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
WEIXIN_STANDALONE_TOKEN='replace_me' \
|
|
33
|
-
WEIXIN_STANDALONE_HOST='127.0.0.1' \
|
|
34
|
-
WEIXIN_STANDALONE_PORT='8788' \
|
|
35
|
-
weixin-standalone-api
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## 环境变量
|
|
39
|
-
|
|
40
|
-
- `WEIXIN_STANDALONE_TOKEN`:API 访问令牌。为空时不鉴权。
|
|
41
|
-
- `WEIXIN_STANDALONE_HOST`:默认 `127.0.0.1`
|
|
42
|
-
- `WEIXIN_STANDALONE_PORT`:默认 `8788`
|
|
43
|
-
- `WEIXIN_STANDALONE_STATE_DIR`:默认 `./.weixin-standalone`
|
|
44
|
-
- `WEIXIN_BASE_URL`:默认 `https://ilinkai.weixin.qq.com`
|
|
45
|
-
- `WEIXIN_CDN_BASE_URL`:默认 `https://novac2c.cdn.weixin.qq.com/c2c`
|
|
46
|
-
- `WEIXIN_BOT_TYPE`:默认 `"3"`
|
|
47
|
-
|
|
48
|
-
## 鉴权
|
|
49
|
-
|
|
50
|
-
设置了 `WEIXIN_STANDALONE_TOKEN` 后,除 `/healthz` 之外都要带:
|
|
51
|
-
|
|
52
|
-
```http
|
|
53
|
-
Authorization: Bearer <WEIXIN_STANDALONE_TOKEN>
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
## 返回格式
|
|
57
|
-
|
|
58
|
-
成功:
|
|
59
|
-
|
|
60
|
-
```json
|
|
61
|
-
{
|
|
62
|
-
"requestId": "uuid",
|
|
63
|
-
"data": {}
|
|
64
|
-
}
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
失败:
|
|
68
|
-
|
|
69
|
-
```json
|
|
70
|
-
{
|
|
71
|
-
"requestId": "uuid",
|
|
72
|
-
"error": "错误信息"
|
|
73
|
-
}
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
## API 说明
|
|
77
|
-
|
|
78
|
-
### 1)健康检查
|
|
79
|
-
|
|
80
|
-
`GET /healthz`
|
|
81
|
-
|
|
82
|
-
返回:
|
|
83
|
-
|
|
84
|
-
```json
|
|
85
|
-
{ "ok": true, "requestId": "..." }
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### 2)发起扫码
|
|
89
|
-
|
|
90
|
-
`POST /v1/login/qr/start`
|
|
91
|
-
|
|
92
|
-
请求体:
|
|
93
|
-
|
|
94
|
-
```json
|
|
95
|
-
{
|
|
96
|
-
"accountId": "可选",
|
|
97
|
-
"botType": "可选",
|
|
98
|
-
"baseUrl": "可选"
|
|
99
|
-
}
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
返回:
|
|
103
|
-
|
|
104
|
-
```json
|
|
105
|
-
{
|
|
106
|
-
"requestId": "...",
|
|
107
|
-
"data": {
|
|
108
|
-
"sessionKey": "...",
|
|
109
|
-
"qrcodeUrl": "..."
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
### 3)等待扫码结果
|
|
115
|
-
|
|
116
|
-
`POST /v1/login/qr/wait`
|
|
117
|
-
|
|
118
|
-
请求体:
|
|
119
|
-
|
|
120
|
-
```json
|
|
121
|
-
{
|
|
122
|
-
"sessionKey": "...",
|
|
123
|
-
"timeoutMs": 480000
|
|
124
|
-
}
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
返回:
|
|
128
|
-
|
|
129
|
-
```json
|
|
130
|
-
{
|
|
131
|
-
"requestId": "...",
|
|
132
|
-
"data": {
|
|
133
|
-
"connected": true,
|
|
134
|
-
"accountId": "xxx-im-bot",
|
|
135
|
-
"userId": "xxx@im.wechat"
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
### 4)账号列表
|
|
141
|
-
|
|
142
|
-
`GET /v1/accounts`
|
|
143
|
-
|
|
144
|
-
### 5)启动账号 worker
|
|
145
|
-
|
|
146
|
-
`POST /v1/workers/start`
|
|
147
|
-
|
|
148
|
-
请求体:
|
|
149
|
-
|
|
150
|
-
```json
|
|
151
|
-
{ "accountId": "xxx-im-bot" }
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
### 6)停止账号 worker
|
|
155
|
-
|
|
156
|
-
`POST /v1/workers/stop`
|
|
157
|
-
|
|
158
|
-
请求体:
|
|
159
|
-
|
|
160
|
-
```json
|
|
161
|
-
{ "accountId": "xxx-im-bot" }
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
### 7)发送文本
|
|
165
|
-
|
|
166
|
-
`POST /v1/messages/text`
|
|
167
|
-
|
|
168
|
-
请求体:
|
|
169
|
-
|
|
170
|
-
```json
|
|
171
|
-
{
|
|
172
|
-
"accountId": "xxx-im-bot",
|
|
173
|
-
"to": "target@im.wechat",
|
|
174
|
-
"text": "hello",
|
|
175
|
-
"contextToken": "可选"
|
|
176
|
-
}
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
说明:
|
|
180
|
-
- `contextToken` 是上游会话关键字段。
|
|
181
|
-
- 不传时,服务会尝试从 `(accountId,to)` 的缓存中取。
|
|
182
|
-
|
|
183
|
-
### 8)发送图片
|
|
184
|
-
|
|
185
|
-
`POST /v1/messages/image`
|
|
186
|
-
|
|
187
|
-
本地文件模式:
|
|
188
|
-
|
|
189
|
-
```json
|
|
190
|
-
{
|
|
191
|
-
"accountId": "xxx-im-bot",
|
|
192
|
-
"to": "target@im.wechat",
|
|
193
|
-
"filePath": "/tmp/a.jpg",
|
|
194
|
-
"text": "可选",
|
|
195
|
-
"contextToken": "可选"
|
|
196
|
-
}
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
远程 URL 模式:
|
|
200
|
-
|
|
201
|
-
```json
|
|
202
|
-
{
|
|
203
|
-
"accountId": "xxx-im-bot",
|
|
204
|
-
"to": "target@im.wechat",
|
|
205
|
-
"imageUrl": "https://example.com/a.jpg",
|
|
206
|
-
"text": "可选",
|
|
207
|
-
"contextToken": "可选"
|
|
208
|
-
}
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
约束:
|
|
212
|
-
- `filePath` 和 `imageUrl` 二选一
|
|
213
|
-
- `imageUrl` 必须为 `https`
|
|
214
|
-
- 图片最大 20MB
|
|
215
|
-
|
|
216
|
-
### 9)拉取事件
|
|
217
|
-
|
|
218
|
-
`GET /v1/events?accountId=xxx-im-bot&limit=100&cursor=<eventId>`
|
|
219
|
-
|
|
220
|
-
参数:
|
|
221
|
-
- `accountId` 必填
|
|
222
|
-
- `limit` 可选(1..500,默认 100)
|
|
223
|
-
- `cursor` 可选
|
|
224
|
-
|
|
225
|
-
### 10)确认事件已处理
|
|
226
|
-
|
|
227
|
-
`POST /v1/events/ack`
|
|
228
|
-
|
|
229
|
-
请求体:
|
|
230
|
-
|
|
231
|
-
```json
|
|
232
|
-
{
|
|
233
|
-
"accountId": "xxx-im-bot",
|
|
234
|
-
"ids": ["event-id-1", "event-id-2"]
|
|
235
|
-
}
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
返回:
|
|
239
|
-
|
|
240
|
-
```json
|
|
241
|
-
{
|
|
242
|
-
"requestId": "...",
|
|
243
|
-
"data": { "acked": 2 }
|
|
244
|
-
}
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
## 最小联调流程
|
|
248
|
-
|
|
249
|
-
1. 启动服务
|
|
250
|
-
2. 调 `/v1/login/qr/start`
|
|
251
|
-
3. 手机微信扫码
|
|
252
|
-
4. 调 `/v1/login/qr/wait` 直到 `connected=true`
|
|
253
|
-
5. 调 `/v1/accounts` 查看账号和 worker
|
|
254
|
-
6. 调 `/v1/events` 拉入站消息
|
|
255
|
-
7. 用事件里的 `contextToken` 调 `/v1/messages/text` 或 `/v1/messages/image`
|
|
256
|
-
8. 调 `/v1/events/ack` 确认消费
|
|
257
|
-
|
|
258
|
-
## 开发
|
|
259
|
-
|
|
260
|
-
```bash
|
|
261
|
-
npm install
|
|
262
|
-
npm run dev
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
构建与启动:
|
|
266
|
-
|
|
267
|
-
```bash
|
|
268
|
-
npm run build
|
|
269
|
-
npm run start
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
类型检查:
|
|
273
|
-
|
|
274
|
-
```bash
|
|
275
|
-
npm run typecheck
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
## 版本脚本
|
|
279
|
-
|
|
280
|
-
Patch:
|
|
281
|
-
|
|
282
|
-
```bash
|
|
283
|
-
npm run version:bump
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
Minor:
|
|
287
|
-
|
|
288
|
-
```bash
|
|
289
|
-
npm run version:bump -- minor
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
Major:
|
|
293
|
-
|
|
294
|
-
```bash
|
|
295
|
-
npm run version:bump -- major
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
指定版本:
|
|
299
|
-
|
|
300
|
-
```bash
|
|
301
|
-
npm run version:bump -- 1.2.3
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
## 发布
|
|
305
|
-
|
|
306
|
-
```bash
|
|
307
|
-
npm login
|
|
308
|
-
npm publish
|
|
309
|
-
```
|