DEV Community

Cover image for Google Calendar API Integration Made Easy
megazear7
megazear7

Posted on

Google Calendar API Integration Made Easy

I recently struggled to integrate the Google Calendar API while trying to create an event listing for a website. While in retrospect most of it should have been easy but there were a few tricky configurations that were required. I wanted to share the steps I took to integrate a website with the Google Calendar API. We will use JWT authentication which is the most secure and flexible way to connect to a Google API. Keep in mind this type of connection is to connect to a Google that you manage, not a users Google account.

Enable the Calendar API

First we need to setup the Google API and gather the various connection information that we will need in order to connect to it. To begin simply enable the calendar API.

  1. The first step is to go to the Google API Console and either select an existing project or create a new project.
  2. Then select the "Enable APIS and Services" button
  3. Type "Calendar" into the search box
  4. Click on "Google Calendar API"
  5. Click "Enable"

Setup JWT Access

Next we need to create a JSON Web Token, commonly referred to as "JWT". This will provide us with the information that we need to programmatically access various Google API's in a secure context.

  1. Go to the Google API Console
  2. Choose "Credentials" from the left hand navigation
  3. Click the "Create Credentials" button
  4. Choose "Service account key"
  5. This will download a JSON file to your computer. We will refer to this as the JWT JSON file throughout this blog post.

Retrieve the Google Project Number

Now we need to retrieve the Google Project Number which will be required by the Google API.

  1. Go to the Google API Consolec
  2. In the top right of the screen click the three dot menu option next to your profile picture.
  3. Click "Project Settings"
  4. Copy the "Project Number" and paste it somewhere for safe keeping. We will refer to this as throughout this blog post in code examples

Setup the Google Calendar

Finally we need to configure the Google calendar and retrieve the ID. This was the tricky step as you have to give the JWT token access to you calendar as mentioned in steps 5-7 below.

  1. Go to Google Calendar
  2. On the left hand side hover over the calendar that you want to list events for and click the three dot menu icon
  3. Click "Settings and sharing"
  4. Scroll down and copy the "Calendar ID" and paste it somewhere for safe keeping. We will refer to this as throughout this blog post in code examples.
  5. Open up the JWT JSON file and copy the client email.
  6. Go to the "share with specific people" section of the calendar and click "Add people"
  7. Paste the client email and submit the dialog

Setup Example Express Project

Now let's create a sample project using Node.JS with an Express server. Create a directory for your project and run the following commands:

npm init
npm install express --save
npm install googleapis --save
Enter fullscreen mode Exit fullscreen mode

Create Your Express Server

Finally we need to write code that will start up an express server to listen to requests, contact the Google Calendar API with our connection details that we retrieved above, and then reply with the result. Note that the constants defined at the start of the file need updated based upon the corresponding values we retrieved earlier. The and values both come from the JWT JSON file.

/index.js

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

const app = express();
const port = 3000;

const SCOPES = 'https://www.googleapis.com/auth/calendar.readonly';
const GOOGLE_PRIVATE_KEY="<private-key>"
const GOOGLE_CLIENT_EMAIL = "<client-email>"
const GOOGLE_PROJECT_NUMBER = "<project-number>"
const GOOGLE_CALENDAR_ID = "<calendar-id>"

app.get('/', (req, res) => {
  const jwtClient = new google.auth.JWT(
    GOOGLE_CLIENT_EMAIL,
    null,
    GOOGLE_PRIVATE_KEY,
    SCOPES
  );

  const calendar = google.calendar({
    version: 'v3',
    project: GOOGLE_PROJECT_NUMBER,
    auth: jwtClient
  });

  calendar.events.list({
    calendarId: GOOGLE_CALENDAR_ID,
    timeMin: (new Date()).toISOString(),
    maxResults: 10,
    singleEvents: true,
    orderBy: 'startTime',
  }, (error, result) => {
    if (error) {
      res.send(JSON.stringify({ error: error }));
    } else {
      if (result.data.items.length) {
        res.send(JSON.stringify({ events: result.data.items }));
      } else {
        res.send(JSON.stringify({ message: 'No upcoming events found.' }));
      }
    }
  });
});

