【问题标题】:Automatically Forwarding EMails using Google App Scrpiting使用 Google App Scripting 自动转发电子邮件
【发布时间】:2021-08-16 23:07:21
【问题描述】:

我使用 gmail,并且正在尝试学习 Javascript。我知道可能还有其他方法,但我想弄清楚这一点,主要是为了了解我的思维过程哪里出了问题。我的目标是学习 JavaScript 和 Google App Script。

我在 gmail 中使用特定标签标记电子邮件,并且我最终希望将所有这些电子邮件转发给特定的人。这个人的变化取决于谁在做这项工作。我的期望:

  • 脚本转到 Google 工作表以查找列、A 客户名称、B 要转发到的电子邮件、C 当前标签和 D 标签以将其存档。 (示例,A:Fire Club,B:example@fireclub.co,C:inbox/FireClub,D:Archive/FireClub
  • 转发电子邮件、附件,将主题更改为“客户名称 - 旧主题”(即从“Burn it”更改为“Fire Club - Burn it”
  • 然后将消息从初始标签(C 列)中删除,并用其新标签(D 列)进行标记

下面是我所拥有的,我知道我可以清理其中的一些(例如将 columnB 更改为收件人),但我还不能让核心工作。当我尝试运行以下内容时,它将遍历标签中大约一半的消息,然后返回“TypeError: Cannot read property 'forward' of undefined myFunction @ Code.js:21”这是实际发送的行消息。

        threads[i].getMessages()[i].forward(recipient, {subject: subject}); // Sends e-mail

感谢您的帮助。我已经包含了下面的整个代码,以防它不仅仅是上面的行。谢谢!

function myFunction() {

  var sheetID = 'ID'; //Edit this to your sheet ID.
  let sheet = SpreadsheetApp.openById(sheetID);
  let rowNum = 6; //Need to make this match to labels, but good enough for a POC
  var values = sheet.getActiveSheet().getDataRange().getValues();
  let columnA = values[rowNum][0]; // get column A - Client Name
  let columnB = values[rowNum][1]; // get column B - email
  let columnC = values[rowNum][2]; // get column C - label
  let columnD = values[rowNum][3]; // get column D - archive

// Grab E-Mails to send
  var labels = GmailApp.getUserLabelByName(columnC);
  var archive = GmailApp.getUserLabelByName(columnD);
  var threads = labels.getThreads();
  var length = threads.length;
  let recipient = columnB;
  for (let i = 0; i < length; i++) {
    let subject = columnA + ' - ' + threads[i].getFirstMessageSubject();
    threads[i].getMessages()[i].forward(recipient, {subject: subject}); // Sends e-mail
    Logger.log("Thread ID: " + threads[i].getId() + " Message Sent: " + columnA + " - " + threads[i].getFirstMessageSubject()) // Changes subject to add Client name in front
    archive.addToThread(threads[i]); // Adds the label that is shown in dolumn D of the spreadsheet
    labels.removeFromThread(threads[i]); // removes the inbox label
  }
}

【问题讨论】:

    标签: javascript google-apps-script gmail


    【解决方案1】:

    您尝试使用相同的索引i 来获取线程和其中的消息,但线程可能包含不同数量的消息。例如,第 10 条线程可能只有 5 条消息,因此如果您尝试访问该线程的第 10 条消息,您将得到undefined

    如果您尝试获取线程的第一条消息(例如,如果它只有一条消息),那么您可以使用getMessages()[0]

    如果要转发所有消息,需要循环遍历getMessages()检索到的消息:

    for (let i = 0; i < length; i++) {
      let subject = columnA + ' - ' + threads[i].getFirstMessageSubject();
      let messages =  threads[i].getMessages();
      for (let j = 0; j < messages.length; j++) {
        messages[j].forward(recipient, {subject: subject}); // Sends e-mail
        Logger.log("Thread ID: " + threads[i].getId() + " Message Sent: " + columnA + " - " + threads[i].getFirstMessageSubject()) // Changes subject to add Client name in front
        archive.addToThread(threads[i]); // Adds the label that is shown in dolumn D of the spreadsheet
        labels.removeFromThread(threads[i]); // removes the inbox label
      }
    }
    

    根据具体情况,您还可以包含 IF 语句以仅转发满足特定条件的消息。

    【讨论】:

    • 线程是一组消息,可以在一个线程中包含多条消息。因此,如果我在线程 #4 上调用,但它只有一条消息,它正在尝试发送线程 4 的消息 4 并返回未定义。这是一个必须解决的有趣问题,我认为线程中的消息通常是第一个,但可能并不总是。
    • 是的,就是这样。我添加了一个 sn-p 显示如何遍历消息,您还可以添加一个 IF 以在转发消息之前检查特定条件。
    • 谢谢你的sn-p。我正在慢慢构建它,但无法让核心按预期工作。你解决了我遇到的问题,谢谢!
    • 我很高兴 sn-p 有帮助。在这种情况下,请考虑接受这个作为问题的答案 (stackoverflow.com/help/someone-answers)。
    【解决方案2】:
    function myFunction1() {
      const ss = SpreadsheetApp.openById("sheetID");
      const sh = ss.getActiveSheet();
      const vs = sh.getRange(2, 1, sh.getLastRow() - 1, sh.getLastColumn()).getValues();
      vs.forEach((r, i) => {
        let recipient = r[1];
        let labels = GmailApp.getUserLabelByName(r[2]);
        let archive = GmailApp.getUserLabelByName(r[3]);
        let threads = labels.getThreads();
        threads.forEach(t => {
          let subject = `${r[0]} - ${t.getFirstMessageSubject()}`;
          t.getMessages().forEach(m => {
            m.forward(r[1], { subject: subject });
            archive.addToThread(t);
            labels.removeFromThread(t);
          });
        });
      });
    }
    

    【讨论】:

    • 这似乎进行了大量优化。我希望你能帮助我理解各个部分。 'vs' 是否在电子表格中查找全部数据? forEach((r, i) 是否将工作表中的每一列定义为一个数组?我不明白 forEach(t 到底定义了什么,或者 't' 和 'm' 调用的是什么。谢谢你的帮助。
    • vs 将第 2 行的数据放到数据的底部。如果你仔细阅读代码并参考这个reference你应该能够弄清楚。
    猜你喜欢
    • 1970-01-01
    • 2012-10-15
    • 2014-01-12
    • 2010-10-27
    • 2021-03-31
    • 1970-01-01
    • 2020-10-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多