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

Node.js版Facebook Webhook无法接收测试POST请求求助

Facebook Webhook无法接收测试POST请求排查方案

问题概述

用Node.js搭建的Facebook Webhook,GET验证请求能正常接收,Postman发送相同JSON POST请求也能正常响应,但Facebook后台显示请求已发送,服务器却收不到测试POST请求,当前处于开发模式。

可能的原因及解决办法

1. 请求解析中间件缺失

Facebook发送的POST请求为application/json格式,若Express应用未配置express.json()中间件,会导致req.body为空,服务器直接返回400错误,而Facebook后台可能仅显示请求已发送,不提示错误状态。

  • 解决:在路由配置前添加中间件:
app.use(express.json()); // 必须放在app.post('/webhook', ...)之前调用

2. 未验证请求签名

Facebook会对Webhook请求做签名验证,若服务器未验证签名,可能被判定为无效接收,或在部分环境下被拦截请求。

  • 解决:添加签名验证逻辑:
const crypto = require('crypto');

app.post('/webhook', (req, res) => {
  // 验证请求签名
  const signature = req.headers['x-hub-signature-256'];
  if (!signature) {
    console.log('请求缺失签名');
    return res.sendStatus(403);
  }

  const hmac = crypto.createHmac('sha256', process.env.FB_APP_SECRET);
  const digest = `sha256=${hmac.update(JSON.stringify(req.body)).digest('hex')}`;
  
  if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(digest))) {
    console.log('签名验证失败');
    return res.sendStatus(403);
  }

  // 原有业务逻辑
  console.log(`收到${req.method}请求:${req.url}`);
  console.log(`请求体:${JSON.stringify(req.body)}`);

  if (!req.body || Object.keys(req.body).length === 0) {
    console.log('请求体为空');
    res.status(400).send('Bad Request: Request body is empty');
    return;
  }
 
  let body = req.body;

  if (body.object === 'page') {
    body.entry.forEach(entry => {
      const webhook_event = entry.messaging[0];
      console.log(webhook_event);
    });
    res.status(200).send('EVENT_RECEIVED');
  } else {
    res.sendStatus(404);
  }
});

3. 服务器响应超时

Facebook要求Webhook在10秒内返回响应,若服务器处理逻辑耗时过长或网络延迟,Facebook会判定请求失败,但后台仍可能显示“已发送”。

  • 解决:先快速返回响应,再异步处理消息:
app.post('/webhook', (req, res) => {
  // 先返回响应避免超时
  res.status(200).send('EVENT_RECEIVED');

  // 异步处理消息逻辑
  process.nextTick(() => {
    console.log(`收到${req.method}请求:${req.url}`);
    console.log(`请求体:${JSON.stringify(req.body)}`);

    if (!req.body || Object.keys(req.body).length === 0) {
      console.log('请求体为空');
      return;
    }
 
    let body = req.body;

    if (body.object === 'page') {
      body.entry.forEach(entry => {
        const webhook_event = entry.messaging[0];
        console.log(webhook_event);
      });
    }
  });
});

4. 开发环境暴露问题

若服务器运行在本地,使用ngrok等工具暴露端口,可能存在隧道过期、连接不稳定的情况,导致Facebook请求无法到达。

  • 解决:
    • 检查ngrok隧道状态,重新生成隧道并更新Facebook后台的回调URL
    • 确保本地防火墙未拦截外部请求

5. Webhook订阅字段未配置

Facebook后台Webhook订阅设置中,若未勾选所需的消息事件字段,不会发送测试请求。

  • 解决:进入Facebook开发者后台,在Webhook设置中勾选messages等需要的事件字段,重新完成订阅。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 15:30:23