rubygoogle-people-api

failedPrecondition: Must be a G Suite domain user. Using service account to manage contacts in ruby


I am trying to manage contacts on my google workplace user using service account using ruby script and google api client.

Below is the code

require 'google/apis/people_v1'
require 'googleauth'
require 'byebug'

# Set up authorization
scopes = ['https://www.googleapis.com/auth/contacts', 'https://www.googleapis.com/auth/directory.readonly']
credentials = Google::Auth::ServiceAccountCredentials.make_creds(
  json_key_io: File.open('g_suite_service_account.json'),
  scope: scopes,
)

# Authorize the client
client = Google::Apis::PeopleV1::PeopleServiceService.new
client.authorization = credentials

# Fetch contacts
response = client.list_person_directory_people(
  sources: 'DIRECTORY_SOURCE_TYPE_DOMAIN_CONTACT',
  read_mask: 'addresses,clientData,emailAddresses,names,phoneNumbers'
)

byebug
puts ''

Here's what I've done,

  1. Create service account using google workplace cloud console.
  2. Assign the service account to the google workplace admin as domain wide delegation. enter image description here

I'm still getting this error failedPrecondition: Must be a G Suite domain user. (Google::Apis::ClientError)

Can anyone help point out where/what I am missing please. Thank you


Solution

  • When using Domain wide delegation you'll need to specify which user in the domain the service account will impersonate. In the current version of your code the API call is being made using the service account identity which caused the reported error.

    You can specify the user using the .sub method:

    # Set up authorization
    scopes = ['https://www.googleapis.com/auth/contacts', 'https://www.googleapis.com/auth/directory.readonly']
    credentials = Google::Auth::ServiceAccountCredentials.make_creds(
      json_key_io: File.open('g_suite_service_account.json'),
      scope: scopes,
    )
    
    credentials.sub = 'A_DOMAIN_USER@your_domain.com' 
    

    By doing this the API call in Google's servers will be performed using the impersonated user's identity.


    Google's documentation: