@tencent-weixin/openclaw-weixin v2.1.10 → v2.4.3 更新分析
> 2026-05-14 · 基于 npm 包代码对比
版本路径
npm 序列:2.1.10 → 2.3.1 → 2.4.1 → 2.4.2 → 2.4.3
中间无 2.2.x、2.3.0 分支。注意 GitHub git tag 只到 v2.1.7(CHANGELOG 同步停止),后续版本仅发布到 npm,无对应 git tag 或 CHANGELOG 记录。本次分析直接从 npm 下载各版本 source tarball 对比得出。
一、核心架构变化:全局 Runtime → Gateway 注入
这是 v2.1.10 → v2.4.3 最根本的架构变化。
对比
| 维度 | v2.1.10 | v2.4.3 |
|---|---|---|
| **全局状态** | `src/runtime.ts` 存储全局 `PluginRuntime` 引用 | **`runtime.ts` 整个文件删除** |
| **获取方式** | monitor 启动时调用 `waitForWeixinRuntime()` → 从全局 store 读取 | `ctx.channelRuntime` 由 gateway 在每个 task scope 直接注入 |
| **竞态风险** | `import` 模块初始化时可能触发宿主 `ensureContextWindowCacheLoaded` 副作用,导致 `loadOpenClawPlugins` 重入 | gateway 按需提供,无重入风险 |
为什么重要
v2.1.7 已经修过一次重入问题(lazy-load monitor)。但那次只是治标——把 monitorWeixinProvider 改成 await import() 懒加载,推迟了加载时机,但全局 runtime store 仍然存在。v2.4.2 彻底去掉全局 store,改为 gateway 通过 ChannelGatewayContext.channelRuntime 在每个 task 生命周期注入。这是更彻底的架构解耦。
变化波及的文件:
index.ts:删除import { setWeixinRuntime }和setWeixinRuntime(api.runtime)调用src/monitor/monitor.ts:opts 直接要求channelRuntime参数,不再内部waitForWeixinRuntime()src/channel.ts:新增ctx.channelRuntime空值校验,缺失时主动抛错并设running: falsesrc/auth/accounts.ts:删除import { getWeixinRuntime }引用src/runtime.ts:整文件删除(v2.4.2+)
二、登录流程大改
登录是变化最大的功能模块。
2.1 扫码 API 升级
v2.1.10: GET ilink/bot/get_bot_qrcode
v2.4.3: POST ilink/bot/get_bot_qrcode
请求体中携带 local_token_list(最近 10 个 bot token)
新增 getLocalBotTokenList() 函数:遍历本地已登录账号,收集最多 10 个 bot token 随请求发送。服务端据此可以判断"这个 OpenClaw 实例是否已经绑定过该 bot"。
2.2 新增登录状态码
| 状态 | 说明 | 触发场景 | 处理方式 |
|---|---|---|---|
| `need_verifycode` | 需要配对码 | 安全策略要求二次验证 | 从 stdin 读取用户输入,暂存 `pendingVerifyCode`,下次轮询携带 `verify_code` 参数 |
| `verify_code_blocked` | 配对码输入被锁定 | 多次输入错误 | 自动刷新二维码,超过重试上限后终止并提示「稍后再试」 |
| `binded_redirect` | 已绑定 | 该 bot 已被此 OpenClaw 绑定过 | 直接返回 `alreadyConnected: true`,不重复写入账号数据,不报错 |
2.3 新增函数
| 函数 | 作用 |
|---|---|
| `displayQRCode()` | qrcode-terminal 展示逻辑提取为独立函数,可被 `loginWithQrStart` 和 `startAccount` 共用 |
| `readVerifyCodeFromStdin()` | 从 stdin 读取一行用户输入作为配对码,超时 / 回车确认 |
| `getLocalBotTokenList()` | 收集本地已登录账号的 bot token 列表,最多 10 个 |
2.4 登录交互优化
| 文本 | v2.1.10 | v2.4.3 |
|---|---|---|
| 启动提示 | `正在启动微信扫码登录...` | `正在启动...` |
| 扫码提示 | `使用微信扫描以下二维码,以完成连接:` | `用手机微信扫描以下二维码,以继续连接:` |
| 等待提示 | `等待连接结果...` | `正在等待操作...` |
| 成功提示 | `✅ 与微信连接成功!` | `已将此 OpenClaw 连接到微信。` |
2.5 loginWithQrStart 接口变化
v2.1.10: loginWithQrStart({ accountId, force, timeoutMs, verbose })
v2.4.3: loginWithQrStart({ accountId, force, verbose })
timeoutMs 参数被移除。
QR 码刷新逻辑也做了调整:当 verify_code_blocked 时需要刷新二维码,提取为独立的 refreshQRCode() 函数,包含重试上限(MAX_QR_REFRESH_COUNT)。
三、API 层重构
3.1 apiPostFetch 对外导出
| 变更 | v2.1.10 | v2.4.3 |
|---|---|---|
| 导出 | `private` | `export` |
| timeoutMs | **必填** | **可选** |
| Content-Length | 根据 `body` 手动计算 | **移除**(由 HTTP 层自动处理) |
apiPostFetch 现在可以被外部调用——login-qr 改用 POST 请求时正是用了它。
3.2 package.json 查找路径改进
// v2.1.10: 固定 2 层向上
const dir = path.dirname(fileURLToPath(import.meta.url));
const pkgPath = path.resolve(dir, "..", "..", "package.json");
// v2.4.3: 递归向上搜索,直到找到属于插件的 package.json
readPackageJsonFromDir(startDir: string) // 从 startDir 开始逐层向上
isOwnPackageJson() 判断依据:检查 ilink_appid 字段或 name 包含 openclaw-weixin。这使插件在 dev(TS 源码 src/ 下)和 publish(编译输出 dist/src/ 下)两种目录结构中都能正确找到 package.json。
3.3 bot_agent 字段
buildBaseInfo() 现在在每个 API 请求中携带 bot_agent:
{
channel_version: CHANNEL_VERSION,
bot_agent: sanitizeBotAgent(loadConfigBotAgent()), // 新增
}
- 配置源:
channels.openclaw-weixin.botAgent(从 openclaw.json 读取) - 默认值:
"OpenClaw" - 格式校验:严格的 UA 格式(
Name/Version,可选(comment)) - 长度上限:256 bytes,超长时截断尾部 token
- 用途:服务端监控聚合、调用方识别,不参与鉴权或路由
3.4 buildHeaders 简化
移除了手动计算的 Content-Length 头——HTTP 层的 fetch() 会自动处理,手动指定反而可能在某些场景下不一致。
四、构建与依赖
| 变更 | v2.1.10 | v2.4.3 |
|---|---|---|
| **package.json** | `extensions` 仅 TS | 新增 `runtimeExtensions: ['./dist/index.js']` |
| **编译输出** | 无 dist/ | 有 dist/(tsc 编译产物) |
| **zod 依赖** | `4.3.6`(精确锁定) | `^4.3.6`(宽松匹配) |
| **其他依赖** | `[email protected]` | 不变 |
runtimeExtensions 是 v2.4.3 新增的字段,用于在 runtime 加载时让 gateway 直接加载编译后的 JS 入口。
五、整体评估
版本演进脉络
| 版本 | 主要变化 |
|---|---|
| v2.1.8 - v2.1.10 | 微小修复,无架构变化 |
| **v2.3.1** | 登录流程初步重构(pairing code 支持) |
| v2.4.1 | 代码结构优化 |
| **v2.4.2** | runtime.ts 删除 → gateway 注入 channelRuntime |
| **v2.4.3** | 登录流程全面升级(POST + local_token_list + 状态码扩展)+ 编译产物输出 |
质量问题
Changlog 自 v2.1.7 后停止更新。v2.1.10 → v2.4.3 之间所有变化没有 CHANGELOG 记录,GitHub 仓库也没有对应 tag。完全靠 npm tarball 反推代码变化。
风险提示
1. runtime.ts 删除:任何依赖 getWeixinRuntime() / waitForWeixinRuntime() 的外部代码(如果有)会中断
2. loginWithQrStart 签名变化:移除 timeoutMs 参数,可能影响自动化工具链
3. API 请求增加 body:get_bot_qrcode 从 GET 改为 POST,网关 / 代理层面需确认无拦截