做个人微信 API 的人,迟早会撞上同一条规则:通过微信接口发出去的消息,通常不会再进微信 Webhook;手机端发出去的,会。

这不是小提示,是整条收发架构的分水岭。搞不清这一点,你会把「没回调」当故障,也会把「有回调」当机器人该回,最后发送记录、人工接管、质检对账全乱。

两条进线,别当成一条

对业务系统来说,表面上都是「微信里出现了一条消息」,来源其实不同:

来源

会不会进 Webhook

含义

好友 / 群成员发来

会

真实入站,可触发自动回

手机端自己发出

会

多端同步,多半是人工在聊

接口调用发出

通常不会

出站动作,回执要自己落库

为什么必须自建发送回执

Webhook 只能证明「收到了什么」,不能证明「你发出去了什么」。若发送成功只打一行应用日志,后面会出现:

  • 客服问:刚才机器人回了没?——查不到稳定记录

  • 质检问:这句话是人回的还是接口回的?——分不清

  • 重试问:上次超时到底有没有发出去?——只能再发一次赌

所以发送层要有自己的账本,而不是指望回调替你记账。最小字段可以很朴素:

{
  "out_id": "out_20261109_88",
  "appid": "wx_xxx",
  "to": "wxid_abc",
  "content_hash": "a1b2",
  "biz": "auto_reply",
  "status": "sent",
  "api_msg_ref": "可选",
  "created_at": 1731148800
}

out_id 在入队前生成,重试沿用同一 ID。超时后是「未知」还是「失败」,要单独状态,不能假装成没发过。

手机端同步进回调,才是人工接管的信号

很多微信机器人只处理 isSelf == false。更完整的做法是:自己手机发出去的消息,也要进会话状态机——不是拿来自动再回一遍,而是标记:

  • 该客户已进入人工会话

  • 机器人进入静默

  • 群发 / 运营触达跳过此人

否则销售正在私聊谈方案,自动化仍按关键词插话。微信自动化里,静默往往比回复更值钱。

决策日志建议写清:

in_msg decision=silence reason=human_phone_sync
out_id=out_xxx decision=send reason=keyword_price

入站有 reason,出站有 out_id,排障才不靠猜。

收发拆开后的最小闭环

可上线的个人微信 API 二次开发,收和发应是两条管道:

  1. 收:Webhook → 3 秒内响应 → 去重 → 归一化 → 入队

  2. 判:该回 / 该静默 / 该转人工(只写决策,不直接打发送接口)

  3. 发:发送队列 → 调微信接口 → 写回执表 → 失败分类

把「发送成功」写进回执表之后,业务侧对账、客服工作台「最后一条机器人回复」、重复点击防抖,都有同一数据源。

上线验收只看三句话

  1. 接口发送成功后,回执表有记录;即使 Webhook 没有这条出站消息,系统仍能证明发过。

  2. 手机端人工回复进回调后,机器人会静默,而不是继续抢话。

  3. 发送超时重试不会凭感觉再造一条新业务消息,而是沿用同一 out_id。

小结

微信 Webhook 解决的是入站感知,不负责出站审计。个人微信 API 能发消息,不代表你的系统「记得自己发过」。先把发送回执和人工同步静默做实,自动回复和 AI 客服才有资格谈稳定。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