日历eTags不匹配错误 - 采取预防措施,仍然出错

时间:2012-09-18 03:06:33

标签: google-apps-script google-calendar-api google-sheets

我正在为我的工作场所创建Google Apps电子表格名单。实际的名单很简单,有一些计算和onEdit脚本可以改变单元格颜色,具体取决于当时的工作时间。

这个新名册的一个主要部分是能够为每个人创建Google日历活动,以通知他们班次。创建名册,每月创建活动。在月初,执行名册的工作人员将运行一个功能,并为每个人创建该月的所有活动。 (我希望这是有道理的......)

我的代码如下所示。名为“Splash”的工作表(工作表索引0)包含团队中每个工作人员的姓名和电子邮件。将在表索引1到无穷大上创建名单。

在名册表上,A栏包含每个员工的名称。 B列包含开始时间,C包含结束时间。

function sendInvites() {
  // Gather Prelim Information
  var splash = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Splash");
  var nameRange = splash.getRange("A6:B9"); // Need to change this to be the full staff list in Splash

  var inviteSheet = Browser.inputBox("Sheet to send invites from (Number)", Browser.Buttons.OK_CANCEL)
  var days = SpreadsheetApp.getActiveSpreadsheet().getSheets()[inviteSheet];
  var dayRange;

  //Initiate iteration through Names, according to the Splash sheet
  for(nameRow=nameRange.getRow(); nameRow<=9; nameRow++){ //Change to Corresponding iterate
    // Gather Name and Email information for the each person
    var col = nameRange.getColumn();
    var row = nameRow;
    var name = splash.getRange(row, col).getValue();
    var email = splash.getRange(row, col+1).getValue();
    var cal = CalendarApp.getCalendarById(email);

    //Initiate iteration through Days, according to the Roster
    for(i=0; i<=6; i++){
      //Specify Day Ranges
      switch(i){
        case 0: //Saturday
          dayRange = days.getRange("A1:O6"); break;
        case 1: //Sunday
          dayRange = days.getRange("A10:O15"); break;
        case 2: //Monday
          dayRange = days.getRange("A19:O41"); break;
        case 3: //Tuesday
          dayRange = days.getRange("A45:O67"); break;
        case 4: //Wednesday
          dayRange = days.getRange("A71:O93"); break;
        case 5: //Thursday
          dayRange = days.getRange("A97:O119"); break;
        case 6: //Friday
          dayRange = days.getRange("A123:O145"); break;
      }

      //Find Name in dayRange
      for(dayRow=dayRange.getRow(); dayRow<=dayRange.getLastRow(); dayRow++){
        var searchCol = dayRange.getColumn();
        var searchRow = dayRow;        
        var searchName = days.getRange(searchRow, searchCol).getValue();

        if (name==searchName){
          // Gather and format Date and Time information for invitation
          var eventName = "Phones";
          var date = Utilities.formatDate(dayRange.getValue(), "GMT+1000", "EEE MMM dd yyyy");
          var startCell = days.getRange(searchRow, searchCol+1).getValue();
          var endCell = days.getRange(searchRow, searchCol+2).getValue();

          if (startCell != ""){
            var startTime = date + " " + Utilities.formatDate(startCell, "GMT+1000", "HH:mm:ss");
            var endTime = date + " " + Utilities.formatDate(endCell, "GMT+1000", "HH:mm:ss");

            //Create a calendar event with the details above
            Utilities.sleep(500); //Pause event creation for half second, to allow the last event to be fully created (Avoids "Calendar: Mismatch: etags error")
            cal.createEvent(eventName, new Date(startTime), new Date(endTime)).removeAllReminders();
          }

          continue;
        }
      }
    }
  }
}

我现在遇到的问题是逻辑有效,但并非所有事件都在创建。我正在测试四名员工,包括我自己。它只会在抛出日历之前完成名称的一次半迭代:不匹配:etags错误。

我知道当一次更改日历两次时会发生此错误。我在事件创建之前添加了半秒的睡眠时间以允许这个。现在这种情况很少见,但仍在发生。我试过让它睡2秒钟,我试过把它移到不同的地方。所有这些仍然会导致eTags错误。

不太确定从哪里开始。我觉得名单几乎已经准备就绪,但它还不够稳定。

如果您有任何想法,或者您需要澄清,请告诉我。

1 个答案:

答案 0 :(得分:1)

你需要一个try / catch来避免“etags”错误。生成错误的操作是removeAllReminders(),因为在Google的分布式存储中创建新的联系人对象需要一些时间。

我使用辅助函数来避免这些可怕的“etags”错误:

function retryMethod(object, method) {
  for (i=0; i<10; i++) {
    try {
      return object[method]();
    }
    catch (e) {
      if (e.message.indexOf('Mismatch: etags') == -1) throw e;
      Utilities.sleep(500);
    }
  }
  throw new Error('retryMethod failed after retrys method ', method, ' object ', object)
}

然后你可以将你的“cal.createEvent(”行重写为:

retryMethod(cal.createEvent(eventName, new Date(startTime), new Date(endTime)), 'removeAllReminders');

请记住检查createEvent是否为空。

实际上我当前的辅助函数略有不同,因为大多数提出“etags”错误的函数调用实际上都是成功的。