You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Sheets与Google Contacts联动异常:B用户新联系人未同步

问题分析

原代码存在两个核心问题导致B用户的联系人无法正常同步:

  1. 无增量同步逻辑:每次运行都会全量追加当前用户的所有联系人,既产生大量重复数据,也无法实现需求中的「新增联系人同步」目标。
  2. 触发器与权限隐患:若A用户创建的触发器被B复用,触发器会以A的身份运行,无法访问B的联系人;同时需确保B对共享表格拥有编辑权限,且脚本已获得B的People API授权。
修正后的解决方案

以下是实现增量同步+权限兼容的代码:

// 同步新增联系人到共享表格
function syncNewContactsToSheet() {
  const sharedSheetId = 'PUT_SHARED_SHEET_ID_HERE';
  const sheet = SpreadsheetApp.openById(sharedSheetId).getSheetByName('联系人同步'); // 指定工作表名称避免误操作
  const currentUser = Session.getActiveUser().getEmail();
  
  // 获取表格中已存在的联系人邮箱(用于去重)
  const existingEmails = sheet.getDataRange().getValues()
    .filter(row => row[1] !== 'No Email')
    .map(row => row[1]);

  // 调用People API获取当前用户的联系人,按最后修改时间倒序排序
  const people = People.People.Connections.list('people/me', {
    personFields: 'names,emailAddresses,phoneNumbers,metadata',
    pageSize: 1000,
    sortOrder: 'LAST_MODIFIED_DESCENDING'
  }).connections;

  if (!people || people.length === 0) {
    Logger.log('未找到联系人');
    return;
  }

  // 筛选出表格中不存在的新增联系人
  const newContacts = people.filter(person => {
    const email = person.emailAddresses?.[0]?.value || 'No Email';
    return email !== 'No Email' && !existingEmails.includes(email);
  });

  // 批量写入新增联系人(比逐行append更高效)
  if (newContacts.length > 0) {
    const rowsToAppend = newContacts.map(person => {
      const name = person.names?.[0]?.displayName || 'No Name';
      const email = person.emailAddresses?.[0]?.value || 'No Email';
      const phone = person.phoneNumbers?.[0]?.value || 'No Phone';
      const lastModified = person.metadata?.sources?.[0]?.updateTime || new Date().toISOString();
      return [name, email, phone, currentUser, lastModified];
    });
    sheet.getRange(sheet.getLastRow() + 1, 1, rowsToAppend.length, 5).setValues(rowsToAppend);
    Logger.log(`成功同步${newContacts.length}个新增联系人`);
  } else {
    Logger.log('无新增联系人需要同步');
  }
}

// 为当前用户设置定时触发器(每小时运行一次)
function setupSyncTrigger() {
  // 先删除现有同名触发器避免重复
  const existingTriggers = ScriptApp.getProjectTriggers();
  for (const trigger of existingTriggers) {
    if (trigger.getHandlerFunction() === 'syncNewContactsToSheet') {
      ScriptApp.deleteTrigger(trigger);
    }
  }

  // 创建新触发器
  ScriptApp.newTrigger('syncNewContactsToSheet')
    .timeBased()
    .everyHours(1)
    .create();
  Logger.log('定时触发器已创建');
}
关键改进点
  • 增量同步:通过读取表格已有邮箱列表,精准筛选当前用户的新增联系人,彻底避免重复数据。
  • 高效写入:使用setValues批量写入替代appendRow,大幅提升同步性能。
  • 权限兼容:每个用户需自行运行setupSyncTrigger,创建以自身身份运行的触发器,确保能访问个人联系人数据。
  • 可追溯性:新增联系人最后修改时间字段,便于追踪同步记录。
部署步骤
  1. 确保A、B两位用户都对共享Google表格拥有编辑权限。
  2. 两位用户分别打开脚本编辑器,运行setupSyncTrigger函数,完成授权流程(需授权People API和Spreadsheet API访问权限)。
  3. 触发器会自动每小时运行一次,同步各自的新增联系人到共享表格。

内容的提问来源于stack exchange,提问作者Jayashree Nandi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 06:50:03