You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WhatsApp Cloud API订单机器人如何关联历史提问与用户回复

问题根因

WhatsApp Cloud API的webhook本身只负责推送用户新发送的消息,不会主动回传机器人历史发送内容、对话流程进度这类上下文信息。你当前的代码是无状态实现,没有存储每个用户的对话进度和已收集信息,自然无法把用户当前回复和之前的提问关联起来。

多轮下单流程实现方案

核心要补的是服务端会话状态管理逻辑,所有上下文、流程节点都需要你自己在服务端存储维护,具体实现分4步:

  • 搭建会话存储层
    初期调试可以直接用内存Map做临时存储,正式上线替换成Redis、MySQL这类持久化存储即可。存储以用户的WhatsApp账号(即webhook payload里的from字段)作为唯一主键,每个用户的会话数据至少存三类信息:
    • 当前流程节点:标记用户现在走到下单流程的哪一步,比如「初始欢迎、选商品、选数量、填地址、确认订单」
    • 已收集的订单信息:比如用户选的商品ID、购买数量、收货地址、联系电话等
    • 会话更新时间:用来做过期判断,比如超过30分钟无回复就重置会话,避免脏数据干扰
  • 预定义流程状态流转规则
    把完整下单流程拆成固定的顺序节点,每个节点明确三个规则:合法的用户输入格式、校验通过后要跳转的下一个节点、当前节点要发送给用户的引导内容。基础流程示例:
    1. 用户首次发消息:处于初始节点,返回可购商品列表,节点更新为「等待用户选商品」
    2. 收到用户商品选择回复:校验商品是否存在,存下选中的商品,发送数量填写提示,节点更新为「等待用户填数量」
    3. 收到用户数量回复:校验是否为合法正整数,存下数量,发送地址填写提示,节点更新为「等待用户填地址」
    4. 按这个逻辑走完所有信息收集步骤,最终生成订单,重置会话状态,发送下单成功通知
  • 改造webhook消息处理逻辑
    每次收到用户消息,先拿用户手机号查询对应的会话记录:
    • 查不到会话/会话已过期:按初始流程处理,创建新的会话记录,返回商品列表
    • 查到有效会话:根据当前存储的流程节点,判断用户当前回复对应哪个待回答问题,先做输入合法性校验:校验通过就把用户输入存到订单信息里,更新流程节点,发送下一段引导;校验不通过就发送错误提示,让用户重新输入当前节点要求的内容,不跳转节点
  • 发消息后同步更新会话状态
    每次调用接口给用户发完引导消息,立刻同步更新存储里的用户会话节点和更新时间,不要等下一次收到用户消息再更新,避免状态错乱
最小改造代码示例

先加会话存储和流程节点定义:

// 临时内存存储,正式环境替换为Redis/MySQL
const userSessions = new Map()
// 会话过期时间:30分钟
const SESSION_TIMEOUT = 30 * 60 * 1000
// 下单流程节点枚举
const OrderStep = {
  INIT: 'init',
  SELECT_GOODS: 'select_goods',
  SELECT_NUM: 'select_num',
  FILL_ADDRESS: 'fill_address',
  CONFIRM: 'confirm'
}

然后修改webhook里的消息处理部分,替换原来固定返回Ack的逻辑:

// 提取到from、msg_body、phone_number_id之后,先查询用户会话
const currentTime = Date.now()
let userSession = userSessions.get(from)
// 会话不存在或过期,初始化新会话
if (!userSession || currentTime - userSession.updateAt > SESSION_TIMEOUT) {
  userSession = {
    currentStep: OrderStep.INIT,
    orderInfo: {},
    updateAt: currentTime
  }
}

let replyText = ''
// 根据当前节点处理用户回复
switch (userSession.currentStep) {
  case OrderStep.INIT:
    replyText = '欢迎下单,在售商品如下:\n1. 商品A 售价99元\n2. 商品B 售价199元\n请回复对应数字选择要购买的商品'
    userSession.currentStep = OrderStep.SELECT_GOODS
    break
  case OrderStep.SELECT_GOODS:
    const goodsId = msg_body.trim()
    if (!['1', '2'].includes(goodsId)) {
      replyText = '输入无效,请回复1或2选择对应商品'
      break
    }
    userSession.orderInfo.goodsId = goodsId
    replyText = '请输入要购买的数量(需为大于0的正整数)'
    userSession.currentStep = OrderStep.SELECT_NUM
    break
  case OrderStep.SELECT_NUM:
    const num = Number(msg_body.trim())
    if (!Number.isInteger(num) || num <= 0) {
      replyText = '数量输入无效,请输入大于0的正整数'
      break
    }
    userSession.orderInfo.buyNum = num
    replyText = '请输入您的详细收货地址和联系电话'
    userSession.currentStep = OrderStep.FILL_ADDRESS
    break
  // 剩余节点按相同逻辑扩展即可
}
// 更新会话最后修改时间,存回存储
userSession.updateAt = currentTime
userSessions.set(from, userSession)

// 调用WhatsApp接口发送回复
axios({
  method: "POST",
  url: "https://graph.facebook.com/v12.0/" + phone_number_id + "/messages?access_token=" + token,
  data: {
    messaging_product: "whatsapp",
    to: from,
    text: { body: replyText },
  },
  headers: { "Content-Type": "application/json" },
});

实操提示:不用尝试依赖消息ID(payload里的wamid字段)做上下文关联,WhatsApp不会自动将机器人发送的消息和用户的回复做绑定回传,自行维护会话状态是最稳定的方案。如果要降低用户输入错误率,可以用WhatsApp官方的交互式消息(列表选择、快捷回复按钮),用户点击后会回传你预先设置的选项ID,比纯文本输入的容错性高很多。

内容的提问来源于stack exchange,提问作者Manspof

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 20:03:25