My Journey Integrating Google Calendar (G-suite) in Node.js
Bridging Google Calendar with Our Internal Platform
In this article, I’ll walk you through the agony of consuming Google Calendar API in Node with non-existent documentation. Particularly, accessing data using service account with domain-wide authority.
If you haven’t been working with Google APIs, or at least not in Node. you might be surprised how incomplete their documentation is. How fussy could it be to integrate a Google API? I will dissect the issues I ran into in latter parts.
Here, in Code Chrysalis, we divide students’ day into atomic unit of Block. Each block will be assigned to at least one instructor to handle the prescribed activities or lectures.
We develop our internal platform, Monarch, to manage students’ schedules, repositories, instructors’ rosters, etc. The back-end is powered by Express.js with GraphQL and TypeORM, written entirely in TypeScript.
Besides Monarch, staffs use G-suite and Google Calendar heavily to reflect their most accurate schedule.
During my first month with Code Chrysalis, I had to manually create events from my roster to reflect my actual schedule on Google Calendar. For a software engineer, this is a pain in the ass. Thus, synchronizing our platform with Google Calendar become my first must-have feature to build.
(left) When an instructor is assigned,.. (right) an event is created automatically.
What I want:
- any block assignment should triggers a event creation/update in the assignee’s Google Calendar;
- the event should also be deleted following any removal of block
Since we are using GraphQL, adding a hook into my Resolver is all I have to do. Whenever a Block is mutated,the logic to update the corresponding Google Calendar event is then triggered.
The requirements are straightforward, consuming Google APIs is not!
My main challenges were:
- setting up service account for domain-wide delegation and properly validating it;
- consuming improperly documented google-auth-library-nodejs and google-apis-client-nodejs.
Challenge #1: Validating My Service Account w/ Domain-wide Authority
Google provides an authentication mechanism for server-to-server application using service account. A service account is an account representing an application instead of an individual user. It allows our application to work with its own data on Google instead of users’ data. However, with domain-wide delegation, we can grant our service account access to members’ data in the organization (provided you are using G-suite). Following this guide, we granted our service account proper privilege to access calendars in the organization
When everything is set (or at least what I think it is), I’d love to validate it. I leaned towards writing code to test if my service account could properly access and mutate our Google Calendar data.
Hence, I dived into the documentation of google-auth-library-nodejs, trying to produce the dumbest code in Node that could read my own calendar, but to no avail.
After several attempts in Node, I decided to try my credentials using Google’s Python library. Using this guide, I managed to read my calendar list with several lines of code within a few minutes.
Accessing calendar data with delegated credentials in Python
Up to this point, I know my service account is properly set up!
Challenge #2: Consulting Non-existent Documentation
Here comes the problem. My service account works, but I can’t seem to find anything related to delegated credential in google-auth-library-nodejs. To access everyone’s calendar, I needed to set up delegated credentials like how I would do in Python.
The best documentation is sometimes the code itself.
I opened up the source code of Google’s Python client lib, and found the code that enables delegated credentials, which is by setting the
subject property. However, I didn’t seem to find any related keyword in the Node client docs. Therefore, I went through the source code of google-auth-library-nodejs and eventually figured out how to create delegated credentials in Node.
Accessing calendar list with delegated credential in Node
I wasted a few hours trying to figure that out and I’m pretty sure the code I wrote wasn’t the best. Hence, I filed an issue on their GitHub, and hopefully the community would guide us the proper way of using delegated credentials.
Lesson Of The Journey
I set an expectation after understanding various authentication mechanism available given their complete step-by-step guide. The documentation of the library is however less anticipated. As a software engineer, keeping documentation updated is perhaps one of the ways to keep users from frustration.
First published on 2019-05-16
Republished on Hackernoon