0

Since Google is deprecating Google contacts API and instead advising us to use Google People API to add/create/delete contacts. I was able to create, get Google contacts, Sample code is below:

const { google } = require("googleapis")
const path = require("path")

const keyFile = path.join(__dirname, "serviceAccCredentials.json")
const scopes = [
  "https://www.googleapis.com/auth/contacts",
  "https://www.googleapis.com/auth/contacts.readonly"
]

function log(arg) {
  console.log(JSON.stringify(arg, null, 4))
}

const run = async () => {
  try {

    const { people, contactGroups } = google.people({
      version: "v1",
      auth: await google.auth.getClient({
        keyFile,
        scopes
      })
    })

    const createContact = await people.createContact(
        {
        requestBody: {
          names: [
            {
              givenName: "Yacov 3",
              familyName: "110$"
            }
          ],
          "memberships": [
            {
              "contactGroupMembership": {
                contactGroupId: 'myContacts'
                // "contactGroupResourceName": "contactGroups/myContacts"
              }
            }
          ]
        }
      }
    )
    log(createContact.data)

    const afterResponse = await people.connections.list({
      resourceName: "people/me",
      personFields: "names",
    })
    log(afterResponse.data)

  } catch (e) {
    console.log(e)
  }
}

run()

Problem is that i don't see the contacts created with the service account under the Google contacts. Normally the service account is created for the G-suit user, under the G-suit domain wide delegation settings, i added the project id with scope as well. Also People API is enabled in the service account.

Further, In the playground area of Google's official documentation when i tried to create the a Google contact, it worked. The request from there API explorer / playground looks like this

     const createContact = await people.createContact({
        "personFields": "names",
        "sources": [
          "READ_SOURCE_TYPE_CONTACT"
        ],
        "prettyPrint": true,
        "alt": "json",
        "resource": {
          "names": [
            {
              "givenName": "test 2",
              "familyName": "playground"
            }
          ],
          "memberships": [
            {
              "contactGroupMembership": {
                "contactGroupResourceName": "contactGroups/myContacts"
              }
            }
          ]
        }
      })

Strangely, all these properties like contactGroupResourceName, personFields, sources, alt, prettyPrint doesn't exists.

can anyone really tell me what is going on. PS: i can not and don't want to use OAuth2 since the application is going to be server to server communication, wouldn't involve any human consent. Thanks

Danish
  • 1,467
  • 19
  • 28
  • **Problem is that i don't see the contacts created with the service account** who are you logging in as. If they were created by the service account then they are the service accounts contacts, you wont see this from your own account as you dont have access. When you create them from the service account are you deligating to a user on the domain ? – Linda Lawton - DaImTo Jan 26 '21 at 09:23
  • @DaImTo make sense, `When you create them from the service account are you deligating to a user on the domain ?` how this is done? can you explain more please – Danish Jan 26 '21 at 11:20

1 Answers1

1

Issue:

You might have enabled domain-wide delegation for your service account, but you are not using it to impersonate a regular user.

The purpose of domain-wide delegation is for the service account to act on behalf of any user in the domain, but in order to do that, you have to specify which user you want the service account to impersonate.

Otherwise, the service account will access its own resources (its Contacts, its Drive, its Calendar, etc.) not the resources of a regular account. Therefore, you'll not see the created contacts if you access Contacts UI with a regular account, since contacts were not created for this account.

Solution:

You need to impersonate the account for which you want to create contacts.

In order to do that, since you're using Node's getClient(), you should specify the email address of the account you want to impersonate, as shown here:

auth.subject = "email-address-to-impersonate";

Update:

In this case, you could do the following:

let auth = await google.auth.getClient({
  keyFile,
  scopes
});
auth.subject = "email-address-to-impersonate";
const { people, contactGroups } = google.people({
  version: "v1",
  auth: auth
})

Reference:

Iamblichus
  • 18,540
  • 2
  • 11
  • 27
  • TypeError: authClient.request is not a function i am getting error after passing auth.subject or i tried auth.email as well inside the create contact like this ```people.createContact({ auth: { email: 'ffbtest@fforb.com' }, requestBody: { names: [ ``` – Danish Jan 26 '21 at 11:25
  • @Danish Where are you adding this? You are building the value for the `auth` parameter inside `google.people`, so where are you setting `auth.subject="email"`? I'd suggest first building the `auth` parameter and then call `google.people({...})`. I edited my answer in order to show how this could be done. – Iamblichus Jan 26 '21 at 11:55
  • Hi again, so yes i tried your example above, now i have a different error. ```Error: unauthorized_client: Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested. at /home/xxx/people-api-project/node_modules/gtoken/build/src/index.js:272:35 at processTicksAndRejections (internal/process/task_queues.js:94:5)``` – Danish Jan 26 '21 at 12:03
  • @Danish This probably means you didn't add the appropriate scopes to the Admin console when setting up domain-wide delegation. Follow the steps specified [here](https://developers.google.com/identity/protocols/oauth2/service-account#delegatingauthority) and make sure `contacts` and `contacts.readonly` are added (step 5). – Iamblichus Jan 26 '21 at 12:06
  • actually thanks for the help i solved it. one of the scope was out from delegation – Danish Jan 26 '21 at 12:07
  • thanks again, marked as accepted answer, cheers buddy! – Danish Jan 26 '21 at 12:07
  • 1
    @Danish You're welcome. Glad your issue was solved. – Iamblichus Jan 26 '21 at 12:07