如何将GmailMessage.getAttachments获取的内嵌图片传递给MailApp.sendEmail
需求说明
- 希望通过GmailMessage的getAttachments方法提取邮件内嵌图片,再通过MailApp类的sendEmail方法发送这些图片。
- 核心问题:前者返回Blob附件数组,而后者要求传入由字符串类型的图片键到图片数据Blob的映射构成的JavaScript对象,二者参数格式不匹配。
问题代码示例
难点出在配置项中的{..., inlineImages: attachments, ...}部分:
function test() { var firstThread = GmailApp.getTrashThreads(0,1)[0]; var message = firstThread.getMessages()[0]; var from = message.getHeader('From'); var attachments = message.getAttachments({includeAttachments: false}); var obj = {htmlBody: message.getBody(), inlineImages: attachments, noReply: false, replyTo: message.getFrom(), name: from}; MailApp.sendEmail("some@one.com", 'Testing', '', obj); }
EML格式参考
注意text/html部分的<img src="cid:key"用法,cid对应的键和附件的Content-ID一一匹配:
MIME-Version: 1.0 Date: Thu, 22 Jul 2021 23:06:23 +0300 Message-ID: <1234567890@mail.gmail.com> Subject: Testing From: Me <just@me.com> To: Someone <some@one.com> Content-Type: multipart/related; boundary="0000000000004aee5205c7bbd26b" --0000000000004aee5205c7bbd26b Content-Type: multipart/alternative; boundary="0000000000004aee5005c7bbd26a" --0000000000004aee5005c7bbd26a Content-Type: text/plain; charset="UTF-8" This is an inline image: [image: image.png] And here's another: [image: image.png] Thanks! --0000000000004aee5005c7bbd26a Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable <div dir="ltr">This is an inline image:<div><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"></div></div></div><div><img src="cid:ii_krfchaks0" alt="image.png" width="117" height="118"><br></div><div>And here's another:</div><div><img src="cid:ii_krfchlll1" alt="image.png" width="41" height="47"><br></div><div>Thanks!</div></div> --0000000000004aee5005c7bbd26a-- --0000000000004aee5205c7bbd26b Content-Type: image/png; name="image.png" Content-Disposition: attachment; filename="image.png" Content-Transfer-Encoding: base64 X-Attachment-Id: ii_krfchaks0 Content-ID: <ii_krfchaks0> --0000000000004aee5205c7bbd26b Content-Type: image/png; name="image.png" Content-Disposition: attachment; filename="image.png" Content-Transfer-Encoding: base64 X-Attachment-Id: ii_krfchlll1 Content-ID: <ii_krfchlll1> --0000000000004aee5205c7bbd26b--
解决方案
核心逻辑是从每个内嵌附件中提取Content-ID(也就是HTML里cid:后面的字符串,去掉外层尖括号),构造键值对映射对象传入inlineImages即可。修改后的可用代码如下:
function test() { var firstThread = GmailApp.getTrashThreads(0,1)[0]; var message = firstThread.getMessages()[0]; var from = message.getHeader('From'); // 只提取内嵌图片,排除普通附件 var attachments = message.getAttachments({includeAttachments: false}); var inlineImageMap = {}; attachments.forEach(function(blob) { // 从blob的Content-ID元数据提取cid键,去掉前后的尖括号 var cid = blob.getContentType()['Content-ID'].replace(/^<|>$/g, ''); inlineImageMap[cid] = blob; }); var obj = { htmlBody: message.getBody(), inlineImages: inlineImageMap, noReply: false, replyTo: message.getFrom(), name: from }; MailApp.sendEmail("some@one.com", 'Testing', '', obj); }
实现说明
- 每个内嵌图片的Blob对象都自带
Content-ID元数据,和HTML代码中img标签的cid:xxx完全对应 - 处理时要注意Content-ID本身是用尖括号包裹的,需要去掉后才能作为inlineImages的键
- 构造完成的映射对象完全符合sendEmail方法的参数要求,内嵌图片可以正常显示不会丢失
内容的提问来源于stack exchange,提问作者LWC
相关产品推荐
相关产品推荐

