Open In App

How to integrate Google Calendar in Node.js ?

Google developers console offers a platform for building top-notch applications with easy integration of services and tools offered by Google. Google Calendar is one of these services and using a calendar can be advantageous to provide functionalities such as planning/creating events in projects like a to-do list app or meeting scheduler. 

While developing a project with numerous functionalities, the work of a developer will be much easier by making use of APIs for minor tasks and actually focusing on the purpose of the application. Instead of coding your own logic for storing calendar attributes, user permissions, and event management details, we can use Google Calendar API which comes with integrated security and calendar modules. We will be saved from the hassle of coordinating overlapping events, sending reminders, notifications, etc.



This article covers the integration of Google Calendar API in the NodeJS application and creating new events with service account authentication. Our aim is to integrate Google Calendar services in the NodeJS application. We need to test whether calendar methods are functioning in our backend NodeJS app with proper error handling mechanisms in case of wrong credentials or lack of permissions given to the user. The 2 functions of the calendar which are integrated into this project are event view and add events.

Approach:



Why are we using “app authentication”? 

Now how will our identity be verified or how will authentication be carried out? 

NodeJS app using service account credentials to create JWT and obtain an access token from Google server via HTTP. This access token is used to make authorized API calls.

  1. View events for current date
  2. Add new event

Flow chart of approach

Now let’s start with the step implementation of the above approach.

Firstly we will see setting up project and credentials in Google Developers Console.

Step 1: Open google console and click on the dropdown for selecting a project. We will be creating a new project. Click on “NEW PROJECT” towards the top right. Give a suitable project name and click on create.

Create project

Step 2: Google console dashboard will be displayed after creating a project. Make sure you are viewing the dashboard of your newly created project to add Google calendar functionality.

Project dashboard in console

Step 3:  Click on APIs & Services tab present under the “More Products” section towards the left and then click on “Enable APIS and Services”.

Step 4:  The API library will be displayed. From here we can select which APIs we want to enable for our project. Since we are going to integrate Google calendar, type “Calendar” in the search box and select “Google Calendar API”.

Google console API library

Select Google Calendar API

Step 5:  All details of Google Calendar API will be displayed, including documentation and services of the API. Click on enable to add this API to your project.

Enable Google Calendar API

Step 6:  Now we will be creating the service account for our application. Click on “CREATE CREDENTIALS” to create a service account.

Step 7: Select “Google Calendar API” as a type of API for the credential.

Select which API we will be using

Step 8: Now you will be asked “What data will you be accessing?”, as we are creating a service account, click on “Application Data” and “Next”.

Step 9:  Next enter service account details such as account name and the service account ID will be generated simultaneously. Then click on “Create and Continue”.

Step 10:  We will select the “Owner” role for giving access to the service account to our application. After adding the role, click on continue.

Select a role for the service account

Step 11:  This step is optional. It is up to you to give admin rights to a specific person or a group of people who can administer the service account. Click on Done.

Step 12:  The service account has been set up. Now the credentials for this service account have to be created. The key associated with this service account can be downloaded as a JSON file. We will refer to this as a “service key file” in later steps. Click on the email under Service Account.

Step 13:  Go to the KEYS tab and click on ADD KEY.

Step 14:  We will create a new key and select JSON as key type. Click on create.

Step 15: The private key is created and downloaded as a JSON file. Remember this file is highly sensitive and its credentials must not be public!

Step 16:  We still require the project number in order to configure the calendar. Click on the 3 dot menu option in the top right and click on “Project Settings”.

Step 17:  Copy the project number and store it in a safe place for future use.

Copy project number and store in notepad for future use

 

Step 18: Now we will set up a Google calendar and retrieve its ID. The calendar will require credentials that we have got in the JSON file. Go to Google Calendar and create a new calendar by clicking ‘+’ beside “Other calendars”.

Step 19:  Enter name and description, then click on “Create calendar”.

Step 20:  Click on the 3 dot menu beside the newly created calendar and click on “Settings and sharing”.

Step 21:  Scroll down to the “Integrate calendar” section and copy the Calendar ID. Store this ID in a safe place for future use. Open the JSON service key file and copy “client email”. Go to the “Share with specific people” section and “Add people” by pasting the copied client email.

Now we will set up Express Application.

Step 1: Create a new folder with a suitable name. We will be using “Google_Calendar”.

Step 2: Run the following commands on the terminal:

npm init -y

npm i express googleapis

Project Structure: It will look like the following.

Step 3:  Create an index.js file. This is going to be the main file where we will integrate Google Calendar. At first, we will view events. In this file the logic sequence is :

Insert the following code in the index.js file:

Filename: index.js




//index.js code for integrating Google Calendar
  
const express = require('express');
const { google } = require('googleapis');
  
const app = express();
  
const GOOGLE_PRIVATE_KEY="<private-key>"
const GOOGLE_CLIENT_EMAIL = "<client-email>"
const GOOGLE_PROJECT_NUMBER = "<project-number>"
const GOOGLE_CALENDAR_ID = "<calendar-id>"
  
  
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
});
  
