使用Nodemailer MailComposer与Gmail API发邮件后附件损坏无法打开
问题
在AWS Lambda上搭建基于Gmail API的简易邮件发送API,使用aws-lambda-multipart-parser解析multipart/form-data,通过Nodemailer的MailComposer构建邮件内容。发送邮件后,附件出现损坏无法打开的情况,尝试调整编码和MIME类型均未解决问题。相关代码如下:
import multipart from 'aws-lambda-multipart-parser' import MailComposer from 'nodemailer/lib/mail-composer'; import { JWT } from "google-auth-library" import { google } from 'googleapis' import privatekey from './../../gw-mailer/gw_mailer_service_keys.json' // 服务账号密钥文件 const scopes = ['https://www.googleapis.com/auth/gmail.send']; export const handler = async (event, context) => { const body = multipart.parse(event, false); const file = [{ filename: body.attachments.filename, content: body.attachments.content, contentType: body.attachments.contentType, }] const mail = new MailComposer({ from: 'from@email.xxx', to: 'to@email.xxx', subject: 'Test', text: 'Test message', attachments: file }) const message = await mail.compile().build() sendMail(message) return { statusCode: 200, body: JSON.stringify(body) } } const sendMail = async (message) => { const jwtClient = new JWT({ email: privatekey.client_email, key: privatekey.private_key, scopes, subject: 'dev@gushwork.ai', }); const gmail = google.gmail({ version: 'v1', auth: jwtClient }); const res = await gmail.users.messages.send({ userId: 'me', requestBody: { raw: Buffer.from(message).toString('base64') } }); }
解决方法
问题出在三个关键环节,逐一修复即可:
- 附件编码未明确指定
aws-lambda-multipart-parser解析得到的附件内容是base64编码字符串,但MailComposer默认会把content当作UTF-8文本处理,导致附件内容解码错误。需要在附件配置中明确指定编码类型:
const file = [{ filename: body.attachments.filename, content: body.attachments.content, contentType: body.attachments.contentType, encoding: 'base64' // 新增:告知MailComposer内容是base64编码 }]
- Gmail API要求URL安全的Base64编码
Gmail API的raw参数需要使用URL安全的Base64编码(替换+为-,/为_,移除末尾的=),原代码直接转换的标准Base64会导致邮件内容解析异常:
const res = await gmail.users.messages.send({ userId: 'me', requestBody: { raw: Buffer.from(message) .toString('base64') .replace(/\+/g, '-') .replace(/\//g, '_') .replace(/=+$/, '') // 转换为URL安全的Base64 } });
- 异步调用未等待完成
原代码中调用sendMail(message)时未加await,Lambda函数可能在邮件发送完成前就终止执行,导致邮件发送不完整或失败:
await sendMail(message) // 添加await等待发送完成
内容的提问来源于stack exchange,提问作者stark_1
相关产品推荐
相关产品推荐

