Google联系人更新失败:People.People.getContact方法报错排查
People.People.getContact()调用失败 背景
我开发了一个Google Apps Script脚本,可从表格读取联系人信息并在Google Contacts中创建新联系人,创建逻辑运行正常。脚本会将外部联系人ID、Resource name和etag保存至名为"Mapping Google Contacts"的第二个表格,用于后续查找那些初始无邮箱/电话但至少有姓名和物理地址的联系人。
表格示例数据:
ID Personne Appsheet Ressource name etag CF32F4F6 people/c184383266205945415 %EigBAgMEBQYHCAkKCwwNDg8QERITFBUWFxkfISIjJCUmJy40NTc9Pj9AGgQBAgUHIgxMNlNjOFJMcG55TT0=
问题详情
执行updateContact函数时失败,经排查定位到const contact = People.People.getContact(resourceName);这行代码报错。相关函数代码片段如下:
function updateContact(personData) { const spreadsheetId = "1NNkW8joHAWXgatSXyAu0O4fjPgkgYeZVjx4s9KZkAZw"; // Replace with your spreadsheet ID const ss = SpreadsheetApp.openById(spreadsheetId); const lookupSheet = ss.getSheetByName("Mapping Google Contacts"); let resourceName = findContactByAppsheetId(personData.appsheetId, lookupSheet); Logger.log("resourceName : " + resourceName) Logger.log("resourceName (before prefix): " + resourceName); if (resourceName) { try { Logger.log("getcontact"); const contact = People.People.getContact(resourceName); Logger.log("getcontact after " + contact); if (contact) { Logger.log("Contact found"); const updatedContact = { // Create a *new* contact object names: [{ givenName: personData.firstName || (contact.names && contact.names.length > 0 ? contact.names[0].givenName : ""), familyName: personData.lastName || (contact.names && contact.names.length > 0 ? contact.names[0].familyName : "") }], phoneNumbers: [], // Initialize phoneNumbers as an empty array emailAddresses: [], // Initialize emailAddresses as an empty array organizations: [], // Initialize organizations as an empty array addresses: [], // Initialize addresses as an empty array birthdays: contact.birthdays ? [...contact.birthdays] : [], user_defined: contact.user_defined ? {...contact.user_defined} : {} }; Logger.log("updatedContact created"); // 后续代码省略
排查与解决方案
1. 校验Resource Name格式
Google People API的getContact方法要求resourceName必须是people/[ID]的完整格式,从表格示例看格式正确,但需确认findContactByAppsheetId返回值是否存在多余空格或拼写错误。可以添加日志查看原始返回值:
Logger.log("Raw resourceName: '" + resourceName + "'"); // 用单引号包裹,便于识别前后空格
若存在空格,用resourceName = resourceName.trim()处理。
2. 确认API权限与启用状态
- 确保脚本已启用People API:在脚本编辑器中依次点击「扩展程序」→「Apps Script API」,确认已启用;同时在左侧「服务」面板添加People API(点击「添加服务」,找到People API并添加)。
- 检查授权状态:运行脚本时是否已授权访问Google Contacts的权限,若授权过期或被撤销,重新授权即可。
3. 验证联系人是否存在
保存的resourceName对应的联系人可能已被手动删除,此时调用getContact会返回404错误。可以添加异常捕获验证:
try { const contact = People.People.getContact(resourceName); } catch (e) { Logger.log("Error fetching contact: " + e.message); if (e.message.includes("404")) { // 联系人不存在,可移除映射表格中的对应记录或重新创建 Logger.log("Contact not found, removing from mapping sheet"); // 此处可添加删除对应行的逻辑 } }
4. 指定API调用的字段参数
People.People.getContact方法可通过personFields参数指定需要获取的字段,显式指定字段可避免默认返回字段不足的问题,同时符合API规范:
const contact = People.People.getContact(resourceName, { personFields: "names,phoneNumbers,emailAddresses,addresses,birthdays,userDefined" });
注意字段名使用驼峰式(如userDefined而非user_defined),多个字段用逗号分隔。
5. 同步etag(可选)
若之前保存的etag已过期,虽不会直接导致getContact报错,但后续更新可能失败。可在获取联系人后对比etag,不一致则更新映射表格中的值:
// 从映射表格中获取对应行的savedEtag const savedEtag = lookupSheet.getRange(row, 3).getValue(); if (contact.etag !== savedEtag) { lookupSheet.getRange(row, 3).setValue(contact.etag); }
内容的提问来源于stack exchange,提问作者Martin Leblanc

