Node.js处理WhatsApp Cloud API媒体二进制数据:FormData发送失败求助
解决Node.js中通过FormData发送WhatsApp媒体文件失败的问题
你的代码里有几个关键问题导致文件无法正常发送,下面是修正方案和解释:
核心问题点
- 直接把
getMediaData返回的响应体丢进FormData,没指定文件名和MIME类型,后端没法正确解析文件 - 手动设置
Content-Type: multipart/form-data会覆盖FormData自动生成的带boundary的头部,导致请求格式错误 getMediaData大概率没正确获取二进制数据,默认axios会把响应转成JSON,把二进制搞坏了
修正后的完整代码
首先要确保getMediaData能拿到正确的二进制数据:
async function getMediaData(url) { return axios.get(url, { responseType: 'stream', // 或者用arraybuffer,看后端接受哪种格式 headers: { // WhatsApp媒体URL需要认证,这里要加你的WhatsApp API令牌 'Authorization': `Bearer ${process.env.WHATSAPP_API_TOKEN}` } }); }
然后修改handleMedia函数:
async function handleMedia(id, number) { try { const mediaRes = await mediaServiceApi(id); const mediaUrl = mediaRes.data.url; const mimeType = mediaRes.data.mime_type; console.log(mediaUrl, mimeType); const mediaDataRes = await getMediaData(mediaUrl); const formData = new FormData(); // 追加普通表单字段 formData.append("mobile_number", number.toString()); formData.append("category", "1"); formData.append("ticket_type", "1"); formData.append("subject", "Device not working"); formData.append("description", "my device is not working"); // 生成合理的文件名,比如用媒体ID+对应扩展名 const fileExt = mimeType.split('/')[1]; const fileName = `${id}.${fileExt}`; // 追加文件时必须指定文件名和MIME类型 formData.append("document", mediaDataRes.data, { filename: fileName, contentType: mimeType }); const requestConfig = { method: "post", url: "你的目标API地址", // 补全你的工单系统API地址 headers: { "Access-Token": "你的访问令牌", // 补全你的令牌 ...formData.getHeaders() // 只用FormData自动生成的头部,不要手动加Content-Type }, data: formData }; const ticketResponse = await axios(requestConfig); console.log("工单创建成功:", JSON.stringify(ticketResponse.data)); const textMsg = `We have registered your query with reference of a media`; await textServiceApi(textMsg, number); } catch (error) { console.error("处理媒体文件或创建工单出错:", error); // 这里可以加失败后的兜底逻辑,比如给用户回复失败消息 } }
关键修改说明
- 改用async/await:嵌套Promise太绕,async/await让流程更直观,错误处理也更方便
- 指定响应类型:
getMediaData里设置responseType为stream或arraybuffer,确保拿到原始二进制数据,不会被转成JSON搞坏 - FormData追加文件的正确姿势:必须传文件名和MIME类型,后端才能识别这是个合法文件
- 删除手动设置的Content-Type:FormData自动生成的头部包含
boundary(分隔符),手动设置会把这个覆盖,导致后端解析不了多部分表单 - 统一错误捕获:用try/catch包裹所有异步操作,任何一步出错都能及时捕获处理
内容的提问来源于stack exchange,提问作者abhishek mehta
相关产品推荐
相关产品推荐

