pythonflaskgoogle-people-api

Adding certain fields to my contacts using Google people API and python


I have used the People API to create a contact, update the contact, get the contact and deleting it. I want to add a few more fields when creating contact but it seems they're not getting added. I want to add the country code, a secondary number, a city and a job title. I've tried implementing what's in the documentation. The job title is in the occupations field, the country code is in the phoneNumbers field, under the canonicalForm field and the city in the addresses field. Despite making the necessary changes, when I create a new contact, these fields aren't populated. I know this because I perform a search of that contact and I miss these fields. It's either I'm missing something when creating the contact or I'm doing the search wrong(though it does bring up results, so I don't know how this would be)

Here is my createcontact.py

import os.path

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

# If modifying these scopes, delete the file token.json.
SCOPES = ["https://www.googleapis.com/auth/contacts"]

CREDENTIALS_FILE_PATH = r'/credentials.json'
def create_new_contact(first_name, phone_number, job_title, company, email, city, primaryNumberCC):
  creds = None
  if os.path.exists("token.json"):
    creds = Credentials.from_authorized_user_file("token.json", SCOPES)
  # 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_FILE_PATH, 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())

  try:
    service = build("people", "v1", credentials=creds)
    service.people().createContact(body={
      "names": [{"givenName": first_name}], 
      "phoneNumbers": [{'value': phone_number,'canonicalForm': primaryNumberCC}],
      "occupations":[{'value':job_title}],
      "organizations":[{'title':company}],
      "emailAddresses":[{'value':email}],
      "addresses": [{"city": city}], 
      }).execute()
    
  except HttpError as err:
    print(err)

Here is how I'm searching for the contact.

import os
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

# 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 get_contact_resource_by_name(name):
    creds = get_credentials()
    service = build('people', 'v1', credentials=creds)
    
    # Perform a search query using the contact's name
    results = service.people().searchContacts(query=name, readMask="names").execute()
    
    if 'results' in results:
        if len(results['results']) > 0:
            # Extract the resource name of the first matching contact
            print(results)
            return results['results'][0]['person']['resourceName']
    
    return None

Solution

  • I think that your function create_new_contact works. But, you say Despite making the necessary changes, when I create a new contact, these fields aren't populated. I know this because I perform a search of that contact and I miss these fields.. When I saw your get_contact_resource_by_name, your function get_contact_resource_by_name returns only the field of names. I'm worried that this might be the reason for it. If my understanding is correct, how about the following modification?

    Modified script:

    In this modification, get_contact_resource_by_name is modified.

    def get_contact_resource_by_name(name):
        creds = get_credentials()
        service = build('people', 'v1', credentials=creds)
    
        # Perform a search query using the contact's name
        results = service.people().searchContacts(query=name, readMask="names,phoneNumbers,occupations,organizations,emailAddresses,addresses").execute()
    
        if 'results' in results:
            if len(results['results']) > 0:
                # Extract the resource name of the first matching contact
                print(results)
                return results['results'][0]['person']['resourceName']
    
        return None
    

    Reference: