# wx_opencode_bridge **Repository Path**: kongfu_yang/wx_opencode_bridge ## Basic Information - **Project Name**: wx_opencode_bridge - **Description**: 用微信随时随地与电脑上的OpenCode沟通 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 0 - **Created**: 2026-04-03 - **Last Updated**: 2026-04-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: AI ## README # WeChat ↔ OpenCode Bridge 微信与本地 OpenCode 的双向对话桥接服务。基于腾讯 iLink (ClawBot) 协议**纯原生 Node.js 实现**,无任何第三方 npm 依赖。 本项目完全由 OpenCode 驱动中国产大模型编写,大部份工作由 MiniMax-M2.5-Free 编写,MiMo-V2-Pro-Free 发布后有部份参与,临发布前2小时Qwen3.6-Plus-Free 发布了用了一点。 **个人玩具,欢迎使用及魔改,风险自担,务必请先阅读[非官方安全警告](docs/WECHAT-SECURITY.md),建议不要使用个人主力微信号玩耍** **欢迎提建议报 Bug,不接受 PR!** ## 功能特性 - 📱 通过微信扫描二维码登录 - 💬 微信消息实时转发到 OpenCode - 🔄 OpenCode 响应自动返回微信 - 📂 支持在微信中切换工作目录 - 👥 每个微信用户独立会话 - 💾 **会话持久化** - 重启后自动恢复 - 🔗 **会话分享** - 可与 TUI 共享会话,观察 TUI 操作 (实验性) - 🤖 **自动拉起** - 检测并自动启动 OpenCode 服务 - ✅ **零第三方依赖** - 直接实现 iLink 协议 - 🛡️ **安全防护** - 路径验证、CDN URL 校验 --- ## 快速开始 ### 前置要求 - Node.js >= 20 - 已安装 OpenCode CLI (`npm install -g opencode`) - 微信版本支持 ClawBot (iLink 协议) - “我的-设置-插件”里查看有没有ClawBot,此功能大约是2026-3-23发布的 ### 1. 克隆与配置 ```bash git clone wx-opencode-bridge cd wx-opencode-bridge cp .env.example .env ``` 编辑 `.env` 文件: ```bash OPENCODE_JAIL_DIR=/path/to/safe/root # 允许访问的根目录 (安全边界) OPENCODE_DIR=/path/to/safe/root/my_prj # 初始工作目录 OPENCODE_MODEL=opencode/minimax-m2.5-free # 使用的模型 OPENCODE_BIN=/path/to/opencode # opencode 二进制路径 LOG_LEVEL=info ``` ### 2. 扫码登录 ```bash node src/login.js ``` 终端会显示二维码 URL。用微信扫描二维码,并在手机上确认登录。 凭证保存在 `data/credentials.json`。 ### 3. 启动桥接服务 ```bash node src/index.js ``` 或使用 npm 脚本: ```bash npm start ``` --- ## 使用方法 ### 基础对话 直接在微信中给 ClawBot 发送消息,会转发给 OpenCode 处理。 ### 本地命令 | 命令 | 说明 | |-----|------| | `/help` | 显示帮助 | | `/reset` | 重置当前会话 | | `/new` | 新建会话 (同 /reset) | | `/session` | 显示当前会话 ID | | `/session ` | 切换到指定会话 | | `/sessions` | 列出所有可用会话 | | `/join ` | 加入指定会话 | | `/leave` | 离开当前会话 | | `/share` | 分享会话给 TUI | | `/unshare` | 停止分享 | | `/who` | 查看会话连接者 | | `/cat <文件> [-n] [-n,m]` | 读取文件内容 | | `/ls [目录]` | 列出目录内容 | | `/tree [目录]` | 树形显示目录结构,超大目录自动发文件 | | `/pwd` | 显示当前工作目录 | | `/models [-free]` | 查看可用模型(加-free筛选免费模型) | | `/model <名称>` | 切换模型 | | `/compact` | 压缩会话上下文 | | `/undo` | 撤销上一条消息 | | `/redo` | 恢复已撤销消息 | | `/init` | 初始化 AGENTS.md | | `/cleanup` | 清理内存中的会话栈(防内存泄漏) | ### 切换目录 ``` cd /path/to/project ``` 切换工作目录,限制在 jailhouse 目录内。`/cat`、`/ls` 等命令会基于当前目录解析相对路径。 工作目录设置会被持久化,bridge 重启后自动恢复。 ### 切换模型 ``` /model opencode/minimax-m2.5-free ``` 切换 AI 模型,使用 `provider/model` 格式。模型设置会被持久化,bridge 重启后自动恢复。 ``` /models /models -free ``` 查看可用模型列表(从 OpenCode 实时查询)。使用 `-free` 参数可仅显示免费模型(名称含 `-free` 或 `:free` 后缀)。 ### 发送文件/图片 直接发送图片或文件给机器人,会自动下载并保存到 `.wechat-media/` 目录,OpenCode 可以访问这些文件。 ### 会话分享 (与 TUI 共享) [实验性] > ⚠️ 由于 OpenCode Server 的 SSE 事件端点尚不稳定,当前使用轮询方式实现。 支持双向加入:WeChat 先或 TUI 先都可以。分享状态会被持久化,bridge 重启后自动恢复轮询。 #### 方式一:WeChat 先创建会话 ``` # 1. 在微信中发送消息创建会话 # 2. 分享给 TUI /share # 3. TUI 加入 (使用会话 ID) opencode attach http://localhost:4096 -s ses_xxxxx ``` #### 方式二:TUI 先创建会话 ``` # 1. TUI 先启动 opencode # 2. 在微信中查看可用会话 /sessions # 3. 加入 TUI 的会话 /join ses_xxxxx ``` #### 其他命令 | 命令 | 说明 | |------|------| | `/who` | 查看当前会话的连接者 | | `/leave` | 离开当前会话 | 分享后,TUI 的操作会实时推送到微信: - TUI 发送的消息 - AI 回复内容 - 工具调用 - 工具执行结果 使用 `/unshare` 停止分享,使用 `/who` 查看当前连接的 WeChat 客户端。 ### 会话管理 (Join/Leave 栈) Bridge 实现了简化的会话管理机制: - **主会话持久化**:只有主会话(通过发送消息创建的会话)会被持久化到存储 - **内存中的 Join/Leave 栈**:`/join` 和 `/leave` 操作在内存中管理会话栈,不持久化 - **重启恢复**:Bridge 重启时,内存中的会话栈会丢失,自动恢复到持久化的主会话 - **栈式回退**:连续多个 `/join` 后,`/leave` 会按加入顺序反向回退 - **内存泄漏防护**:使用 `/cleanup` 命令手动清理会话栈 #### 示例流程: ``` # 1. 发送消息创建主会话 (持久化) 你好 # 2. 加入其他会话 (内存栈) /join ses_aaa /join ses_bbb /join ses_ccc # 3. 离开会话 (栈式回退) /leave # 回到 ses_bbb /leave # 回到 ses_aaa /leave # 回到主会话 # 4. 重启 Bridge 后 # 内存栈丢失,自动恢复到主会话 # 可使用 /cleanup 清理残留栈 ``` #### 内存管理: - 会话栈仅在内存中,Bridge 重启后丢失 - 使用 `/cleanup` 命令手动清理特定用户的会话栈 - 长时间不活动的用户会话栈会被自动清理 (1小时 TTL) --- ## 配置说明 | 环境变量 | 说明 | 默认值 | |---------|------|-------| | `DATA_DIR` | 数据存储目录 | `./data` | | `OPENCODE_JAIL_DIR` | 允许访问的根目录 (安全边界) | 当前目录 | | `OPENCODE_DIR` | 初始工作目录 | 等于 JAIL_DIR | | `OPENCODE_MODEL` | 使用的模型 | 系统默认 | | `OPENCODE_AGENT` | 使用的 agent | 系统默认 | | `OPENCODE_BIN` | opencode 二进制路径 | `opencode` | | `OPENCODE_SERVER_PORT` | OpenCode HTTP 服务端口 | `4096` | | `OPENCODE_SERVER_HOSTNAME` | OpenCode HTTP 服务地址 | `127.0.0.1` | | `ILINK_BOT_TYPE` | iLink Bot 类型 | `3` | | `LOG_LEVEL` | 日志级别 (debug/verbose/info/warn/error) | `info` | --- ## 系统架构 ``` ┌──────────────────────────────────────────────────────────────┐ │ WeChat (ClawBot) │ │ ilinkai.weixin.qq.com │ └──────────────────────┬───────────────────────────────────────┘ │ iLink Protocol (HTTPS/JSON) ▼ ┌──────────────────────────────────────────────────────────────┐ │ wx-opencode-bridge │ ├──────────────────────────┬───────────────────────────────────┤ │ ilink-api.js │ iLink 协议 HTTP 请求封装 │ │ ilink-login.js │ QR 码登录、凭证管理 │ │ ilink-bot.js │ 消息轮询、消息处理、防限速策略 │ │ storage.js │ 会话/模型/工作目录持久化 │ │ context_token │ 用户会话上下文持久化 │ │ opencode.js │ OpenCode HTTP API 客户端 │ │ opencode-events.js │ 轮询监听会话消息 (会话分享) │ │ cdn.js │ 微信 CDN 媒体上传下载 (AES-128) │ │ bridge-commands.js │ Bridge 本地命令 (/cat, /ls, cd) │ │ opencode-commands.js │ OpenCode 命令 (session, models) │ │ index.js │ 主程序,消息路由与模块整合 │ └──────────────────────┬───────────────────────────────────────┘ │ HTTP API (REST) ▼ ┌──────────────────────────────────────────────────────────────┐ │ OpenCode Server │ │ (本地大模型对话服务) │ └──────────────────────────────────────────────────────────────┘ ``` ### 核心模块 | 模块 | 职责 | |-----|------| | `ilink-api.js` | iLink 协议 HTTP 请求封装 | | `ilink-login.js` | QR 码登录、凭证管理 | | `ilink-bot.js` | 消息轮询、消息处理、防限速 | | `storage.js` | 会话、模型、工作目录、get_updates_buf 持久化 | | `opencode.js` | OpenCode HTTP API 客户端 | | `opencode-events.js` | 轮询监听会话消息 (会话分享功能) | | `cdn.js` | 微信 CDN 媒体上传下载 (AES-128) | | `bridge-commands.js` | Bridge 本地命令 (/cat, /ls, /tree, cd) | | `opencode-commands.js` | OpenCode 命令 (session, share, models, compact 等) | | `index.js` | 主程序,消息路由与模块整合 | ### 模块依赖关系 ``` index.js ├── ilink-login.js (登录) ├── ilink-bot.js (消息处理) │ └── storage.js (持久化) │ └── ilink-api.js (协议) │ └── cdn.js (媒体) ├── opencode.js (执行命令) ├── bridge-commands.js (本地命令: /cat, /ls, /tree, cd) └── opencode-commands.js (OpenCode 命令: session, share, models 等) ``` --- ## 设计与实现 ### iLink 协议实现 参考 `@tencent-weixin/openclaw-weixin` 官方插件重新实现,直接调用以下 API: | API | 方法 | 用途 | |-----|------|------| | `/ilink/bot/get_bot_qrcode` | GET | 获取登录二维码 | | `/ilink/bot/get_qrcode_status` | GET | 轮询扫码状态 | | `/ilink/bot/getupdates` | POST | 长轮询消息 (35s) | | `/ilink/bot/sendmessage` | POST | 发送消息 | | `/ilink/bot/getconfig` | POST | 获取 typing_ticket | | `/ilink/bot/sendtyping` | POST | 发送 typing 状态 | #### 认证机制 所有 API 请求需要以下 Headers: ```javascript { 'Content-Type': 'application/json', 'AuthorizationType': 'ilink_bot_token', 'Authorization': 'Bearer ', 'X-WECHAT-UIN': '', 'iLink-App-ClientVersion': '131074', } ``` #### 消息格式 发送消息时必须使用正确的格式: ```javascript { from_user_id: '', // 必须为空字符串 to_user_id: '', client_id: randomUUID(), // 每次消息不同 message_type: 2, message_state: 2, item_list: [ { type: 1, text_item: { text: 'Hello' } } ] } ``` ### OpenCode 集成 使用 OpenCode 的 HTTP API 进行通信: 1. **检测已有服务**:启动时检查 `http://:/global/health` 2. **智能启动**:如果无运行中的服务则启动一个 3. **HTTP API 调用**: - `POST /session` - 创建会话 - `POST /session/:id/message` - 发送消息并等待响应 4. **退出清理**:如果服务由本程序启动,退出时自动关闭 #### 消息格式 ```javascript // 发送消息 POST /session/{sessionId}/message { "parts": [{ "type": "text", "text": "用户消息" }], "model": { "providerID": "opencode", "modelID": "minimax-m2.5-free" } } ``` ### 会话持久化 实现三层持久化确保服务重启后不丢失状态: #### 1. get_updates_buf (`data/.sync.json`) 长轮询同步缓冲区,用于消息去重和断点续传: - 每次 poll 后保存 - 启动时恢复,避免漏消息 #### 2. context_token (`data/.context-tokens.json`) 每个用户的会话上下文,发送消息时必须携带: - 结构: `{ "userId": "token", ... }` - 每次收到消息时更新 - 发送消息时取出对应用户的 token #### 3. credentials (`data/credentials.json`) 登录凭证: ```json { "botToken": "xxx", "botId": "xxx@im.bot", "baseUrl": "https://ilinkai.weixin.qq.com", "userId": "xxx@im.wechat" } ``` ### 安全防护 #### 1. 路径验证 (Jailhouse) 用户只能访问 `OPENCODE_JAIL_DIR` 目录下的文件,防止目录遍历攻击。 #### 2. CDN URL 校验 下载媒体前验证 URL 格式,防止路径遍历攻击。 #### 3. 文件名安全 保存媒体文件时,过滤文件名防止路径遍历。 #### 4. 用户可手动启用沙盒 由于 Bridge 无法对外部启动的进程应用沙盒,用户可手动用沙盒工具启动 OpenCode: ```bash # Linux (需要 root) sudo unshare -n -m --mount --pid --ipc -r opencode serve --port 4096 # macOS sandbox-exec opencode serve --port 4096 ``` ### 防微信限速策略 #### 1. 速率限制 - 每分钟最多 20 条消息 - 消息间隔至少 1 秒 #### 2. 指数退避 连续失败后使用指数退避: - 初始延迟: 5 秒 - 最大延迟: 5 分钟 - 最大重试次数: 3 次 #### 3. Typing 状态 发送消息前显示 "对方正在输入...",提供更好的用户体验。 --- ## 消息流程 ``` 1. 微信用户发送消息 ↓ 2. getUpdates 长轮询返回消息 (35s timeout) ↓ 3. 解析消息 item_list,提取 text/image/voice 等 ↓ 4. 保存 context_token 到持久化存储 ↓ 5. 显示 "对方正在输入..." (sendTyping) ↓ 6. 调用 OpenCode HTTP API (POST /session/:id/message) ↓ 7. 获取回复内容 ↓ 8. 停止 typing,调用 sendMessage 返回回复 ↓ 9. 循环回到步骤 2 ``` --- ## 错误处理 | 错误码 | 含义 | 处理方式 | |-------|------|---------| | -14 | Session 过期 | 提示重新登录 | | -2 | 参数错误 | 记录日志 | | HTTP 4xx | 认证失败 | 检查 token | | HTTP 5xx | 服务器错误 | 等待重试 | --- ## 文件结构 ``` wx-opencode-bridge/ ├── src/ │ ├── config.js # 配置管理 (加载 .env) │ ├── logger.js # 5级日志 (debug, verbose, info, warn, error) │ ├── ilink-api.js # iLink 协议 HTTP 请求封装 │ ├── ilink-login.js # QR 码登录流程 │ ├── ilink-bot.js # 消息轮询、发送、防限速 │ ├── storage.js # 会话持久化 │ ├── cdn.js # 微信 CDN 媒体上传下载 (AES-128) │ ├── opencode.js # OpenCode HTTP API 客户端 │ ├── opencode-events.js # 轮询监听会话消息 (会话分享) │ ├── bridge-commands.js # Bridge 本地命令 (/cat, /ls, /tree, cd) │ ├── opencode-commands.js # OpenCode 命令 (session, share, models 等) │ ├── index.js # 主入口,消息路由 │ └── login.js # 登录工具 ├── data/ # 数据存储 │ ├── credentials.json # 登录凭证 │ ├── default.sync.json # get_updates_buf │ └── default.context-tokens.json # context tokens ├── .env # 环境配置 ├── .env.example # 配置示例 ├── package.json # 无依赖! ├── README.md # 本文档 └── tests/ # 回归测试 ├── mocks/ # Mock 服务器 (iLink, OpenCode, Fixture) ├── fixtures/ # 真实录制数据 (已脱敏) ├── unit/ # 单元测试 ├── integration/ # 集成测试 ├── security/ # 安全测试 └── regression_design.md # 测试设计文档 ``` --- ## 常见问题 ### Q: 登录后提示 "Session expired" A: 登录凭证已过期。运行 `node src/login.js` 重新扫码登录。 ### Q: 消息发送失败 A: 检查网络连接,确保可以访问 `ilinkai.weixin.qq.com`。 ### Q: OpenCode 模型不可用 A: 确保 `OPENCODE_MODEL` 配置为有效的模型名称。可用 `opencode models` 查看可用模型。 ### Q: 如何查看日志? A: 修改 `.env` 中的 `LOG_LEVEL` 为 `debug` 或 `verbose` 获取更多日志信息。 --- ## 许可证 本项目基于 Apache License 2.0 开源。详见 [LICENSE](LICENSE) 文件。 --- ## 注意事项 1. 需要 Node.js >= 20 2. 需要安装 opencode CLI 3. 微信版本需要支持 ClawBot 4. 首次登录需要手机确认 5. **无任何 npm 依赖** - 纯 Node.js 内置模块实现 --- ## 参考 - [腾讯官方 @tencent-weixin/openclaw-weixin](https://www.npmjs.com/package/@tencent-weixin/openclaw-weixin) - [OpenCode 官方文档](https://open-code.ai/docs) - [iLink 协议文档](https://www.wechatbot.dev/en/protocol)