我想根据每个标签将所有基本电子邮件数据加载到一个数组中

时间:2014-11-20 02:25:45

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

我的Google App脚本的目的是将给定时间段内的所有传入和传出电子邮件记录到当天结束或一周结束时的Google电子表格中。电子邮件全天收到,并在收到邮件后立即标记。

我开始只是记录当前收件箱中所有邮件的详细信息。

  // ** CREATE EMPTY DATA ARRAYS **
  var emailFrom = [];
  var emailTo = [];
  var emailBody = [];
  var emailDate = [];
  var emailLabel = [];
  var emailSubject = [];
  var emailLabel = [];

  // ** PUSH DATA INTO EMPTY ARRAYS **
  for(var i = 0; i < threads.length; i++) {
    emailBody.push(["  "]);    
    emailFrom.push([messages[i][0].getFrom()]);
    emailTo.push([messages[i][0].getTo()]);
    emailDate.push([messages[i][0].getDate()]);
    emailSubject.push([messages[i][0].getSubject()]);
  };

   // ** THEN, LOG THE FILLED DATA ARRAYS TO ROWS **
  // hint: getSheetValues(startRow, startColumn, numRows, numColumns)
    mysheet.getRange(2,4,threads.length,1).setValues(emailFrom);
    mysheet.getRange(2,3,threads.length,1).setValues(emailTo);
    mysheet.getRange(2,1,threads.length,1).setValues(emailDate);
    mysheet.getRange(2,5,threads.length,1).setValues(emailSubject);
    mysheet.getRange(2,6,threads.length,1).setValues(emailBody);

但是,大多数相关的电子邮件都存储在标签中,我很难提取这些。任何时候我尝试设置两层循环:第一个循环标签名称,第二个从每个标签获取线程,我要么 (a)没用的Logger.log数据

   for (var i = 0; i < labels.length; i++) {
     var label = labels[i].getName();
     var labelObject = GmailApp.getUserLabelByName(label).getThreads();
     for (var t = 0; t < labelObject.length; i++){
       Logger.log(labelObject[t]);
     }
   }

制作本

记录输出:

[14-11-19 19:51:19:283 CST] [GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread]
[14-11-19 19:51:19:385 CST] [GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread]
[14-11-19 19:51:23:932 CST] [GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread]

或者我从Google获得了各种超时。

消息详情

Service invoked too many times in a short time: gmail rateMax. Try Utilities.sleep(1000) between calls.

Exceeded maximum execution time Dismiss

我是Google Script的新手,并且一般都没有使用过多的API。我想让这个实用程序来处理我应该做的一些死记硬背和可编程工作,并学习一些关于javascript迭代的过程。我似乎也会学习一些关于服务配额的事情。

任何人都可以帮助我(a)解决这个问题或(b)指出我可以学习如何解决这个问题的地方。任何资源都会有所帮助,即使它在 HOW 上有一些指示来阅读Google Script文档。

链接到完整脚本 - &gt;的 http://pastie.org/9732292

1 个答案:

答案 0 :(得分:2)

所以,好消息是,你肯定是在正确的轨道上,但是你做出的一两个错误就是把你踢到了这里。首先,快速解释您收到的错误消息。

问题1:

你为什么得到:

[14-11-19 19:51:19:283 CST] [GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread, GmailThread]

是因为这一行:

var labelObject = GmailApp.getUserLabelByName(label).getThreads();

字面上 刚刚获得该帖子。如果将它与您的行进行比较:

  var threads = GmailApp.getInboxThreads();
  var messages = GmailApp.getMessagesForThreads(threads); 

你可以看到你真正想要的东西:

var labelObject = GmailApp.getUserLabelByName(label).getThreads();
var labelMessages = GmailApp.getMessagesForThreads(labelObject);

这会为您提供实际的消息,这是您正在寻找的内容。

问题2:

你得到的原因:

Exceeded maximum execution time Dismiss

