将(大量)Gmail数据记录到Google表格中

时间:2014-12-01 04:42:02

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

我的Google App脚本的目的是在一定时间范围内(尚未实施)将所有基本数据从所有标签中记录到Google表格中。

这目前在有限的程度上有效。它会收集少量的电子邮件,但如果我增加这个(我有很多电子邮件要记录),如果我暂停500或1000毫秒(如下所示),这段代码将‘Exceeded maximum execution time’,否则我点击另一个ratemax配额Service invoked too many times in a short time: gmail rateMax. Try Utilities.sleep(1000) between calls.

在下面的代码中,我相信我尝试使用WHILE循环重复主循环20次,这是一种查看我是否可以执行此单次抓取加载var labelThreads = GmailApp.getUserLabelByName(label).getThreads(start, 1) 20次的方法。这将是开始跟踪"批次" - 它没有相当的工作,我相信有更好的方法来解决这个问题,需要一些帮助。

function whenV24() {  
  function setColumnNames(range, columnNames){
    var cell = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0].getRange(range);
    cell.setValues(columnNames);
  }
  setColumnNames("A1:G1", [["Date","Label","To","From","Subject","Body","File Names"]]);
  betterGetV24();
}



  function betterGetV24() {
  var myspreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var mysheet = myspreadsheet.getSheets()[0];
  var threads = GmailApp.getInboxThreads();
  var messages = GmailApp.getMessagesForThreads(threads); 

  // ** LABEL NAME COLLECTION **  
  var labels = GmailApp.getUserLabels();

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

  // ** LOAD "INBOX EMAIL 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()]);
    emailSubject.push([messages[i][0].getSubject()]);
    emailDate.push([Utilities.formatDate(messages[i][0].getDate(), "GMT", "yyyy-MM-dd'T'HH:mm:ss'Z'")]);
    emailLabel.push(["Inbox"]);
  };

  // ** LOAD "LABELED EMAIL DATA" INTO EMPTY ARRAYS **
  for (var l = 0; l < labels.length; l++) {                                       // ** Runs a for-loop over "labels array". 
      var label = labels[l].getName();                                            //    Gets "this" label name.       
      var start = 0; // sets start number as 0
      var tracker = 0;


    // this section of code has to loop based on a separate set of logic
    while (start < 20){
      tracker++;
      Logger.log("tracker :" + tracker);
        var labelThreads = GmailApp.getUserLabelByName(label).getThreads(start, 1); //    Gets threads in "this" label. (*Set Limits Here*) 
        var labelMessages = GmailApp.getMessagesForThreads(labelThreads);         //    Gets array with each email from "this" thread. 


        Utilities.sleep(500);       // pause in the loop for 500 milliseconds

        for (var t = 0; t <labelThreads.length; t++){                                 // ** Runs a for-loop over threads in a label. 
            Logger.log("part 1 - inside for-loop over message number: " + labelMessages[t][0].getId());
            Utilities.sleep(500);// **pause in the loop for 500 milliseconds

          if (labelMessages[t] == undefined){}      // If it's empty, skip.
            else {                                  // If it's not empty.
              Logger.log("part 2 - inside if statement in for-loop > push emailData into arrays");

              emailBody.push([" "]);    
              emailFrom.push([labelMessages[t][0].getFrom()]);
              emailTo.push([labelMessages[t][0].getTo()]);        
              emailDate.push([Utilities.formatDate(labelMessages[t][0].getDate(), "GMT", "yyyy-MM-dd'T'HH:mm:ss'Z'")]);
              emailSubject.push([labelMessages[t][0].getSubject()]);
              emailLabel.push([labels[l].getName()]);
              mysheet.getRange(2,2,emailLabel.length,1).setValues(emailLabel);
          }
       }
      Logger.log("part 3 - outside if statement -> start += 2")
      var start = start + 3;
    }
      Logger.log("part 4 - outside while loop"); 

  }
  // ** THEN, LOG THE FILLED DATA ARRAYS TO ROWS **
  //getSheetValues(startRow, startColumn, numRows, numColumns)
  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);
}

我认为此时我应该使用触发器,但似乎我还必须跟踪上一批电子邮件记录并继续下一批。我也不知道如何将其与触发器联系起来。

感谢阅读。任何帮助表示赞赏。

修改

我在这里错误地将数据设置到电子表格中。对于每个循环,我试图在电子表格中设置数据。我不确定我是怎么做到的。只需将其移出循环并稍后进行设置即可解决问题。这里更新了代码:http://pastie.org/9793256#96,100,109,117,123-125,131,135-139

    for (var t = 0; t <labelThreads.length; t++){                                 // ** Runs a for-loop over threads in a label. 
                    Logger.log("part 1 - inside for-loop over message number: " + labelMessages[t][0].getId());
                    Utilities.sleep(500);// **pause in the loop for 500 milliseconds

                  if (labelMessages[t] == undefined){}      // If it's empty, skip.
                    else {                                  // If it's not empty.
                      Logger.log("part 2 - inside if statement in for-loop > push emailData into arrays");

                      emailBody.push([" "]);    
                      emailFrom.push([labelMessages[t][0].getFrom()]);
                      emailTo.push([labelMessages[t][0].getTo()]);        
                      emailDate.push([Utilities.formatDate(labelMessages[t][0].getDate(), "GMT", "yyyy-MM-dd'T'HH:mm:ss'Z'")]);
                      emailSubject.push([labelMessages[t][0].getSubject()]);
                      emailLabel.push([labels[l].getName()]);

// ** INCORRECTLY TRYING TO SET DATA PER LOOP **
                      mysheet.getRange(2,2,emailLabel.length,1).setValues(emailLabel);
                  }
               }

1 个答案:

答案 0 :(得分:4)

您可以使用PropertiesService在本地存储上次处理的电子邮件的索引。然后,您可以将“start”参数添加到GmailApp.search()方法,以便从最后一个位置开始搜索,并将整个事件设置为每5或10分钟触发一次。

function myTrigger() {
  var start = PropertiesService.getScriptProperties().getProperty("startIndex");
  var threads = GmailApp.search("in:inbox", start, 200);
  for (var t in threads) {
     // Log the thread using your existing code
     start++;
  }
  PropertiesService.getScriptProperties().setProperty("startIndex", start);
}