You need to enable JavaScript to run this app. Gmail API Node.js客户端发送邮件时正文转为附件问题求助
优惠活动
大模型
产品
解决方案
定价
更多

Gmail API Node.js客户端发送邮件时正文转为附件问题求助

问题根因

你遇到的正文被自动判定为附件的问题,全部来自手写MIME邮件结构时的语法错误,和OAuth授权、接口调用流程无关:

  • 核心错误:原代码中Content-Type头行缺失参数分隔符。你写的是Content-Type: text/html charset=utf-8,按照MIME规范,主类型和参数之间必须用分号分隔,正确写法是Content-Type: text/html; charset=utf-8。
    这个标点缺失会直接导致邮件解析器识别不到合法的内容类型标识,会把无合法内联属性的内容自动归类为无类型附件,最终呈现的效果就是你传入的text内容被生成了.html后缀的附件,没有正常内联展示。
  • 兼容优化点:目前代码用\n做行分隔,虽然Gmail自身的解析器多数场景下可以兼容,但严格遵循邮件传输规范的链路要求用\r\n作为行分隔符,非规范的换行在部分邮件网关的解析逻辑里,也可能触发异常把正文判定为附件。
修正后的可运行代码
import {google} from 'googleapis'

const accessToken = '通过Google OAuth2流程获取的有效访问令牌'

async function sendMail(subject: string, text: string, to: string, from: string)
{
    const utf8Subject = `=?utf-8?B?${Buffer.from(subject).toString('base64')}?=`
    const messageParts = [
        `From: ${from}`,
        `To: ${to}`,
        // 修正Content-Type语法错误,补上参数分隔分号
        'Content-Type: text/html; charset=utf-8',
        'MIME-Version: 1.0',
        `Subject: ${utf8Subject}`,
        '',
        text,
    ]
  
    // 用规范的CRLF做行分隔,提升全链路兼容性
    const message = messageParts.join('\r\n')
    const encodedMessage = Buffer.from(message)
        .toString('base64')
        // 适配Gmail要求的URL安全Base64编码
        .replace(/\+/g, '-')
        .replace(/\//g, '_')
        .replace(/=+$/, '')

  const gmail = google.gmail({version: 'v1', auth: accessToken})

  await gmail.users.messages.send({
    userId: 'me',
    requestBody: {
      raw: encodedMessage,
    }
  })
}

sendMail('测试主题', '<p>这是可以正常内联展示的HTML正文</p>', '收件人@example.com', '发件人@example.com')

注意事项:手写单部分MIME邮件时,只需要在头字段正确标注Content-Type、空行之后直接写正文内容即可,不需要额外添加Body:、HTML:这类自定义标签——这类标签不属于标准MIME结构,加了反而会破坏解析逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.01 03:24:04