在Node.js中将SendGrid Inbound Parse返回的Buffer转换为可读JSON
核心原因
SendGrid Inbound Parse Webhook POST的是multipart/form-data格式的二进制数据,并非JSON序列化后生成的Buffer,所以直接调用JSON.parse()只能得到Buffer对象的序列化结果,无法拿到邮件字段。你将Buffer转为字符串后看到的是multipart表单的原始报文,不是JSON格式字符串,因此也无法直接转成JSON对象。
处理流程(Node.js环境,符合Buffer -> String -> 结构化对象要求)
我们需要先把Buffer转成UTF-8字符串,再解析multipart表单格式提取字段,最终得到可直接读取的结构化对象。这里使用轻量的multipart解析库busboy实现:
- 首先安装依赖
npm install busboy
- 解析代码实现
const Busboy = require('busboy'); /** * 解析SendGrid入站Parse的原始Buffer * @param {Buffer} buf 从Webhook拿到的原始Buffer * @param {string} contentType 请求头里的content-type值,包含multipart分隔符 * @returns {Promise<Object>} 包含所有邮件字段的结构化对象 */ function parseSendGridEmail(buf, contentType) { return new Promise((resolve, reject) => { const busboy = Busboy({ headers: { 'content-type': contentType } }); const emailData = {}; // 处理普通表单字段(From、To、Subject等邮件元信息都在这里) busboy.on('field', (fieldName, value) => { emailData[fieldName] = value; }); // 处理邮件附件 busboy.on('file', (fieldName, fileStream, filename, encoding, mimetype) => { const fileChunks = []; fileStream.on('data', chunk => fileChunks.push(chunk)); fileStream.on('end', () => { emailData[fieldName] = { filename, mimetype, content: Buffer.concat(fileChunks) }; }); }); // 解析完成返回结构化对象 busboy.on('finish', () => resolve(emailData)); busboy.on('error', reject); // 传入原始Buffer开始解析 busboy.end(buf); }); } // 调用示例 parseSendGridEmail(yourRawBuffer, req.headers['content-type']) .then(data => { // 直接提取需要的字段 console.log('发件人:', data.From); console.log('收件人:', data.To); console.log('邮件主题:', data.subject); console.log('邮件正文:', data.html || data.text); }) .catch(err => console.error('解析失败:', err));
注意事项
- 必须从请求头中获取完整的
content-type值,里面包含multipart表单的分隔符boundary,缺少该参数无法正常解析 - 如果使用Express、Koa等Web框架,需要关闭框架默认的
multipart/form-data类型body自动解析,否则无法拿到原始Buffer - 如果你只需要纯文本的邮件字段不需要处理附件,可以删除代码中的
file事件监听逻辑,进一步精简代码
内容的提问来源于stack exchange,提问作者Lakshmi
相关产品推荐
相关产品推荐

