Google Apps脚本随机停止或拒绝启动

时间:2012-12-19 08:57:58

标签: google-apps-script

我在Google云端硬盘电子表格中开发了一个Google Apps脚本,用于处理带有特定标签的电子邮件(下载通知)并将其添加到电子表格中。我正在通过电子表格的脚本编辑器运行它。

我的初始解决方案非常低效 - 每次在所有电子邮件上重复整个分析,这导致运行时间每天都在增加。几天前我收到一条错误消息“超出运行时间”,这并不奇怪。

我的问题是,当尝试更新脚本以提高效率时,我会遇到一些奇怪的问题。处理完几封电子邮件后,脚本会随机停止,或者只是拒绝启动。特别是脚本调试器,它开始加载但从未启动。

我在过去几天尝试了几次,甚至创建了一个具有相同代码(在同一帐户中)的新电子表格,但仍然存在这些问题。

有时当脚本运行一段时间后,我注意到脚本输出日志与日志记录中的最近更改不匹配。我当然在运行之前保存了脚本。感觉有一些锁阻止我的脚本运行/更新/刷新?

这里有没有人认识到这些问题?

代码如下。 两个相关的切入点是:

processInbox:根据具有特定标签的新(已加星标)电子邮件更新电子表格。标签和星标由接收时的电子邮件过滤器设置。处理后,每条消息中都会删除星号(表示“新”)。

resetAllMsgs:清除电子表格并标记所有相关消息,导致processInbox处理使用相关标签收到的所有消息。

function resetAllMsgs() {
  Logger.log("Starting ResetAll");

  var d = SpreadsheetApp.getActive();

  var dl_sheet = d.getSheetByName("Download List");
  var dlperday_sheet = d.getSheetByName("DownloadsPerDay");

  dl_sheet.clear();
  dlperday_sheet.clear();

  Logger.log("Clearing spreadsheet");

  dl_sheet.appendRow(["", "", "Downloads", ""]);
  dl_sheet.appendRow(["", "", "Downloaders", ""]);

  dl_sheet.appendRow(["Last Download Date", "First Download Date", "Email" , "Product", "Download Count"]);

  dlperday_sheet.appendRow(["Date", "Download Count"]);

  var label = GmailApp.getUserLabelByName("Download Notification");

  // get all threads of the label
  var threads = label.getThreads();

  for (var i = 0; i < threads.length; i++) {
    // get all messages in a given thread
    var messages = threads[i].getMessages();

    Logger.log("Starring thread " + i);

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

      Logger.log("   Starring message " + j);

      // Only starred messages are processed by processInbox
      messages[j].star();

      Utilities.sleep(100);

    }
  }
};

function processInbox() {

  var d = SpreadsheetApp.getActive();

  var dl_sheet = d.getSheetByName("Download List");
  var dlperday_sheet = d.getSheetByName("DownloadsPerDay");

  // If empty spreadsheet, reset the status of all relevant e-mails and add the spreadsheet headers
  if (dl_sheet.getLastRow() <= 1) {
    resetAll();
  }

  var label = GmailApp.getUserLabelByName("Download Notification");
  var k = 0;

  // get all threads of the label
  var threads = label.getThreads();

  for (var i = 0; i < threads.length; i++) {

    if (threads[i].hasStarredMessages()) {

      // get all messages in a given thread
      var messages = threads[i].getMessages();

      // iterate over each message
      for (var j = 0; j < messages.length; j++) {

        // Unread messages are not previously processed...
        if (messages[j].isStarred()) {

          var msg = messages[j].getBody();

          msg = msg.replace(/\r?\n/g, "");

          var email = getDownloader(msg);

          if (email == "") {
            Logger.log("Found no downloader info: " + messages[j].getSubject() + " " + messages[j].getDate());
          }

          var date = formatDate(getDownloadDate(msg));

          // Check if a new date
          var dateCell = find(date, dlperday_sheet.getDataRange(), 0);

          if (dateCell == null) {
            // If new date, append row in "downloads per day"
            dlperday_sheet.appendRow([date, 1]);
            dlperday_sheet.getRange(2, 1, dl_sheet.getLastRow()-1, 2).sort([1]);
          }
          else
          {
            // If existing date, update row in "downloads per day"
            var dlcount = dlperday_sheet.getRange(dateCell.getRow(), dateCell.getColumn()+1).getValue();
          }

          var productname = getProductName(msg);

          // Check if e-mail (user) already exists in the downloads list
          var matchingCell = find(email, dl_sheet.getDataRange(), 0);

          if ( matchingCell != null ) { 
            // If user e-mail exists, update this row

            var lastDownloadDate = dl_sheet.getRange(matchingCell.getRow(), matchingCell.getColumn()-1).getValue();
            var lastDownloadCount = dl_sheet.getRange(matchingCell.getRow(), matchingCell.getColumn()+2).getValue();

            if (lastDownloadDate != date) {                
              dl_sheet.getRange(matchingCell.getRow(), matchingCell.getColumn()-1).setValue(date);                
            }

            dl_sheet.getRange(matchingCell.getRow(), matchingCell.getColumn()+2).setValue(lastDownloadCount+1);          

          }
          else // If new user e-mail, add new download row
          {
            dl_sheet.appendRow([date, date, email, productname, 1]);
            dl_sheet.getRange(2, 4).setValue(dl_sheet.getRange(2, 4).getValue() + 1);  
            dl_sheet.getRange(4, 1, dl_sheet.getLastRow()-3, 5).sort([1]);
          }

          // Mark message as processed, to avoid processing it on the next run
          messages[j].unstar();

        }
      }
    }
  }     
};

