【问题标题】:Google Apps Script Contacts Services errorGoogle Apps 脚本联系人服务错误
【发布时间】:2012-07-24 15:41:36
【问题描述】:

首先,我知道,有一个similar question,但它只是相似而不是相同:)

此脚本在电子表格中导入 Google 联系人 -> Contacts Sevices

function onOpen()
{
  var menuItems = [{name: "Gmail Contact Import", functionName: "getContacts"}];
  SpreadsheetApp.getActiveSpreadsheet().addMenu("import", menuItems);
}

function getContacts()
{
  var groupName = "MyGroup";
  var contacts;
  var sheet = SpreadsheetApp.getActiveSheet();

  if (groupName) {
    var contactGroup = ContactsApp.findContactGroup(groupName);

    if (contactGroup) {
      contacts = contactGroup.getContacts();
    }
  } 
  else {
    contacts = ContactsApp.getAllContacts();
  }

  if (!contacts) {
    Browser.msgBox("no contacts found!");
    return;
  }  

  sheet.clear();

  sheet.getRange("A1").setValue("forename");
  sheet.getRange("B1").setValue("lastname");
  sheet.getRange("C1").setValue("private email");
  sheet.getRange("D1").setValue(groupName + " email");
  sheet.getRange("E1").setValue("phone");
  sheet.getRange("F1").setValue("mobile");
  sheet.getRange("G1").setValue("street");
  sheet.getRange("H1").setValue("zip");
  sheet.getRange("I1").setValue("city");
  sheet.getRange("J1").setValue("group");
  sheet.getRange("K1").setValue("date1");
  sheet.getRange("L1").setValue("date2");
  sheet.getRange("M1").setValue("date3");
  sheet.getRange("N1").setValue("date4");

  for ( var i = 0; i < contacts.length; i++) {
    var addressArray = new Array();
    addressArray = contacts[i].getAddresses(ContactsApp.Field.HOME_ADDRESS);
    var addressArrayLength = addressArray.length;    
    for ( var ii = 0; ii < addressArrayLength; ii++ ) {
      var address = addressArray[ii].getAddress();
      var addressSplit = address.split(/\r\n|\r|\n/);
      var street = addressSplit[0];
      var city = addressSplit[1].split(" ")[0];
      var zip = addressSplit[1].split(" ")[1];
    }
    var homePhone = contacts[i].getHomePhone().replace("0049-","0").toString();
    var mobilePhone = contacts[i].getMobilePhone().replace("0049-","0").toString();
    var fireMail = ""
    var privateMail = "";
    var mailArray = new Array();
    mailArray = contacts[i].getEmails(ContactsApp.Field.HOME_EMAIL);
    var mailArrayLength = mailArray.length;    
    for ( var ii = 0; ii < mailArrayLength; ii++ ) {
      privateMail = contacts[i].getEmails(ContactsApp.Field.HOME_EMAIL)[ii].getAddress();
    }

    if (!privateMail)
    {
      mailArray = contacts[i].getEmails(ContactsApp.Field.WORK_EMAIL);
      mailArrayLength = mailArray.length;

      for ( var ii = 0; ii < mailArrayLength; ii++ ) {
        privateMail = contacts[i].getEmails(ContactsApp.Field.WORK_EMAIL)[ii].getAddress();
      }
    }

    mailArray = contacts[i].getEmails(groupName);
    mailArrayLength = mailArray.length;

    for ( var ii = 0; ii < mailArrayLength; ii++ ) {
      fireMail = contacts[i].getEmails(groupName)[ii].getAddress();
    }

    sheet.getRange(1*i+2, 1, 1, 1).setValue(contacts[i].getGivenName());
    sheet.getRange(1*i+2, 2, 1, 1).setValue(contacts[i].getFamilyName());
    sheet.getRange(1*i+2, 3, 1, 1).setValue(privateMail);
    sheet.getRange(1*i+2, 4, 1, 1).setValue(fireMail);
    sheet.getRange(1*i+2, 5, 1, 1).setValue(homePhone);
    sheet.getRange(1*i+2, 6, 1, 1).setValue(mobilePhone);
    sheet.getRange(1*i+2, 7, 1, 1).setValue(street);
    sheet.getRange(1*i+2, 8, 1, 1).setValue(zip);
    sheet.getRange(1*i+2, 9, 1, 1).setValue(city);

    var groups = contacts[i].getContactGroups();

    for ( var j = 0; j < groups.length; j++) {
      var name = groups[j].getName();
      switch (name) {
        case "group1":
          sheet.getRange(1*i+2, 10, 1, 1).setValue(1);
          break;
        case "group2":
          sheet.getRange(1*i+2, 10, 1, 1).setValue(2);
          break;
        case "group3":
          sheet.getRange(1*i+2, 10, 1, 1).setValue(3);
          break;
        case "group4":
          sheet.getRange(1*i+2, 10, 1, 1).setValue(4);
          break;
        case "group5":
          sheet.getRange(1*i+2, 10, 1, 1).setValue(5);
          break;
        default:
          break;
      }

      if (name.indexOf("datetrigger1") > -1)
      {
        var dateArray = contacts[i].getDates("date1");
        var dateArrayLength = dateArray.length;        
        for ( var ii = 0; ii < dateArrayLength; ii++ ) {
          var date = contacts[i].getDates("date1")[ii];
          var day = date.getDay();
          var month = date.getMonth();
          var year = date.getYear();
          sheet.getRange(1*i+2, 11, 1, 1).setValue(day.toString() + "." + month.toString() + "." + year.toString());
        }
        sheet.getRange(1*i+2, 11, 1, 1).setBackgroundColor('green');
      }

      if (name.indexOf("datetrigger2") > -1)
      {
        var dateArray = contacts[i].getDates("date2");
        var dateArrayLength = dateArray.length;        
        for ( var ii = 0; ii < dateArrayLength; ii++ ) {
          var date = contacts[i].getDates("date2")[ii];
          var day = date.getDay();
          var month = date.getMonth();
          var year = date.getYear();
          sheet.getRange(1*i+2, 12, 1, 1).setValue(day.toString() + "." + month.toString() + "." + year.toString());
        }
        sheet.getRange(1*i+2, 12, 1, 1).setBackgroundColor('green');
      }

      if (name.indexOf("datetrigger3") > -1)
      {
        var dateArray = contacts[i].getDates("date3");
        var dateArrayLength = dateArray.length;        
        for ( var ii = 0; ii < dateArrayLength; ii++ ) {
          var date = contacts[i].getDates("date3")[ii];
          var day = date.getDay();
          var month = date.getMonth();
          var year = date.getYear();
          sheet.getRange(1*i+2, 13, 1, 1).setValue(day.toString() + "." + month.toString() + "." + year.toString());
        }
        sheet.getRange(1*i+2, 13, 1, 1).setBackgroundColor('green');
      }

      if (name.indexOf("datetrigger4") > -1)
      {
        var dateArray = contacts[i].getDates("date4");
        var dateArrayLength = dateArray.length;
        if (dateArrayLength > 0) {
          for ( var ii = 0; ii < dateArrayLength; ii++ ) {
            var date = contacts[i].getDates("date4")[ii];
            var day = date.getDay();
            var month = date.getMonth();
            var year = date.getYear();
            sheet.getRange(1*i+2, 14, 1, 1).setValue(day.toString() + "." + month.toString() + "." + year.toString());
          }
          sheet.getRange(1*i+2, 14, 1, 1).setBackgroundColor('green');
        }
      }
    }
  }

  Browser.msgBox(contacts.length + " contacts imported.");
}