app.listen(port, () => console.log(`Example app listening on port ${port}!`));
Enter fullscreen mode Exit fullscreen mode

Now run your server with node index.js and go to localhost:3000 to see the result. Remember to move the private key and other constants into environment variables instead of committing them to source control. You should see the next 10 events that were added to the Google Calendar. This can be used to integrate a Google Calendar with an upcoming events feature on a website or could serve as a starting point for other features requiring a Google Calendar integration. Lastly the JWT authentication shown here can be used for a wide variety of Google APIs.

Top comments (13)

Collapse
 
juniorgodoi profile image
Junior Godoi

Hello, trying this code and getting:

{"error":{"library":"PEM routines","function":"get_name","reason":"no start line","code":"ERR_OSSL_PEM_NO_START_LINE"}}

Can't figure out why, all the settings are correct and calendar is shared with the correct service account.

Collapse
 
ksbeasle profile image
Kahlil Beasley

Hi, don't know if you already figured it out but for you or anyone else running into the same issue I solved it by doing the following.

  1. Put the entire jwt json file you get from google into an env variable in the .env file.
    example: SOME_VAR='{"key": "value"}'
    NOTE The entire json file has to be on a single line

  2. Then read in the value in your index.js file
    example: const { SOME_VAR } = process.env; //JSON

3.Parse it.
example: const someVar = JSON.parse(SOME_VAR);

  1. Use dot notation to access that key and pass it wherever you need it. example: someVar.key // 'value'
Collapse
 
james6m profile image
James McLean

This is great. So much of the documentation out there assumes that you want to access /other/ people's calendars.
At step 4 of "Setup JWT Access", I do not get a JSON file download. There are a bunch of fields to fill out, including granting access to the project with a bewildering array of access options. Is that expected and just glossed over in these instructions? What access roles to choose?

Collapse
 
megazear7 profile image
megazear7

This article is specifically designed for the "server to server" authentication scenario. This means that your express server communicates with the Google API with authorization that has been setup ahead of time.

The scenario that you are describing is where a user gives certain authorizations to your app in order to do things such as add events to the users calendar. This would be where the user would see the " wants to add events to your calendar" and the user would say yes. At this point your app would receive a token to use in order to authenticate with the google API for that user.

While it is outside the scope of a comment to explain this in more detail, I hope this at least gets you on the right track.

Collapse
 
vitality82 profile image
vitality82 • Edited

I'm also very interested in this scenario. Some apps will have just have a one-time connect with google calendar (OAuth + consent) and from there on, any events created in that app will show up on my calendar, or on any users google calendars within that app.

I don't see how this could be automated as if you imported a webcal URL into google. I assume each time your application created an event it needs to push that event to all your users calendars (who already autorized your app) or, there is just one syncing server (Google CalDAV?) that your application can push events to, and that server knows how to update client calendars?

Thread Thread
 
megazear7 profile image
megazear7

This is specifically designed to integrate an "administrated calendar" into a website. So this doesn't display user data, it displays data from a calendar that is administered behind the scenes and then displayed on a website.

Thread Thread
 
vitality82 profile image
vitality82

Thanks!

Collapse
 
shaikabbas051 profile image
shaik abbas

Can we make other people as an organizer of the meeting?

Collapse
 
vikramchandra profile image
Vikram Sharma

Hi. Thanks for the detailed tut. For those interested in looking at other options, here is a list of calendar apis.

Collapse
 
sarang87 profile image
Sarang Joshi

Is it possible to post events on someone else's calendar? If so how would these permissions be enabled to allow posting or getting data from other people's calenders?

Collapse
 
zeealik profile image
Zeeshan Ali Khan

How can we integrate this with a ReactJS application?
Using the MERN stack?

Collapse
 
jmbodz profile image
JMBodz

Hello, is there a way to get the response from the invitee when an event was sent using this googlecalendarapi?