wechat-clawbot
v0.9.1
Published
Connect DeepSeek Harness to WeChat via the official WeChat ClawBot (Tencent iLink) bridge — a DSH plugin bundle.
Maintainers
Readme
wechat-clawbot
把 DeepSeek Harness(DSH)profile 通过微信官方 微信ClawBot(腾讯 iLink API)接入你的微信。绑定后,你可以在外面用微信给 DSH agent 发消息——让它查看电脑上的文件、帮你编辑、执行命令——agent 会把结果(包括权限确认问题)直接回发到微信对话里。
状态:v0.5.0 — 文本消息 + agent → 微信 文件/图片发送(
send_wechat_file,发原图)+ 微信图片/文件入站(解密落盘、可识图)+ 引用消息解析 + 识图前自动预览加速 + 微信对话规范 prompt(先确认、结尾一次归纳)。群聊暂不支持。
工作原理
手机微信 ──► 腾讯 iLink 云 ──► 本插件(长轮询监控)
◄──────────────────────── (文本回复、审批提问)
│
▼
一个固定的 DSH agent 会话("wechat-main")
(持久化、自动压缩,与普通 DSH 会话相同)- 协议客户端复用官方 MIT 许可的
@tencent-weixin/openclaw-weixin包(见NOTICE),只把 OpenClaw 集成层替换成了 DeepSeek Harness 集成。 - 微信对话映射到一个固定会话(默认
wechat-main):上下文共享、重启后历史保留、 自动上下文压缩控制 token 消耗。 - 微信会话的审批策略强制为
ask:权限请求(文件访问、命令执行、沙箱升级)会转发到 微信,你回复同意/拒绝(或yes/no)即可。 - 文件/图片发送:微信 agent 自带
send_wechat_file工具——直接说 (例如"把 README.md 发给我"或"生成一张图表发给我")。文件走腾讯 CDN + 官方 AES-128-ECB 加密上传链路;支持图片、PDF、Office 文档、压缩包等。 - 插件运行在 profile 进程内部:只要 profile 在运行,桥接就在线。连接方式为手动扫码
(每次绑定一次即可),token 存在
$DSH_HOME/clawbot,重启后自动复用。
环境要求
- Node.js >= 22
- 一个 DSH profile(如
webprofile),已配置模型 provider - 手机微信,且可用官方微信ClawBot插件(设置 → 插件;首次扫码时微信可能提示升级版本)
安装
# 1. 把插件装进 profile(需要 pnpm)
dsh plugin --profile web add wechat-clawbot
# 2. 重启 profile
# (先停掉 `dsh web`,再重新启动)
dsh web插件默认随 profile 启动(autoStart: true)。如需改配置,在 profile 的
cordis.patch.yml 里加一个 clawbot 行:
- id: clawbot
config:
allowFrom: [] # 微信用户 id 白名单;[] = 仅绑定者本人
sessionId: wechat-main # 微信消息对应的固定 DSH 会话
forwardQuestions: false
approvalTimeoutMs: 0 # 0 = 审批等待无限期
logLevel: info连接(一次性,手动)
# 在任意目录执行(状态目录全局共享):
clawbot login终端会打印二维码,用 微信 → 扫一扫 扫描并确认。之后:
- 微信通讯录出现新联系人 「微信ClawBot」,打开即可对话。
- 正在运行的 profile 会在 1 秒内自动发现凭据并启动监控——无需重启。
其他命令:
clawbot status # 查看当前绑定账号
clawbot logout # 解除绑定并删除凭据环境变量:
| 变量 | 默认值 | 含义 |
|---|---|---|
| CLAWBOT_STATE_DIR | $DSH_HOME/clawbot | 凭据/状态目录 |
| CLAWBOT_LOG_LEVEL | info | debug / info / warn / error |
安全
- 白名单:默认只有扫码绑定者本人能向 agent 发消息;如需加人,用
allowFrom配置(用户 id 见日志或clawbot status)。 - 审批:微信会话审批策略为
ask,敏感操作仍需你在微信里明确回复。其他会话 (如本机 Web GUI)保持各自的策略。 - 陌生人的消息会被静默忽略。
配置项
| 键 | 类型 | 默认 | 含义 |
|---|---|---|---|
| autoStart | boolean | true | 启动时若有已绑定账号则自动开始监控 |
| allowFrom | string[] | [] | 允许发消息的用户 id;空 = 仅绑定者 |
| sessionId | string | wechat-main | 微信流量对应的固定 DSH 会话 |
| cwd | string | process.cwd() | 新建会话的工作目录 |
| forwardQuestions | boolean | false | 把 ask_user_question/plan review 转发到微信(见下) |
| approvalTimeoutMs | number | 0 | 审批等待超时;0 = 无限期 |
| botAgent | string | DSH-ClawBot/0.1.0 … | 上报给 iLink 的 bot_agent |
| compressImages | boolean | true | 大图发送前自动压缩(macOS sips) |
| maxImageEdge | number | 2048 | 压缩图长边像素上限 |
| imageQuality | number | 80 | 压缩 JPEG 质量 |
| compressThresholdBytes | number | 1048576 | 超过此大小才压缩 |
| apiBaseUrl | string | https://ilinkai.weixin.qq.com | iLink API 地址(测试用) |
| logLevel | debug\|info\|warn\|error | info | 协议层日志级别 |
forwardQuestions:每个 DSH 上下文只能有一个userQuestionsprovider。 Web UI 在浏览器连接时会注册自己的 provider,所以此选项只在没有 Web provider 的部署中生效。审批转发(approval/request)与它无关,对微信会话始终开启。
Claude 桥(双向)
两个方向,机制不同、失效方式也不同。完整说明见 README.md 的 「The Claude bridge」,这里只放最容易踩的几条。
出站 —— Claude Code 驱动 DSH:/plugins/clawbot/mcp/{sessions,read,send,notify,status},
由 dsh-mcp-bridge(一个 MCP server,不是 DSH 插件)调用。
notify没有收件人参数,只发account.userId(扫码绑定的那个 id)—— 「发给别人」在结构上无法表达。send到不了微信。注入的消息来源标clawbot-mcp,会话监听把非schedule的插件轮次一律当 GUI-only。改这个字符串就破掉隔离。- 每个路由都要 bearer token(
<state>/mcp-token,0600)。只有status不要, 因为浏览器页面存不住密钥——所以它只报 token 的路径,绝不报值。 mcpBridge: false让四个路由都返回 403,路由仍注册着。标志位每请求现读, 所以开关两个方向都不用重启。
入站 —— DSH 看见并驱动 Claude Code:三个工具
list_claude_sessions / read_claude_session / send_to_claude_session。
- 列表和读取直接走文件(
~/.claude/sessions/*.json+projects/*/<id>.jsonl), 这是稳定的那一半。 - 投递没有官方 CLI,真机制是
/tmp/cc-socks/<pid>.sock上的peerProtocol 1。 这里不逆它,而是拉起一个短命的claude -p … --allowed-tools ListAgents,SendMessage --model haiku, 让 Claude Code 用自己的实现去走那个 socket。 - 会话名会漂移(实测一天内
harvard-96→harvard-35→harvard-ef)。 所以每次发送都重新解析,从不缓存;对不上就报错,不猜。 - 运行态和队列必须显式说出来,哪怕是零。 少了这个字段,模型会编一句 「都没有正在运行的任务」——字段缺失在模型眼里不读作「未知」,读作「没有」。
- 队列有三种操作:
enqueue/dequeue/remove(按内容撤回)。只数前两个 会把撤回的算成在排(实测 15/9/6,真实待处理是 0)。 - transcript 里的时间是 UTC。用
toLocaleTimeString,别切 ISO 字符串—— 切出来会把 16:33 的消息报成 20:33。
已知限制
- 语音消息需要 silk 转码,暂不支持。
- 队列里正在等的那条消息看不到(transcript 里不记录未投递项)。要拿到活的 答案只能讲 peer socket,本插件刻意不讲。
- 一个状态目录绑定一个微信账号(只监控第一个账号)。
- 不支持群聊(官方渠道行为)。
- 只有 DSH profile 进程运行时桥接才在线。需要 7×24 小时可用的话,请保持
dsh web常驻(如 launchd / systemd 服务)。
开发
npm install
npm run typecheck # tsc --noEmit
npm run build # tsc → lib/,并把 src/client.js 拷成 lib/client.js
node test/regression.mjs # 55 项离线检查
node test/claude-peer.mjs # 29 项,真读 ~/.claude
node scripts/bot-sim.mjs # 用真实提示词跑回复风格,不碰真微信两个测试套件都是离线的:不调模型、不联网、不碰微信,失败返回非零,可以用来 把关构建。
加了新的「热」配置项时注意:regression.mjs 会 grep 源文件里有没有
config.X 这样的读法。只在 apply() 里读一次的字段不是热的,不管
HOT_FIELDS 里怎么写——这条检查就是拦这个的。新增会读设置的源文件,记得同时
加进那个文件列表。
claude-peer.mjs 里队列记账、空闲判断和时区都是对着合成的 transcript 断言的
(已知答案),不依赖机器此刻在干什么。send_to_claude_session 只注册、从不
调用——它会拉起进程并把消息投进一个真会话。
移植的 iLink 协议层在 src/ilink/(MIT,腾讯);DSH 集成代码为
src/bridge.ts、src/inbound.ts、src/approvals.ts、src/monitor.ts、
src/questions.ts、src/index.ts。
License
MIT。移植的 iLink 客户端为 MIT © Tencent——见 NOTICE。
