32 KiB
WeChat-iLink Bridge 开发版需求文档草案
状态:待确认草案
最后更新:2026-05-16
原始资料:ilink-wechat-requirements.md
目标:把现有需求整理到可以进入开发评审和任务拆分的程度。详细开发分段规划和详细测试方案将在本草案确认后补充。
1. 背景与目标
WeChat-iLink Bridge,代号 wxb,是一套基于腾讯 iLink Bot API 的本地微信消息桥接工具,供 WorkBuddy / Codex / Claude Code 等 AI Agent 调用,实现:
- AI Agent 可以主动向已建立上下文的微信用户发送文本消息。
- AI Agent 可以按需拉取用户发来的微信消息。
- 工具在本地维护登录凭证、轮询游标、
context_token、消息历史和去重状态。 - 配套 Skill 文档指导 Agent 正确调用工具,并约束主动推送行为。
本项目不是微信客户端替代品,也不是通用微信机器人平台。它只解决“AI 工作流需要用微信触达用户或接收用户反馈”的窄场景。
2. 依据与外部约束
2.1 协议依据
需求基于以下公开资料和原始需求整理:
- iLink Bot API 协议页:https://www.wechatbot.dev/zh/protocol
- Tencent/openclaw-weixin README:https://github.com/Tencent/openclaw-weixin
- 原始需求文档:
iLinkBot/ilink-wechat-requirements.md
2.2 关键协议约束
- 登录通过二维码扫码完成,登录后得到
bot_token。 - 业务接口使用 HTTP/JSON,不是 WebSocket。
- 入站消息通过
getupdates长轮询获取。 - 出站消息必须携带目标用户最近一次有效的
context_token。 context_token来自入站消息,必须按用户持久化。get_updates_buf是不透明轮询游标,必须按账号持久化。bot_token没有刷新接口,过期后只能重新扫码登录。- 协议支持文本、图片、语音、文件、视频等消息项。
- 媒体文件通过 CDN 上传/下载,并使用 AES-128-ECB 加密。
2.3 待实测校准项
以下字段在资料中存在版本差异或需要真实接口验证,开发前必须通过 Spike 校准:
| 项目 | 原始文档值 | 公开资料/风险 | 开发处理 |
|---|---|---|---|
channel_version |
0.1.0 |
公开协议示例出现 2.0.0 |
配置化,Spike 后确定默认值 |
| 消息 ID 字段 | msg_id |
README 中也出现 message_id |
标准化层兼容二者 |
| 时间字段 | timestamp |
README 中也出现 create_time_ms |
标准化层兼容二者 |
item_list[].type |
文本=1,图片=3,文件=4 | README 中 MessageItem 映射为文本=1,图片=2,语音=3,文件=4,视频=5 | Spike 校准,内部枚举隔离 |
| 登录接口路径 | /ilink/bot/... |
OpenClaw 也提供封装路径 | P0 使用原生路径,封装路径作为备选 |
3. 核心结论:不强制基于 CLI
本项目不应把 CLI 作为核心实现本身。推荐架构是:
WorkBuddy / Codex / Claude Code
|
| 调用 CLI 或未来工具适配器
v
Thin CLI Adapter: wxb
|
v
Core Library: login / fetch / send / state / crypto / normalize
|
v
iLink Bot API
3.1 为什么不把 CLI 作为核心
CLI 适合 Agent 调用,天然简单、透明、易调试。但如果所有逻辑都写在 CLI 命令里,会带来这些问题:
- WorkBuddy、Codex、Claude Code 之外的调用方难以复用。
- 单元测试会被命令行解析、stdout/stderr、进程退出码污染。
- 后续接入 MCP、本地 HTTP 服务或计划任务时会重复实现。
- 并发读写状态文件、重试、分片、脱敏等逻辑容易散落在命令里。
3.2 推荐实现方式
P0 实现核心库,CLI 只做薄封装:
core/client.js:封装 iLink API 请求。core/state-store.js:账号、token、游标、消息和队列持久化。core/message-normalizer.js:原始消息标准化。core/send-text.js:文本发送、分片、重试。core/fetch-messages.js:长轮询、去重、上下文保存。bin/wxb.js:命令行入口。
3.3 轻量但稳定的运行模式
| 模式 | 是否 P0 | 稳定性 | 复杂度 | 说明 |
|---|---|---|---|---|
| Thin CLI 按需调用 | 是 | 中 | 低 | 最轻;适合用户主动触发或短期任务 |
| CLI + 计划任务 heartbeat | 建议 P1 | 高 | 低-中 | 用系统计划任务定时 wxb fetch --timeout,降低 token 长期不活跃风险 |
wxb poll 前台长轮询 |
建议 P1 | 高 | 中 | 无 HTTP 服务,进程可由用户或系统守护 |
| 本地 HTTP/MCP 服务 | 暂不做 | 高 | 中-高 | 适合后续深度集成,但不是 MVP 必需 |
确认建议:P0 做 Thin CLI + Core Library;P1 增加 wxb poll 或 heartbeat,不在 P0 引入常驻 HTTP 服务。
4. 范围定义
4.1 P0 范围
P0 目标是完成一个“文本完整处理 + 非文本不丢失”的消息桥接 MVP:
- 扫码登录并保存账号凭证。
- 按账号保存
bot_token、context_token、get_updates_buf。 - 调用
wxb fetch拉取新消息,先落盘保存,再标准化输出 JSON 给 AI Agent。 - 调用
wxb send向已知用户发送文本消息。 - 自动分片长文本。
- 自动保存和读取目标用户
context_token。 - 检测
-14会话过期并提示重新登录。 - 检测
-2参数错误并输出可诊断错误。 - 对入站图片、语音、文件、视频做类型识别和元数据保存,P0 不要求下载/解密媒体正文。
- 账号状态查看。
- 日志脱敏。
- 状态文件原子写入和基础并发保护。
- Windows 环境优先适配和测试,状态目录、路径处理、命令执行兼容 Windows。
- WorkBuddy Skill 草案,指导 Agent 调用 CLI,并明确把
wxb fetch返回的用户消息视作用户输入。
4.2 P1 范围
wxb poll或计划任务 heartbeat,提升 token 保活稳定性。- 延迟补发队列。
- 用户 alias 管理。
- 多账号增强。
- typing 状态。
- 图片发送和接收解密。
- 文件发送。
- 语音、视频、文件的接收下载和本地附件保存。
- 更完整的消息历史查询。
- 消息历史和附件的保留周期配置、清理命令和定时清理。
4.3 P2 范围
- 本地 HTTP 服务或 MCP Server 适配器。
- 语音转写、视频摘要、引用消息解析等高级富媒体理解。
- 更完整的运维监控和告警。
- 跨设备/跨环境状态迁移。
4.4 明确不做
- 不实现微信通讯录读取。
- 不实现添加好友或群发。
- 不绕过 iLink 协议限制。
- 不逆向微信客户端。
- 不保证消息“必达”,只做尽力投递和可恢复处理。
- 不在 P0 实现后台 HTTP 服务。
5. 角色与典型流程
5.1 角色
| 角色 | 说明 |
|---|---|
| 使用者 | 拥有微信账号和本地运行环境的人 |
| AI Agent | 通过 WorkBuddy / Codex / Claude Code 调用 wxb |
| 微信用户 | 与该 bot 账号发生过会话的目标用户,通常也是使用者本人 |
5.2 首次登录流程
- 用户运行
wxb login。 - CLI 获取二维码并在终端展示。
- 用户用微信扫码并确认。
- CLI 轮询登录状态直到
confirmed。 - 保存账号凭证到本地状态目录。
- 输出账号 ID 和下一步提示。
5.3 接收消息流程
- Agent 或用户运行
wxb fetch --json。 - 工具读取账号凭证和
get_updates_buf。 - 调用
getupdates长轮询。 - 保存新的
get_updates_buf。 - 对消息去重并标准化。
- 保存每条消息的
context_token。 - 将新消息写入本地消息历史。
- 输出新消息 JSON 给 Agent。
- Agent 将返回的新消息视作用户输入,并据此继续任务、回复微信或向用户追问。
说明:本地存储和输出给 Agent 不是二选一。P0 默认先存储再输出,避免 Agent 处理失败、进程中断、重复拉取或 context 丢失时无法恢复。是否长期保留消息正文由后续保留策略控制。
5.4 发送文本流程
- Agent 调用
wxb send --user <userId> --text <text> --json。 - 工具读取目标用户最近的
context_token。 - 若没有 token,返回明确错误,提示需要目标用户先发一条消息。
- 工具将长文本分片。
- 每片生成独立
client_id并调用sendmessage。 - 保存出站消息历史。
- 输出发送结果 JSON。
6. 功能需求
F1. 扫码登录与账号管理
F1.1 扫码登录
优先级:P0
需求:
- 命令:
wxb login [--account <alias>] [--json] - 获取二维码并在终端可读展示。
- 轮询二维码状态,支持
wait、scaned、confirmed、expired。 - 登录成功后保存:
accountIdbotTokenownerUserIdbaseUrlsavedAtchannelVersion
- 登录失败或二维码过期时输出明确错误。
验收标准:
- 用户可以完成扫码并在本地看到保存的账号。
wxb accounts可以列出该账号。- token 不出现在普通日志中。
F1.2 账号列表与默认账号
优先级:P0
需求:
- 命令:
wxb accounts [--json] - 支持列出本地账号。
- 支持默认账号文件。
- 若只有一个账号,命令可以自动选择。
- 若有多个账号且未指定,交互式命令可提示;非交互命令必须返回错误。
验收标准:
- 多账号场景不会误用账号。
- JSON 输出可被 Agent 稳定解析。
F1.3 会话过期处理
优先级:P0
需求:
- 任意业务接口返回
errcode: -14或等价会话过期信号时:- 标记账号为 expired。
- 不删除原始状态文件,避免误清历史。
- 输出需要重新扫码登录的错误。
- 重新登录成功后清理旧
botToken,保留消息历史和 alias。
验收标准:
- 模拟
-14时命令退出码为可识别错误码。 - 日志中包含账号 ID、接口名、错误类型,不包含 token 明文。
F2. 状态存储
F2.1 本地状态目录
优先级:P0
默认目录必须按平台选择,不能在代码中硬编码 / 或 ~/.wxb:
| 平台 | 默认状态目录 | P0 要求 |
|---|---|---|
| Windows | %LOCALAPPDATA%\wxb,如 C:\Users\<User>\AppData\Local\wxb |
优先适配和测试 |
| macOS | ~/Library/Application Support/wxb |
设计兼容,后续验证 |
| Linux | ${XDG_DATA_HOME:-~/.local/share}/wxb |
设计兼容,后续验证 |
可通过环境变量覆盖:
WX_STATE_DIR=...
目录结构:
{stateDir}/
├── config.json
├── aliases.json
├── inbox/
│ └── {accountId}/
└── accounts/
├── {accountId}.account.json
├── {accountId}.context-tokens.json
├── {accountId}.sync-buffer.json
├── {accountId}.seen-msg-ids.json
├── {accountId}.messages.jsonl
├── {accountId}.deferred-replies.json
└── {accountId}.lock
实现要求:
- 使用 Node
path、os和平台环境变量解析路径。 - 所有内部存储路径都必须支持 Windows 反斜杠和包含空格的路径。
- CLI JSON 输出中的附件路径使用绝对路径。
WX_STATE_DIR覆盖后必须解析为绝对路径。
F2.2 原子写入与并发保护
优先级:P0
需求:
- 所有 JSON 状态文件写入使用临时文件 + rename。
- 对同一账号状态写操作使用 lock file。
- lock 超时后失败,不无限等待。
- 任何写入失败不得留下半截 JSON。
验收标准:
- 并发执行
wxb fetch不会破坏 JSON 文件。 - 中断写入后状态文件仍可解析。
F2.3 敏感信息保护
优先级:P0
需求:
- token 只保存于账号状态文件,不自动写入
.env。 - 普通日志和错误输出必须脱敏。
- JSON 输出默认不包含
botToken。 - 明确避免将状态目录提交到 Git。
验收标准:
- 测试覆盖常见 token 字段脱敏。
wxb status --json不泄露 token。
F3. 消息接收
F3.1 一次性 fetch
优先级:P0
命令:
wxb fetch [--timeout <ms>] [--account <id>] [--json]
需求:
- 执行一次长轮询。
- 默认 timeout 使用
WX_FETCH_TIMEOUT_MS。 - 超时且无消息时返回空数组,不作为错误。
- 每次成功响应后保存新的
get_updates_buf。 - 收到消息时保存
context_token。 - 新消息必须先写入本地消息历史,再输出给 Agent。
- 支持 JSON 输出。
wxb fetch --json的返回结果是 Agent 的用户输入入口之一,Skill 必须明确这一点。
验收标准:
- 无消息时返回成功和
messages: []。 - 有消息时返回标准化消息。
- 再次 fetch 不重复返回已处理消息。
- 即使 Agent 处理失败,本地也能在消息历史中找到已拉取消息。
F3.2 消息标准化
优先级:P0
内部标准结构:
{
"id": "msg_id_or_message_id",
"accountId": "account_id",
"direction": "incoming",
"fromUserId": "user_id_xxx",
"toUserId": "bot_owner_user_id",
"createdAt": "2026-05-16T08:00:00.000Z",
"createdAtMs": 1778918400000,
"type": "text",
"text": "你好",
"items": [
{
"type": "text",
"text": "你好",
"supported": true
}
],
"attachments": [],
"contextTokenAvailable": true,
"contentAvailable": true,
"contentStored": true,
"raw": {}
}
规则:
raw可配置是否写入历史,默认不在 stdout 输出。contextToken不在默认 JSON 输出中展示,避免 Agent 日志泄露。id兼容msg_id和message_id。- 时间字段兼容秒级
timestamp和毫秒级create_time_ms。 type取值包括text、image、voice、file、video、mixed、unknown。- 非文本消息在 P0 至少输出类型、原始消息 ID、发送方、时间、是否可处理、媒体引用是否存在。
attachments用于 P1/P2 下载后的本地文件路径;P0 可以为空。
F3.3 去重与处理确认
优先级:P0
需求:
- 维护
seen-msg-ids,避免重复输出。 - P0 可以在 fetch 成功输出前标记 seen,但必须同时写入
messages.jsonl,保留可追溯历史。 - P1 考虑升级为 inbox pending/ack 模型,避免 Agent 收到消息但处理失败后的语义丢失。
验收标准:
- 同一 API 响应重复出现相同消息时只输出一次。
seenIds超过阈值时裁剪,保留最近记录。
F3.4 本地消息存储与 Agent 输入交付
优先级:P0
需求:
- 每条通过
wxb fetch拉取到的新消息都必须写入本地消息历史。 - 文本消息默认保存文本正文。
- 非文本消息 P0 默认保存元数据,不要求保存媒体正文。
- stdout JSON 是交付给 Agent 的即时输入;本地历史是恢复、去重、排障和上下文管理依据。
context_token必须写入 context token store,但默认不写入 stdout。- 后续可增加保留策略,例如最多保留 N 天、最多 N 条、是否保存正文。
推荐处理顺序:
- API 返回消息。
- 标准化消息。
- 保存
context_token。 - 写入
messages.jsonl。 - 更新
seen-msg-ids。 - 输出 JSON 给 Agent。
验收标准:
- 拉取到的消息在 stdout 和
messages.jsonl中可以用同一个id对应。 messages.jsonl中不保存明文context_token。- 文本消息可以从历史中恢复正文。
F3.5 非文本入站消息处理
优先级:P0/P1/P2
协议允许的用户消息类型包括文本、图片、语音、文件、视频。项目必须显式处理这些类型,不能静默丢弃。
P0 行为:
- 文本:完整支持,作为 Agent 可直接理解的用户输入。
- 图片:识别类型并保存元数据;stdout 标记为
supported: false或contentAvailable: false,提示 P1 才会下载/解密。 - 语音:识别类型并保存元数据;不做语音转写。
- 文件:识别类型并保存元数据;不下载正文。
- 视频:识别类型并保存元数据;不下载正文。
- 混合消息:逐项标准化,文本项可直接输出,媒体项输出元数据。
- 未知类型:保存 raw 摘要并输出
type: "unknown"。
P1 行为:
- 图片:下载、解密、保存到本地 inbox,并在
attachments中返回路径。 - 文件:下载、解密、保存到本地 inbox,并在
attachments中返回路径。 - 语音:下载、解密、保存原始 SILK 或协议返回格式;是否转码另行确认。
- 视频:下载、解密、保存到本地 inbox;生成缩略图可选。
P2 行为:
- 语音转文字。
- 视频关键帧抽取或摘要。
- 多模态 Agent 直接消费图片/视频附件。
验收标准:
- P0 收到图片、语音、文件、视频时不会报解析失败。
- P0 stdout 明确告诉 Agent:消息类型、是否有可直接消费内容、用户是否需要改用文本补充。
- P1 下载后的附件路径使用绝对路径,并受状态目录或 inbox 目录约束。
F4. 文本发送
F4.1 发送文本
优先级:P0
命令:
wxb send --user <userId|alias> --text <text> [--account <id>] [--json]
wxb send --user <userId|alias> --stdin [--account <id>] [--json]
需求:
- 根据 userId 或 alias 找到目标用户。
- 读取目标用户最近一次
context_token。 - 若没有
context_token,返回可诊断错误:NO_CONTEXT_TOKEN- 提示需要目标用户先发送一条微信消息。
- 每次发送生成新的
client_id。 - 发送成功后记录
messages.jsonl。
验收标准:
- 能向已缓存 context 的用户发送文本。
- 无 context 时不会静默失败。
- stdout JSON 可被 Agent 解析。
F4.2 长文本分片
优先级:P0
配置:
WX_MAX_CHUNK_CHARS=3800
WX_MIN_CHUNK_CHARS=20
WX_CHUNK_INTERVAL_MS=350
WX_MAX_DELIVERY_MESSAGES=10
规则:
- 文本长度小于等于
WX_MAX_CHUNK_CHARS时不分片。 - 优先在句号、叹号、问号、换行处分片。
- 其次在逗号、分号处分片。
- 最后按字符边界强制切割。
- 相邻短段可以合并。
- 单次调用最多发送
WX_MAX_DELIVERY_MESSAGES片,超过则失败并提示用户缩短内容或改发文件。
验收标准:
- 分片不超过最大字符数。
- 顺序发送。
- 某一片失败时返回已发送和失败详情。
F4.3 发送失败处理
优先级:P0/P1
P0:
- 5xx 和网络错误按指数退避重试。
-14返回重新登录错误。-2返回参数/context 错误,不盲目无限重试。
P1:
- context 失效或网络长期不可用时可入延迟补发队列。
- 延迟补发默认关闭,由配置开启。
F5. 状态查看
F5.1 连接状态
优先级:P0
命令:
wxb status [--account <id>] [--json]
需求:
- 显示账号是否存在。
- 显示最后登录时间。
- 显示最后 fetch 时间。
- 显示本地是否有
get_updates_buf。 - 显示本地缓存的 conversation 数量。
- 不主动发敏感业务请求,除非加
--check-remote。
验收标准:
- 不泄露 token。
- 状态缺失时给出下一步建议。
F6. WorkBuddy Skill
优先级:P0
需求:
- 输出 Skill 文档草案,说明什么时候使用
wxb。 - 明确 Agent 不直接处理
context_token。 - 明确
wxb fetch --json返回的入站消息就是用户通过微信给 Agent 的输入。 - 当 Agent 主动推送后需要等待用户反馈时,应调用
wxb fetch --json或提示用户稍后由任务流程拉取。 - Agent 读取到用户消息后,应把消息内容并入当前任务上下文,而不是只把它当成日志事件。
- 对非文本消息,Agent 必须检查
type、contentAvailable、supported、attachments:- 文本可直接作为用户输入。
- 已下载图片/文件附件可在支持的运行环境中继续处理。
- 暂不支持正文的语音/视频/图片应向用户说明限制,并请求补充文本或等待媒体处理能力。
- 明确主动推送原则:
- 只在任务完成、需要用户输入、定时提醒、用户明确要求时推送。
- 消息要短、自然、包含必要上下文。
- 避免频繁打扰。
- 明确 JSON 命令示例。
- 明确错误处理策略。
验收标准:
- Agent 能根据 Skill 正确调用
wxb fetch和wxb send。 - Agent 能把
wxb fetch返回的用户消息作为输入继续任务。 - Agent 遇到非文本消息时不会静默忽略。
- Skill 不包含 token 或本地敏感路径。
7. P1 功能需求草案
F7. 轻量保活与持续轮询
优先级:P1,若强稳定性要求较高可提升到 P0。
命令候选:
wxb poll [--account <id>] [--interval <ms>] [--jsonl]
wxb heartbeat [--account <id>] [--timeout <ms>]
需求:
wxb poll前台运行,不提供 HTTP 服务。- 持续调用
getupdates,收到消息写入 inbox/history。 - 适合交给系统计划任务、PM2、systemd、Windows Task Scheduler 管理。
- 退出时不破坏游标。
说明:
- 如果只使用按需 CLI,长期不调用时 token 过期风险更高。
- 若产品目标强调稳定主动推送,建议至少实现 heartbeat。
F8. 延迟补发队列
优先级:P1
需求:
- 发送失败且符合可恢复条件时入队。
- 队列项包含 userId、text、createdAt、retryCount、lastError。
- 每次收到该用户新入站消息后,只尝试补发该用户队列第一条。
- 补发成功后删除。
- 超过最大重试次数后标记 failed。
F9. Alias 管理
优先级:P1
命令:
wxb alias set <userId> <alias>
wxb alias get <userId>
wxb alias list
wxb alias remove <alias>
需求:
- alias 全局唯一。
- alias 不允许覆盖已有 userId,除非加
--force。 - 发送命令支持 userId 或 alias。
F10. 媒体消息
优先级:P1/P2
需求:
- P0 已完成媒体类型识别和元数据保存,不负责正文下载。
- 图片发送 P1。
- 文件发送 P1。
- 入站图片下载与解密 P1。
- 入站文件下载与解密 P1。
- 入站语音下载与保存 P1,转写 P2。
- 入站视频下载与保存 P1,摘要/关键帧分析 P2。
- 出站视频 P2。
- 出站语音 P2,除非协议 Spike 确认实现成本很低。
媒体功能必须在 Spike 校准 CDN 上传参数和 AES key 编码后开发。
F11. 数据保留与清理
优先级:P1
需求:
- 支持配置消息正文保留天数,避免
messages.jsonl长期膨胀。 - 支持配置附件保留天数,避免 inbox 占用过大。
- 支持配置每个账号最多保留消息条数。
- 提供手动清理命令:
wxb cleanup [--account <id>] [--dry-run] [--json]
- P1 的
wxb poll或 heartbeat 可以按天触发一次轻量清理。 - 清理时不得删除账号凭证、context token、alias 和仍在延迟补发队列中引用的内容。
- 清理前后输出摘要,包括删除消息条数、删除附件数量、释放空间估算。
建议默认值:
WX_MESSAGE_RETENTION_DAYS=90
WX_ATTACHMENT_RETENTION_DAYS=30
WX_MAX_HISTORY_MESSAGES=10000
WX_AUTO_CLEANUP=false
验收标准:
wxb cleanup --dry-run --json能输出将删除内容,但不实际删除。- 清理后历史文件仍是合法 JSONL。
- 清理不会破坏去重、context token 和账号状态。
8. 配置
P0 配置:
WX_BASE_URL=https://ilinkai.weixin.qq.com
WX_CDN_BASE_URL=https://novac2c.cdn.weixin.qq.com/c2c
WX_QR_BOT_TYPE=3
WX_CHANNEL_VERSION=2.0.0
WX_STATE_DIR= # 为空时使用平台默认状态目录
WX_FETCH_TIMEOUT_MS=15000
WX_LOGIN_POLL_TIMEOUT_MS=35000
WX_MIN_CHUNK_CHARS=20
WX_MAX_CHUNK_CHARS=3800
WX_CHUNK_INTERVAL_MS=350
WX_MAX_DELIVERY_MESSAGES=10
WX_LOG_LEVEL=info
WX_MESSAGE_RETENTION_DAYS=90
WX_ATTACHMENT_RETENTION_DAYS=30
WX_MAX_HISTORY_MESSAGES=10000
WX_AUTO_CLEANUP=false
说明:
.env只用于配置,不用于保存扫码得到的bot_token。WX_CHANNEL_VERSION默认值待 Spike 后最终确认。- 配置加载顺序:命令行参数 > 环境变量 >
.env> 默认值。 WX_STATE_DIR为空时根据当前平台选择默认状态目录。
9. CLI 输出契约
9.1 JSON 成功响应
{
"ok": true,
"command": "fetch",
"accountId": "account_id",
"data": {}
}
9.2 JSON 错误响应
{
"ok": false,
"command": "send",
"accountId": "account_id",
"error": {
"code": "NO_CONTEXT_TOKEN",
"message": "No context token for target user. Ask the user to send a WeChat message first.",
"retryable": false
}
}
9.3 建议错误码
| 错误码 | 含义 | 是否可重试 |
|---|---|---|
NO_ACCOUNT |
未找到账号 | 否 |
MULTIPLE_ACCOUNTS |
多账号但未指定 | 否 |
SESSION_EXPIRED |
bot_token 过期 |
否,需要重新登录 |
NO_CONTEXT_TOKEN |
目标用户无上下文 token | 否,需要用户先发消息 |
INVALID_CONTEXT_TOKEN |
context token 失效或参数错误 | 条件可重试 |
NETWORK_ERROR |
网络失败 | 是 |
SERVER_ERROR |
5xx | 是 |
STATE_LOCK_TIMEOUT |
状态锁超时 | 是 |
STATE_CORRUPTED |
本地状态文件损坏 | 否,需要人工处理 |
VALIDATION_ERROR |
参数错误 | 否 |
10. 数据结构
10.1 Account
{
"schemaVersion": 1,
"accountId": "ilink_bot_id_xxx",
"displayName": "optional_alias",
"botToken": "secret",
"baseUrl": "https://ilinkai.weixin.qq.com",
"ownerUserId": "ilink_user_id_xxx",
"channelVersion": "2.0.0",
"status": "active",
"savedAt": "2026-05-16T08:00:00.000Z",
"lastLoginAt": "2026-05-16T08:00:00.000Z",
"lastFetchAt": null,
"lastError": null
}
10.2 ContextTokens
{
"schemaVersion": 1,
"tokens": {
"user_id_xxx": {
"contextToken": "secret",
"updatedAt": "2026-05-16T08:00:00.000Z",
"sourceMessageId": "msg_id"
}
}
}
10.3 SyncBuffer
{
"schemaVersion": 1,
"buffer": "opaque_cursor_string",
"updatedAt": "2026-05-16T08:00:00.000Z"
}
10.4 SeenMessageIds
{
"schemaVersion": 1,
"seenIds": [
"msg_id_001"
],
"updatedAt": "2026-05-16T08:00:00.000Z"
}
10.5 MessageHistory JSONL
每行一个 JSON 对象,避免大数组频繁重写:
{"schemaVersion":1,"id":"msg_id_123","direction":"incoming","accountId":"account_id","fromUserId":"user_id","toUserId":"owner_user_id","type":"text","text":"你好","contentAvailable":true,"contentStored":true,"attachments":[],"createdAt":"2026-05-16T08:00:00.000Z"}
媒体消息示例:
{"schemaVersion":1,"id":"msg_id_456","direction":"incoming","accountId":"account_id","fromUserId":"user_id","toUserId":"owner_user_id","type":"image","text":null,"contentAvailable":false,"contentStored":false,"attachments":[],"items":[{"type":"image","supported":false,"mediaRefAvailable":true}],"createdAt":"2026-05-16T08:00:00.000Z"}
10.6 Attachment
P1 下载媒体后使用:
{
"id": "attachment_id",
"type": "image",
"mimeType": "image/jpeg",
"fileName": "msg_id_456.jpg",
"absolutePath": "F:/path/to/.wxb/inbox/account_id/msg_id_456.jpg",
"sizeBytes": 12345,
"sha256": "hex",
"createdAt": "2026-05-16T08:00:00.000Z"
}
11. 非功能需求
11.1 运行环境
- Node.js 18+。
- 优先使用 Node 内置
fetch、crypto、fs。 - P0 允许
dotenv。 - 是否使用官方 SDK 需确认;默认 P0 不依赖 SDK,直接封装 HTTP 协议。
11.2 系统平台适配
项目最终应支持 Windows、macOS 和 Linux。考虑当前开发与测试设备为 Windows,P0 优先适配 Windows,macOS/Linux 保持设计兼容并在后续阶段验证。
要求:
- CLI 入口必须能在 Windows PowerShell 中运行。
- 不依赖 Bash 专属语法作为核心运行路径。
- 路径处理必须使用 Node
pathAPI。 - 文件锁、原子写、rename、临时文件策略必须在 Windows 上可用。
- 命令示例优先给出跨平台写法;涉及 shell 差异时分别说明。
- 测试 fixture 和状态目录不得假设 POSIX 路径。
- 后续发布包应验证 npm bin shim 在 Windows/macOS/Linux 均可执行。
11.3 可靠性
- 网络错误和 5xx 使用指数退避。
- 状态文件必须原子写。
- 游标更新必须在 API 成功返回后进行。
- 每次 fetch 都要处理空响应。
- 不能因为某条消息解析失败导致整批消息丢失,失败项应记录为 unknown/raw。
11.4 安全性
- token 不进普通 stdout。
- token 不进普通日志。
- JSON 输出默认不包含
contextToken。 - 状态目录建议设置为仅当前用户可读写。
- 附件路径必须做路径校验,避免路径穿越。
11.5 可观测性
- 日志包含:
- 命令名
- accountId
- API 名称
- requestId/clientId
- 错误码
- 重试次数
- 日志不包含:
botTokencontextToken- 原始 Authorization header
12. 已确认产品与架构决策
以下决策已确认,可作为开发规划和测试方案的输入:
-
采用 Core Library + Thin CLI 架构。
当前需求面向 AI Agent,但未来可能有其他调用方式。核心能力必须封装为可复用 library,CLI 只是默认适配器。 -
P0 采用“文本完整处理 + 媒体识别元数据”边界。
图片、语音、文件、视频在 P0 不静默丢弃,但媒体正文下载、解密和进一步理解进入 P1/P2。 -
P0 默认无常驻进程。
wxb poll或 heartbeat 放 P1,用于提升 token 保活和消息接收稳定性。 -
token 只存本地状态目录,不写
.env。
.env只放配置项。 -
多账号完整管理放 P1。
P0 只保证底层数据结构和命令参数兼容多账号。 -
P0 不承诺严格可靠投递。
P0 做明确错误、历史记录和可诊断失败;P1 做延迟补发。 -
AI Agent 不接触底层 token 和 context token。
Agent 只处理 CLI 返回的用户消息、文件路径、错误码,并通过 CLI 发送回复或文件。 -
默认不依赖官方 SDK。
P0 直接 HTTP 封装;Spike 阶段可以参考 SDK 字段和媒体实现。 -
默认保存用户文本消息正文到本地历史。
用于去重、恢复、上下文追踪和排障。P1 必须加入保留时长、最大条数和定时清理,避免数据文件膨胀。 -
Agent 工作循环正式纳入需求。
AI Agent 的标准交互循环是:通过 CLI 接收用户微信消息 -> 将消息视作用户输入并产出回复 -> 通过 CLI 将回复传递给用户微信。Agent 也可以基于自动化任务主动发送消息,具体触发策略由 Agent 自身配置决定。 -
跨平台支持是最终目标,Windows 优先。
项目最终适配 Windows、macOS 和 Linux。P0 优先保证 Windows 环境可运行、可测试;macOS/Linux 保持路径、状态层和命令设计兼容。
13. 验收边界
P0 完成时应满足:
- 可以通过
wxb login完成扫码登录。 - 可以通过
wxb fetch --json获取新文本消息。 wxb fetch --json返回的消息已经写入本地历史。- Agent/Skill 明确把
wxb fetch返回的用户消息视作输入。 - 收到图片、语音、文件、视频时,P0 至少返回类型和元数据,不静默丢弃。
- 可以通过
wxb send --user <id> --text <text> --json回复已互动用户。 - 重启进程后仍可读取账号、游标和 context token。
- 长文本会自动分片。
- 无 context、token 过期、网络失败都有明确错误码。
- token 和 context token 不出现在日志和默认 JSON 输出中。
- 状态文件不会因并发调用轻易损坏。
- Windows PowerShell 环境下可以完成 P0 命令验收。
- WorkBuddy Skill 能指导 Agent 正确调用 P0 命令。
- P1 规划中包含消息历史和附件清理机制。
14. 下一步
详细开发分段规划和测试方案已经拆分为独立文档:
ilink-wechat-development-plan.mdilink-wechat-test-plan.md
后续进入实现前,建议先执行协议 Spike,校准 channel_version、消息字段、媒体 item type 和错误码行为。