Apps 脚本:将附件添加到邮件合并

Apps Script: Add attachment to a mail merger

问题:

在@Cooper 的大力帮助下,我能够使用 html 模板(“emailEinladung.html”)和收件人列表(“terminBestaetige”)优化我的邮件合并脚本。每个收件人都会收到一封基于 html 模板的个性化电子邮件,只要第 11 列(因此,“K”)中的 his/her 状态未设置为“EMAIL SENT”。现在我想在每封发送的电子邮件中添加一个或多个附件。

尝试的解决方案:

function terminEinladungVersendenWithAttachments() {
  // variables to reference the sheet and its content
  const anrede = 2;
  const nachname = 3;
  const emailAdresse = 5;
  const terminTag = 6;
  const terminUhrzeit = 8;
  const terminURL = 9;
  let emailTemp = HtmlService.createTemplateFromFile('emailEinladung');
  const sh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("terminBestaetigen");

  // variables for "Betreff" (in English: "subject") coming from the google Sheet named "Vorlagen"
  var wsVorlagen = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Vorlagen");
  var betreff = wsVorlagen.getRange("B1").getValue();

  const sr = 3;//start row of data
  const data = sh.getRange(sr, 1, sh.getLastRow() - sr + 1, 11).getValues();
  data.forEach((row, i) => {
    if (row[10] == "EMAIL NOT SENT YET") {
      emailTemp.anrede1 = (row[anrede]);
      emailTemp.nachname1 = (row[nachname]);
      emailTemp.emailAdresse1 = (row[emailAdresse]);
      emailTemp.terminTag1 = (row[terminTag]);
      emailTemp.terminUhrzeit1 = (row[terminUhrzeit]);
      emailTemp.terminURL1 = (row[terminURL]);
  // including attachements to each email being sent.
      var attachment1 = DriveApp.getFileById("[FILE_ID1]")
      var attachment2 = DriveApp.getFileById("[FILE_ID2]")
      var blob1 = attachment1.getBlob()
      var blob2 = attachment2.getBlob()
      var htmlMessage = emailTemp.evaluate().getContent();
      GmailApp.sendEmail(row[emailAdresse],
        betreff, "Dies ist eine Nachricht im HTML-Format. Sie müßen Ihre Email-Software entsprechend einrichten.",
        { htmlBody: htmlMessage, replyTo: "f.dore@skillgainer.de", attachments: [blob1, blob2]});
      sh.getRange(i + sr, 11).setValue("EMAIL SENT");//stops emails from being sent again
    }
  });
}

问题:

我的脚本有什么地方应该改进以提高效率吗?如果是,那改进是什么?您的脚本会是什么样子?

非常感谢您的帮助。

我相信你的目标如下。

  • 您想减少脚本的处理成本。

修改点:

  • 当我看到你的脚本时,我认为 blob1blob2 可以退出循环。我觉得这样一来,工艺成本可能会有点低。
  • 但是,当GmailApp.sendEmail循环发送500封邮件时,这个过程成本会很高。我以为这个成本比上面那点要大
  • 为了减少发送 500 封电子邮件的过程成本,在这个答案中,作为一种解决方法,我想建议使用 Gmail API 和批量请求。但我不确定这是否是您问题的直接解决方案。所以请测试下面的脚本。

修改后的脚本如下

修改后的脚本:

在使用此脚本之前,请先安装a Google Apps Script library of BatchRequest. You can see how to install this library at here

还有,please enable Gmail API at Advanced Google services.

请设置[FILE_ID1][FILE_ID2]的文件ID。

const convert_ = ({ to, subject, textBody, htmlBody, attachmentfile1, attachmentfile2 }) => {
  const boundary1 = "boundaryboundary001";
  const boundary2 = "boundaryboundary002";
  const mailData = [
    `MIME-Version: 1.0`,
    `To: ${to}`,
    `Subject: =?UTF-8?B?${Utilities.base64Encode(subject, Utilities.Charset.UTF_8)}?=`,
    `Content-Type: multipart/mixed; boundary=${boundary1}`,
    ``,
    `--${boundary1}`,
    `Content-Type: multipart/alternative; boundary=${boundary2}`,
    ``,
    `--${boundary2}`,
    `Content-Type: text/plain; charset=UTF-8`,
    ``,
    textBody,
    `--${boundary2}`,
    `Content-Type: text/html; charset=UTF-8`,
    `Content-Transfer-Encoding: base64`,
    ``,
    Utilities.base64Encode(htmlBody, Utilities.Charset.UTF_8),
    `--${boundary2}--`,
    `--${boundary1}`,
    `Content-Type: image/png; charset=UTF-8; name="sample1.png"`,
    `Content-Transfer-Encoding: base64`,
    ``,
    attachmentfile1,
    `--${boundary1}`,
    `Content-Type: image/png; charset=UTF-8; name="sample2.png"`,
    `Content-Transfer-Encoding: base64`,
    ``,
    attachmentfile2,
    `--${boundary1}--`,
  ].join("\r\n");
  return Utilities.base64EncodeWebSafe(mailData);
};

// Please run this function.
function terminEinladungVersendenWithAttachments() {
  const anrede = 2;
  const nachname = 3;
  const emailAdresse = 5;
  const terminTag = 6;
  const terminUhrzeit = 8;
  const terminURL = 9;
  let emailTemp = HtmlService.createTemplateFromFile('emailEinladung');
  const sh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("terminBestaetigen");
  var wsVorlagen = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Vorlagen");
  var betreff = wsVorlagen.getRange("B1").getValue();
  const sr = 3;
  const data = sh.getRange(sr, 1, sh.getLastRow() - sr + 1, 11).getValues();
  var attachmentfile1 = Utilities.base64Encode(DriveApp.getFileById("[FILE_ID1]").getBlob().getBytes());
  var attachmentfile2 = Utilities.base64Encode(DriveApp.getFileById("[FILE_ID2]").getBlob().getBytes());

  var {requests, sent} = data.reduce((o, row, i) => {
    if (row[10] == "EMAIL NOT SENT YET") {
      emailTemp.anrede1 = (row[anrede]);
      emailTemp.nachname1 = (row[nachname]);
      emailTemp.emailAdresse1 = (row[emailAdresse]);
      emailTemp.terminTag1 = (row[terminTag]);
      emailTemp.terminUhrzeit1 = (row[terminUhrzeit]);
      emailTemp.terminURL1 = (row[terminURL]);
      var htmlMessage = emailTemp.evaluate().getContent();
      const obj = {
        to: row[emailAdresse],
        subject: betreff,
        textBody: "Dies ist eine Nachricht im HTML-Format. Sie müßen Ihre Email-Software entsprechend einrichten.",
        htmlBody: htmlMessage,
        attachmentfile1, attachmentfile2
      };
      o.requests.push({method: "POST", endpoint: "https://gmail.googleapis.com/gmail/v1/users/me/messages/send", requestBody: { raw: convert_(obj) }});
      o.sent.push("K" + (i + 3));
    }
    return o;
  }, {requests: [], sent: []});
  if (sent.length > 0) sh.getRangeList(sent).setValue("EMAIL SENT");
  const res = BatchRequest.EDo({ batchPath: "batch/gmail/v1", accessToken: ScriptApp.getOAuthToken(), requests: requests });
  console.log(res)
}

注:

  • 这个方法是我的尝试。所以请测试上面的脚本。

参考文献: