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

如何通过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.searchContacts API接口
  • 传入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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 09:01:06