首页 > 解决方案 > 映射函数不传递列表中的最后一项

问题描述

我创建了一个在 Gmail 中搜索我的收件箱的功能,然后将每个消息分类为 3 个类别(姓名、电子邮件和正文)。然后将其粘贴到 Google 表格的 3 列中。但是,当我运行它时,它只会在前 2 列中粘贴名称和电子邮件。问题出在身体上。尽管如此,当我运行Logger.log(d.getPlainBody());它时,它会显示我正在寻找的正文。

我正在使用的代码:

// extract emails from label in Gmail
function extractEmails() {
  
  // get the spreadsheet
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getActiveSheet();
  
  // get all email threads that match label from Sheet
  var threads = GmailApp.getInboxThreads();
  
  // get all the messages for the current batch of threads
  var messages = GmailApp.getMessagesForThreads(threads);
  
  var emailArray = [];
  
  // get array of email addresses
  messages.forEach(
    function(message) {
    message.forEach(
      function(d) {
      emailArray.push(d.getFrom(),d.getTo(),d.getPlainBody());
      Logger.log(d.getPlainBody());
    });
  });
  
  // de-duplicate the array
  var uniqueEmailArray = emailArray.filter(function(item, pos) {
    return emailArray.indexOf(item) == pos;
  });
  
  var cleanedEmailArray = uniqueEmailArray.map(
    function(el) {
      
      var matches = el.match(/\s*"?([^"]*)"?\s+<(.+)>/);
      
      if (matches) {
        name = matches[1]; 
        email = matches[2];
        body = matches[3];
      }
      
      return [name, email, body];
      
  });
  
  // clear any old data
  sheet.getRange(2,1,sheet.getLastRow(), 3).clearContent();
  
  // paste in new names and emails
  var printing = sheet.getRange(2 ,1,cleanedEmailArray.length, 3);
  printing.setValues(cleanedEmailArray);


}

标签: javascriptgoogle-apps-scriptgoogle-sheetsgmail

解决方案


您的逻辑似乎有问题,尤其是在地图功能上。您实际上是在匹配每个元素,而不是每条消息。而且您的正则表达式仅捕获 2 种模式,因此预计matches[3]会返回空白。

我稍微修改了你的代码。他们是这样的:

  1. 将变量作为数组(消息)的元素传递,并getTo在您不使用它时将其删除。但是,如果您是,请随时再次添加。
  // get array of email addresses
  messages.forEach(function(message) {
    message.forEach(function(d) {
      // Push the data as array to easily process them
      // Removed getTo as you only are getting name and email from getFrom data based on your regex
      emailArray.push([d.getFrom(),d.getPlainBody()]);
    });
  });
  1. 地图功能被更简单的forEach. 这是可能的,因为我们将消息数据作为上面的数组。
  var cleanedEmailArray = [];
  uniqueEmailArray.forEach(function(message){
    // match name and email from pattern "name <email>" in d.getFrom()
    // only pass match[1] and match[2], since match[0] = message[0]
    [, name, email] = message[0].match(/\s*"?([^"]*)"?\s+<(.+)>/);
    // get body from d.getPlainBody()
    body = message[1];
    cleanedEmailArray.push([name, email, body])
  });
  1. (Nitpick)你没有使用printing所以我结合了 2 行
  // paste in new names and emails
  sheet.getRange(2 ,1,cleanedEmailArray.length, 3).setValues(cleanedEmailArray);

这就是您的代码的样子:

代码:

function extractEmails() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getActiveSheet();
  var threads = GmailApp.getInboxThreads();
  var messages = GmailApp.getMessagesForThreads(threads);
  var emailArray = [], cleanedEmailArray = [];

  messages.forEach(function(message) {
    message.forEach(function(d) {
      emailArray.push([d.getFrom(),d.getPlainBody()]);
    });
  });

  var uniqueEmailArray = emailArray.filter(function(item, pos) {
    return emailArray.indexOf(item) == pos;
  });
  
  uniqueEmailArray.forEach(function(message){
    [, name, email] = message[0].match(/\s*"?([^"]*)"?\s+<(.+)>/);
    body = message[1];
    cleanedEmailArray.push([name, email, body])
  });

  sheet.getRange(2,1,sheet.getLastRow(), 3).clearContent();
  sheet.getRange(2 ,1,cleanedEmailArray.length, 3).setValues(cleanedEmailArray);
}

输出:

输出


推荐阅读