通过wechatapi对接openclaw终于接好了
这篇文章更多是我当前阶段的技术总结。把微信入口层做得更稳定把微信 / 企微这类入口能力逐渐抽象成可复用网关如果你也在做类似方向,欢迎交流。我这次的底层接入验证主要基于这类能力做的,后面如果我继续往下打磨,应该也会围绕“入口层 + 场景方案”这个方向继续展开。
技术支持 wechatapi.net
最近我一直在做一个比较实际的方向:
把微信接成 OpenClaw 的一个真实入口。
不是做一个简单的“消息转发脚本”,而是希望做到下面这种完整链路:
- 用户在微信里发消息
- 本地网关接收回调
- 根据私聊 / 群聊 / 会话类型做路由
- 调用 OpenClaw
- 再把结果发回微信
这个项目做到后面,我越来越觉得:
真正有价值的不是“机器人脚本”,而是“入口层”。
一、为什么我会做这个方向
现在很多 AI Agent、工作流、自动化平台,能力已经很强了:
- 大模型调用
- 工具执行
- 工作流编排
- 任务状态管理
但这些东西最后经常卡在一个问题上:
用户到底从哪里进入?
如果只是网页入口,那适合部分场景。
但对于很多国内真实业务来说,微信仍然是最高频、最自然的入口之一。
所以我想验证一件事:
能不能把微信变成 OpenClaw 的一个可用入口,而不是单纯做个演示脚本?
我手里本身就有微信接口能力,所以这次的底层接入是基于 wechatapi.net 这类接口能力来完成的。对我来说,这个项目一方面是技术验证,另一方面也在反过来检验微信接口在真实 Agent 场景里的可用性。
二、整体架构是怎么设计的
我最后没有把它继续写成一个“收到消息就直接调用 AI”的短脚本,而是拆成了几层:
微信回调
↓
FastAPI 接口层
↓
回调解析层
↓
消息标准化
↓
Session 路由
↓
Worker 队列
↓
OpenClaw 调用层
↓
微信发送层
这样设计的原因很简单:
- 回调层只负责接和拆
- 路由层负责区分私聊 / 群聊 / 会话
- 执行层负责真正调用 OpenClaw
- 发送层统一做文本 / 图片回发
如果把这些全堆在一个函数里,项目一旦变复杂,基本就很难继续维护。
三、先说一个最容易踩的坑:微信回调不能按想当然来解析
一开始我以为只要拿到 Content.string 就够了,后来发现不是这样。
根据真实回调结构,至少要关心这些字段:
TypeNameWxidData.MsgTypeData.FromUserName.stringData.ToUserName.stringData.Content.string
而且有几个逻辑一定要做对。
1. 是否自己发送
不能只看 FromUserName,而要结合 Wxid 判断:
is_self = bool(wxid and from_user == wxid)
2. 是否群消息
群消息不能只看一个字段,要结合发送人和接收人判断:
is_group = from_user.endswith("@chatroom") or to_user.endswith("@chatroom")
3. 群内真实发送人
群消息里真实发送人,可能在 Content.string 前半段:
if is_group and raw_content and ":\n" in raw_content:
possible_sender, possible_text = raw_content.split(":\n", 1)
if possible_sender.startswith("wxid_"):
sender_wxid = possible_sender
actual_text = possible_text.strip()
如果这些解析不做严谨,后面上下文一定会乱。
四、我为什么没有把它继续做成“简单聊天脚本”
如果只是最小 demo,其实一段逻辑就能跑:
@app.post("/wechat/callback")
async def handle_wechat(request: Request):
data = await request.json()
text = extract_text(data)
result = call_openclaw(text)
send_back(result)
return {"ok": True}
但这种写法有几个明显问题:
- 群聊和私聊混在一起
- 没有会话层
- 没有去重
- 没有排队
- 没有白名单
- 后续很难扩展到企微、TG 或别的入口
所以我后来改成了 网关思维,而不是脚本思维。
五、我最终保留了哪些关键能力
1. 首次命令行初始化
第一次运行时直接输入:
WX_API_TOKENPUBLIC_URL- 群触发词
- 地区 ID
并自动生成 config.ini。
这里我故意把初始化做得更像“产品入口”,因为我越来越觉得:
如果连接入体验都很糟糕,别人根本不会认真评估这套方案。
2. 配置自动生成
配置文件自动写出,并保留中文注释,后续可调。
3. 白名单
私聊不做白名单限制的话,很快就会失控。
4. 群触发词
群里不是所有消息都应该触发机器人,至少先用触发词收口。
5. 同会话串行,不同会话并行
这是入口层最关键的一点之一:
def shard_index_for_session(session_id: str, worker_count: int) -> int:
h = int(hashlib.md5(session_id.encode("utf-8")).hexdigest(), 16)
return h % worker_count
这样不同用户不会互相阻塞,但同一个会话也不会乱序。
六、这套东西最核心的瓶颈其实不在微信
这一点我一开始判断错了。
我最开始以为慢,主要是微信回调慢。
但后来打日志后发现,真正慢的是这一段:
cmd = ["openclaw", "agent", "--session-id", sid, "--message", message.strip()]
res = subprocess.run(cmd, ...)
也就是说,每来一条微信消息,我实际上都在重新起一次 OpenClaw CLI 进程。
这意味着每次都要:
- 启动进程
- 读取配置
- 恢复上下文
- 初始化 provider
- 再请求模型
- 再退出
所以体感上一定比前端慢。
这一点后来也让我更明确地认识到:
微信入口层是值得做的,但要想做到真正流畅,后面还是要考虑 OpenClaw 常驻化,而不是长期依赖 CLI 单次调用。
七、这个项目对我最大的价值是什么
说实话,一开始我以为它最大的价值是“做出一个机器人”。
但做到后面,我的判断变了。
我现在觉得,它真正的价值是:
1. 验证微信是不是一个值得投入的 Agent 入口
答案是:是。
2. 验证微信 API 在真实场景里能不能承接 AI 工作流
答案也是:可以,但前提是入口层要认真做。
3. 验证接口能力是不是应该只卖“API”
我现在越来越觉得,单卖接口太抽象。
相比之下,把接口能力做成一个可见、可跑、可理解的入口方案,更容易让别人看懂价值。
这也是为什么我这次做下来,对 wechatapi.net 这种底层能力的看法更明确了:
底层接口当然重要,但真正放大价值的,往往是入口方案和场景包装。
八、这套方案适合哪些场景
目前我觉得比较适合这些:
- 微信 AI 助手
- 私域群聊问答
- 知识库入口
- 指令型机器人
- 自动客服
- 业务流程触发器
尤其适合已经有:
- 模型能力
- OpenClaw 工作流
- 私有知识库
但缺“用户入口”的团队。
九、我现在的结论
如果只是做一个 demo,
把微信接上 OpenClaw 并不难。
但如果想让它变成 真实可用的入口层,需要做的事情会比想象中多很多:
- 解析回调
- 做好群聊判断
- 过滤自己消息
- 做会话路由
- 控制上下文
- 做并发与顺序
- 处理 CLI 延迟问题
不过这件事依然值得做。
因为在很多真实业务里,
用户不会先问你用了什么模型、什么框架。
他们先问的是:
能不能在微信里直接用?
而这,恰恰就是入口层的价值。
十、最后
这篇文章更多是我当前阶段的技术总结。
如果后面我把这套东西再往前推一步,我更想继续做两件事:
- 把微信入口层做得更稳定
- 把微信 / 企微这类入口能力逐渐抽象成可复用网关
如果你也在做类似方向,欢迎交流。
我这次的底层接入验证主要基于 wechatapi.net 这类能力做的,后面如果我继续往下打磨,应该也会围绕“入口层 + 场景方案”这个方向继续展开。
更多推荐


所有评论(0)