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

如何使用Gmail API在Node.js中发送带附件的邮件?新手求助

嘿,作为Node.js新手碰到这种找不到对应文档的情况真的挺闹心的!别慌,Gmail API其实有专门适配Node.js的附件上传方案,我给你一步步捋清楚:

核心思路:Gmail API的Node.js附件上传逻辑

Gmail API发送带附件的邮件核心是要把邮件内容构造成MIME格式,Node.js里有两种主流实现方式:用工具库简化操作,或者手动构造MIME内容。不管哪种方式,都需要把本地文件读取成二进制后转成base64编码——这是Gmail API对附件内容的硬性要求。

具体实现步骤(附代码示例)

先假设你已经通过googleapis库获取了授权的gmail客户端实例(比如完成了OAuth2授权流程)。

方式1:用Nodemailer + Gmail API(推荐,更简洁)

Nodemailer有专门适配Gmail API的传输器,处理附件超级省心,不用自己折腾MIME格式:

  1. 先安装依赖:
npm install nodemailer googleapis
  1. 完整代码示例:
const nodemailer = require('nodemailer');
const { google } = require('googleapis');

// 创建Gmail API传输器
const createTransporter = async () => {
  return nodemailer.createTransport({
    service: 'gmail',
    auth: {
      type: 'OAuth2',
      user: '你的邮箱@gmail.com',
      clientId: '你的OAuth2客户端ID',
      clientSecret: '你的OAuth2客户端密钥',
      refreshToken: '你的刷新令牌',
      // accessToken可以不用手动传,transporter会自动刷新获取
    }
  });
};

// 发送带附件的邮件
const sendEmailWithAttachment = async () => {
  const transporter = await createTransporter();
  const mailOptions = {
    from: '你的名字 <你的邮箱@gmail.com>',
    to: '收件人邮箱@example.com',
    subject: '测试带附件的邮件',
    text: '这是一封带附件的测试邮件',
    attachments: [
      // 方式1:直接指定本地文件路径
      {
        filename: 'test.txt',
        path: './test.txt'
      },
      // 方式2:读取文件内容后传入
      {
        filename: '头像.jpg',
        content: fs.readFileSync('./avatar.jpg'),
        encoding: 'base64'
      }
    ]
  };

  try {
    await transporter.sendMail(mailOptions);
    console.log('带附件的邮件发送成功啦!');
  } catch (error) {
    console.error('发送失败:', error);
  }
};

// 调用发送函数
sendEmailWithAttachment();

方式2:直接调用Gmail API的users.messages.send接口(手动构造MIME)

如果不想依赖Nodemailer,也可以手动构造MIME消息后发送:

  1. 安装辅助依赖:
npm install mime-types
  1. 完整代码示例:
const fs = require('fs');
const mime = require('mime-types');
const { google } = require('googleapis');

// 假设你已经有授权好的gmail客户端
const gmail = google.gmail({ version: 'v1', auth: 你的授权客户端实例 });

// 构造MIME格式的邮件内容
const createMimeMessage = (to, from, subject, text, attachments) => {
  const boundary = `----=_Part_${Date.now()}`;
  let mimeParts = [
    `From: ${from}`,
    `To: ${to}`,
    `Subject: ${subject}`,
    'MIME-Version: 1.0',
    `Content-Type: multipart/mixed; boundary="${boundary}"`,
    '',
    `--${boundary}`,
    'Content-Type: text/plain; charset="UTF-8"',
    'Content-Transfer-Encoding: 7bit',
    '',
    text,
    ''
  ];

  // 逐个添加附件
  attachments.forEach(attachment => {
    const fileContent = fs.readFileSync(attachment.path);
    const base64Content = fileContent.toString('base64');
    const contentType = mime.lookup(attachment.path) || 'application/octet-stream';
    
    mimeParts.push(
      `--${boundary}`,
      `Content-Type: ${contentType}; name="${attachment.filename}"`,
      `Content-Disposition: attachment; filename="${attachment.filename}"`,
      'Content-Transfer-Encoding: base64',
      '',
      base64Content,
      ''
    );
  });

  mimeParts.push(`--${boundary}--`);
  return mimeParts.join('\n');
};

// 发送邮件
const sendEmail = async () => {
  const to = '收件人邮箱@example.com';
  const from = '你的名字 <你的邮箱@gmail.com>';
  const subject = '手动构造MIME带附件测试';
  const text = '这是手动构造MIME格式的带附件邮件';
  const attachments = [
    { path: './report.pdf', filename: '月度报告.pdf' },
    { path: './screenshot.png', filename: '界面截图.png' }
  ];

  // 生成MIME消息并转成Gmail要求的base64编码(需要替换特殊字符)
  const mimeMessage = createMimeMessage(to, from, subject, text, attachments);
  const encodedMessage = Buffer.from(mimeMessage)
    .toString('base64')
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=+$/, '');

  try {
    await gmail.users.messages.send({
      userId: 'me', // 'me'代表当前授权用户的邮箱
      requestBody: {
        raw: encodedMessage
      }
    });
    console.log('邮件发送成功!');
  } catch (error) {
    console.error('发送失败:', error);
  }
};

sendEmail();
常见问题排查
  • 确认你的OAuth2授权范围包含https://www.googleapis.com/auth/gmail.send(发送邮件)或者https://www.googleapis.com/auth/gmail.compose(创建草稿),没有足够权限会导致上传失败
  • 检查本地文件路径是否正确,确保Node.js进程有读取该文件的权限
  • Gmail普通邮件最大支持25MB附件,如果你的文件超过这个大小,需要使用**可恢复上传(resumable upload)**方案,不过一般中小附件用上面的方法就足够了

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:30:53