Pulling Google Calendar Events with Node.js
At my office the competition for conference rooms has gotten fierce. The importance of a meeting can vary greatly so it's good to know what's going on in a room before you interrupt someone inside to see if you can steal it. There's always the option of opening a laptop to check the schedule for a room, but we were looking for a more slick solution. The idea of mounting iPads near each conference room that explained the details on the current meeting was born. This had previously been investigated, but was fairly difficult when using Outlook for scheduling. Luckily we had just switched to Google Apps for our organization so we gave it another shot. Each room has it's own Google Calendar that is viewable by anyone in our organization which makes this possible.
The goal was to have a web page that would display the owner, title, and duration of the current meeting, or if the room was open, what time was free until. The finished product is a combination of Node, Express, and Angular. This tutorial will focus just on the bit pulling the events themselves since it's the most tricky. I usually use PHP for larger projects, but Node is great for these kind of fun small one off projects.
This tutorial assumes you have Node.js installed and a basic familiarity with it as well as the command line. You should also already have a Google account.
Setup
Starting in an empty directory, create the file package.json with the following contents
You can then run the following command to install the three required node modules.
You should now have the express, googleapis, and moment node modules installed in a local folder named node_modules. The module versions are the most recent at the time of this tutorial, but you should try using * for the version number to get the latest and greatest to see if that works first.
Google Configuration
Head over to Google Developer Console and click Create Project. The project may take a minute to fire up. Afterwards click APIs & auth over the left and then APIs. Look for Google Calendar and then turn it on.
Over on the left click Credentials under APIs & auth. Click Create new Client ID under OAuth. Choose Web Application. Fill out Product Name and Email on the consent screen. On the Create Client ID screen use the following values and then click Create Client ID
After everything is setup you should see the following.
Save the values for CLIENT ID and CLIENT SECRET. You'll need them in a later step.
Google Calendar ID
You'll need the ID of the calendar that you want to pull events for. The easiest way is to find the calendar you want, and then look for Calendar settings. Down the screen you should see Calendar ID which will either look like username@gmail.com or something like sjb1qhbicuu3u0kl6suat53h8c@group.calendar.google.com
Code
Place the following source code in a file named app.js
You'll need to edit the following lines (3:5) with the credentials you saved from the Google API Console and also your Calendar ID.
Save the file and at this point you should be all set. Run the following command and then visit http://localhost:2002 in your browser.
You should be redirected to a Google OAuth page where you can grant your app permission to read your calendar. If you have multiple Google accounts, be sure to choose the one that has access to the calendar you want to display. After accepting you should be bounced back to http://localhost:2002 where you should see JSON output for the events on the calendar you specified. Make sure you have events on your calendar for the current day if you don't see anything and then refresh the page.
Next Steps
Now that you have the data you need, you can write frontend Javascript to process this JSON at a set frequency and iterate through the events to display which returned event coincides with the current time. Looking through the JSON above you can see that I had a bike race all day today.
Notes
- The entire source for this application is available at: https://github.com/mtoigo/NodeGoogleCalendarTutorial
- OAuth can be a little tricky to understand at first so you should read through Google's implementation here and also the related scopes.
- There are better ways to architect this type of application, but this is designed to be as concise as possible.
- IMPORTANT: Do not run this at a public URL if the calendar you are showing is private. This would mean you are showing private events at an open public URL.
- If it's possible, it's best to setup a generic google user to pull these calendars that has read only access to them rather than your own personal Google account.
- This implementation persists the OAuth refresh token in memory which is not ideal. You only get a refresh token when you initially authorize an application. If you do not have a proper refresh token, requests to Google will fail after an hour. The workaround for this is to revoke your application's access from your Google account whenever you start it or to persist the token information in a data store.
- One gotcha is that cancelled events will still come back so be sure to check the status field to make sure events are still valid.