@core-workspace/infoflow-openclaw-plugin 2026.3.8 → 2026.3.27-beta.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/CHANGELOG.md +91 -0
- package/CLAUDE.md +135 -0
- package/COLLABORATION_REPORT.md +209 -0
- package/PROJECT_GUIDE.md +355 -0
- package/README.md +158 -66
- package/docs/dev-guide.md +63 -50
- package/docs/qa-feature-list.md +452 -0
- package/docs/webhook-guide.md +178 -0
- package/index.ts +28 -2
- package/openclaw.plugin.json +131 -21
- package/package.json +20 -3
- package/scripts/deploy.sh +66 -7
- package/scripts/postinstall.cjs +80 -0
- package/skills/infoflow-dev/SKILL.md +2 -2
- package/skills/infoflow-dev/references/api.md +1 -1
- package/src/adapter/inbound/webhook-parser.ts +27 -5
- package/src/adapter/inbound/ws-receiver.ts +304 -43
- package/src/adapter/outbound/markdown-local-images.ts +80 -0
- package/src/adapter/outbound/reply-dispatcher.ts +146 -65
- package/src/adapter/outbound/target-resolver.ts +4 -3
- package/src/channel/accounts.ts +97 -22
- package/src/channel/channel.ts +456 -12
- package/src/channel/media.ts +20 -6
- package/src/channel/monitor.ts +8 -3
- package/src/channel/outbound.ts +358 -21
- package/src/channel/streaming.ts +740 -0
- package/src/commands/changelog.ts +80 -0
- package/src/commands/doctor.ts +545 -0
- package/src/commands/logs.ts +449 -0
- package/src/commands/version.ts +20 -0
- package/src/compat/openclaw-sdk.ts +218 -0
- package/src/handler/message-handler.ts +673 -166
- package/src/logging.ts +1 -1
- package/src/runtime.ts +1 -1
- package/src/security/dm-policy.ts +1 -4
- package/src/security/group-policy.ts +174 -51
- package/src/tools/actions/index.ts +15 -13
- package/src/tools/cron/relay.ts +1154 -0
- package/src/tools/hooks/index.ts +13 -1
- package/src/tools/index.ts +714 -32
- package/src/types.ts +144 -25
- package/src/utils/audio/g722/dct_tables.ts +381 -0
- package/src/utils/audio/g722/decoder.ts +919 -0
- package/src/utils/audio/g722/defs.ts +105 -0
- package/src/utils/audio/g722/hd-parser.ts +247 -0
- package/src/utils/audio/g722/huff_tables.ts +240 -0
- package/src/utils/audio/g722/index.ts +78 -0
- package/src/utils/audio/g722/output_decoded.pcm +0 -0
- package/src/utils/audio/g722/output_decoded.wav +0 -0
- package/src/utils/audio/g722/tables.ts +173 -0
- package/src/utils/audio/g722/test_api.ts +31 -0
- package/src/utils/audio/g722/test_voice.hd +0 -0
- package/src/utils/bos/im-bos-client.ts +219 -0
- package/src/utils/group-agent-cache.ts +142 -0
- package/src/utils/token-adapter.ts +120 -51
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
开发规范:新改动写在 "## 开发中" 下方。
|
|
3
|
+
发布时由 publish.sh 自动将 "## 开发中" 替换为版本号和日期(如 "## 1.1.0 (2026-03-18)")。
|
|
4
|
+
-->
|
|
5
|
+
|
|
6
|
+
# 更新日志
|
|
7
|
+
|
|
8
|
+
## 2026-03-26
|
|
9
|
+
|
|
10
|
+
**问题修复**
|
|
11
|
+
- 修复非标准 npm 全局路径下 SDK 加载失败的问题:通过 `realpathSync` 解析 `process.argv[1]` 的 symlink,使 `createRequire` 从真实安装目录而非 `bin/` 出发解析模块;同时新增 `npm_config_prefix` 环境变量作为 fallback 路径来源,覆盖自定义 npm prefix 场景(如 `/home/work/opt/npm-global/`)
|
|
12
|
+
|
|
13
|
+
## 2026-03-25
|
|
14
|
+
|
|
15
|
+
**新功能**
|
|
16
|
+
- 新增 `wsConnectDomain` 配置项:支持两阶段 WebSocket 连接的独立域名/端口指定。`wsGateway` 控制 Phase 1 端点分配请求,`wsConnectDomain` 控制 Phase 2 实际 WS 握手地址,内网/NAT 环境下可分别指定,格式支持 `domain:port`
|
|
17
|
+
|
|
18
|
+
## 2026-03-24
|
|
19
|
+
|
|
20
|
+
**兼容性**
|
|
21
|
+
- 兼容 openclaw 2026.3.22 及以上版本:新增统一兼容层 `src/compat/openclaw-sdk.ts`,适配 SDK 拆包后的各子路径导入(`plugin-entry`、`core`、`reply-runtime`、`channel-contract` 等),升级 SDK 版本无需逐一修改业务代码
|
|
22
|
+
|
|
23
|
+
**新功能**
|
|
24
|
+
- 支持发送文件消息
|
|
25
|
+
- 支持在单聊和群聊中引用回复指定消息
|
|
26
|
+
- 新增获取群成员列表接口,用于拉取群内其他机器人的 agents 信息
|
|
27
|
+
- 支持 @ 其他机器人:可在群消息中主动 @ 并触发其他机器人响应
|
|
28
|
+
|
|
29
|
+
**问题修复**
|
|
30
|
+
- 修复接收所有消息时的 bug,确保消息不被意外丢弃
|
|
31
|
+
- 修复域名配置问题,恢复外网连接可用性
|
|
32
|
+
- 修复机器人无法响应群内其他机器人消息的问题:显式区分消息来源类型(`regular` 普通用户 / `robot` 机器人),避免机器人消息被误过滤
|
|
33
|
+
- 修复 @ 其他机器人的边界条件处理,优化请求发送策略,提升稳定性
|
|
34
|
+
- 减少日志冗余输出,新增日志分级控制,按级别过滤更清晰
|
|
35
|
+
- 修复在开发机环境下因网络限制导致请求失败的问题
|
|
36
|
+
|
|
37
|
+
## 2026.3.39 (2026-03-19)
|
|
38
|
+
|
|
39
|
+
**问题修复**
|
|
40
|
+
- 修复群聊 @ 检测不依赖 `robotName` 配置:WebSocket 模式通过 SDK `eventtype` 字段区分(`MESSAGE_RECEIVE` = @机器人,`ALL_MESSAGE_FORWARD` = 全量消息);Webhook 模式通过 body AT 元素的 `robotid` 字段判断,两种模式均无需配置 `robotName`
|
|
41
|
+
- 修复 Token 获取接口路径错误(缺少 `/api/v1` 前缀导致返回 HTML 404)
|
|
42
|
+
- 修复默认 `apiHost` 与 SDK 不一致(由 `api.im.baidu.com` 改为 `api.im.baidu.com`)
|
|
43
|
+
|
|
44
|
+
**安装工具(@baidu/infoflow-openclaw-tools)**
|
|
45
|
+
- 新增 `uninstall` / `remove` 命令:一键卸载插件并清理配置
|
|
46
|
+
- 安装/升级流程调整:先选择连接方式,再按模式填写最小配置(websocket 只需 AppKey + AppSecret;webhook 额外需要 Token + EncodingAESKey)
|
|
47
|
+
- 修复连接方式选项(移除不支持的 `polling`,改为正确的 `webhook`)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
**新功能**
|
|
52
|
+
- 消息格式默认改为 Markdown,加粗、代码块、列表等格式开箱即用,无需手动配置 `dmMessageFormat` / `groupMessageFormat`
|
|
53
|
+
- `/infoflow-doctor` 支持 `/infoflow-doctor <userId>` 参数,Web UI 场景下也可向指定用户发送自检消息
|
|
54
|
+
- `/infoflow-logs` 日志可读性优化:按会话聚合展示,每条显示发送方、消息内容预览、回复耗时和字数;支持 `/infoflow-logs error` / `warn` 按等级过滤
|
|
55
|
+
|
|
56
|
+
**问题修复**
|
|
57
|
+
- 修复 WebSocket 重连后消息被丢弃的问题(`receiver stopped`):SDK 自动重连是正常行为,现在重连后消息可以正常接收和处理
|
|
58
|
+
- 修复 `/infoflow-doctor` 自检时 WebSocket 连通性检查报错 `client.start is not a function` 的问题
|
|
59
|
+
- 修复 `/infoflow-logs` 中回复字数统计不准、指令类消息显示"无回复"的问题
|
|
60
|
+
|
|
61
|
+
**其他**
|
|
62
|
+
- `/infoflow-doctor` 自检报告改为 Markdown 格式发送,加粗和表情符号现在可以正常渲染
|
|
63
|
+
- `/infoflow-changelog` 更新日志改为 Markdown 格式发送
|
|
64
|
+
|
|
65
|
+
## 1.0.0 (2026-03-17)
|
|
66
|
+
|
|
67
|
+
**新功能**
|
|
68
|
+
- 新增定时任务工具 `infoflow_cron`:支持向如流发送定时消息,可设置一次性触发(`at`)、固定间隔(`every`)或 Cron 表达式(`cron`),让 AI 能主动按时推送提醒/报告
|
|
69
|
+
- 新增定时任务结果转发(`cronRelay`):OpenClaw 定时任务完成后自动将结果转发到如流会话
|
|
70
|
+
|
|
71
|
+
**问题修复**
|
|
72
|
+
- 新增 WebSocket 断连/重连日志,断线后在 `/infoflow-logs` 中可查看完整时间线
|
|
73
|
+
|
|
74
|
+
## 0.9.0 (2026-03-17)
|
|
75
|
+
|
|
76
|
+
**问题修复**
|
|
77
|
+
- 修复了机器人名称未填写时,群聊消息全部收不到的问题
|
|
78
|
+
- 修复了群聊中机器人的回复有时因为内容过长而发送失败的问题
|
|
79
|
+
- 修复了不填写连接方式时,机器人无法启动的问题
|
|
80
|
+
- 修复了 WebSocket 模式下消息发送报错的问题
|
|
81
|
+
- 修复了「自检」工具在 WebSocket 模式下误报验签和加密密钥未配置的问题
|
|
82
|
+
|
|
83
|
+
**新功能**
|
|
84
|
+
- 连接方式默认改为 WebSocket,只需配置 AppKey 和 AppSecret 即可使用,无需额外填写 Token 和密钥
|
|
85
|
+
- 新增「查看日志」命令:在如流中发送 `/infoflow-logs` 即可查看机器人最近的收发消息记录,方便排查问题
|
|
86
|
+
- 新增「查看更新日志」命令:在如流中发送 `/infoflow-changelog` 即可查看插件更新历史
|
|
87
|
+
- 新增每条消息最大长度配置项,超长回复会自动拆成多条消息发送,默认每条不超过 1800 字
|
|
88
|
+
- 「自检」报告优化:排查工具 `/infoflow-doctor` 的输出更加简洁易读
|
|
89
|
+
|
|
90
|
+
**其他**
|
|
91
|
+
- 长消息自动拆分时,现在会在段落或列表的自然边界处断开,避免内容被切断到奇怪的位置
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
OpenClaw channel plugin for Baidu Infoflow (如流) enterprise messaging platform. Enables AI chatbots to integrate with Infoflow, supporting private/group chat, Webhook and WebSocket connections, image handling, message recall, and sophisticated group reply modes.
|
|
8
|
+
|
|
9
|
+
## Commands
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Install dependencies
|
|
13
|
+
npm install
|
|
14
|
+
|
|
15
|
+
# Run tests
|
|
16
|
+
npm test
|
|
17
|
+
npm test -- --watch # Watch mode
|
|
18
|
+
|
|
19
|
+
# Deploy to OpenClaw (sync to extensions dir and restart gateway)
|
|
20
|
+
./scripts/deploy.sh
|
|
21
|
+
|
|
22
|
+
# Manual deploy
|
|
23
|
+
rsync -av --delete . ~/.openclaw/extensions/infoflow/ --exclude node_modules --exclude dist --exclude .git
|
|
24
|
+
openclaw gateway restart
|
|
25
|
+
|
|
26
|
+
# View logs
|
|
27
|
+
openclaw logs | grep infoflow
|
|
28
|
+
tail -f ~/.openclaw/logs/gateway.log | grep -i infoflow
|
|
29
|
+
|
|
30
|
+
# Debug commands
|
|
31
|
+
openclaw doctor # Check config
|
|
32
|
+
openclaw status # Channel status
|
|
33
|
+
openclaw directory groups infoflow # List group IDs
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Architecture
|
|
37
|
+
|
|
38
|
+
### Layered Structure
|
|
39
|
+
|
|
40
|
+
| Layer | Directory | Responsibility |
|
|
41
|
+
|-------|-----------|----------------|
|
|
42
|
+
| Plugin Entry | `channel/` | OpenClaw SDK integration, network I/O |
|
|
43
|
+
| Message Adapter | `adapter/` | Format conversion (pure functions) |
|
|
44
|
+
| Event Bridge | `handler/` | Event routing, security decisions |
|
|
45
|
+
| Security Policy | `security/` | Pure policy logic, no I/O |
|
|
46
|
+
| Tool Registration | `tools/` | LLM function calling tools |
|
|
47
|
+
| Shared Utilities | `utils/` | Cross-layer utilities |
|
|
48
|
+
|
|
49
|
+
### Key Files
|
|
50
|
+
|
|
51
|
+
| File | Purpose |
|
|
52
|
+
|------|---------|
|
|
53
|
+
| `index.ts` | Plugin entry: registers channel, HTTP route, tools, hooks |
|
|
54
|
+
| `src/types.ts` | All TypeScript type definitions |
|
|
55
|
+
| `src/channel/channel.ts` | ChannelPlugin definition with actions, config, security |
|
|
56
|
+
| `src/handler/message-handler.ts` | Core message routing and LLM dispatch |
|
|
57
|
+
| `src/tools/index.ts` | LLM tools: `infoflow_send`, `infoflow_recall` |
|
|
58
|
+
| `src/security/group-policy.ts` | Reply mode logic, @mention detection, follow-up window |
|
|
59
|
+
| `src/channel/outbound.ts` | Send/recall message API wrappers |
|
|
60
|
+
| `openclaw.plugin.json` | Plugin metadata and JSON Schema for configuration |
|
|
61
|
+
|
|
62
|
+
### Data Flow (Inbound)
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
如流服务器 → POST /webhook/infoflow
|
|
66
|
+
→ channel/monitor.ts (AES decrypt, checkToken verify)
|
|
67
|
+
→ adapter/inbound/webhook-parser.ts (dedup, route)
|
|
68
|
+
→ handler/message-handler.ts (policy check, replyMode)
|
|
69
|
+
→ LLM dispatch → adapter/outbound/reply-dispatcher.ts
|
|
70
|
+
→ channel/outbound.ts → 如流 API
|
|
71
|
+
→ utils/store/message-store.ts (record for recall)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Critical Conventions
|
|
75
|
+
|
|
76
|
+
### ESM Import Paths
|
|
77
|
+
|
|
78
|
+
**All TypeScript imports must use `.js` extension** (ESM runtime requirement):
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
// ✅ Correct
|
|
82
|
+
import { sendInfoflowMessage } from "../channel/outbound.js";
|
|
83
|
+
|
|
84
|
+
// ❌ Wrong - will fail at runtime
|
|
85
|
+
import { sendInfoflowMessage } from "../channel/outbound";
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 64-bit Integer Handling
|
|
89
|
+
|
|
90
|
+
Infoflow message IDs exceed JavaScript's `Number.MAX_SAFE_INTEGER`. Always extract from raw JSON as strings:
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
import { extractIdFromRawJson } from "../channel/outbound.js";
|
|
94
|
+
const messageId = extractIdFromRawJson(rawJsonText, "messageid");
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Mock Paths in Tests
|
|
98
|
+
|
|
99
|
+
Use `.js` extension in `vi.mock` paths:
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
vi.mock("../../src/channel/outbound.js", () => ({
|
|
103
|
+
sendInfoflowMessage: vi.fn().mockResolvedValue({ ok: true }),
|
|
104
|
+
}));
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Testing
|
|
108
|
+
|
|
109
|
+
- Test files mirror `src/` structure in `tests/` directory
|
|
110
|
+
- `security/` functions require branch coverage ≥ 80%
|
|
111
|
+
- Network functions are mocked; no real HTTP requests in tests
|
|
112
|
+
|
|
113
|
+
## Message ID Requirements
|
|
114
|
+
|
|
115
|
+
- **Group recall**: requires `messageid` + `msgseqid` (stored in SQLite via `message-store.ts`)
|
|
116
|
+
- **Private recall**: requires `msgkey` + `appAgentId` (config field)
|
|
117
|
+
|
|
118
|
+
## Group Reply Modes
|
|
119
|
+
|
|
120
|
+
| Mode | Trigger Condition |
|
|
121
|
+
|------|-------------------|
|
|
122
|
+
| `mention-only` | Only when bot is @mentioned |
|
|
123
|
+
| `mention-and-watch` | @bot, @watchMentions users, or watchRegex match |
|
|
124
|
+
| `proactive` | All messages go to LLM (LLM decides NO_REPLY or respond) |
|
|
125
|
+
| `record` | Log only, no reply |
|
|
126
|
+
| `ignore` | Discard completely |
|
|
127
|
+
|
|
128
|
+
## Configuration Hierarchy
|
|
129
|
+
|
|
130
|
+
Priority: `groups.<groupId>` > `accounts.<id>` > top-level defaults
|
|
131
|
+
|
|
132
|
+
Key config paths:
|
|
133
|
+
- `channels.infoflow` - main config
|
|
134
|
+
- `channels.infoflow.accounts.<id>` - multi-account
|
|
135
|
+
- `channels.infoflow.groups.<groupId>` - per-group override
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# Infoflow 插件项目协作报告
|
|
2
|
+
|
|
3
|
+
**生成日期**: 2026-03-23
|
|
4
|
+
**团队成员**: researcher, analyst
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 1. 项目概述
|
|
9
|
+
|
|
10
|
+
OpenClaw 的百度如流(Infoflow)企业消息平台插件,使 AI 聊天机器人能够与如流平台集成,支持私聊/群聊、Webhook 和 WebSocket 连接、图片处理、消息撤回、以及灵活的群回复模式。
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## 2. 架构分析
|
|
15
|
+
|
|
16
|
+
### 2.1 分层架构
|
|
17
|
+
|
|
18
|
+
| 层级 | 目录 | 职责 |
|
|
19
|
+
|------|------|------|
|
|
20
|
+
| 插件入口层 | `channel/` | OpenClaw SDK 集成、网络 I/O |
|
|
21
|
+
| 消息适配层 | `adapter/` | 格式转换(纯函数) |
|
|
22
|
+
| 事件桥接层 | `handler/` | 事件路由、安全决策 |
|
|
23
|
+
| 安全策略层 | `security/` | 纯策略逻辑,无 I/O |
|
|
24
|
+
| 工具注册层 | `tools/` | LLM function calling 工具 |
|
|
25
|
+
| 共享工具层 | `utils/` | 跨层工具 |
|
|
26
|
+
|
|
27
|
+
### 2.2 核心模块
|
|
28
|
+
|
|
29
|
+
#### 插件入口层 (`src/channel/`)
|
|
30
|
+
- `channel.ts` - ChannelPlugin 定义:actions、config、security
|
|
31
|
+
- `monitor.ts` - Webhook 入口,AES 解密、checkToken 验证
|
|
32
|
+
- `outbound.ts` - 发送/撤回消息 API 封装
|
|
33
|
+
- `accounts.ts` - 多账号管理
|
|
34
|
+
- `streaming.ts` - 流式响应处理
|
|
35
|
+
- `media.ts` - 媒体文件处理
|
|
36
|
+
|
|
37
|
+
#### 消息适配层 (`src/adapter/`)
|
|
38
|
+
- `inbound/webhook-parser.ts` - 入站消息解析、去重、路由
|
|
39
|
+
- `inbound/ws-receiver.ts` - WebSocket 接收器
|
|
40
|
+
- `outbound/reply-dispatcher.ts` - 回复分发
|
|
41
|
+
- `outbound/target-resolver.ts` - 目标解析
|
|
42
|
+
- `outbound/markdown-local-images.ts` - Markdown 本地图片处理
|
|
43
|
+
|
|
44
|
+
#### 事件桥接层 (`src/handler/`)
|
|
45
|
+
- `message-handler.ts` - 核心消息路由和 LLM 分发
|
|
46
|
+
|
|
47
|
+
#### 安全策略层 (`src/security/`)
|
|
48
|
+
- `group-policy.ts` - 群回复模式逻辑、@mention 检测、follow-up 窗口
|
|
49
|
+
- `dm-policy.ts` - 私聊策略
|
|
50
|
+
|
|
51
|
+
#### 工具注册层 (`src/tools/`)
|
|
52
|
+
- `index.ts` - LLM 工具:`infoflow_send`、`infoflow_recall`
|
|
53
|
+
- `hooks/index.ts` - 工具钩子
|
|
54
|
+
- `actions/index.ts` - 动作定义
|
|
55
|
+
- `cron/relay.ts` - 定时任务中继
|
|
56
|
+
|
|
57
|
+
#### 共享工具层 (`src/utils/`)
|
|
58
|
+
- `store/message-store.ts` - 消息存储(SQLite,用于撤回)
|
|
59
|
+
- `audio/g722/` - G.722 音频解码器
|
|
60
|
+
- `bos/im-bos-client.ts` - BOS 存储客户端
|
|
61
|
+
- `token-adapter.ts` - Token 适配器
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## 3. 消息处理流程
|
|
66
|
+
|
|
67
|
+
### 3.1 入站数据流
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
如流服务器 → POST /webhook/infoflow
|
|
71
|
+
→ channel/monitor.ts (路由分发)
|
|
72
|
+
→ adapter/inbound/webhook-parser.ts
|
|
73
|
+
├─ AES 解密 (encodingAESKey)
|
|
74
|
+
├─ 64位整数ID精度修复
|
|
75
|
+
├─ 消息去重 (5分钟TTL, 1000条缓存)
|
|
76
|
+
└─ 按聊天类型路由
|
|
77
|
+
→ handler/message-handler.ts
|
|
78
|
+
├─ 安全校验 (dm-policy / group-policy)
|
|
79
|
+
├─ 群回复模式判断 (replyMode)
|
|
80
|
+
│ ├─ mention-only: 仅 @机器人 时响应
|
|
81
|
+
│ ├─ mention-and-watch: @机器人 / @监控用户 / 正则匹配
|
|
82
|
+
│ ├─ proactive: 全部消息送 LLM 决策
|
|
83
|
+
│ ├─ record: 仅记录,不响应
|
|
84
|
+
│ └─ ignore: 完全忽略
|
|
85
|
+
└─ LLM 分发
|
|
86
|
+
→ adapter/outbound/reply-dispatcher.ts
|
|
87
|
+
→ channel/outbound.ts → 如流 API
|
|
88
|
+
→ utils/store/message-store.ts (记录消息ID用于撤回)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 3.2 关键处理细节
|
|
92
|
+
|
|
93
|
+
#### Webhook 入口 (`monitor.ts`)
|
|
94
|
+
- 仅接受 POST 请求
|
|
95
|
+
- 支持多账号,按路径注册
|
|
96
|
+
- 最大请求体 20MB
|
|
97
|
+
|
|
98
|
+
#### 消息解析 (`webhook-parser.ts`)
|
|
99
|
+
- **私聊**: `application/x-www-form-urlencoded`,包含 `messageJson` 字段
|
|
100
|
+
- **群聊**: `text/plain`,请求体即 AES 加密内容
|
|
101
|
+
- **echostr 验证**: MD5 签名验证用于服务器配置
|
|
102
|
+
|
|
103
|
+
#### AES 解密
|
|
104
|
+
- 模式: AES-ECB (Infoflow API 约束)
|
|
105
|
+
- 密钥: Base64 URLSafe 编码 (支持 128/192/256 位)
|
|
106
|
+
- 支持多账号密钥尝试
|
|
107
|
+
|
|
108
|
+
#### 64位整数处理
|
|
109
|
+
如流消息 ID 超过 JavaScript `Number.MAX_SAFE_INTEGER`:
|
|
110
|
+
- 从原始 JSON 文本中用正则提取为字符串
|
|
111
|
+
- 修复 JSON.parse 的精度丢失
|
|
112
|
+
|
|
113
|
+
#### 消息去重
|
|
114
|
+
- TTL: 5 分钟
|
|
115
|
+
- 最大缓存: 1000 条
|
|
116
|
+
- 键值: `messageid` 或 `{fromuserid}_{groupid}_{ctime}`
|
|
117
|
+
|
|
118
|
+
### 3.3 群回复模式
|
|
119
|
+
|
|
120
|
+
| 模式 | 触发条件 |
|
|
121
|
+
|------|----------|
|
|
122
|
+
| `mention-only` | 仅 @机器人 时响应 |
|
|
123
|
+
| `mention-and-watch` | @机器人 / @监控用户 / watchRegex 匹配 |
|
|
124
|
+
| `proactive` | 全部消息送 LLM,由 LLM 决定是否响应 |
|
|
125
|
+
| `record` | 仅记录,不响应 |
|
|
126
|
+
| `ignore` | 完全丢弃 |
|
|
127
|
+
|
|
128
|
+
### 3.4 Follow-up 机制
|
|
129
|
+
- 机器人回复后开启时间窗口(默认 300 秒)
|
|
130
|
+
- 窗口内用户消息直接触发回复
|
|
131
|
+
- 用于多轮对话场景
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## 4. 关键约定
|
|
136
|
+
|
|
137
|
+
### 4.1 ESM 导入路径
|
|
138
|
+
**所有 TypeScript 导入必须使用 `.js` 扩展名**(ESM 运行时要求):
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
// ✅ 正确
|
|
142
|
+
import { sendInfoflowMessage } from "../channel/outbound.js";
|
|
143
|
+
|
|
144
|
+
// ❌ 错误 - 运行时失败
|
|
145
|
+
import { sendInfoflowMessage } from "../channel/outbound";
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### 4.2 测试 Mock 路径
|
|
149
|
+
`vi.mock` 路径也需使用 `.js` 扩展名:
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
vi.mock("../../src/channel/outbound.js", () => ({
|
|
153
|
+
sendInfoflowMessage: vi.fn().mockResolvedValue({ ok: true }),
|
|
154
|
+
}));
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### 4.3 消息 ID 提取
|
|
158
|
+
```typescript
|
|
159
|
+
import { extractIdFromRawJson } from "../channel/outbound.js";
|
|
160
|
+
const messageId = extractIdFromRawJson(rawJsonText, "messageid");
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## 5. 配置层级
|
|
166
|
+
|
|
167
|
+
优先级: `groups.<groupId>` > `accounts.<id>` > 顶层默认值
|
|
168
|
+
|
|
169
|
+
关键配置路径:
|
|
170
|
+
- `channels.infoflow` - 主配置
|
|
171
|
+
- `channels.infoflow.accounts.<id>` - 多账号配置
|
|
172
|
+
- `channels.infoflow.groups.<groupId>` - 群级覆盖
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## 6. 常用命令
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
# 安装依赖
|
|
180
|
+
npm install
|
|
181
|
+
|
|
182
|
+
# 运行测试
|
|
183
|
+
npm test
|
|
184
|
+
npm test -- --watch # 监视模式
|
|
185
|
+
|
|
186
|
+
# 部署
|
|
187
|
+
./scripts/deploy.sh
|
|
188
|
+
|
|
189
|
+
# 查看日志
|
|
190
|
+
openclaw logs | grep infoflow
|
|
191
|
+
tail -f ~/.openclaw/logs/gateway.log | grep -i infoflow
|
|
192
|
+
|
|
193
|
+
# 调试
|
|
194
|
+
openclaw doctor # 检查配置
|
|
195
|
+
openclaw status # Channel 状态
|
|
196
|
+
openclaw directory groups infoflow # 列出群 ID
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## 7. 测试规范
|
|
202
|
+
|
|
203
|
+
- 测试文件镜像 `src/` 结构于 `tests/` 目录
|
|
204
|
+
- `security/` 函数要求分支覆盖率 ≥ 80%
|
|
205
|
+
- 网络函数需 mock,测试中不发真实 HTTP 请求
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
**报告完成**
|