@core-workspace/infoflow-openclaw-plugin 2026.3.8
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 +989 -0
- package/docs/architecture-data-flow.md +429 -0
- package/docs/architecture.md +423 -0
- package/docs/dev-guide.md +611 -0
- package/index.ts +29 -0
- package/openclaw.plugin.json +138 -0
- package/package.json +40 -0
- package/scripts/deploy.sh +34 -0
- package/skills/infoflow-dev/SKILL.md +88 -0
- package/skills/infoflow-dev/references/api.md +413 -0
- package/src/adapter/inbound/webhook-parser.ts +433 -0
- package/src/adapter/inbound/ws-receiver.ts +226 -0
- package/src/adapter/outbound/reply-dispatcher.ts +281 -0
- package/src/adapter/outbound/target-resolver.ts +109 -0
- package/src/channel/accounts.ts +164 -0
- package/src/channel/channel.ts +364 -0
- package/src/channel/media.ts +365 -0
- package/src/channel/monitor.ts +184 -0
- package/src/channel/outbound.ts +934 -0
- package/src/events.ts +62 -0
- package/src/handler/message-handler.ts +801 -0
- package/src/logging.ts +123 -0
- package/src/runtime.ts +14 -0
- package/src/security/dm-policy.ts +80 -0
- package/src/security/group-policy.ts +271 -0
- package/src/tools/actions/index.ts +456 -0
- package/src/tools/hooks/index.ts +82 -0
- package/src/tools/index.ts +277 -0
- package/src/types.ts +277 -0
- package/src/utils/store/message-store.ts +295 -0
- package/src/utils/token-adapter.ts +90 -0
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
# 如流 (Infoflow) API 参考文档
|
|
2
|
+
|
|
3
|
+
本文档是如流机器人开发的官方API参考,用于OpenClaw插件开发。
|
|
4
|
+
|
|
5
|
+
**原始文档**: https://ku.baidu-int.com/knowledge/HFVrC7hq1Q/2tsPs8CtSd/Bu7DDg4dpB/O7gUd6RJUGn7Ix
|
|
6
|
+
|
|
7
|
+
## 核心概念
|
|
8
|
+
|
|
9
|
+
### API 端点
|
|
10
|
+
|
|
11
|
+
- **生产环境**: `http://apiin.im.baidu.com/api/v1/robot/msg/groupmsgsend`
|
|
12
|
+
- **预发布环境**: `http://xplatform-preonline.dev.weiyun.baidu.com/open-plat/api/devp/v1/robot/msg/groupmsgsend`
|
|
13
|
+
|
|
14
|
+
### 权限要求
|
|
15
|
+
|
|
16
|
+
调用API前必须:
|
|
17
|
+
1. 在企业后台开启权限【以机器人身份发送消息到群聊】
|
|
18
|
+
2. 路径:企业后台 > 应用中心 > 你的机器人 > 功能 > 机器人 > 设置 > 功能 > 群聊场景 > 开放API > 设置
|
|
19
|
+
|
|
20
|
+
### 限流规则
|
|
21
|
+
|
|
22
|
+
- **QPS限制**: 10 QPS/机器人(默认)
|
|
23
|
+
- **频率限制**: 20条消息/分钟/群
|
|
24
|
+
- 超出限流会返回错误码 40046,限流5分钟
|
|
25
|
+
|
|
26
|
+
## 消息格式
|
|
27
|
+
|
|
28
|
+
### 基础消息结构
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"message": {
|
|
33
|
+
"header": {
|
|
34
|
+
"toid": 8331527, // 群ID
|
|
35
|
+
"totype": "GROUP", // 消息类型
|
|
36
|
+
"msgtype": "TEXT", // 内容类型
|
|
37
|
+
"clientmsgid": 1569398477302,
|
|
38
|
+
"role": "robot"
|
|
39
|
+
},
|
|
40
|
+
"body": [
|
|
41
|
+
{
|
|
42
|
+
"type": "TEXT",
|
|
43
|
+
"content": "消息内容"
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Header 字段说明
|
|
51
|
+
|
|
52
|
+
| 字段 | 类型 | 必须 | 说明 |
|
|
53
|
+
|------|------|------|------|
|
|
54
|
+
| toid | long | 是 | 目标群组ID |
|
|
55
|
+
| totype | String | 是 | 目标类型,固定为 "GROUP" |
|
|
56
|
+
| msgtype | String | 是 | 消息类型:TEXT/IMAGE/LINK/MD |
|
|
57
|
+
| clientmsgid | long | 是 | 客户端生成的唯一标识 |
|
|
58
|
+
| clienttime | long | 否 | 客户端时间戳,不传则使用服务器时间 |
|
|
59
|
+
| role | String | 是 | 固定为 "robot" |
|
|
60
|
+
|
|
61
|
+
## 消息类型
|
|
62
|
+
|
|
63
|
+
### 1. TEXT - 文本消息
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"message": {
|
|
68
|
+
"header": {
|
|
69
|
+
"toid": 123456,
|
|
70
|
+
"totype": "GROUP",
|
|
71
|
+
"msgtype": "TEXT",
|
|
72
|
+
"clientmsgid": 1569398477302,
|
|
73
|
+
"role": "robot"
|
|
74
|
+
},
|
|
75
|
+
"body": [
|
|
76
|
+
{
|
|
77
|
+
"type": "TEXT",
|
|
78
|
+
"content": "这是一条文本消息"
|
|
79
|
+
}
|
|
80
|
+
]
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**限制**:
|
|
86
|
+
- 总长度 ≤ 2048字符
|
|
87
|
+
- 错误码 40061: 超过2k
|
|
88
|
+
|
|
89
|
+
### 2. MD - Markdown消息
|
|
90
|
+
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"message": {
|
|
94
|
+
"header": {
|
|
95
|
+
"toid": 123456,
|
|
96
|
+
"totype": "GROUP",
|
|
97
|
+
"msgtype": "MD",
|
|
98
|
+
"clientmsgid": 1569398477302,
|
|
99
|
+
"role": "robot"
|
|
100
|
+
},
|
|
101
|
+
"body": [
|
|
102
|
+
{
|
|
103
|
+
"type": "MD",
|
|
104
|
+
"content": "# 标题\n**粗体** *斜体*"
|
|
105
|
+
}
|
|
106
|
+
]
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**支持的语法**:
|
|
112
|
+
- 标题: `# 标题` (1-6级)
|
|
113
|
+
- 粗体: `**文本**`
|
|
114
|
+
- 斜体: `*文本*`
|
|
115
|
+
- 引用: `> 引用内容`
|
|
116
|
+
- 颜色: `<font color="green">文本</font>` (green/gray/red)
|
|
117
|
+
- 链接: `[文本](URL)`
|
|
118
|
+
- 有序列表: `1. 项目`
|
|
119
|
+
- 无序列表: `- 项目`
|
|
120
|
+
- 行内代码: `` `代码` ``
|
|
121
|
+
|
|
122
|
+
**限制**:
|
|
123
|
+
- 内容长度 ≤ 2048字符
|
|
124
|
+
- 错误码 40068: 超过限制
|
|
125
|
+
|
|
126
|
+
### 3. IMAGE - 图片消息
|
|
127
|
+
|
|
128
|
+
```json
|
|
129
|
+
{
|
|
130
|
+
"message": {
|
|
131
|
+
"header": {
|
|
132
|
+
"toid": 123456,
|
|
133
|
+
"totype": "GROUP",
|
|
134
|
+
"msgtype": "IMAGE",
|
|
135
|
+
"clientmsgid": 1569398477302,
|
|
136
|
+
"role": "robot"
|
|
137
|
+
},
|
|
138
|
+
"body": [
|
|
139
|
+
{
|
|
140
|
+
"type": "IMAGE",
|
|
141
|
+
"content": "图片URL或Base64"
|
|
142
|
+
}
|
|
143
|
+
]
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**限制**:
|
|
149
|
+
- 图片数量: 1个
|
|
150
|
+
- 图片大小 ≤ 1MB
|
|
151
|
+
- 错误码 40063: 图片数量超限
|
|
152
|
+
- 错误码 40066: 图片大小超限
|
|
153
|
+
|
|
154
|
+
### 4. LINK - 链接消息
|
|
155
|
+
|
|
156
|
+
```json
|
|
157
|
+
{
|
|
158
|
+
"message": {
|
|
159
|
+
"header": {
|
|
160
|
+
"toid": 123456,
|
|
161
|
+
"totype": "GROUP",
|
|
162
|
+
"msgtype": "LINK",
|
|
163
|
+
"clientmsgid": 1569398477302,
|
|
164
|
+
"role": "robot"
|
|
165
|
+
},
|
|
166
|
+
"body": [
|
|
167
|
+
{
|
|
168
|
+
"type": "LINK",
|
|
169
|
+
"url": "https://example.com",
|
|
170
|
+
"title": "链接标题",
|
|
171
|
+
"desc": "链接描述"
|
|
172
|
+
}
|
|
173
|
+
]
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**限制**:
|
|
179
|
+
- 单个链接长度 ≤ 1024字符
|
|
180
|
+
- 错误码 40062: 链接长度超限
|
|
181
|
+
|
|
182
|
+
## 引用回复功能
|
|
183
|
+
|
|
184
|
+
支持引用回复的消息类型: TEXT、IMAGE、LINK
|
|
185
|
+
|
|
186
|
+
**结构**: reply 字段与 header 和 body 同级
|
|
187
|
+
|
|
188
|
+
```json
|
|
189
|
+
{
|
|
190
|
+
"message": {
|
|
191
|
+
"header": { /* ... */ },
|
|
192
|
+
"body": [ /* ... */ ],
|
|
193
|
+
"reply": {
|
|
194
|
+
"messageid": "1859257727716544500",
|
|
195
|
+
"preview": "被引用的消息内容",
|
|
196
|
+
"imid": "102752365",
|
|
197
|
+
"replyType": "1"
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Reply 字段说明
|
|
204
|
+
|
|
205
|
+
| 字段 | 类型 | 必须 | 说明 |
|
|
206
|
+
|------|------|------|------|
|
|
207
|
+
| messageid | String | 是 | 被引用消息的ID |
|
|
208
|
+
| preview | String | 否 | 被引用消息的预览文本 |
|
|
209
|
+
| imid | String | 否 | 被引用消息发送者的imid(数字用户ID) |
|
|
210
|
+
| replyType | String | 是 | "1"=回复模式, "2"=引用模式 |
|
|
211
|
+
|
|
212
|
+
**注意事项**:
|
|
213
|
+
- `messageid` 必须是字符串类型
|
|
214
|
+
- `replyType` 使用驼峰命名(不是 replytype)
|
|
215
|
+
- `imid` 是发送者的数字ID,可以从消息的 `fromid` 字段获取
|
|
216
|
+
|
|
217
|
+
## @提及功能
|
|
218
|
+
|
|
219
|
+
### @用户
|
|
220
|
+
|
|
221
|
+
```json
|
|
222
|
+
{
|
|
223
|
+
"message": {
|
|
224
|
+
"header": {
|
|
225
|
+
"toid": 123456,
|
|
226
|
+
"totype": "GROUP",
|
|
227
|
+
"msgtype": "TEXT",
|
|
228
|
+
"clientmsgid": 1569398477302,
|
|
229
|
+
"role": "robot"
|
|
230
|
+
},
|
|
231
|
+
"body": [
|
|
232
|
+
{
|
|
233
|
+
"type": "AT",
|
|
234
|
+
"content": "username1,username2" // 逗号分隔
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
"type": "TEXT",
|
|
238
|
+
"content": "消息内容"
|
|
239
|
+
}
|
|
240
|
+
]
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### @全员
|
|
246
|
+
|
|
247
|
+
```json
|
|
248
|
+
{
|
|
249
|
+
"body": [
|
|
250
|
+
{
|
|
251
|
+
"type": "AT",
|
|
252
|
+
"content": "all"
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
"type": "TEXT",
|
|
256
|
+
"content": "消息内容"
|
|
257
|
+
}
|
|
258
|
+
]
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
**限制**:
|
|
263
|
+
- @人数 ≤ 50人
|
|
264
|
+
- 错误码 40071: 超过50人
|
|
265
|
+
|
|
266
|
+
## 返回结果
|
|
267
|
+
|
|
268
|
+
### 成功响应
|
|
269
|
+
|
|
270
|
+
```json
|
|
271
|
+
{
|
|
272
|
+
"code": "ok",
|
|
273
|
+
"data": {
|
|
274
|
+
"errcode": 0,
|
|
275
|
+
"errmsg": "ok",
|
|
276
|
+
"data": {
|
|
277
|
+
"messageid": 1835260055958702611,
|
|
278
|
+
"msgseqid": 300010003,
|
|
279
|
+
"ctime": 1750240379318
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### 错误码
|
|
286
|
+
|
|
287
|
+
| 错误码 | 说明 |
|
|
288
|
+
|--------|------|
|
|
289
|
+
| 0 | 成功 |
|
|
290
|
+
| -1 | 系统错误 |
|
|
291
|
+
| 40000 | 参数错误 |
|
|
292
|
+
| 40035 | 群聊ID不合法 |
|
|
293
|
+
| 40036 | 群聊非企业群 |
|
|
294
|
+
| 40044 | 机器人未被添加到群中 |
|
|
295
|
+
| 40045 | agentId不合法 |
|
|
296
|
+
| 40046 | 发送消息频率超限(20条/分钟) |
|
|
297
|
+
| 40047 | 文件上传失败 |
|
|
298
|
+
| 40060 | body超过9k |
|
|
299
|
+
| 40061 | text类型文本长度超过2k |
|
|
300
|
+
| 40062 | link类型单个链接长度超过1k |
|
|
301
|
+
| 40063 | image类型图片数量超过1个 |
|
|
302
|
+
| 40066 | image类型图片大小超过1m |
|
|
303
|
+
| 40068 | markdown内容长度超过2048字符 |
|
|
304
|
+
| 40071 | at超过50人 |
|
|
305
|
+
| 40200 | 机器人发送消息权限已被封禁 |
|
|
306
|
+
| 40201 | 机器人接收消息权限已被封禁 |
|
|
307
|
+
| 40300 | 机器人已被停用 |
|
|
308
|
+
|
|
309
|
+
## 开发最佳实践
|
|
310
|
+
|
|
311
|
+
### 1. 消息去重
|
|
312
|
+
|
|
313
|
+
使用 `clientmsgid` 和 `clienttime` 实现消息去重:
|
|
314
|
+
- `clientmsgid`: 使用时间戳或UUID
|
|
315
|
+
- `clienttime`: 使用当前毫秒时间戳
|
|
316
|
+
- **重要**: 不要传0,会触发排重机制
|
|
317
|
+
|
|
318
|
+
### 2. 引用回复实现
|
|
319
|
+
|
|
320
|
+
```typescript
|
|
321
|
+
// 从接收的消息中提取关键字段
|
|
322
|
+
const messageId = String(msgData.message.header.messageid);
|
|
323
|
+
const senderImid = String(msgData.fromid); // 注意:是 fromid 不是 imid
|
|
324
|
+
const preview = extractPreviewText(msgData.message.body);
|
|
325
|
+
|
|
326
|
+
// 构建reply对象
|
|
327
|
+
const reply = {
|
|
328
|
+
messageid: messageId, // 必须是字符串
|
|
329
|
+
preview: preview.slice(0, 100), // 截断预览文本
|
|
330
|
+
imid: senderImid, // 可选,但建议提供
|
|
331
|
+
replyType: "1" // "1"=回复, "2"=引用
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
// 发送消息时包含reply
|
|
335
|
+
const payload = {
|
|
336
|
+
message: {
|
|
337
|
+
header: { /* ... */ },
|
|
338
|
+
body: [ /* ... */ ],
|
|
339
|
+
reply: reply // 与header、body同级
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### 3. 错误处理
|
|
345
|
+
|
|
346
|
+
```typescript
|
|
347
|
+
try {
|
|
348
|
+
const response = await sendMessage(payload);
|
|
349
|
+
const data = await response.json();
|
|
350
|
+
|
|
351
|
+
if (data.data?.errcode === 0) {
|
|
352
|
+
console.log('消息发送成功');
|
|
353
|
+
} else {
|
|
354
|
+
console.error(`发送失败: ${data.data?.errmsg} (${data.data?.errcode})`);
|
|
355
|
+
}
|
|
356
|
+
} catch (error) {
|
|
357
|
+
console.error('API调用失败:', error);
|
|
358
|
+
}
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
### 4. 调试技巧
|
|
362
|
+
|
|
363
|
+
**添加详细日志**:
|
|
364
|
+
```typescript
|
|
365
|
+
console.log('[DEBUG] Request payload:', JSON.stringify(payload, null, 2));
|
|
366
|
+
console.log('[DEBUG] API response:', JSON.stringify(data, null, 2));
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
**验证字段类型**:
|
|
370
|
+
```typescript
|
|
371
|
+
console.log('[DEBUG] messageid type:', typeof reply.messageid); // 应该是 string
|
|
372
|
+
console.log('[DEBUG] imid type:', typeof reply.imid); // 应该是 string
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
## 常见问题排查
|
|
376
|
+
|
|
377
|
+
### 问题1: 引用回复不显示
|
|
378
|
+
|
|
379
|
+
**可能原因**:
|
|
380
|
+
1. `messageid` 是 number 而不是 string → 转换为字符串
|
|
381
|
+
2. 字段名错误(replytype vs replyType)→ 使用驼峰命名
|
|
382
|
+
3. `reply` 对象未传递到API → 检查参数解构
|
|
383
|
+
4. `imid` 字段缺失或错误 → 从 `msgData.fromid` 提取
|
|
384
|
+
|
|
385
|
+
**解决方法**: 参考"引用回复实现"章节
|
|
386
|
+
|
|
387
|
+
### 问题2: 频率限流
|
|
388
|
+
|
|
389
|
+
**错误**: 40046 - 发送消息频率超限
|
|
390
|
+
|
|
391
|
+
**原因**: 超过 20条/分钟/群
|
|
392
|
+
|
|
393
|
+
**解决**:
|
|
394
|
+
- 实现消息队列和延迟发送
|
|
395
|
+
- 合并多条消息
|
|
396
|
+
- 联系技术支持申请扩容
|
|
397
|
+
|
|
398
|
+
### 问题3: 参数错误
|
|
399
|
+
|
|
400
|
+
**错误**: 40000 - 参数错误
|
|
401
|
+
|
|
402
|
+
**检查清单**:
|
|
403
|
+
- [ ] header.toid 是否为有效的群ID(number类型)
|
|
404
|
+
- [ ] header.msgtype 与 body[0].type 是否匹配
|
|
405
|
+
- [ ] clientmsgid 是否为唯一值
|
|
406
|
+
- [ ] role 是否为 "robot"
|
|
407
|
+
- [ ] 内容长度是否超限
|
|
408
|
+
|
|
409
|
+
## 相关链接
|
|
410
|
+
|
|
411
|
+
- 企业后台: https://qy.baidu-int.com/index.html
|
|
412
|
+
- API完整文档: https://ku.baidu-int.com/knowledge/HFVrC7hq1Q/2tsPs8CtSd/Bu7DDg4dpB/O7gUd6RJUGn7Ix
|
|
413
|
+
- 技术支持: 魏小伟 (weixiaowei@baidu.com)
|