乐于分享
好东西不私藏

从 2.5 小时到 5 分钟:OpenClaw 接入微信的“避坑”实录

从 2.5 小时到 5 分钟:OpenClaw 接入微信的“避坑”实录
最近想把 OpenClaw 接入微信,让 AI 助手能通过微信回复消息。我的第一反应是直接把网关跑在 Android 手机的 Termux 环境里,通过它提供 24 小时在线的服务能力。
原本的微信接入思路很直接:在 Termux 中启动本地 OpenClaw Gateway,通过 openclaw-weixin 插件挂载到网关上,实现消息收发。这套方案的前提是,需要一个稳定在线、可正常对外提供服务的 Gateway 实例。
但实际测试后很快发现此路不通。
  • openclaw-weixin本质是 OpenClaw 的一个 Channel 类型插件,必须挂载在 Gateway 上,通过 Gateway 的 HTTP JSON API 与微信后端交互,本身不具备独立运行能力。
  • 更关键的是,OpenClaw Gateway 虽然能在 Termux 中启动,但微信相关的底层依赖、设备环境限制以及风控策略,导致该组合在 Android 环境下无法正常工作。
最终,这条路线宣告失败。

最终选择的替代方案

于是改变思路:使用项目通过 HTTP 模式接入——直接让 weclaw 接管了微信消息的收发,OpenClaw 只负责 AI 推理部分。这条路径恰好规避了 Gateway 的依赖。
本来以为是个简单的配置活,结果硬生生折腾了2.5 小时
最讽刺的是:最后解决问题的方法,只需要改两行配置,5 分钟就能搞定。
但在此之前,我在错误的方向上狂奔了整整 2 个小时……

目标:让微信消息通过 weclaw 转发给 OpenClaw

先简单介绍一下技术栈:
  • OpenClaw:开源 AI 助手框架,支持多种聊天渠道。
  • weclaw:微信消息桥接工具,能把微信消息转发给 AI 代理。
  • 目标架构:微信 → weclaw → OpenClaw → AI 回复 → weclaw → 微信。
看起来很简单对吧?我也是这么想的。

第一阶段:信心满满的开始

第一步:CLI 模式 + Wrapper 脚本
weclaw 支持 CLI 模式接入第三方 Agent,原理是:
# weclaw 调用脚本,传入消息内容./openclaw-wrapper.sh -p "你好" --session-id wechat-user
我写了一个 wrapper 脚本,把参数转给 OpenClaw:
#!/bin/bashNODE_BIN=/data/data/com.termux/files/usr/bin/nodeENTRY_FILE=/data/data/com.termux/files/home/.npm-global/lib/node_modules/openclaw/dist/entry.js# 解析参数...# 调用 OpenClaw...OUTPUT=$($NODE_BIN "$ENTRY_FILE" "${ARGS[@]}" 2>&1)echo "$OUTPUT"
测试结果:❌ Error: openclaw returned empty response

第二阶段:越陷越深

尝试 2-10:在同一个坑里反复横跳
接下来的2 个小时,我陷入了「打地鼠」式的调试循环:

尝试

修改内容

结果

2

修复 Node 路径

❌ 模块找不到

3

重新安装 openclaw

❌ 还是空响应

4

修改参数解析逻辑

❌ 空响应

5

添加 --json 参数

❌ 空响应

6

添加 --no-color 禁用颜色

❌ 空响应

7

改用 printf 输出

❌ 空响应

8

调整 stdout/stderr 捕获

❌ 空响应

9

尝试 ACP 模式

❌ 无法 fork 进程

10

尝试 HTTP 模式

❌ 404 Not Found

典型的「现象层修复」陷阱:每次看到错误信息就针对那条信息修,修完再测,测完再改,始终在「如何让 wrapper 输出正确内容」这个层面打转。

第三阶段:关键转折点

一个被忽视的矛盾信号
在排查过程中,有一个细节在日志里非常显眼,但我始终没有认真对待:
# wrapper.log 显示:Output length10754JSON length9678Message: '你好。'Success, outputting message

脚本明明输出了 10KB 的内容,OpenClaw 也正常回复了!

