【问题标题】:Is there any way to get Google People API resource ID from Google Contacts contact Id?有没有办法从 Google Contacts 联系人 ID 获取 Google People API 资源 ID?
【发布时间】:2021-05-04 07:00:47
【问题描述】:

我们将用户的contactId 存储在我们的数据库中,并在用户从我们的应用发出请求时使用它来获取/编辑/删除联系人。现在 Google Contacts API 即将停用,我们需要使用资源 ID 为这些操作调用 Google People API。

有什么方法可以从 Google Contacts 联系人 ID 中获取 Google People API 资源 ID?

我在 Stackoverflow 中找到了following answer

Contacts API 和 People API 是独立的 API,并不意味着 互操作。

也就是说,执行此操作的逆向工程方法是采用 Contacts API 联系人 ID,解析该十六进制值,将其转换为 十进制,并为其添加一个“c”前缀,这就是 People API 人员资源 ID。

例如如果 Contacts API 联系人 ID 为 100,则 People API 个人 ID 为 c256。当您从 People API 获取联系人时 以这种方式,它将具有加入的个人资料信息,如果 现在。

我尝试了该解决方案并且它正在工作,但需要知道我们是否可以使用此转换无错误(即没有任何例外)将相应的资源 ID 填充到联系人 ID。

【问题讨论】:

    标签: google-contacts-api google-people-api


    【解决方案1】:

    答案:

    虽然this answer 中提供的解决方法似乎有效,但我认为有一个更详细的方法可以根据contactId 找到 People API 的resourceName

    只要连接来自CONTACTS,此contactId 就是Person resource 的一部分。

    更具体地说,可以在以下资源中找到此信息:

    {
      "resourceName": "people/c...",
      "metadata": {
        "sources": [
          {
            "type": "CONTACT",
            "id": "CONTACT_ID" // Converting to decimal and adding "people/c" results in resource name
          }
        ]
      }
    }
    

    因此,如果您有一个有效的contactId 数组,您可以通过列出您的连接(参见people.connections.list)并检查contactId 是否与嵌套字段中的id 匹配来找到相应的resourceNames如果是这种情况,则检索该连接的resourceName

    代码示例:

    例如,使用 Apps 脚本,您可以检索 contactIdresourceName 的映射,如下所示:

    function getResourceNamesFromContactIds(contactIds) { // contactIds: array with valid contactIds
      const resourceName = "people/me";
      const optionalArgs = {
        personFields: "metadata",
        sources: "READ_SOURCE_TYPE_CONTACT"
      }
      const connections = People.People.Connections.list(resourceName, optionalArgs)["connections"];
      const mapping = contactIds.map(contactId => {
        const foundConnection = connections.find(connection => {
          return contactId == connection["metadata"]["sources"][0]["id"];
        });
        if (foundConnection) {
          return {
            contactId: contactId,
            resourceName: foundConnection["resourceName"]
          }
        }
      }).filter(el => el);
      return mapping;  
    }
    

    【讨论】:

    • 感谢您的回答。我们确实看到 People API 的源参数包含 contactId。但在我们的例子中,我们将通过调度程序同步调用编辑/删除 API。因此,我们正在寻找一种在将用户移动到 People API 之前获取“联系人 ID - 资源 ID”映射的方法。同样在不调用任何 API 的情况下获取资源 ID 对我们来说是最好的,因为 1. 每个用户最多可以有 25k 个联系人。 people.connections.list 的最大限制是 1000。所以这是 1 个用户的 25 次调用。 2. 我们有大约 15k 用户,因此 API 调用将成倍增加。
    • 那么如果“转换为十进制并添加“people/c”导致资源名称”有效,我们可以继续吗?
    • @Ranjani 如果您不想使用 People API,我认为转换为十进制将是您的最佳选择。它没有记录,但似乎有效。
    • 如果我将此转换用于“联系人 ID - 资源 ID”映射,它是否会为所有联系人 ID 返回正确的资源 ID?或者对任何一组用户都会有任何破坏吗?
    • @Ranjani 好吧,十六进制 - 十进制转换似乎有效,但由于没有记录,它可能会更改,恕不另行通知。我认为我建议的转换更安全,因为它基于 People API 的文档化人员资源。当然,你也可以在进行十进制转换后随时检查检索到的资源名称是否有效,但无论如何都需要使用 API。
    【解决方案2】:

    接受的答案不适用于没有电子邮件地址的联系人。

    无需从person.emailAddresses 获取元数据对象,我们可以直接从人员对象中获取,不需要在人员信息中出现任何其他字段。

    此外,接受的答案假定第一个来源始终是“CONTACT”类型,但情况可能并非如此,在这种情况下,您可能会得到错误的联系人 ID

    这是改进的版本(Java):

    List<Person> people = getPeople();// fetch all pages of the user contacts, with "personFields" set to "metadata" only.
    
    Map<String, String> mapping = new HashMap<>();
    
    people.forEach(person -> {
        PersonMetadata metadata = person.getMetadata();
        if (metadata != null) {
            List<Source> sources = metadata.getSources();
            if (sources != null) {
                sources.stream()
                    .filter(srcObj -> "CONTACT".equalsIgnoreCase(srcObj.getType()))
                    .findFirst()
                    .ifPresent(source ->
                        mapping.put(source.getId(), person.getResourceName()));
            }
        }
    });
    

    【讨论】:

    • 是的,我没有注意到 metadata 是有效的 personField,谢谢。另外,sources可以在发出请求时使用,收到响应后无需过滤。最后,请注意,我提供的 Apps 脚本示例只是一个示例。用户没有要求提供特定代码,只要有办法检索此信息即可。
    • 此外,十六进制到十进制的转换甚至适用于没有电子邮件地址的联系人。我向 Google 询问了这一点,并被告知如果我在下个月内完成转换,我可以使用该 hack 进行一次性迁移。在那之后,他们不能说它是否会保持不变。
    猜你喜欢
    • 1970-01-01
    • 2021-02-13
    • 2014-08-15
    • 1970-01-01
    • 1970-01-01
    • 2016-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多