如何在Google Apps Script中为已有Gmail草稿添加Drive附件且保留结构
问题
开发Google Apps Script项目时,需要将两个Google Drive文件作为附件添加到已有的Gmail草稿中,要求不修改草稿的主题、正文等内容,也不能改变草稿ID、破坏原有结构。但当前使用的方法(获取草稿后更新内容并添加附件)会破坏草稿结构,甚至导致草稿ID变更。
当前代码片段:
var fileId1 = 'xxxxxxxxxxxxxxxxxxxxxx'; var fileId2 = 'yyyyyyyyyyyyyyyyyyyyyy'; // Retrieve the existing draft var draft = GmailApp.getDraft(draftId); var recipient = draft.getMessage().getTo(); var subject = draft.getMessage().getSubject(); var body = draft.getMessage().getBody(); // Get the existing attachments of the draft var existingAttachments = draft.getMessage().getAttachments(); // Attach the first file to the email var file1 = DriveApp.getFileById(fileId1); var attachmentBlob1 = file1.getAs(MimeType.PDF); // Attach the second file to the email var file2 = DriveApp.getFileById(fileId2); var attachmentBlob2 = file2.getAs(MimeType.PDF); // Combine existing attachments with new attachments var allAttachments = existingAttachments.concat(attachmentBlob1, attachmentBlob2); // Update the draft with recipient, subject, body, and attachments draft.update(recipient, subject, body, { attachments: allAttachments });
解决方案
核心问题分析
原方法的问题在于:
draft.getMessage()获取的是邮件内容的简化副本,会丢失原始草稿的部分结构(比如HTML格式的内嵌元素、特殊排版)。draft.update()并非真正在原草稿上修改,而是创建一个新草稿覆盖旧的,导致草稿ID变更。
替代方案:使用Gmail Advanced Service(Gmail API)
通过Gmail API的users.drafts.modify接口,可以直接在原有草稿上追加附件,完全保留原始内容和草稿ID。
步骤1:启用Gmail Advanced Service
在Apps Script编辑器中,点击左侧菜单栏的「服务」→「添加服务」,找到「Gmail」并启用。
步骤2:实现代码
function addAttachmentsToDraft(draftId, fileIds) { // 获取原始草稿的完整结构 var draft = Gmail.Users.Drafts.get('me', draftId); // 转换目标文件为API要求的附件格式 var newAttachmentParts = fileIds.map(fileId => { var file = DriveApp.getFileById(fileId); var blob = file.getBlob(); return { filename: file.getName(), mimeType: blob.getContentType(), body: { data: Utilities.base64Encode(blob.getBytes()) }, headers: [{ name: 'Content-Disposition', value: `attachment; filename="${file.getName()}"` }] }; }); // 构造修改请求:仅追加附件,保留原有所有内容 var modifyRequest = { message: { payload: { parts: draft.message.payload.parts.concat(newAttachmentParts) } } }; // 执行修改,更新原草稿 Gmail.Users.Drafts.modify(modifyRequest, 'me', draftId); } // 调用示例 var targetDraftId = 'your-draft-id-here'; var targetFileIds = ['xxxxxxxxxxxxxxxxxxxxxx', 'yyyyyyyyyyyyyyyyyyyyyy']; addAttachmentsToDraft(targetDraftId, targetFileIds);
代码说明
Gmail.Users.Drafts.get('me', draftId):获取原始草稿的完整元数据和内容部件,避免丢失结构信息。- 新附件通过
Utilities.base64Encode转换为Gmail API要求的Base64编码格式。 modifyRequest仅在原始邮件的payload.parts中追加新的附件部件,不改动主题、正文、收件人等任何原有内容。Gmail.Users.Drafts.modify直接修改原草稿,不会创建新草稿,因此草稿ID保持不变,原始结构完全保留。
注意事项
- 运行脚本时需要授权Gmail和Drive的访问权限,确保权限范围足够。
- 无论原始草稿是纯文本还是HTML格式,该代码都能兼容,因为会自动识别并追加附件部件。
内容的提问来源于stack exchange,提问作者Hamed
相关产品推荐
相关产品推荐

