避免在线程中导入所有消息

时间:2017-12-10 21:44:59

标签: google-apps-script gmail

我编写了一个将Gmail邮件导入电子表格的脚本。收件箱规则将其移至“等待导入”Gmail标签,脚本处理该邮件,然后删除此标签并将其添加到“导入”标签。

问题是,当收到这个“等待导入”标签的电子邮件时,标签似乎应用于整个帖子。由于消息与先前导入的消息具有相同的主题,因此它会导入线程中的所有其他消息(这些消息已经导入)。

这是我的剧本:

  var importedCount = 0;
  var label = GmailApp.getUserLabelByName('Monitor/AwaitingImport');
  var threads = label.getThreads(0,50);      // An array of threads (limit set to 50, this could be increased)

  if (threads.length != 0) { // If a thread exists
    for (var i = 0; i < threads.length; i++) { // for each thread in the label
      var threadsubject = threads[i].getFirstMessageSubject();      
      if (threadsubject.match(/(Check In)/)) { // if the subject contains "Check In"
        var messages = threads[i].getMessages(); // get ALL the messages
        for (var j = 0; j < messages.length; j++) { // for each message
          var body = messages[j].getPlainBody();
          // Get key:value pairs from email into an array
          var array = body.trim().split("\n");
          var newArray = [];
          for (k = 0; k < array.length; k++) {
            newArray = newArray.concat(array[k].toString().split("="));
          }

          // Push other data to array that isn't in body of email
          newArray.push("GmailMessageID", messages[j].getId());
          newArray.push("MessageDate", messages[j].getDate());

          // Create object
          var newObj = {};
          for (var l =0 ; l< newArray.length ; l++) {
            if (l%2 == 0){
              newObj[newArray[l]] = newArray[l+1];
            }
          }

          // Now insert object as record into the spreadsheet
          insertRecordWithAnyFieldsIntoAnySheet('Incoming Logs', newObj, true);
        }
        // Finally remove the label from this message, mark it as read, and update the importedCount (for logging)
        threads[i].removeLabel(GmailApp.getUserLabelByName('Monitor/AwaitingImport'));
        threads[i].addLabel(GmailApp.getUserLabelByName('Monitor/Imported'));
        importedCount++;
      }
    }    
  }
  SpreadsheetApp.getActiveSpreadsheet().toast(importedCount + ' messages imported');

如何防止导入线程中的所有邮件,只导入刚收到的邮件?

  • 不希望使用Gmail邮件ID检查已导入邮件的传入邮件,因为这会涉及资源密集型搜索已导入的数千条邮件片材。

  • 我不想仅导入线程中的最后一条消息,因为这可能会遗漏未导入的其他消息

  • 最后,我尝试通过向脚本添加另一个条件(即if (messages[j].isRead()))来导入未读取的消息,因为我的脚本会将消息标记为已读(未在上面的代码段中显示)但这仍然似乎导入线程中的所有消息

1 个答案:

答案 0 :(得分:1)

默认情况下,Gmail适用于线程,GmailApp仅适用于线程。有一种可能的解决方法。首先,您需要转到Gmail设置并将对话视图设置为关闭。这将使每封电子邮件成为它的独立对象。这样标签就会被应用到消息中(请注意,第一次执行此操作时,线程中的所有消息都将具有标签,但之后每条消息都可以拥有它自己的标签)。

据我所知,GmailApp仍然可以使用线程。您需要使用Gmail API。阅读here以了解如何开始使用它。那么你想要做的就是这样:

queriedMessages =
      Gmail.Users.Messages.list(userInfo.mail, {
        'q': queryString,
        'pageToken': execProperties.nextPageId
      });

这是我脚本中的一个例子。 UserInfo.mail可以替换为简单的'me',用于检查您的电子邮件。 queryString是重要的一部分。这与Gmail中的高级搜索字符串相同。例如,'in:all newer_than:2d -in:chats -in:trash -in:draft'将搜索所有邮件,不超过2天,不在环聊聊天中,不在垃圾邮件中,也不在草稿中。阅读有关如何编写这些查询的herepageToken实际上是queriedMessages.nextPageToken。只有当您想要再次搜索并从让我们说搜索结果的第2页而不是第1页开始时,才需要这样做。

如果您认为自己将超过6分钟,这将非常有用。将pageToken存储在用户或脚本属性中,创建触发器以重新启动脚本并终止当前运行。然后当它重新启动时,你拉出属性并从你离开的页面开始。