0
votes

Referencing this doc JSON Web Tokens, I have tried to access the Analytics Reporting API, trying first "Application Default Credentials" then "JSON Web Tokens" authentication.
Each time I receive the error Request had insufficient authentication scopes.

I have no problem accessing the data through Query Explorer, and I really don't want to use OAuth2, since I would only ever be accessing my own account to begin with. The scopes listed below were derived from "Google Analytics API, v3" in Google scopes.

Given the error message, I've tried various iterations of other scopes, most notably those for "Analytics Reporting API, v4."
Note: the email provided in the service account key from the Google Developers Console has been added to all permissions (account, property, view) of the Analytics Admin Console. I have also tried something similar as described in "Service <--> Service authentication".

Attempting "Application Default Credentials" (setting path to service account key in .env):

const {auth} = require('google-auth-library');
async function main() {
  const client = await auth.getClient({
    scopes: [
      'https://www.googleapis.com/auth/analytics',
      'https://www.googleapis.com/auth/analytics.edit',
      'https://www.googleapis.com/auth/analytics.manage.users',
      'https://www.googleapis.com/auth/analytics.manage.users.readonly',
      'https://www.googleapis.com/auth/analytics.provision',
      'https://www.googleapis.com/auth/analytics.readonly',
      'https://www.googleapis.com/auth/analytics.user.deletion'
    ]
  });
  const projectId = await auth.getProjectId();
  const url = `https://www.googleapis.com/dns/v1/projects/${projectId}`;
  const res = await client.request({ url });
  console.log(res.data);
}
main().catch(console.error);

Attempting "JSON Web Tokens:"

const {JWT} = require('google-auth-library');
const keys = require('../service-account-credentials.json');

async function main() {
  console.log('keys.client_email: ', keys.client_email)
  console.log('keys.private_key: ', keys.private_key)
  const client = new JWT(
    keys.client_email,
    null,
    keys.private_key,
    [
    'https://www.googleapis.com/auth/analytics',
    'https://www.googleapis.com/auth/analytics.edit',
    'https://www.googleapis.com/auth/analytics.manage.users',
    'https://www.googleapis.com/auth/analytics.manage.users.readonly',
    'https://www.googleapis.com/auth/analytics.provision',
    'https://www.googleapis.com/auth/analytics.readonly',
    'https://www.googleapis.com/auth/analytics.user.deletion'
    ],
  );
  const url = `https://www.googleapis.com/dns/v1/projects/${keys.project_id}`;
  const res = await client.request({url});
  console.log(res.data);
  const tokenInfo = await client.getTokenInfo(client.credentials.access_token);
  console.log(tokenInfo);
}

main().catch(console.error);
1

1 Answers

1
votes

The url specified in the boilerplate example needs to be replaced with the analytics query, such as that from "API Query URI".

For example, if I want number of page views, I would replace the url used in the question's snippet:

https://www.googleapis.com/dns/v1/projects/${projectId}

with that specified in the Query Explorer:

https://www.googleapis.com/analytics/v3/data/ga?ids=ga%${analyticsViewOrProfileId}&start-date=30daysAgo&end-date=2018-08-28&metrics=ga%3Apageviews&dimensions=ga%3ApagePath&sort=-ga%3Apageviews

The resulting (functioning) code is as follows:

const {auth} = require('google-auth-library');

async function main() {
  const client = await auth.getClient({
    scopes: [
      'https://www.googleapis.com/auth/analytics',
      'https://www.googleapis.com/auth/analytics.readonly'
    ]
  });
  const viewId = <VIEW ID FROM ANALYTICS CONSOLE>
  const url = `https://www.googleapis.com/analytics/v3/data/ga?ids=ga%3A${viewId}&start-date=30daysAgo&end-date=2018-08-28&metrics=ga%3Apageviews&dimensions=ga%3ApagePath&sort=-ga%3Apageviews`;
  const res = await client.request({ url });
  console.log(res.data);
}
main().catch(console.error);