Google Sheets通过Apps Script发邮件时QR码缺失问题求助
问题分析与解决方案
你的问题核心是邮件合并过程中,草稿中的内嵌QR码未能正确传递到发送的邮件中,根源在于原代码中内嵌图片的获取逻辑错误,以及Gmail API方法的误用。以下是具体修正方案:
一、修正内嵌图片的获取逻辑(适用于草稿中已有固定QR码的场景)
原代码中getAttachments()方法并不支持includeInlineImages这类参数,导致无法正确提取内嵌图片。替换为Gmail API原生的getInlineImages()方法即可解决问题,该方法直接返回{cid: Blob}格式的对象,完全匹配sendEmail的inlineImages参数要求。
修正后的getGmailTemplateFromDrafts_函数
function getGmailTemplateFromDrafts_(subject_line){ try { // 获取所有草稿并筛选匹配主题的草稿 const drafts = GmailApp.getDrafts(); const draft = drafts.filter(d => d.getMessage().getSubject() === subject_line)[0]; if (!draft) throw new Error("未找到匹配主题的Gmail草稿"); const msg = draft.getMessage(); // 分离普通附件与内嵌图片 const attachments = msg.getAttachments().filter(att => !att.isInlineImage()); // 直接获取内嵌图片的cid与Blob映射 const inlineImages = msg.getInlineImages(); return { message: { subject: subject_line, text: msg.getPlainBody(), html: msg.getBody() }, attachments: attachments, inlineImages: inlineImages }; } catch(e) { throw new Error(`获取Gmail草稿失败: ${e.message}`); } }
关键修改点
- 替换了模糊的草稿筛选逻辑,直接通过主题匹配定位目标草稿
- 使用
msg.getInlineImages()替代错误的参数调用,正确获取内嵌图片的cid与Blob对象 - 用
filter(att => !att.isInlineImage())排除内嵌图片,避免重复处理
二、动态生成唯一QR码(适用于每行数据对应不同QR码的场景)
如果你的需求是给每个收件人发送专属唯一QR码(而非草稿中的固定图片),需要在邮件合并时动态生成并替换占位符,步骤如下:
1. 添加QR码生成函数
借助Google Charts API免费生成QR码Blob:
function generateQRCodeBlob(text, size = 200) { const encodedText = encodeURIComponent(text); const qrUrl = `https://chart.googleapis.com/chart?cht=qr&chs=${size}x${size}&chl=${encodedText}`; return UrlFetchApp.fetch(qrUrl).getBlob().setName("unique_qr.png"); }
2. 修改邮件发送逻辑
假设你的Sheets表格中,某列(比如索引为QR_CODE_COL)存储了生成QR码的唯一内容(如用户ID、专属链接),在邮件草稿中添加占位符<img src="{{QR_CID}}" alt="专属QR码">,然后替换为动态生成的QR码:
// 替换原有的循环逻辑 obj.forEach(function(row, rowIdx){ if (row[EMAIL_SENT_COL] == ''){ try { const msgObj = fillInTemplateFromObject_(emailTemplate.message, row); // 从表格获取QR码专属内容 const qrUniqueText = row[QR_CODE_COL]; // 生成QR码Blob与唯一CID const qrBlob = generateQRCodeBlob(qrUniqueText); const qrCid = `qr_${rowIdx}_${Date.now()}`; // 替换HTML中的占位符为动态CID const modifiedHtml = msgObj.html.replace('{{QR_CID}}', `cid:${qrCid}`); // 合并原有内嵌图片与新QR码 const inlineImages = {...emailTemplate.inlineImages, [qrCid]: qrBlob}; GmailApp.sendEmail(row[RECIPIENT_COL], msgObj.subject, msgObj.text, { htmlBody: modifiedHtml, attachments: emailTemplate.attachments, inlineImages: inlineImages }); out.push([new Date()]); } catch(e) { out.push([e.message]); } } else { out.push([row[EMAIL_SENT_COL]]); } });
三、额外排查要点
- 确认草稿中的QR码是内嵌图片:插入图片时选择「嵌入到邮件正文中」,而非作为附件添加
- 检查权限:确保脚本已获得
GmailApp和UrlFetchApp的授权(首次运行时会提示授权) - 调试日志:可以在代码中添加
console.log(inlineImages),查看内嵌图片是否被正确提取
内容的提问来源于stack exchange,提问作者FEBzX
相关产品推荐
相关产品推荐

