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

如何在Google Apps Script中通过Gmail API回复时引用原始邮件

实现Gmail API回复时引用原始邮件内容(含附件)

当前在Google Apps Script中使用Gmail API回复线程首条邮件时,Gmail用户能在同一线程收到回复,但非Gmail用户收到的是独立邮件,未包含原始邮件引用内容。需要修改代码实现类似Gmail UI的回复引用效果,让所有收件人都能看到原始邮件内容及附件。

修改后的完整代码

var thread = GmailApp.getThreadById(existingThreadId);
var messages = thread.getMessages();

if (messages.length > 0) {
  var originalMessage = messages[0];
  var recipientEmail = originalMessage.getTo();
  var senderEmail = Session.getActiveUser().getEmail();
  var originalMessageId = originalMessage.getHeader("Message-ID");
  var references = originalMessage.getHeader("References") || "";
  var subject = originalMessage.getSubject();
  // 避免重复添加Re:前缀
  var replySubject = subject.startsWith("Re:") ? subject : `Re: ${subject}`;

  // 1. 准备回复的核心正文
  var replyText = "This is a reminder for previous email";
  
  // 2. 格式化原始邮件的纯文本引用
  var originalText = originalMessage.getPlainBody();
  var quotedText = originalText.split("\n").map(line => `> ${line}`).join("\n");
  var fullTextBody = `${replyText}\n\n\nOn ${originalMessage.getDate().toLocaleString()}, ${originalMessage.getFrom()} wrote:\n${quotedText}`;

  // 3. 格式化原始邮件的HTML引用
  var originalHtml = originalMessage.getBody();
  var quotedHtml = `<blockquote style="border-left: 2px solid #ccc; padding-left: 10px; margin-left: 0;">${originalHtml}</blockquote>`;
  var fullHtmlBody = `${replyText}<br><br><br><div style="color:#555;">On ${originalMessage.getDate().toLocaleString()}, ${originalMessage.getFrom()} wrote:</div>${quotedHtml}`;

  // 4. 处理原始邮件的附件
  var attachments = originalMessage.getAttachments();
  var attachmentParts = [];
  attachments.forEach(attach => {
    var attachmentPart = [
      `Content-Type: ${attach.getContentType()}`,
      `Content-Disposition: attachment; filename="${encodeURIComponent(attach.getName())}"`,
      `Content-Transfer-Encoding: base64`,
      "",
      Utilities.base64Encode(attach.getBytes()),
      ""
    ].join("\r\n");
    attachmentParts.push(attachmentPart);
  });

  // 5. 构建完整的MIME邮件结构
  var boundary = "----=_Part_" + Utilities.getUuid();
  var mimeParts = [
    "MIME-Version: 1.0",
    `From: ${senderEmail}`,
    `To: ${recipientEmail}`,
    `Subject: ${replySubject}`,
    `In-Reply-To: ${originalMessageId}`,
    `References: ${references} ${originalMessageId}`,
    `Content-Type: multipart/mixed; boundary="${boundary}"`,
    "",
    `--${boundary}`,
    "Content-Type: multipart/alternative; boundary=\"alt-boundary\"",
    "",
    `--alt-boundary`,
    "Content-Type: text/plain; charset=UTF-8",
    "Content-Transfer-Encoding: quoted-printable",
    "",
    fullTextBody,
    "",
    `--alt-boundary`,
    "Content-Type: text/html; charset=UTF-8",
    "Content-Transfer-Encoding: quoted-printable",
    "",
    fullHtmlBody,
    "",
    `--alt-boundary--`,
    "",
    ...attachmentParts,
    `--${boundary}--`
  ].join("\r\n");

  // 6. 创建并发送草稿
  var draftReplyRequestBody = {
    message: {
      threadId: existingThreadId,
      raw: Utilities.base64EncodeWebSafe(mimeParts)
    }
  };
  var draftReplyResponse = Gmail.Users.Drafts.create(draftReplyRequestBody, "me");
  Gmail.Users.Drafts.send({ id: draftReplyResponse.id }, "me");
}

关键改动说明

  • MIME结构优化:采用multipart/mixed嵌套multipart/alternative的格式,同时支持纯文本、HTML内容和附件,适配不同邮件客户端的解析能力
  • 引用内容格式化:
    • 纯文本版本给原始内容的每一行添加>前缀,模拟标准邮件引用样式
    • HTML版本用<blockquote>标签包裹原始HTML内容,添加左侧边框的视觉标识,保持原始格式
  • 线程关联强化:同时设置In-Reply-To和References头,确保所有邮件客户端都能识别邮件线程关系
  • 附件处理:提取原始邮件的所有附件,编码后添加到回复的MIME结构中,实现附件随回复转发
  • 主题处理:自动判断原始主题是否已包含Re:前缀,避免重复添加,保持主题一致性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 17:59:51