Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing Google My Business API without login (using service account)

I want to access the locations associated with my account and their reviews, for that I am using the google my business API and I have access to it (it does work on oAuthplayground).

Now I want to access the google my business api without logging into my account, for that I am trying to make it work with the service account. But no luck so far, please advice how to proceed with this. I have enabled the G suite in the service account and I have also tried to give access to the service account email (ID) for the my business manage but it stays in Invited state, as there is no way to actually accept the invite.

When I try to send request using my account as subject.

$client = new Google_Client();
$client->addScope('https://www.googleapis.com/auth/plus.business.manage');
$client->setAuthConfig(dirname(__FILE__) . '/Xyz Review API-service account.json');
$client->setSubject('xyz*****[email protected]');
$business_service_class = new Google_Service_Mybusiness($client);
$result_accounts = $business_service_class->accounts->listAccounts();
echo json_encode($result_accounts);
exit;

Response: {"nextPageToken":null}

If I use the google service account ID as email id in subject then I get following response.

$client->setSubject('[email protected]');

Response: Error 500 { "error": "unauthorized_client", "error_description": "Unauthorized client or scope in request." }

If I am doing this completely wrong then please do advice how to proceed with this. Thank you.

like image 811
Hmmm Avatar asked Nov 21 '16 12:11

Hmmm


2 Answers

I faced the problem of authentication for my internal service with google apis. Basically exists two method:

  1. create the page to accept your application to access the google account
  2. create a certificate to authenticate the application with "implicit" approval

as i said i'm using the google api for an internal project, so the first option is out of question (the service is not public). Go to https://console.cloud.google.com and create a new project then go to "api manager" then "credentials" then create a "service credential".

If you follow all those steps you have a certificate with .p12 extension, it's your key to access to google api (remember you have to enable the key to access the specific google api you want).

I paste an example extracted from my project, i'm using google calendar, but the authentication is the same for each service.

   $client_email = '[email protected]';
    $private_key = file_get_contents(__DIR__ . '/../Resources/config/xxxx.p12');
    $scopes = array('https://www.googleapis.com/auth/calendar');
    $credentials = new \Google_Auth_AssertionCredentials(
        $client_email,
        $scopes,
        $private_key
    );

    $this->client = new \Google_Client();
    $this->client->setAssertionCredentials($credentials);  
like image 84
m47730 Avatar answered Nov 17 '22 14:11

m47730


Here is what I got working in 2021 with NodeJS:

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: `[email protected]`
});

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
like image 3
Julian-Life Avatar answered Nov 17 '22 14:11

Julian-Life