Programmatically accept Google My Business invitation for service account

Viewed 1088

I'm trying to use a service account to retrieve locations/reviews using the Google My Business API.

So far I have:

  1. Created a project in Developers Console
  2. Enabled access to the Google My Business API (it's been approved/whitelisted by Google)
  3. Created a service account with an associated OAuth identity
  4. Invited the OAuth identity (i.e. service account) as a manager for the Google My Business location

I am able to see the invitation when programmatically listing invites from https://mybusiness.googleapis.com/v4/accounts/[ACCOUNT NAME]/invitations using Google's sample .NET client available for download from https://developers.google.com/my-business/samples

However, when I try to accept the invitation through https://mybusiness.googleapis.com/v4/accounts/[ACCOUNT NAME]/invitations/[INVITATION NAME]:accept the request fails with a 500 server error.

When creating the MyBusinessService instance, I first create a service account credential like:

ServiceAccountCredential credential;

using (Stream stream = new FileStream("credentials.json", FileMode.Open, FileAccess.Read, FileShare.Read))
{
   credential = (ServiceAccountCredential)GoogleCredential
                   .FromStream(stream)
                   .CreateScoped(new [] { "https://www.googleapis.com/auth/plus.business.manage" })
                   .UnderlyingCredential;
}

Next I create an initializer like:

var initializer = new BaseClientService.Initializer()
{
   HttpClientInitializer = credential,
   ApplicationName = "My GMB API Client",
   GZipEnabled = true,
};

Finally I create a MyBusinessService instance like: var service = new MyBusinessService(initializer);

I can list invitations with:

service.Accounts
       .Invitations
       .List("[ACCOUNT NAME]")
       .Execute()
       .Invitations;

However, trying to accept an invitation fails:

service.Accounts
       .Invitations
       .Accept(null, "[INVITATION NAME]")
       .Execute();

The first parameter is null as this documentation states that the request body should be empty.

Or is there perhaps some other way to accept the invitation in order to enable the service account to retrieve Google My Business reviews for our location(s)?

2 Answers

To log in as a service account for server to server authentication you need to enable domain wide delegation for your service account. https://developers.google.com/admin-sdk/directory/v1/guides/delegation

Once you do this, you can make your service account log into the Google My Business API by impersonating the email address of an approved My Business manager. This is in NodeJS, here is what I used:

const { google } = require('googleapis'); // MAKE SURE TO USE GOOGLE API
const { default: axios } = require('axios'); //using this for api calls

const key = require('./serviceaccount.json'); // reference to your service account
const scopes = 'https://www.googleapis.com/auth/business.manage'; // can be an array of scopes

const jwt = new google.auth.JWT({
  email: key.client_email,
  key: key.private_key,
  scopes: scopes,
  subject: `impersonated@email.com`
});

async function getAxios() {

  const response = await jwt.authorize() // authorize key
  let token = response.access_token // dereference token
  console.log(response)

    await axios.get('https://mybusiness.googleapis.com/v4/accounts', {
      headers: {
        Authorization: `Bearer ${token}`
      } // make request
    })
    .then((res) => { // handle response
      console.log(res.data);
    })
    .catch((err) => { // handle error
      console.log(err.response.data);
    })
  }

await getAxios(); // call the function

Service accounts in the GMB API can't substitute for a Google user account authentication. You'll need to use Oauth with a user account — for example, a gmail account that has access to the GMB web interface - so that you can perform actions on behalf of a user.

Related