如何通过WhatsApp API创建动态列表?Node.js+WATI开发问题排查
问题背景
- 开发场景:基于Node.js开发WhatsApp聊天机器人,选用WATI作为WhatsApp API服务提供商
- 实现目标:封装列表类交互消息发送方法,无需每次硬编码列表行标题,仅传入标题数组即可自动生成符合格式要求的
rows字段,单条row的目标格式为{"title":"对应行标题"} - 故障表现:封装完成的方法调用后,列表消息未成功发送,且未返回明确报错信息
- 运行截图:程序运行输出截图
现有问题代码
server.js
// packages const express = require('express'); require('dotenv').config("./env"); const WA = require('./whatsapp.js'); const cors = require('cors'); const webApp = express(); webApp.use(express.json()); webApp.use(cors()); // Route for WhatsApp webApp.post('/whatsapp', async (req, res) => { var data = ['row 1', 'row 2'] WA.sendListInteractive(data, whatsapp_number) res.end(); }); webApp.listen(process.env.PORT, () => { console.log(`Server is up and running at ${process.env.PORT}`); });
whatsapp.js
const sendListInteractive = async (data, senderID) => { data = [] var options = { 'method': 'POST', 'url': 'https://' + process.env.URL + '/api/v1/sendInteractiveListMessage?whatsappNumber=' + senderID, 'headers': { 'Authorization': process.env.API, 'Content-Type': 'application/json', }, body: JSON.stringify({ "header": "", //optional "body": "Body", "footer": "", //optional "buttonText": "Button Text", "sections": [ { "title": "string", "rows": [ data.forEach( e => { { "title :" + e } } ) ] } ] }) }; request(options, function (error, response) { if (error) console.log(error); console.log(response.body); }); }
问题排查与修复方案
按代码执行顺序,共有5处核心问题,逐一修复即可正常发送消息:
- 入参被意外清空
问题:sendListInteractive方法第一行写了data = [],直接把外部传入的标题数组重置为空数组,后续遍历拿不到任何传入的行数据
修复:直接删除这行覆盖入参的代码 - rows字段生成逻辑完全错误
问题:forEach方法本身没有返回值,且代码中写的"title :" + e既不是合法对象,键名还多打了空格,最终生成的rows是全空的无效数组,完全不符合接口要求
修复:改用map方法遍历数组,返回结构合法的对象,正确写法为data.map(e => ({ title: e })) - 请求回调无法捕获接口参数错误
问题:现有回调仅判断了网络请求层的error,没有校验HTTP状态码,也没有把返回的字符串格式body解析为JSON,WATI接口的参数校验错误不会触发request层的error,只会在响应体里返回错误码,现有逻辑拿不到真实报错
修复:回调中增加HTTP状态码判断,对响应体做JSON解析,方便定位参数问题 - 请求参数不符合WATI接口规范
问题:header、footer字段传空字符串会被接口判定为无效参数,不需要时直接删除字段即可;sections下的title不能传无意义的"string",需填写实际的分组名称;另外要确认Authorization头格式为Bearer <你的API密钥>,漏写Bearer前缀会导致鉴权失败但无明确提示 - 接收方号码变量未定义、方法未正确导出
问题:server.js路由中直接使用了未声明的whatsapp_number变量,实际接收方号码需要从WhatsApp webhook的请求体中解析获取,传空值会导致请求地址无效;同时whatsapp.js未导出写好的方法,外部引用时会拿到undefined
修复:从req.body中解析出发送消息的用户手机号再传入发送方法,补全模块导出逻辑
修复后参考代码
whatsapp.js 修复版
const request = require('request'); // 确认已安装并引入request依赖 const sendListInteractive = async (data, senderID) => { const options = { method: 'POST', url: `https://${process.env.URL}/api/v1/sendInteractiveListMessage?whatsappNumber=${senderID}`, headers: { Authorization: `Bearer ${process.env.API}`, // 补全Bearer鉴权前缀 'Content-Type': 'application/json', }, body: JSON.stringify({ // 移除无内容的空header、footer字段 body: "请选择选项", buttonText: "点击选择", sections: [ { title: "选项列表", // 替换为实际业务分组名称 rows: data.map(e => ({ title: e })) // 用map生成符合格式的rows数组 } ] }) }; request(options, function (error, response) { if (error) { console.log('网络请求错误:', error); return; } // 打印完整响应信息方便排查 console.log('HTTP状态码:', response.statusCode); console.log('接口返回内容:', JSON.parse(response.body)); }); } module.exports = { sendListInteractive }; // 补全方法导出
server.js 路由修复版
webApp.post('/whatsapp', async (req, res) => { const data = ['row 1', 'row 2']; // 从WATI webhook回调体中取用户手机号,字段名可根据实际回调结构调整 const whatsappNumber = req.body.waId || req.body.sender; if (whatsappNumber) { WA.sendListInteractive(data, whatsappNumber); } res.end(); });
内容的提问来源于stack exchange,提问作者Dummy Cron
相关产品推荐
相关产品推荐

