【问题标题】:How to fetch all (more than 2000) contacts from Google Contacts using People API如何使用 People API 从 Google 联系人中获取所有(超过 2000 个)联系人
【发布时间】:2018-06-14 04:20:13
【问题描述】:

我正在使用 Node.js 开发 Google API。我需要从谷歌联系人中检索所有联系人列表。列表中有超过 2000 个联系人,但页面大小限制为 2000,所以我只得到 2000 个联系人,使用“people.connections.list”方法。有人可以帮忙吗?如何获取所有联系人?

【问题讨论】:

  • 您可以使用pageToken 检索超过 2000 的值。要使用它,请在字段中包含nextPageToken 并请求它。返回前 2000 个值时,您可以在值中看到 nextPageToken。接下来,请通过将nextPageToken 的值添加到查询中来请求它。这样,您可以检索 2001 年的值。如果您想要的值超过 4000,请继续此流程。当返回值中不包含nextPageToken时,表示检索到所有数据。
  • 如果值超过 2000,我将在响应中获取 nextPageToken 值。现在,如何使用该字符串并获取剩余值?
  • 我真的很抱歉我的英语水平不好。接下来,请通过将 nextPageToken 的值添加到查询中来请求它。这样,您可以检索 2001 年的值。如果您想要的值超过 4000,请继续此流程。当返回值中不包含 nextPageToken 时,表示检索到所有数据。

标签: node.js oauth-2.0 google-api


【解决方案1】:

我设法通过使用 recursion 和一些 ES6 特性使其工作。

诀窍是在您的下一个请求中使用从上一个请求返回的nextPageToken,因为根据文档,people.connections.list 的最大限制为 2000。

const getAllContacts = async (googleApi, current = [], pageToken = undefined) => {
  const { 
    data: { connections, nextPageToken, totalItems } 
  } = await googleApi.connections.list({
    resourceName: 'people/me',
    pageSize: 2000,
    personFields: 'emailAddresses,phoneNumbers', // or whatever personFields you want
    ...(pageToken ? { pageToken } : {})
  });

  // merge contacts from this request with data from your previous requests
  const contacts = [...current, ...connections];

  if (nextPageToken && contacts.length < totalItems) {
    return getAllContacts(googleApi, contacts, nextPageToken);
  }

  return contacts;
}

要使用此方法,请确保googleAPI 是 people api 的实例,如下所示

const { people } = google.people({ version: 'v1' });
const contacts = await getAllContacts(people);

【讨论】:

    【解决方案2】:

    这出乎意料地复杂,所以我将我的解决方案分享给其他人。可能有一种更简单的方法可以做到这一点,但这就是我让它工作的方式。这是 javascript ES6 解决方案。

    在尝试了一堆方法之后,异步递归最终对我有用。

    这是我的基本获取联系人调用:

    const fetchContacts = _gapi =>
        _gapi.client.people.people.connections
          .list({
            resourceName: 'people/me',
            pageSize: 2000,
            personFields,
          })
          .then(async response => {
            const { connections, nextPageToken } = response.result;
            const contacts = [...connections];
    
            if (contacts.length >= 2000) {
              await getAllContacts(contacts, nextPageToken, _gapi);
            }
    
            return contacts;
          }).catch(console.error)
    

    在 then 块中,如果有超过 2000 个联系人,我有一个条件调用 getAllContacts

    getAllContacts 是一个异步递归函数,只要有更多联系人要获取,就会调用getContacts

    const getAllContacts = async (_people, _token, _gapi) => {
      if (_people.length < 2000) {
        // terminal case
        const result = await getContacts(_gapi, _token);
        return _people.push(...result.people);
      }
    
      // block to execute
      const { people, nextPageToken } = await getContacts(_gapi, _token);
      _people.push(...people);
      getAllContacts(people, nextPageToken, _gapi);
    };
    

    get contacts 只是 gapi fetch 调用的简单包装,它返回联系人和下一页令牌。

    const getContacts = (_gapi, _nextPageToken) =>
      _gapi.client.people.people.connections
        .list({
          resourceName: 'people/me',
          pageSize: 2000,
          personFields,
          pageToken: _nextPageToken,
        })
        .then(response => {
          const { connections, nextPageToken } = response.result;
          return { people: connections, nextPageToken };
        });
    
    

    【讨论】:

    • 如果你使用这个,别忘了填写personFields。所以我有一个全局变量const personFields='emailAddresses,names,photos';
    • 如果有更简单/更好的方法,请分享。
    【解决方案3】:

    我发现 pageSize 的限制为 1000 -> https://developers.google.com/people/api/rest/v1/people.connections/list#try-it

    所以当联系人超过 1000 时,应该应用上述建议。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多