在Python中使用Google的People API更新联系人多个字段的帮助

1 投票
1 回答
33 浏览
提问于 2025-04-14 15:19

我一直在尝试使用Google People API来更新一个联系人的多个字段。下面是我的代码和我一直遇到的错误。

from google.oauth2.credentials import Credentials
from google.auth.transport.requests import Request
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
import os

# Define the scopes required for accessing the People API
SCOPES = ['https://www.googleapis.com/auth/contacts']

def get_credentials():
    creds = None
    # The file token.json stores the user's access and refresh tokens, and is created automatically when the authorization flow completes for the first time.
    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json')
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.json', 'w') as token:
            token.write(creds.to_json())
    return creds

def update_contacts(contact_id, given_name, family_name, email_address, phone_number):
    creds = get_credentials()
    new_data = {
        'names': [{'givenName': given_name, 'familyName': family_name}],
        'emailAddresses': [{'value': email_address}],
        'phoneNumbers': [{'value': phone_number}]
    }
    service = build('people', 'v1', credentials=creds)
    contact = service.people().get(resourceName=contact_id).execute()
    contact.update(new_data)
    updated_contact = service.people().updateContact(
        resourceName=contact_id,
        # updatePersonFields='names,emailAddresses,phoneNumbers',
        personFields = 'names,emailAddresses,phoneNumbers',
        body=contact
    ).execute()
    print('Contact updated:', updated_contact)

# Example usage:
# contact_id = 'people/c2288946713327522882'
    
# update_contacts(contact_id, given_name, family_name, email_address, phone_number)
googleapiclient.errors.HttpError: <HttpError 400 when requesting https://people.googleapis.com/v1/people/c2288946713327522882?alt=json returned "personFields mask is required. Please specify one or more valid paths. Valid paths are documented at https://developers.google.com/people/api/rest/v1/people/get.". Details: "personFields mask is required. Please specify one or more valid paths. Valid paths are documented at https://developers.google.com/people/api/rest/v1/people/get.">

我尝试按照错误提示,把personFields替换成updatePersonFields,但没有成功。从我在StackOverflow上的研究来看,我能成功地更新一个字段。不过,更新多个字段却很困难。请帮帮我。

1 个回答

1

修改要点:

  • 当我看到你展示的脚本和错误信息时,我猜测你当前错误的原因可能是因为 contact = service.people().get(resourceName=contact_id).execute() 这行代码。在这种情况下,personFields="names,emailAddresses,phoneNumbers" 是必须包含的。
  • 关于更新联系人的脚本,我猜测需要使用 updatePersonFields

当你在脚本中反映这些要点时,下面的修改怎么样呢?

修改后的脚本:

在这个修改中,请按照以下方式修改你的函数 update_contacts

def update_contacts(contact_id, given_name, family_name, email_address, phone_number):
    creds = get_credentials()
    new_data = {
        'names': [{'givenName': given_name, 'familyName': family_name}],
        'emailAddresses': [{'value': email_address}],
        'phoneNumbers': [{'value': phone_number}]
    }
    service = build('people', 'v1', credentials=creds)
    contact = service.people().get(resourceName=contact_id, personFields="names,emailAddresses,phoneNumbers").execute()
    contact.update(new_data)
    updated_contact = service.people().updateContact(
        resourceName=contact_id,
        updatePersonFields='names,emailAddresses,phoneNumbers',
        personFields='names,emailAddresses,phoneNumbers',
        body=contact
    ).execute()
    print('Contact updated:', updated_contact)
  • 当这个脚本运行时,contact_id 对应联系人的 names,emailAddresses,phoneNumbers 会被更新。

注意:

  • 在这种情况下,假设你的访问令牌和 contact_id, given_name, family_name, email_address, phone_number 的值都是有效的。请对此保持谨慎。

参考资料:

撰写回答