但 weclaw 始终报告:openclaw returned empty response
正确的推断应该是
  1. 脚本没问题 ✅
  2. OpenClaw 没问题 ✅
  3. 问题在 weclaw 读取输出的那一侧
但我当时的反应是:继续修脚本……(现在回想起来简直不可思议)

第四阶段:跳出陷阱

其他 AI 的分析
我把完整的排查日志发给另一个 AI,它只用了 1 分钟就定位到了根源:

AI 的分析路径

  1. 查 weclaw 官方文档 → 发现 OpenClaw 的推荐接入模式是 HTTP不是 CLI
  1. 查 OpenClaw 文档 → 发现 /v1/chat/completions 端点默认关闭,需手动启用。
  1. 修改配置 → 重启服务 → 5 分钟解决。
核心问题
CLI 模式从一开始就走在了一条非官方推荐的路上。
HTTP 模式的 404 错误,只是因为端点没启用。

第五阶段:5 分钟解决方案

第一步:启用 OpenClaw Gateway 的 HTTP 端点
编辑 ~/.openclaw/openclaw.json:
{  "gateway": {    "services": {      "openai": {        "enabled": true,        "chatCompletions": {          "enabled": true        }      }    }  }}
重启 Gateway
验证端点

第二步:更新 weclaw 配置
编辑 ~/.weclaw/config.json:
{  "agent": {    "type": "http",    "url""http://localhost:3000/v1/chat/completions",    "headers": {      "Content-Type": "application/json"    }  }}
重启 weclaw

第三步:微信测试
发送「你好」→ 收到 AI 回复 ✅
从开始到结束,实际只需要 5 分钟。

复盘:为什么我花了 2.5 小时?

思维模式问题

问题

表现

正确做法

过度聚焦最近报错

看到empty response 就修脚本

跳出来看整体异常模式

未重视矛盾信号

脚本成功 vs weclaw 报空,未质疑方案本身

矛盾出现时立即停止当前方向

缺乏前置文档验证

直接动手写脚本

先查官方文档确认推荐方案

失败阈值未触发换向

同类错误出现 10+ 次

3 次失败后强制切换思路


5 条血泪教训

1️⃣ 矛盾信号优先于错误信息
当「子进程输出正常」和「调用方报告空响应」同时存在时,这是一个强烈信号:问题在两者之间的接口层,而不在任何一方内部。
正确反应:立即停止修改脚本或 weclaw,转而调查接口协议是否匹配。

2️⃣ 文档先行,动手在后
对于任何第三方工具的集成,第一步应该是查阅官方文档,确认推荐的接入方式。5 分钟的文档阅读可以避免数小时的无效调试。

3️⃣ 设定「失败次数上限」触发强制换向
同一类修复方向连续失败3 次后,应主动停下来重新审视:
当前的根本假设是否正确?
是否存在完全不同的解决路径?
我是不是在错误的方向上越走越远?

4️⃣ 区分「现象层」和「机制层」的报错
openclaw returned empty response 是现象,不是原因
在没有确认原因之前,不应该针对现象做修复。正确的做法是:
先用最小化测试隔离问题所在的层次。
直接 curl 测试 HTTP 端点。
手动运行脚本验证输出。

5️⃣ 「修好了」的判断要基于端到端验证
脚本手动运行成功 ≠ weclaw 调用成功每次声称「修好了」之前,必须完成完整的端到端测试(从微信发消息到收到回复),而不是只验证脚本的局部行为。

正确的排查路径(事后验证)

查 weclaw 文档 → 发现 OpenClaw 推荐 HTTP 模式。
查 OpenClaw 文档 → 发现端点需手动启用。
修改配置 → 启用 chatCompletions 端点。
重启服务 → curl 验证返回 200。
更新 weclaw 配置 → 切换到 HTTP 模式。

总耗时:5–10 分钟


写在最后

这次排查经历给我上了深刻的一课:

方向错了,努力白费。

当你在一个问题上花费超过 30 分钟还没有进展时,停下来问自己:
我是不是在错误的方向上?
我有没有查过官方文档?
有没有更简单的解决方案?
有时候,慢就是快。