/**
 * Finds a value within a given range. 
 * @param value The value to find.
 * @param range The range to search in.
 * @return A range pointing to the first cell containing the value, 
 *     or null if not found.
 */
function find(value, range, log) {
  var data = range.getValues();
  for (var i = 0; i < data.length; i++) {
    for (var j = 0; j < data[i].length; j++) {
      if (log == 1)
      {
        Logger.log("Comparing " + data[i][j] + " and " + value);
      }
      if (data[i][j] == value) {
        return range.getCell(i + 1, j + 1);
      }
    }
  }
  return null;
};

function getDownloader(bodystring) {
  var marker = "Buyer Info";
  var marker_begin_index = bodystring.indexOf(marker, 1000);
  var email_begin_index = bodystring.indexOf("mailto:", marker_begin_index) + 7;

  var email_end_index = bodystring.indexOf("\"", email_begin_index);

  if (email_end_index < 1000)
  {
    return "";
  }

  var email = bodystring.substring(email_begin_index, email_end_index);

  if (log == 1)
  {
    Logger.log("Found e-mail address: " + email + "");
    Logger.log("   marker_begin_index: " + marker_begin_index);
    Logger.log("   email_begin_index: " + email_begin_index);
    Logger.log("   email_end_index: " + email_end_index);
  }

  latestIndex = email_end_index;

  return email;

};


function formatDate(mydate)
{  
  var str = "" + mydate;

  var dateParts = str.split("/");

  var day = dateParts[1];
  if (day.length == 1)
    day = "0" + day;

  var month = dateParts[0];
  if (month.length == 1)
    month = "0" + month;

  return dateParts[2] + "-" + month + "-" + day; 
};

function getDownloadDate(bodystring) {
  var marker = "Download Date:</strong>";
  var marker_begin_index = bodystring.indexOf(marker, latestIndex);
  var date_begin_index = marker_begin_index + marker.length;

  var date_end_index = bodystring.indexOf("<br>", date_begin_index);

  latestIndex = date_end_index;

  return bodystring.substring(date_begin_index, date_end_index).trim();  
};


function getProductName(bodystring) {
  var marker = "Item:</strong>";
  var marker_begin_index = bodystring.indexOf(marker, latestIndex);
  var pname_begin_index = marker_begin_index + marker.length;
  var pname_end_index = bodystring.indexOf("</td>", pname_begin_index);

  latestIndex = pname_end_index;

  return bodystring.substring(pname_begin_index, pname_end_index).trim();

};

1 个答案:

答案 0 :(得分:0)

更新:我运行的任何脚本在大约5秒后停止,即使它没有调用任何服务。 我尝试了以下代码:

function test() {
  Logger.log("Test begins");
  Utilities.sleep(5000);
  Logger.log("Test ends");
} 

脚本在大约5秒后终止,但不打印最后一行。如果将延迟减少到3秒,则表现如预期。

此外,为了在修改脚本后正确更新脚本,我需要保存它,启动它,单击取消,然后再次启动它,否则日志输出似乎来自旧版本。 (我是通过脚本编辑器运行的。)

此外,调试器拒绝启动,即使对于上面的小脚本也是如此。似乎是我帐户的一些问题(johan.kraft@percepio.se)。那里有谷歌员工可以查看吗?