Google Sheets与Google Contacts联动异常:B用户新联系人未同步
问题分析
原代码存在两个核心问题导致B用户的联系人无法正常同步:
- 无增量同步逻辑:每次运行都会全量追加当前用户的所有联系人,既产生大量重复数据,也无法实现需求中的「新增联系人同步」目标。
- 触发器与权限隐患:若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,创建以自身身份运行的触发器,确保能访问个人联系人数据。 - 可追溯性:新增联系人最后修改时间字段,便于追踪同步记录。
部署步骤
- 确保A、B两位用户都对共享Google表格拥有编辑权限。
- 两位用户分别打开脚本编辑器,运行
setupSyncTrigger函数,完成授权流程(需授权People API和Spreadsheet API访问权限)。 - 触发器会自动每小时运行一次,同步各自的新增联系人到共享表格。
内容的提问来源于stack exchange,提问作者Jayashree Nandi
相关产品推荐
相关产品推荐

