好友把发错的价格撤了。任务表仍是发送成功,客服系统还引用那句。对账时两边都觉得对方在扯谎。个人微信机器人若把 postText 回执当成当前聊天真相,撤回之后下游全错。撤回改的是会话可见性。它不会把当时那次 HTTP 改写成失败。

没发出去,是失败。发出去又拿掉,是补偿。两类工单不能并成一条「发送异常」。

回执不要被 UPDATE 成失败

成功表示那一时刻通道接受了投递。之后可以撤回。若把 outbound 改成 failed,补发会把已达内容再打一遍。应另记补偿:哪条消息、哪个 toWxid、何时撤、要不要更正。主键用回调或回执里的消息 ID,不要用正文哈希。改一个数字,哈希对不上。

出站时把通道消息 ID 和业务单号绑在一起。字段名以文档为准:

def after_send(order_id, app_id, to_wxid, content, receipt, db):
    db.save_outbound({
        "order_id": order_id,
        "appId": app_id,
        "toWxid": to_wxid,
        "content": content,
        "new_msg_id": receipt.get("newMsgId") or receipt.get("msgId"),
        "state": "sent",
    })

def on_revoke(msg_id, db):
    row = db.find_by_msg(msg_id)
    if not row:
        return
    db.save_compensate(row["order_id"], "revoked")

看到 revoked 默认停。更正句必须已审。自动把原句再 postText 一次,等于撤回失败。回执里到底是 newMsgId 还是别的名字,以文档为准,示例仅表示「要有一条能对上的 ID」。对不上就不要做自动对齐。

对方撤回问句,路上的回复要取消

问句没了,答还在路上,会话会只剩一句莫名其妙的报价。入站撤回应取消未发送的回复任务。已发送的是否再撤,按产品定。未出站取消成本低,应作为默认。isSelf 为真的撤回是自己撤的,不要拿去触发自动更正。

验收:测试句撤回后任务是 sent+revoked 不是 failed;补发不应重送原文;对方撤回后未发送的自动回被取消。价格更正走人工。机器人没有「撤回所以号掉了」这种状态。掉线是存活问题,撤回是会话问题。

查看个人微信 API 文档:
https://doc.geweapi.com/

Logo

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

更多推荐