2
votes

I'm suadmin of a Google Apps domain and working on Calendar API. The Calendar Application is marked as activated for all users in the Admin Console. The sharing parameters: Sharing all informations without modification permissions for inside and outside users - via the Admin Calendar App Console. I created a shared resource and subscribed to it's agenda. To simplify I shared the agenda for everyone for availability informations.

I implemented an app different ways to figure the best - to me. Everything is working fine from a Google App Script (HTML), from a browser-side script and from a nodejs server-side script (browser-side grant). The users are always being asked to interactively grant access via the google login and permissions dialogs.

Now I want a nodejs server-side app with delegated access to the agenda (i.e. of the shared resource) without the users having to grant access interactively. So I'm using a Service Account. Now go code.

So project is created, I activated the calendar API, validated the source (the google-verification page is served static http://ip:8080 by the nodejs express script and verified). The domain validation doesn't really make sens (no reverse DNS name). The authorization URL settings are set but useless for the server app, it was set for the browser-side apps.

I created the Service Account, with delegation and got the json file with private key and copied it on the server. The OAuth2 client got created fine and I authorized the Client ID to get access to the Calendar API R/W. Everything seems fine.

var google = require('googleapis')
var calendar = google.calendar('v3')
var scopes = ['https://www.googleapis.com/auth/calendar']
var key = require ('./xxx'); // private json
var jwtClient = new google.auth.JWT(key.client_email, null, key.private_key, scopes, null );
jwtClient.authorize(function(err, token) {
  if(err) { ... }
  console.log('token',token);
  listCalendars(jwtClient);
});

The script is getting authorized and I get the access token.

{ access_token: 'xxxxxxxxxx',
  token_type: 'Bearer',
  expiry_date: 1464780030000,
  refresh_token: 'jwt-placeholder' }

The call to calendarList.list succeeds ...

function listCalendars(auth) {
  calendar.calendarList.list({ auth: auth }, function(err, response) {
    if (err) { ... }
    console.log(response);
    listEvents(auth)
  })
}

but no items

{ kind: 'calendar#calendarList',
  etag: '"1464776865512000"',
  nextSyncToken: 'xxxxxx',
  items: [] }

The service account has no agenda, so it's not necessarily a surprise but, well, I thought that with delegated access I would get the list of all the agendas in the domain (users and resources).

  1. So my first question is why no calendars are listed here ?

Now I want to list the upcoming events of my own agenda (I'm owner of the service account).

function listEvents(auth) {
  calendar.events.list({
    auth: auth,
    // calendarId: 'primary',
    calendarId: '[email protected]',
    timeMin: new Date().toISOString(),
    maxResults: 10,
    singleEvents: true,
    orderBy: 'startTime'
  }, function(err, response) {
    if(err) { ... }
    var events = response.items;
    if(events.length == 0) { ... }
    ...
  });
}

I get an error

The API call returned an error: Error: Not Found
  1. My second question is why I can't get access to my user calendar events, even when I specify the ID explicitely ?

  2. My last question will be about getting access to the shared resource agenda and events ? ([email protected])

Appreciate your help, I'll follow on that problem

1
No problem I removed most of the bold partsGil
Looks like you have to explicitely add the email address of the service account (agenda sharing parameters), even if you set public sharing, event if you grant access for the all@ your domainGil

1 Answers

2
votes

(Posted on behalf of the OP).

The email address of the Service Account has to be explicitly set for sharing for each calendar, even if the calendar is publicly shared.