app.get('/', (req, res) => {
  
  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(3000, () => console.log(`App listening on port 3000!`));
  
// This code is contributed by Yashi Shukla

The private key, client email can be obtained from JSON file. The calendar ID and project number which you previously stored will be used here.

Step to run the application:

node index.js

or

nodemon index.js

Output: Output can be viewed on your browser by using this link: http://localhost:3000/

Run the app using nodemon index.js or node index.js

This route will display 10 upcoming events on the calendar or “No upcoming events found” if no events have been added.

Initially no upcoming events 

Since this is a newly created calendar, there are no upcoming events. 

Step 4: Insert new events. Google offers different methods for managing and controlling events being added to the calendar. We can add new events by using the calendar.events.insert() method. We will have to make a few changes in the role of the user added in step 6 of setting up Google Calendar. Go back to the “Share with specific people” section and change the role of your service account from “See all event details” to “Make changes to events”.

Step 5: Since we are now going to edit events, our application needs to be authenticated as a service account. For this type, the following in command prompt(root directory of project) and in place of KEY_PATH, put the entire path of your JSON service key file.

set GOOGLE_APPLICATION_CREDENTIALS=KEY_PATH

Step 6: Create a new route for adding an event(/createEvent) in index.js. For simplicity, we will hard code the details of the event. As per documentation for Calendar API, the event object can be defined as:




//A sample event object for calendar
  
var event = {
    'summary': 'My first event!',
    'location': 'Hyderabad,India',
    'description': 'First event with nodeJS!',
    'start': {
      'dateTime': '2022-01-12T09:00:00-07:00',
      'timeZone': 'Asia/Dhaka',
    },
    'end': {
      'dateTime': '2022-01-14T17:00:00-07:00',
      'timeZone': 'Asia/Dhaka',
    },
    'attendees': [],
    'reminders': {
      'useDefault': false,
      'overrides': [
        {'method': 'email', 'minutes': 24 * 60},
        {'method': 'popup', 'minutes': 10},
      ],
    },
  };

You can give your own values of date, time, location, description as per your choice.

Step 7: The JWT client defined a “read-only” scope for API calls. However, if we want to add new events, a “read-only” scope will not be sufficient. 

The following is the code for declaring “auth” client:




//Creating an aunthenticated client to call events.insert()
  
const auth = new google.auth.GoogleAuth({
    keyFile: '<FULL-PATH-OF-JSON-FILE>',
    scopes: 'https://www.googleapis.com/auth/calendar', //full access to edit calendar
  });
  auth.getClient().then(a=>{
    calendar.events.insert({
      auth:a,
      calendarId: GOOGLE_CALENDAR_ID,
      resource: event,
    }, function(err, event) {
      if (err) {
        console.log('There was an error contacting the Calendar service: ' + err);
        return;
      }
      console.log('Event created: %s', event.data);
      res.jsonp("Event successfully created!");
    });
  })

In the final code of index.js we have:

Below is the final code for index.js:

Filename: index.js




//Final index.js code
  
const express = require('express');
const { google } = require('googleapis');
  
const app = express();
  
  
const GOOGLE_PRIVATE_KEY="<private-key>";
const GOOGLE_CLIENT_EMAIL = "<client-email>"
const GOOGLE_PROJECT_NUMBER = "<project-number>"
const GOOGLE_CALENDAR_ID = "<calendar-id>"
  
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
});
  
app.get('/', (req, res) => {
  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.get("/createEvent",(req,res)=>{
  var event = {
    'summary': 'My first event!',
    'location': 'Hyderabad,India',
    'description': 'First event with nodeJS!',
    'start': {
      'dateTime': '2022-01-12T09:00:00-07:00',
      'timeZone': 'Asia/Dhaka',
    },
    'end': {
      'dateTime': '2022-01-14T17:00:00-07:00',
      'timeZone': 'Asia/Dhaka',
    },
    'attendees': [],
    'reminders': {
      'useDefault': false,
      'overrides': [
        {'method': 'email', 'minutes': 24 * 60},
        {'method': 'popup', 'minutes': 10},
      ],
    },
  };
    
  const auth = new google.auth.GoogleAuth({
    keyFile: '<full-path-of-JSON-file>',
  });
  auth.getClient().then(a=>{
    calendar.events.insert({
      auth:a,
      calendarId: GOOGLE_CALENDAR_ID,
      resource: event,
    }, function(err, event) {
      if (err) {
        console.log('There was an error contacting the Calendar service: ' + err);
        return;
      }
      console.log('Event created: %s', event.data);
      res.jsonp("Event successfully created!");
    });
  })
})
  
app.listen(3000, () => console.log(`App listening on port 3000!`));
  
// This code is contributed by Yashi Shukla

Now Checking event created. Open your browser and go to http://localhost:3000/createEvent.

Output:

Adding a new event.

The following output will be shown

The event is successfully created when /createEvent is opened in the browser.

Now as you remember, previously in the output section, “No upcoming events” was displayed. Now again go to http://localhost:3000/. Your newly created event details will be displayed!

Event details at the home route.

Proceed to Google Calendar and you can also see the newly created event added there.

GFG calendar events in red

Event details are displayed by clicking on the event

Final Output:

Inserting new event and checking


Article Tags :