工作正常,但在“导入 xy 联系人”消息后,我收到以下错误消息:

序列化延续时的意外异常

我不知道出了什么问题。

2012-07-26 更新:

我还有一个错误:

Dienst-Fehler:ContactsApp:临时问题 - 请稍后再试 并考虑使用批处理操作。用户超出配额。 (泽勒 96)

关于这一行:var groups = contacts[i].getContactGroups();

我已经稍后再试了...错误仍然出现。我总是在我的列表中得到结果。错误出现在循环的各种迭代之后。

2012-07-27 更新:

我在var groups = contacts[i].getContactGroups(); 之后添加了Utilities.sleep(2000);。这已经足够了。没有那么多联系人...

【问题讨论】:

  • 由于这个问题与Google Apps Script有关,与App Engine无关,所以我编辑了标签。

标签: google-apps-script google-docs-api google-contacts-api


【解决方案1】:

我经常收到这样的错误消息。这是我的工作:

  1. 这可能是 msgBox 调用的结果。替换 Browser.msgBox("...");与 Logger.log("...");然后您可以在脚本编辑器 > 查看 > 日志中查看结果...

  2. 脚本可能需要无法在电子表格 UI 中触发的授权。通过脚本编辑器运行脚本 > 运行 > getContacts。

希望这会有所帮助。

2012 年 7 月 27 日更新:

回答您后来关于配额错误的问题:

Google 有多层防御拒绝服务,其中之一是用户配额。这里列出了一些 GAS 服务配额https://script.google.com/dashboard(转到配额限制选项卡),但并非所有这些配额都是公开的。例如,您的错误不是针对那里列出的配额。

另一层是速率限制,如果您在短时间内(例如 1 秒)进行过多次 API 调用,您可能会达到阈值,这就是我认为发生在您身上的事情。好的做法是使用指数退避。谷歌说你应该使用指数退避执行最多 5 次重试,延迟大约 1、2、4、8 秒,然后 16 秒,总共大约 32 秒,然后你放弃一个不可恢复的错误。见:https://developers.google.com/google-apps/documents-list/#implementing_exponential_backoff

我有一个 GASRetry 库函数,用于自动执行指数退避。我维护它here,它也可作为公共图书馆项目密钥:MGJu3PS2ZYnANtJ9kyn2vnlLDhaBgl_dE

以您的代码行为例,您可以将其包装在 GASRetry 调用中,如下所示:

//var groups = contacts[i].getContactGroups();
var groups = GASRetry.call(function(){contacts[i].getContactGroups()});

这应该可以克服任何短期费率限制。让我们知道你的进展。

【讨论】:

  • 谢谢,但我得到一个额外的错误。查看 UPDATE 2012-07-26 下的问题
  • @XmlmXmlmX 在您更新新错误后,我已经更新了我的答案。
  • 啊,好的。我试过了,但组总是空的?现在我只在var groups = contacts[i].getContactGroups(); 之后添加了Utilities.sleep(2000);。这已经足够了。没有那么多联系人...
猜你喜欢
  • 1970-01-01
  • 2015-05-19
  • 2012-10-02
  • 2021-09-30
  • 1970-01-01
  • 1970-01-01
  • 2015-01-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多