Open In App

How to integrate Google Calendar in Node.js ?

Improve
Improve
Like Article
Like
Save
Share
Report

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:

  • We will first create a new Google cloud project on the Google developers console. This is the starting step for using Google Cloud services, managing APIs and permissions, and controlling the collaborators for the project.
  • After creating a new project, the next step is to enable API. A project can have more than one API enabled. We will require only one and that is “Google Calendar API“.
  • Now we need to understand how authentication and authorization work in Google Workspace. First, let’s revise the definitions of these 2 terms.
  • Authentication: the process of verifying identity.
  • Authorization: verifying whether the application/user can access certain resources.
  • Google Workspace offers 2 types of authentication: user authentication and app authentication. We will be using app authentication, in which the app authenticates on behalf of the user to use Google services.

Why are we using “app authentication”? 

  • Since our problem statement is to integrate calendar services in NodeJS, we will not be dealing with any frontend code. With app authentication, no user sign-in is required and our server will communicate directly with Google servers.

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

  • Authentication in Google Workspace requires “credentials”. Credentials are a “form of identification”, which will verify the identity of the app/user.
  • Among the 3 authentication credentials offered by Google( API key, OAuth 2 consent, Service Account), we will be using “Service Account“. A service account is mainly used for “server-to-server interactions” and can also be extended to access user data if necessary. A service account is useful when we have a backend application that will directly communicate with Google servers.
  • The service account will be an account that belongs to our application instead of the user. Our application will handle the job of calling calendar API without involving the users directly.
  • The credentials for this account require the creation of a key, which will be downloaded in the form of a JSON file in the user’s system. The data in the JSON file are the credentials that will be used in our app.
  • The authorization will be carried out by the code which we will write. Google stores calendars in the cloud and our app needs to have the rights to access cloud-stored data/resources.
  • Whenever we will access a calendar method, the service account credentials and our method call will be combined into a request(to make an authorized API call) and sent to the Google Authorization Server. This request will be delivered by a “client” either by making use of Google’s Client Library or directly via HTTP/REST.
  • In our project, we will send via HTTP by declaring a JWT client. The server will then return an access token. Our app will use this access token to make changes to the calendar.

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.

  • The next step would be to create a new calendar on the Google Calendar website(mentioned further in the article) and add the service account email as a user who is given permission to make changes to the calendar.
  • Finally, we create our NodeJS application using Express and we will install “googleapis“(a NodeJS client library for accessing Google APIs) package.
  • We will perform 2 operations on the calendar using the calendar.events call:
  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 :

  • Require necessary packages like express and googleapis.
  • Declare all necessary credentials from JSON “service key file” such as private key, client email, etc.
  • Use project number and calendar ID which we had acquired in previous steps.
  • Declare a JWT(JSON Web Token) client using credentials. This JWT client will use service account credentials to authenticate our application to Google servers.
  • The SCOPE defines the level of authorization associated with the API call using the JWT client. Since we will first display upcoming events, the SCOPE is “read-only”.
  • The JWT client will be used to issue a request to Google servers.
  • Google server will return an access token.
  • This access token will be used to call Google API.
  • Define a calendar object using project number and JWT client.
  • Declare home route which will display 10 upcoming events added to the calendar ordered by their start time. If there is no event scheduled for a future or current date, then “No upcoming events found” will be displayed.
  • The events are accessed by calendar.events.list. The results returned from this call will be returned to the browser using JSON.stringify.

Insert the following code in the index.js file:

Filename: index.js

javascript




//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:

Javascript




//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. 

  • So now let’s declare another client “auth”, which contains the credentials for authentication such as the path of JSON service key file and authorization SCOPE as “https://www.googleapis.com/auth/calendar” for full access to Google Calendar API.
  • auth client will perform the background process similar to JWT client of requesting for access token from Google authentication servers to make API call.

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

Javascript




//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:

  • Created a new route “/createEvent” for allowing users to add new events to the calendar.
  • Since we are using only NodeJS, the event details will be hardcoded. An event object is declared with necessary values for key fields like description, name, summary, start time, end time, etc.
  • This event can be added by our application by using “calendar.events.insert“. This operation is authenticated and authorized by an instance of google.auth.GoogleAuth “auth” client.
  • After adding an event, when the user again visits the home route, the new event details will be displayed(provided the start date for the event is on the current date or future date).

Below is the final code for index.js:

Filename: index.js

javascript




//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



Last Updated : 10 Apr, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads