You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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')
    }
  });
}
解决方法

问题出在三个关键环节,逐一修复即可:

  1. 附件编码未明确指定
    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编码
}]
  1. 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
  }
});
  1. 异步调用未等待完成
    原代码中调用sendMail(message)时未加await,Lambda函数可能在邮件发送完成前就终止执行,导致邮件发送不完整或失败:
await sendMail(message) // 添加await等待发送完成

内容的提问来源于stack exchange,提问作者stark_1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 00:58:13