如何通过Google People API的people.searchContacts获取超30条联系人数据
问题说明
问题简要描述
我们需要基于指定域名搜索查询对应的Google联系人,因此调用Google People API提供的people.searchContacts方法实现联系人搜索功能。
该方法可根据传入的域名参数正确返回匹配的联系人结果,基础功能运行正常,但存在明确限制:根据Google官方people.searchContacts方法的文档说明,接口默认返回10条联系人数据,pageSize参数最大仅支持设置为30。
核心疑问:若业务场景需要通过
people.searchContacts方法获取超过30条匹配的联系人数据,应采用什么解决方案?
复现问题的代码示例
public async init(token?): Promise<any> { return new Promise((resolve, reject) => { const clientObj = gapi.client.init({ apiKey: this.googleApiKey, clientId: this.googleClientKey, discoveryDocs: this.DISCOVERY_DOCS, scope: this.SCOPES, prompt: 'select_account' }).then(async () => { try { // 监听登录状态变化 await gapi.auth2.getAuthInstance().isSignedIn.listen(this.updateSigninStatus); if (!gapi.auth2.getAuthInstance().isSignedIn.get()) { await gapi.auth2.getAuthInstance().signIn(); } this.updateSigninStatus(token, gapi.auth2.getAuthInstance().isSignedIn.get()).then(async (result) => { const handleState = [{ 'handleState': result ? [...result.connections] : [] }, { currentUser: await gapi.auth2.getAuthInstance().currentUser.get() }]; const nextPageToken = result.nextPageToken; resolve({handleState, nextPageToken}); }, (err) => { reject(err); }) } catch (err) { if (err) { reject(err); } } }, function (error) { if (error) { reject(error); } }); }) } /** * 按钮点击触发用户登录 */ public async handleAuthClick(): Promise<any> { await gapi.auth2.getAuthInstance().signIn(); } /** * 按钮点击触发用户登出 */ public async handleSignoutClick(): Promise<any> { await gapi.auth2.getAuthInstance().signOut(); } /** * 登录状态变化时触发,用于更新UI * 登录完成后调用接口拉取数据 */ public async updateSigninStatus(token, isSignedIn): Promise<any> { return new Promise(async (resolve, reject) => { if (isSignedIn) { try { const result = await this.listConnectionNames(token); resolve(result); } catch (error) { reject(error) } } else { console.log("无状态需要更新"); } }); } /** * 拉取联系人信息 */ public async listConnectionNames(token): Promise<any> { return new Promise((resolve, reject) => { gapi.client.people.people.searchContacts({ 'readMask': 'names,emailAddresses,phoneNumbers', 'pageSize': 30, 'query': 'sharklasers.com', }).then(function (response) { const connections = response.result.results; const nextPageToken = response.result.nextPageToken; resolve({connections, nextPageToken}); }, (err) => { reject(err); let result = confirm("你未勾选对应权限选项"); gapi.auth2.getAuthInstance().signIn().then(res => { if (result) { alert("正在刷新页面...") window.location.reload(); } }, (err) => { reject(err); }) }); }); }
问题复现步骤
- 调用上述
people.searchContactsAPI接口 - 传入
readMask、pageSize、query三个请求参数 - 接口正常返回匹配结果,但最多仅能获取30条联系人数据
预期实现效果
- 可通过Google People API的
people.searchContacts方法获取超过30条符合搜索条件的联系人数据
解决方案
people.searchContacts接口和Google全系列列表类接口的分页逻辑一致,不需要对接其他替代接口,通过分页循环拉取即可拿到全量匹配数据,具体实现逻辑如下:
- 首次调用接口时
pageSize固定传支持的最大值30,拿到第一批次结果的同时,保存响应体中返回的nextPageToken字段 - 如果
nextPageToken不为空,就把该token作为pageToken参数传入下一次people.searchContacts请求,其余参数(query、readMask、pageSize)和首次请求完全一致,拉取下一批最多30条数据 - 重复上述请求逻辑,直到某次接口返回的
nextPageToken为空,说明已经拉取完所有匹配的联系人,将所有批次返回的结果合并即可得到全量数据
实现过程中的注意事项:
- 分页请求过程中不要修改
query参数,否则会导致搜索条件变化,出现结果重复或遗漏的问题 - 控制请求频率,避免短时间内发送大量请求触发接口限流
- 若匹配的联系人总量较大,前端实现时建议增加加载提示,避免用户长时间等待无感知
核心功能代码参考:
// 全量拉取指定搜索条件下的所有联系人 public async getAllMatchedContacts(query: string): Promise<any[]> { const allContacts: any[] = []; let nextPageToken: string | undefined = undefined; do { const reqParams: any = { readMask: 'names,emailAddresses,phoneNumbers', pageSize: 30, query: query }; // 存在分页token时带入请求 if (nextPageToken) { reqParams.pageToken = nextPageToken; } const res = await gapi.client.people.people.searchContacts(reqParams); const resData = res.result; if (resData.results?.length) { allContacts.push(...resData.results); } nextPageToken = resData.nextPageToken; // 无下一页token时终止循环 } while (nextPageToken); return allContacts; }
内容的提问来源于stack exchange,提问作者Darshita Soni
相关产品推荐
相关产品推荐

