why a service account can't access a public shared calendar for listing events?

70 views Asked by At

I'm using deno and https://googleapis.deno.dev/ to try to get some events from a publicly shared calendar.

Basically, this is the code:

import { Calendar, auth } from "https://googleapis.deno.dev/v1/calendar:v3.ts";

const serviceAccountConfig = await Deno.readTextFile(Deno.env.get('GOOGLE_APPLICATION_CREDENTIALS'));

const credentials = auth.fromJSON(JSON.parse(serviceAccountConfig));
const calendar = new Calendar(credentials);

const cal = await calendar.eventsGet('<my-public-calendar-id-here>');
console.log(cal);

but this is what I get:

error: Uncaught (in promise) GoogleApiError: 401: Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.
      throw new GoogleApiError(
            ^
    at request (https://googleapis.deno.dev/_/base@v1/mod.ts:27:13)
    at eventLoopTick (ext:core/01_core.js:183:11)
    at async Calendar.eventsGet (https://googleapis.deno.dev/v1/calendar:v3.ts:476:18)

I've tried to check if some calendar privilege is needed for the google service account I use, but I haven't found any. Plus, this code is supposed to run on a backend, so I guess I should use a service account, not a user token (and keep in mind what I want to get has public access). Any piece of suggestion?

1

There are 1 answers

2
Linda Lawton - DaImTo On
  • You are not building the service object correctly.
  • That's not a valid calendar id.
  • You are not building the proper authorization credentials.

My code.

   // npm install googleapis@105 @google-cloud/[email protected] --save
// npm install googleapis

const {google} = require('googleapis');

// If modifying these scopes, delete token.json.
const SCOPES = ['https://www.googleapis.com/auth/calendar'];

const CREDENTIALS_PATH = 'C:\\Development\\FreeLance\\GoogleSamples\\Credentials\\ServiceAccountCred.json';

/**
 * Load or request or authorization to call APIs.
 *
 */
async function authorize() {
    let client =  new google.auth.GoogleAuth({keyFile: CREDENTIALS_PATH, scopes: SCOPES});
    return client
}

/**
 * Lists the next 10 events on a public holiday calendar.
 * @param {google.auth.OAuth2} auth An authorized OAuth2 client.
 */
async function listEvents(auth) {
    const calendar = google.calendar({version: 'v3', auth});
    const res = await calendar.events.list({
        calendarId: 'en.danish#[email protected]',
        timeMin: new Date().toISOString(),
        maxResults: 10,
        singleEvents: true,
        orderBy: 'startTime',
    });
    const events = res.data.items;
    if (!events || events.length === 0) {
        console.log('No upcoming events found.');
        return;
    }
    console.log('Upcoming 10 events:');
    events.map((event, i) => {
        const start = event.start.dateTime || event.start.date;
        console.log(`${start} - ${event.summary}`);
    });
}

authorize().then(listEvents).catch(console.error);