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

WhatsApp Business API Webhook多次触发重复回复问题求助

解决WhatsApp Business API Webhook重复触发导致重复回复的问题

核心问题分析

  1. 响应不及时:你的代码要完成自有API调用和WhatsApp回复后才返回200响应,WhatsApp服务器如果在10秒内没收到响应,会重复推送相同的Webhook事件,导致重复处理。
  2. 无去重机制:即使WhatsApp重复推送,代码没有判断消息是否已处理,会重复执行回复逻辑。
  3. 代码语法错误:现有axios请求存在语法问题(END_POINT_URL后缺少逗号、Authorization行末尾缺少逗号),可能导致请求失败,进一步触发重试。

解决方案

1. 立即返回200响应

优先给WhatsApp服务器返回200 OK,告知已收到事件,再异步处理业务逻辑。

2. 添加消息去重机制

利用每个WhatsApp消息的唯一id字段,用缓存(比如Redis)记录已处理的消息ID,处理前先校验是否已处理过,避免重复执行。

3. 修复代码语法错误

修正axios请求中的语法问题,确保请求能正常执行。

修改后的代码示例

const redis = require('redis'); // 引入Redis客户端,需先执行npm install redis
const client = redis.createClient(); // 根据你的Redis配置初始化客户端
client.connect().catch(console.error);

app.post("/webhook", async (req, res) => {
  // 第一步:立即返回200响应,避免WhatsApp触发重试
  res.status(200).end();

  const body = req.body;
  console.log(JSON.stringify(body, null, 2));

  if (body.object) {
    const messageEntry = body.entry[0]?.changes[0]?.value?.messages?.[0];
    if (!messageEntry) return;

    const phone_number_id = body.entry[0].changes[0].value.metadata.phone_number_id;
    const from = messageEntry.from;
    const msg_body = messageEntry.text.body;
    const messageId = messageEntry.id; // 获取消息唯一标识ID

    // 第二步:检查消息是否已处理过
    const isProcessed = await client.get(`processed:${messageId}`);
    if (isProcessed) {
      console.log(`消息${messageId}已处理,跳过执行`);
      return;
    }

    try {
      // 调用自有API
      const apiResponse = await axios({
        method: "POST",
        url: API_URL,
        data: {
          id: phone_number_id,
          question: msg_body,
          email: "N/A",
          conversation: [],
          save: true,
          resolved: "N/A",
          ads: 0,
        },
        headers: {
          "Content-Type": "application/json",
          "x-api-key": process.env.API_KEY,
        },
      });

      if (apiResponse.status !== 200) {
        throw new Error(`请求失败,状态码${apiResponse.status}`);
      }

      const responseData = apiResponse.data;
      console.log(responseData);

      // 发送WhatsApp回复消息
      await axios({
        method: "POST",
        url: END_POINT_URL,
        headers: {
          "Content-Type": "application/json",
          Authorization: TOKEN,
        },
        data: {
          to: from,
          type: "text",
          text: {
            preview_url: false,
            body: responseData.answer,
          },
          messaging_product: "whatsapp",
          recipient_type: "individual",
        },
      });

      // 标记消息为已处理,设置24小时过期时间,避免缓存无限增长
      await client.setEx(`processed:${messageId}`, 86400, "true");
    } catch (error) {
      console.error("业务处理出错:", error);
    }
  }
});

额外注意事项

  • 如果没有Redis,也可以用内存缓存(比如Map),但重启服务后会丢失已处理记录,生产环境建议使用持久化缓存。
  • 优化自有API的响应速度,避免业务逻辑耗时过长影响用户体验。
  • 确认WhatsApp Webhook的重试规则,确保去重逻辑覆盖所有可能的重试场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 04:17:19