从Gmail主题收集唯一的电子邮件地址

时间:2015-11-04 05:58:22

标签: javascript arrays google-apps-script google-sheets gmail

我是Google Apps脚本的新手,我正在尝试为电子表格创建一个脚本,我会在表单中存储.getFrom()方法找到的所有电子邮件地址,并忽略相同的电子邮件地址我只获得一个电子邮件地址而不是多次。到目前为止存储工作成功但忽略相同的电子邮件是行不通的。我在工作表的专栏中多次收到相同的电子邮件。

这是我的代码:

      var n=threads.length;
      var messages=thread.getMessages();
      var getfrom = 0;
      var allMails = [];
      for (var i=0; i<n; i++)
      {
         for (var j=0; j<messages.length; j++)
         {
            var message=messages[j];
            getfrom = message.getFrom();
            var first_name = getfrom.substring(0, getfrom.indexOf(" "));
            var last_name = getfrom.substring(getfrom.indexOf(" ")+1, getfrom.indexOf(" <"));
            var email_address = 0;
            if (first_name == '' && last_name == '')
            {
               email_address = getfrom;
            } else {
               email_address = getfrom.substring(getfrom.indexOf("<")+1, getfrom.indexOf(">"));
            }

            // This is how I check if I already have the email address or not

            if (email_address == my_email || email_address[j] == email_address[j-1])
            {
               continue;
            }
          }
          allMails.push([email_address]);
      }
      Logger.log(allMails);
      sheet1.getRange(2, 3, n, 1).setValues(allMails);
      Browser.msgBox("Operation complete");

如何忽略重复值并获取一个电子邮件地址而不是多次?

3 个答案:

答案 0 :(得分:1)

您需要交叉检查您的allMails数组以查找给定的电子邮件地址,以确保它不在列表中,但是您无法直接检查allMails,因为它是一个二维数组。

我会添加一个单维数组,纯粹是为了交叉检查。

  var n=threads.length;
  var messages=thread.getMessages();
  var getfrom = 0;
  var allMails = [];
  var cross_check = [];

  for (var i=0; i<n; i++)
  {
     for (var j=0; j<messages.length; j++)
     {
        var message=messages[j];
        getfrom = message.getFrom();
        var first_name = getfrom.substring(0, getfrom.indexOf(" "));
        var last_name = getfrom.substring(getfrom.indexOf(" ")+1, getfrom.indexOf(" <"));
        var email_address = 0;
        if (first_name == '' && last_name == '')
        {
           email_address = getfrom;
        } else {
           email_address = getfrom.substring(getfrom.indexOf("<")+1, getfrom.indexOf(">"));
        }

        if(email_address != my_email && cross_check.indexOf(email_address) == -1){
           cross_check.push(email_address);
           allMails.push([email_address]);
        } 
      }

  }
  Logger.log(allMails);
  sheet1.getRange(2, 3, n, 1).setValues(allMails);
  Browser.msgBox("Operation complete");

请参阅indexOf函数的文档,该文档解释了为什么我们检查-1,这里:

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf

答案 1 :(得分:1)

您可以在将电子邮件添加到列表之前确保唯一性,也可以先构建完整列表,然后再删除重复项。

选项1:预过滤

此示例构建一维地址数组;因为它是一个简单的数组,我们可以使用JavaScript内置的.indexOf()方法来检查唯一性。在检查完所有线程之后,使用内置的另一个数组map()将简单数组转换为二维数组以存储在电子表格中。在此之前,数组被排序 - 只是因为我们可以。您可能希望进行其他过滤,例如删除&#34; no-reply&#34;地址。

function getUniqueFromAddresses1() {

  var my_email = Session.getActiveUser().getEmail();

  var threads = GmailApp.getInboxThreads();
  var n=threads.length;
  var allMails = [];
  for (var i=0; i<n; i++)
  {
    var thread = threads[i];
    var messages=thread.getMessages();
    for (var j=0; j<messages.length; j++)
    {
      var message=messages[j];
      var getfrom = message.getFrom();
      // Use RegEx to extract just email address
      var email_address = getfrom.match(/[^<> ]*\@[^> ]*/)[0];

      // Skip messages I sent or addresses already collected
      var index = allMails.indexOf(email_address);
      if (email_address !== my_email && allMails.indexOf(email_address) == -1) {
        allMails.push(email_address);
      }
    }
  }
  // Could do further filtering & sorting of allEmails here
  allMails = allMails.sort()
  Logger.log(JSON.stringify(allMails));

  // convert allMails array to two-dimensional array
  allMails = allMails.map( function(item){
    return [item];
  });

  Logger.log(JSON.stringify(allMails));

  // Store in spreadsheet; use dimensions of array to avoid mismatching range size
  sheet1.getRange(2, 3, allMails.length, allMails[0].length).setValues(allMails);

  debugger;  // Pause in debugger
  Browser.msgBox("Operation complete");
}

选项2:后置过滤器

这是替代方法,在构建阵列后删除重复项。这里的JavaScript魔法从this answer解除了。我们仍然使用一维数组来收集和过滤地址。从列表中删除我们自己的地址还需要一个额外的步骤。

效果:这应该比接近1更快,因为所需的比较会更少。但是,整个操作中使用的大部分时间都与访问消息有关,因此本机JavaScript的时间节省可以忽略不计。

function getUniqueFromAddresses2() {

  var my_email = Session.getActiveUser().getEmail();

  var threads = GmailApp.getInboxThreads();
  var n=threads.length;
  var allMails = [];
  for (var i=0; i<n; i++)
  {
    var thread = threads[i];
    var messages=thread.getMessages();
    for (var j=0; j<messages.length; j++)
    {
      var message=messages[j];
      var getfrom = message.getFrom();
      // Use RegEx to extract just email address
      var email_address = getfrom.match(/[^<> ]*\@[^> ]*/)[0];

      // Save the address      
      allMails.push(email_address);

      // Skip messages I sent or addresses already collected
      var index = allMails.indexOf(email_address);
      if (email_address !== my_email && allMails.indexOf(email_address) == -1) {
        allMails.push(email_address);
      }
    }
  }

  // Remove duplicates - https://stackoverflow.com/a/32533637/1677912
  allMails = allMails.sort().reduce(function(a, b){ if (b != a[0]) a.unshift(b); return a }, []);
  // Remove my address
  if ((mine=allMails.indexOf(my_email)) > -1) allMails.splice(mine,1);

  // Could do further filtering & sorting of allEmails here
  allMails = allMails.sort()
  Logger.log(JSON.stringify(allMails));

  // convert allMails array to two-dimensional array
  allMails = allMails.map( function(item){ return [item]; });

  Logger.log(JSON.stringify(allMails));
  sheet1.getRange(2, 3, n, 1).setValues(allMails);
  debugger;  // Pause in debugger
  Browser.msgBox("Operation complete");
}

您是如何获得电子邮件地址的?

原始功能需要几个步骤来识别message.getFrom()返回的字符串中的电子邮件地址。这很棘手,因为该字符串只能包含电子邮件地址,或名称和地址。通过使用正则表达式仅匹配电子邮件地址,可以简化操作,并忽略字符串中的任何其他文本。

      // Use RegEx to extract just email address
      var email_address = getfrom.match(/[^<> ]*\@[^> ]*/)[0];

表达式查找@及其前后的文本,以空格或角括号为界。您可以在online demo中尝试此操作。

/[^<> ]*\@[^> ]*/
  [^<> ]* match a single character not present in the list below
    Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
   <>  a single character in the list "<> " literally (case sensitive)
  \@ matches the character @ literally

答案 2 :(得分:0)

另请检查Gmail Extractor - 它会将电子邮件地址从Gmail保存在Google电子表格中。

相关问题