Andre M
Andre M

Reputation: 7534

Google service account unable to list calendars?

Can anyone indicate the right settings to give allow a service account access to a Google calendar?

We have a node.js project that is meant to provide access to the Google calendars it has been given access to, but we can't work out why it can't see the calendars.

At the same time, we were able to trying a different account that has been working in another environment and this worked, but the problem is that no one who previously worked on the project has access to the configuration for it to compare.

The response.data we are getting with the problem account:

{
  "kind": "calendar#calendarList",
  "etag": "\"p33k9lxxjsrxxa0g\"",
  "nextSyncToken": "COias9Pm4vUCEjxvdGurdXRob24tZGV2LXNlcnZpY2UxQG90YxxxdGhvbi1kZXYuaWFtLmdzZXJ2aWNlYWNxb3VudC5jb20=",
  "items": []
}

Either way this would suggest the issue is with the configuration of the service account, rather than the code itself, but will share the code anyhow:

import { Auth, calendar_v3 as calendarV3 } from 'googleapis';
const Calendar = calendarV3.Calendar;

async getCalendarApi () {
  const jwtClient = new Auth.JWT(
    this.keyConfig.clientEmail,
    undefined,
    this.keyConfig.privateKey.replace(/\\n/g, '\n'),
    [
      'https://www.googleapis.com/auth/calendar.readonly',
      'https://www.googleapis.com/auth/calendar.events'
    ]
  );

  const calendarApi = new Calendar({
    auth: jwtClient
  });

  await jwtClient.authorize();

  return calendarApi;
}

async init () {
  // loads the configuration from our app's configuration file
  this.keyConfig = getKeyConfig('google-calendar');
  
  const calendarApi = await this.getCalendarApi();
  const response = await calendarApi.calendarList.list();
  console.log(JSON.stringify(response.data, undefined, 2));
}

As for the service account, in the Google console, this is the how it was set up:

From the above steps we take the client_email and the private_key field values to user with our nodejs app.

Then in the calendar we want it to access, we add the email address of the service account as a viewer.

Trying all the above still results in the list of calendars visible by the service account to be empty.

Any ideas?

Upvotes: 1

Views: 1253

Answers (1)

Tanaike
Tanaike

Reputation: 201338

From your explanation and the returned value, I'm worried that in your situation, you might have never inserted the shared Calendar with the service account. If my understanding is correct, how about the following modification?

Modification points:

  1. Insert the shared Calendar to the service account.

    • In this case, please modify the scope https://www.googleapis.com/auth/calendar.readonly to https://www.googleapis.com/auth/calendar.

        async init () {
          // loads the configuration from our app's configuration file
          this.keyConfig = getKeyConfig('google-calendar');
      
          const calendarApi = await this.getCalendarApi();
          const response = await calendarApi.calendarList.insert({resource: {id: "###@group.calendar.google.com"}}); // Please set the Calendar ID here. Or {requestBody: {id: "###@group.calendar.google.com"}}
          console.log(JSON.stringify(response.data, undefined, 2));
        }
      
  2. Retrieve the calendar list using your script.

    • After the Calendar was inserted to the service account using the above script, you can obtain the shared Calendar in the Calendar list.

Reference:

Upvotes: 1

Related Questions