0
votes

I am trying to update a Google contact using People API. Unfortunately I am getting an error:

Invalid JSON payload received. Unknown name "": Root element must be a message.

when executing the request. Anyone has any clue how can I resolve it? The JSON itself seems to be OK because I used https://developers.google.com/people/api/rest/v1/people/updateContact to test it and I got 200 response and the contact was modified.

from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request


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

def modifyContact(service, resourceName, JSON):
    print (JSON)
    service.people().updateContact(resourceName=resourceName, updatePersonFields='phoneNumbers', body=JSON).execute()

def buildJSON(phoneNumbers, etag):
    JSON = ""
    for x in range(0, len(phoneNumbers)):
        if phoneNumbers[x].get('type') == 'mobile':
            if phoneNumbers[x].get('value').find('+48') != -1:
                oldNUmber = phoneNumbers[x].get('value')
                newNumber = phoneNumbers[x].get('value')[3:]
                JSON += """
                        {
                            "type": "mobile",
                            "value": "%s"
                        },
                        {
                            "type": "mobile",
                            "value": "%s"
                        },
                        """ % (oldNUmber, newNumber)
            else:
                JSON += """
                        {
                            "type": "mobile",
                            "value": "%s"
                        },
                        """ % (phoneNumbers[x].get('value'))
        else:
            JSON += """
                        {
                          "type": "%s",
                            "value": "%s"
                        },
                    """ % (phoneNumbers[x].get('type'), phoneNumbers[x].get('value'))
    # remove last whitespaces + character which is exceeding comma
    JSON = JSON.rstrip()[:-1]
    JSON = """
              "phoneNumbers": [
                %s
              ],
              "etag": "%s"
            """ % (JSON, etag)
    #print (JSON)
    return JSON

def main():

    creds = None
    # The file token.pickle 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.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    # 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.pickle', 'wb') as token:
            pickle.dump(creds, token)

    service = build('people', 'v1', credentials=creds)





    # Call the People API
    print('List 10 connection names')
    results = service.people().connections().list(
        resourceName='people/me',
        pageSize=1000,
        personFields='names,phoneNumbers').execute()
    connections = results.get('connections', [])

    for person in connections:
        names = person.get('names', [])
        phoneNumbers = person.get('phoneNumbers', [])
        if names:
            name = names[0].get('givenName')
            if name == "testAPI":
                print(name)
                print (person.get('etag'))
                print (person.get('resourceName'))
                if phoneNumbers:
                    JSON = buildJSON(phoneNumbers, person.get('etag'))
                    modifyContact(service, person.get('resourceName'), JSON)
                    #print (phoneNumbers[x].get('value'))
                print (person)
if __name__ == '__main__':
    main()
1
Where does the error occur?Tanaike
Problem solved, please see the answer below.Hellraiser
Thank you for replying. I'm glad your issue was resolved. I deeply apologize I couldn't help.Tanaike

1 Answers

2
votes

Problem solved.

First of all when I was troubleshooting I've removed the initial/ending brackets from JSON string.

Should be:

JSON = """{
          "phoneNumbers": [
            %s
          ],
          "etag": "%s"
      }
    """ % (JSON, etag)

And second, I had to deserialize JSON string with loads()

return json.loads(JSON)

And now it works like a charm :)