Skip to content
Shek Yu Hong edited this page Oct 14, 2017 · 6 revisions

node-google-calendar

Simple node module that supports Google Calendar API

Overview

Preparations Needed

Setup Service Accounts

This module does server to server authentication with Google APIs without any users being involved. When using Google APIs from the server (or any non-browser based application), authentication is performed through a Service Account, which is a special account representing your application.

  1. Create a service account in the Google Developer Console, if you don't have one yet. For more information about service accounts and server-to-server interactions such as those between a web application and a Google service: https://developers.google.com/identity/protocols/OAuth2ServiceAccount#authorizingrequests

  2. A public/private key pair is generated for the service account, which is created from the Google API console. Take note of the service account's email address and store the service account's json or P12 private key file in a location accessible to your application. Your application needs them to make authorized API calls.

  3. If a user wants to give access to his Google Calendar to your application, he must give specific permission for each of the calenders to the created Service Account using the supplied email address.

    • Go to the specified Google Calendar's settings > "Share this calendar" tab > Check "Make this calendar public".
    • Under "Share with specific people" section, grant permissions to the created service account (<service_account>@<project_name>.iam.gserviceaccount.com) to make changes/read events.

Setup App Configs

  1. Create a config file for your application (I'll call mine settings.js) (sample file here) with the google account email address under USERID and the generated service account id as SERVICE_ACCT_ID.

  2. Update settings.js config file and specify calendar IDs of each calendar that the service account has been granted access to. Specify as many as you need & modify config according.

    • To get the IDs of each of the calendar, go to calendar's settings page > "Calendar Details" Tab > Under "Calendar Address" Section > Calendar ID.

Providing key or keyfile for Google OAuth

To use the PEM keyfile
Convert the downloaded .p12 key to PEM. To do this, run the following in Terminal:

openssl pkcs12 -in downloaded-key-file.p12 -out converted-key-file.pem -nodes

Once done, export the keyfile var in settings.js.

OR

To use the JSON key
Read the json key's private key and export the key var in settings.js.

To do that, add the following code in your settings.js.

const key = require('./googleapi-key.json').private_key;
module.exports.key = key;

Getting Started

First, install the package with: npm i node-google-calendar.

Update the settings.js config file with calendarId, calendarUrl, serviceAcctId & keyfile location.

Your config file should look something like this:

const KEYFILE = '<yourpem.pem>';
const SERVICE_ACCT_ID = '<your service account id>';

const CALENDAR_URL = '<your calendar url>';
const CALENDAR_ID = {
  'primary': '<main calendar calendar id>@gmail.com',
  'calendar-1': 'calendar1@group.calendar.google.com',
  'calendar-2': 'calendar2@group.calendar.google.com'
};
const TIMEZONE = 'UTC+08:00';

module.exports.calendarUrl = CALENDAR_URL;
module.exports.serviceAcctId = SERVICE_ACCT_ID;
module.exports.calendarId = CALENDAR_ID;
module.exports.keyFile = KEYFILE;           //or if using json keys - module.exports.key = key; 
module.exports.timezone = TIMEZONE;

To use, require the module in your application and pass in the necessary config file.

  const CONFIG = require('./config/Settings');
  const CalendarAPI = require('node-google-calendar');
  let cal = new CalendarAPI(CONFIG);  

You should now be able to query your specified calendar and try out the following examples.

APIs

Most Google Calendar APIs v3 are now supported! This includes APIs in resource types of Calendars, CalendarList, Acl, Events, FreeBusy, Settings, Colors & Channels. You can refer to Google's documentation on what parameters to supply, and choose to include or exclude the parameters that you need.

Some examples are as follows:

CalendarList Examples

CalendarList.list - Returns a promise of a CalendarList of calendar entries and their metadata that the service account has visibility to.

let params = {
  showHidden: true
};

cal.CalendarList.list(params)
  .then(resp => {
	console.log(resp);
  }).catch(err => {
	console.log(err.message);
  });

Acl Examples

Acl.insert - Granting a user owner permission of to a calendar. Calendar entry should be automatically added to user's CalendarList after success. (Appear on calendarlist on left side of Google Calendar's WebUI)

let params = {
	scope: {
		type: 'user',
		value: 'your-user@gmail.com'
	},
	role: 'owner'
};

cal.Acl.insert(calendarId, params)
  .then(resp => {
	console.log(resp);
  }).catch(err => {
	console.log(err.message);
  });

Events Examples

Events.list - To get a promise of all single events in calendar within a time period.

let params = {
	timeMin: '2017-05-20T06:00:00+08:00',
	timeMax: '2017-05-25T22:00:00+08:00',
	q: 'query term',
	singleEvents: true,
	orderBy: 'startTime'
}; 	//Optional query parameters referencing google APIs

cal.Events.list(calendarId, params)
  .then(json => {
	//Success
	console.log('List of events on calendar within time-range:');
	console.log(json);
  }).catch(err => {
	//Error
	console.log('Error: listSingleEvents -' + err.message);
  });

Events.insert - Insert an event on a specified calendar. Returns promise of details of new event.

let event = {
	'start': { 'dateTime': '2017-05-20T07:00:00+08:00' },
	'end': { 'dateTime': '2017-05-20T08:00:00+08:00' },
	'location': 'Coffeeshop',
	'summary': 'Breakfast',
	'status': 'confirmed',
	'description': '',
	'colorId': 1
};

cal.Events.insert(calendarId, event)
  .then(resp => {
	console.log('inserted event:');
	console.log(resp);
  })
  .catch(err => {
	console.log('Error: insertEvent-' + err.message);
  });

Events.delete - Deletes an Event on a specified Calendar with EventId. Returns promise of results.

let params = {
	sendNotifications: true
};
  
cal.Events.delete(calendarId, eventId, params)
  .then(results => {
	console.log('delete Event:' + JSON.stringify(results));
  }).catch(err => {
        console.log('Error deleteEvent:' + JSON.stringify(err.message));
  });

FreeBusy Examples

FreeBusy.query - Checks if queried calendar slot is busy during selected period. Returns promise of list of events at specified slot.

let params = {
	"timeMin": '2017-05-20T08:00:00+08:00',
	"timeMax": '2017-05-20T09:00:00+08:00',
	"items": [{ "id": calendarId }]
};

cal.FreeBusy.query(calendarId, params)
  .then(resp => {
  	console.log('List of busy timings with events within defined time range: ');
        console.log(resp);
  })
  .catch(err => {
	console.log('Error: checkBusy -' + err.message);
  });

Settings Examples

Settings.list - List user settings

let params = {};
cal.Settings.list(params)
  .then(resp => {
	console.log('List settings: ');
	console.log(resp);
  })
  .catch(err => {
	console.log('Error: listSettings -' + err.message);
  });

More examples here.