是因为你超过了每个脚本可以拥有的maximum execution time of 6 minutes。您可能已经注意到您的脚本需要很长时间才能运行,然后失败。这就是为什么你得到的超过最长执行时间&#39;。

第二个:

Service invoked too many times in a short time: gmail rateMax. Try Utilities.sleep(1000) between calls.

是一个&#39;速率限制&#39;因为服务被调用太多次,太快了。通常你可以减慢一点,但这可能没有必要。如果你在一切正常的情况下继续这样做,请提出一个新问题,我们可以谈论&#39; Utilities.sleep(1000)&#39;。

现在我已经覆盖了错误消息:

解释我是如何完成它的最简单方法可能是给你带有注释的代码:

  for (var i = 0; i < labels.length; i++) {//Runs a for loop to get all the labels. 
     var label = labels[i].getName();//Gets the label name. 
     var labelObject = GmailApp.getUserLabelByName(label).getThreads();//Gets the threads in that label. 
    for (var j = 0; j <labelObject.length; j++){//Runs a for loop for all the threads in a label. 
     var labelMessages = GmailApp.getMessagesForThreads(labelObject);//Gets the actual messages in the thread. 
    if (labelMessages[j] == undefined){// The label might be empty, so we have to tell it what to do if that's the case. 
    //Do nothing. 
    //Or log that it was undefined. 
    //I don't care, I'm a comment not a cop. 
    }else{//If it's not empty.
     emailBody.push(["  "]);    
     emailFrom.push([labelMessages[j][0].getFrom()]);
     emailTo.push([labelMessages[j][0].getTo()]);
     emailDate.push([labelMessages[j][0].getDate()]);
     emailSubject.push([labelMessages[j][0].getSubject()]);
    }
   }
  }

旁注:

这实际上会破坏脚本的当前值设置部分:

   // ** THEN, LOG THE FILLED DATA ARRAYS TO ROWS **
  //getSheetValues(startRow, startColumn, numRows, numColumns)
    mysheet.getRange(2,4,threads.length,1).setValues(emailFrom);
    mysheet.getRange(2,3,threads.length,1).setValues(emailTo);
    mysheet.getRange(2,1,threads.length,1).setValues(emailDate);
    mysheet.getRange(2,5,threads.length,1).setValues(emailSubject);
    mysheet.getRange(2,6,threads.length,1).setValues(emailBody);

在这里你要告诉它你希望行数等于&#39; threads.length&#39;,由于数组长度与线程长度相同,所以直到现在才行,但是现在它们不可能(因为收件箱中的线程数已将标签添加到阵列中的线程数)。这是一个简单的修复,您希望它等于数组的长度:

mysheet.getRange(2,4,emailFrom.length,1).setValues(emailFrom);
mysheet.getRange(2,3,emailTo.length,1).setValues(emailTo);
mysheet.getRange(2,1,emailDate.length,1).setValues(emailDate);
mysheet.getRange(2,5,emailSubject.length,1).setValues(emailSubject);
mysheet.getRange(2,6,emailBody.length,1).setValues(emailBody);

(无论如何这都是好习惯!)

如果您遇到问题,可以找到我已修改的完整代码here

注意事项:

目前,脚本设置为获取收件箱中的所有邮件以及标签中的所有邮件,因此,基本上是您帐户中的所有邮件。 这不起作用,因为消息量可能非常高。相反,您应该在收件箱更频繁中获得数量的邮件,方法是使用a range for the 'getInboxThreads'并设置&#39; for&#39;标签的语句仅索引一些最新的消息,例如,而不是:

for (var j = 0; j <labelObject.length; j++)

您可以将其设置为获取每个标签中的最后50个:

 for (var j = 0; j < 50; j++)

如果你继续得到我上面谈到的超时或速率限制错误,这可能就是原因,你需要缩小你的索引的范围(Scripts赢得了&#39; Get如果您收到大量邮件,则会在您的帐户中收到所有邮件。