无法在Hostinger配置WhatsApp Cloud API Webhook URL求助
WhatsApp Cloud API Webhook 部署到Hostinger(巴西服务器)验证失败问题
我本地用Node.js配置WhatsApp Cloud API的Webhook完全正常,在localhost的8000、3000端口测试都没问题,但部署到巴西Hostinger服务器后,提交的Webhook URL始终不被Meta认可。我已经指定用标准80端口,现在搞不清是代码问题还是Hostinger的配置没做好,也不确定服务器端是不是需要额外的PHP/HTML文件,求配置指导和排查方案。
我的配置文件
.env文件
WEBHOOK_VERIFY_TOKEN = "123" GRAPH_API_TOKEN = "EAAQUA14XZBPwBO7M7sqU46sO7eSbVjYQAGJiD9rqOnOhTLIUyPPZBT2SZAbJLzOPUIGZAblwp5TiwWsPe1AgxuGtiZAJlumDrZBXH7ROct5IDZCOmJXji8OWUnfQPFrmmI3LTCkPjJygkmyx2MmtPXKp9KFcAGVRoLErlMKQl2JbFBjAi8KDyDe2rgQ9ouGd37PAozBALTQ1B48jpKYbZBUZD" # token temporary PORT = 80
index.js文件
// ------ IMPORTANDO MODULOS const express = require("express"); // framework para aplicativos web do Node.js const body_parser = require("body-parser"); // middleware para analisar corpos de solicitação em middleware antes de seus manipuladores const axios = require("axios"); // biblioteca HTTP cliente para fazer requisições HTTP require('dotenv').config(); // módulo para carregar variáveis de ambiente do arquivo .env // configuracao do Express. Criamos uma instância do aplicativo Express e usamos o body_parser.json() para analisar os corpos das solicitações como JSON const app = express().use(body_parser.json()); const token = process.env.GRAPH_API_TOKEN; //temporary access token dashboard api wpp const mytoken = process.env.WEBHOOK_VERIFY_TOKEN; // inicia o servidor Express na porta 8000 ou na porta definida em process.env.PORT app.listen(process.env.PORT,()=>{ console.log("webhook is listening..."); }) app.get("/",(req,res) => { res.status(200).send("hello this is webhook setup"); }); // é definida uma rota GET para a URL /webhook que será usada para verificação e configuração do webhook do Facebook // para verificar a url de retorno no painel de apps (cloud api) app.get("/webhook", (req, res) =>{ let mode = req.query["hub.mode"]; let token = req.query["hub.verify_token"]; let challenge = req.query["hub.challenge"]; // check the mode and token sent are correct if (mode && token) { if(mode === "subscribe" && token === mytoken){ // respond with 200 OK and challenge token from the request res.status(200).send(challenge); console.log("Webhook verified successfully!"); }else { // respond with '403 Forbidden' if verify tokens do not match res.sendStatus(403); } } }); // trata as solicitações POST recebidas no endpoint /webhook, onde as mensagens recebidas do WhatsApp serão processadas e respondidas app.post("/webhook",(req,res) => { let body_param = req.body; console.log(JSON.stringify(body_param,null,2)); // obtem a resposta e coloca no console // https://developers.facebook.com/docs/whatsapp/cloud-api/webhooks/payload-examples if(body_param.object){ if(body_param.entry && // Verifica se a propriedade entry existe em body_param e se não é null ou undefined body_param.entry[0].changes && // Verifica se o primeiro elemento do array entry possui a propriedade changes e se não é null ou undefine body_param.entry[0].changes[0].value.message && // Verifica se o primeiro elemento do array changes possui a propriedade value com uma subpropriedade message e se não é null ou undefined body_param.entry[0].changes[0].value.message[0] // Verifica se o primeiro elemento do array message existe. ){ let phone_no_id = body_param.entry[0].changes[0].value.metadata.phone_number_id; let from = body_param.entry[0].changes[0].value.messages[0].from; let msg_body = body_param.entry[0].changes[0].value.messages[0].text.body; axios({ method: "POST", url: "https://graph.facebook.com/v19.0/"+phone_no_id+"/messages?access_token="+token, data: { messaging_product: "whatsapp", to: from, text:{ body: "Hi..." } }, headers:{ "Content-Type": "application/json" } }) res.sendStatus(200); }else{ res.sendStatus(404); } } });
我尝试过将URL填入Webhook的“user”字段,但仍未被认可。
排查与解决步骤
1. 服务器端口与权限检查
- Hostinger共享主机默认可能限制80端口直接绑定,因为共享环境通常用Apache/Nginx做反向代理:
- 优先考虑用Hostinger面板配置反向代理,将你的域名指向Node.js服务使用的非80端口(比如3000),避免端口权限问题
- 如果必须用80端口,确认Node.js进程有绑定低端口的权限:Linux下非root用户可执行
sudo setcap 'cap_net_bind_service=+ep' $(which node)赋予权限,或用端口转发工具
- 检查Hostinger防火墙规则,确保入站的80端口请求被允许
2. Webhook URL格式验证
- Meta要求Webhook必须是公网可访问的HTTPS地址:
- 必须使用完整的HTTPS URL,比如
https://你的域名.com/webhook,不能用HTTP或纯IP地址 - Hostinger共享主机默认提供免费SSL证书,确保你的域名已启用HTTPS
- 测试URL是否能被公网访问:用在线工具检查你的
/webhook端点是否可达
- 必须使用完整的HTTPS URL,比如
3. 代码逻辑修复
- 你的
/webhookGET端点存在逻辑漏洞:当mode或token参数缺失时,没有返回状态码,Meta会判定验证失败,补充如下代码:app.get("/webhook", (req, res) =>{ let mode = req.query["hub.mode"]; let token = req.query["hub.verify_token"]; let challenge = req.query["hub.challenge"]; if (mode && token) { if(mode === "subscribe" && token === mytoken){ res.status(200).send(challenge); console.log("Webhook verified successfully!"); }else { res.sendStatus(403); } } else { // 补充:参数缺失时返回403 res.sendStatus(403); } }); - 确认
process.env.PORT是否正确读取:在服务器启动时添加console.log("Running on port:", process.env.PORT),检查端口是否为80
4. Hostinger环境配置
- 无需额外PHP/HTML文件,Node.js服务可独立运行,但需注意:
- 用PM2或Hostinger自带的Node.js管理器后台运行进程,避免终端关闭后服务停止
- 确保服务器Node.js版本与本地一致(推荐v16及以上),避免语法兼容问题
5. 本地模拟验证测试
- 在服务器上执行curl命令,模拟Meta的验证请求:
curl "https://你的域名.com/webhook?hub.mode=subscribe&hub.verify_token=123&hub.challenge=123456"- 若返回
123456,说明验证逻辑正常;若返回403或其他错误,优先排查代码或服务器路由配置
- 若返回
内容的提问来源于stack exchange,提问作者Mares
相关产品推荐
相关产品推荐

