如何在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
相关产品推荐
相关产品推荐

