Skip to main content
Version: 5.34.0

Third party calendar integration

Overview

The Calendar Integration is an optional plugin, that includes synchronization with your Google and Outlook calendar services. It can be installed and used with the Mobiscroll Event Calendar as described below.

info

Currently, the calendar integration plugins cannot be used in Chrome extensions, because the CSP rules do not allow loading scripts from 3rd party domains.

Installing the Calendar Integration Plugin

When your Mobiscroll package is created with the Download Builder and you have access to the Calendar Integration, you can choose to include it in the built package. In this case you will need to make sure you checked the Calendar Integration before downloading the package from the download page. After installing your downloaded package, the Calendar Integration will be available for import.

When you're using the full Mobiscroll package from NPM, then you have the possibility to install the Calendar Integration as an additional package (also from NPM). In this case, after successfully using the Mobiscroll CLI to configure the project, you will have to install the @mobiscroll/calendar-integration package from npm. Use the following command:

npm install @mobiscroll/calendar-integration

Google calendar integration

The Google Calendar Integration is a part of the third party calendar integrations plugin that manages the synchronization with your Google calendar services.

Public google calendars

Calling the init function will do the necessary initializations for the third party. After the init, you can list the events from the public calendar.

import { googleCalendarSync } from "@mobiscroll/calendar-integration";

const calInst = mobiscroll.eventcalendar('#myDiv'. {
view: { schedule: { type: 'week' }},
});

// init google client
googleCalendarSync.init({
apiKey: 'YOUR_APY_KEY',
onInit: () => {
googleCalendarSync.getEvents(
'PUBLIC_CALENDAR_ID',
new Date(2022, 1, 1),
new Date(2022, 3, 0)
).then((events) => {
calInst.setEvents(events);
});
},
});

Private google calendars

Calling the init function will do the necessary initializations for the third party. For this step you need to use an API key and a client ID. After the init, you can sign in, list your calendars and events and create, update or delete the events on the calendars you have permission to.

import { googleCalendarSync } from "@mobiscroll/calendar-integration";

const calInst = mobiscroll.eventcalendar('#myDiv'. {
view: { schedule: { type: 'week' }},
});

// init google client
googleCalendarSync.init({
apiKey: 'YOUR_APY_KEY',
clientId: 'YOUR_CLIENT_ID',
onSignedIn: () => {
googleCalendarSync.getEvents(
['MY_FIRST_CALENDAR_ID', 'MY_SECOND_CALENDAR_ID'],
new Date(2022, 1, 1),
new Date(2022, 3, 0)
).then((events) => {
calInst.setEvents(events);
});
},
onSignedOut: () => {
calInst.setEvents([]);
},
});

Server side tokens

By default the authentication happens entirely on the client side. However, since the introduction of the new Google Identity Services, the received access token, which ensures access to the user's calendars, is only valid for an hour. After expiry, the user will be prompted again for consent.

You can refresh an access token without prompting the user for permission, but this needs to be done server side. To enable this, in the init config object set the auth option to 'server', and specify the authUrl and refreshUrl pointing to your server endpoints.

The authUrl endpoint will receive a POST request, containing a unique authorization code. To exchange an authorization code for an access token, send a POST request to the https://oauth2.googleapis.com/token endpoint and set the following parameters:

  • client_id - The client ID obtained from the Google API Console Credentials page.
  • client_secret - The client secret obtained from the Google API Console Credentials page.
  • code - The received authorization code.
  • grant_type - This field's value must be set to authorization_code.
  • redirect_uri - This field's value must be set to postmessage.
POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded

code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
client_id=your_client_id&
client_secret=your_client_secret&
redirect_uri=postmessage&
grant_type=authorization_code
{
"access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
"expires_in": 3599,
"token_type": "Bearer",
"scope": "https://www.googleapis.com/auth/calendar.events.public.readonly https://www.googleapis.com/auth/calendar.readonly https://www.googleapis.com/auth/calendar.events.owned",
"refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
}

Return the received response from the request.

The refreshUrl endpoint will also receive a POST request, containing the refresh token, received earlier. To refresh an access token, send a POST request to the https://oauth2.googleapis.com/token endpoint and set the following parameters:

  • client_id - The client ID obtained from the Google API Console Credentials page.
  • client_secret - The client secret obtained from the Google API Console Credentials page.
  • refresh_token - The received refresh token.
  • grant_type - This field's value must be set to refresh_token.
POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded

client_id=your_client_id&
client_secret=your_client_secret&
refresh_token=your_refresh_token&
grant_type=refresh_token
{
"access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
"expires_in": 3599,
"token_type": "Bearer",
"scope": "https://www.googleapis.com/auth/calendar.events.public.readonly https://www.googleapis.com/auth/calendar.readonly https://www.googleapis.com/auth/calendar.events.owned"
}

Return the received response from the request.

Complete example

A complete example with Node.js, ASP.NET and PHP

// Client
import { googleCalendarSync } from '@mobiscroll/calendar-integration';

googleCalendarSync.init({
auth: 'server',
authUrl: 'http://example.com/auth',
clientId: 'YOUR_CLIENT_ID',
refreshUrl: 'http://example.com/refresh',
});

// Server
const http = require('http');
const https = require('https');

const YOUR_CLIENT_ID = 'YOUR_CLIENT_ID';
const YOUR_CLIENT_SECRET = 'YOUR_CLIENT_SECRET';

function getToken(type, codeOrToken, callback) {
const postData =
'client_id=' + YOUR_CLIENT_ID + '&' +
'client_secret=' + YOUR_CLIENT_SECRET + '&' +
(type === 'refresh' ?
'grant_type=refresh_token&' +
'refresh_token=' + codeOrToken
:
'grant_type=authorization_code&' +
'code=' + codeOrToken + '&' +
'redirect_uri=postmessage&' +
'code_verifier='
)

const postOptions = {
host: 'oauth2.googleapis.com',
port: '443',
path: '/token',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(postData)
}
};

const postReq = https.request(postOptions, function (response) {
response.setEncoding('utf8');
response.on('data', d => {
callback(d);
});
});

postReq.on('error', (error) => {
console.log(error)
});

// Post the request with data
postReq.write(postData);
postReq.end();
}

function getPostData(req, callback) {
let body = '';

req.on('data', (data) => {
body += data;
});

req.on('end', () => {
const parsed = new URLSearchParams(body);
const data = {}
for (const pair of parsed.entries()) {
data[pair[0]] = pair[1];
}
callback(data);
});
}

function checkCSRF(req, res) {
// Check if CSRF header is present
if (req.headers['x-requested-with'] === 'XmlHttpRequest') {
return true;
}
// Otherwise end the request
res.statusCode = 500;
res.end();
return false;
}

function sendResponse(res, data) {
// Set the headers in case of CORS request
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With');
// Send data
res.end(data);
}

const server = http.createServer(function (req, res) {
if (req.method === 'OPTIONS') { // Handle preflight request (in case of CORS request)
res.setHeader('Access-Control-Allow-Origin', '*'); // Use your own domain instead of the '*'
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With');
res.end();
} else if (req.url.startsWith('/auth')) { // Handle auth
if (checkCSRF(req, res)) {
getPostData(req, (data) => {
// Exchange auth code to access token (on sign in)
getToken('auth', data.code, (token) => {
sendResponse(res, token);
});
});
}
} else if (req.url.startsWith('/refresh')) { // Handle refresh
if (checkCSRF(req, res)) {
getPostData(req, (data) => {
// Exchange refresh token to access token (on access token expiry)
getToken('refresh', data.refresh_token, (token) => {
sendResponse(res, token);
});
});
}
}
});

server.listen(8080);

API

Configuration options

apiKey

string

The API Key obtained from the Google API Console Credentials page.

auth

"client" | "server"

When set to 'server', server-side endpoints must be implemented to get the auth access token from Google.

authUrl

string

Server side endpoint for receiving an access token from Google on sign in, when the auth option is set to 'server'.

clientId

string

The client ID obtained from the Google API Console Credentials page.

gapi

any

The gapi object, if already loaded. If not specified, the library will load it.

gis

any

The Google Identity Services client library, if already loaded. If not specified, the library will load it.

refreshUrl

string

Server side endpoint for receiving a new access token from Google on expiry, when the auth option is set to 'server'.

scopes

string

Specify custom scopes for Google authentication. The default scopes are 'https://www.googleapis.com/auth/calendar.events.public.readonly https://www.googleapis.com/auth/calendar.readonly https://www.googleapis.com/auth/calendar.events.owned'

timezone

string

If specified, the event dates will be returned in this timezone.

timezonePlugin

MbscTimezonePlugin

The timezone plugin, needed if timezone is specified.

The MbscTimezonePlugin type has the following properties:

  • createDate: (s: any, year: string | number | Date | MbscTimezonedDate, month: number, date: number, h: number, min: number, sec: number, ms: number) => MbscTimezonedDate -
  • parse: (date: string | number, s: any) => MbscTimezonedDate -

Events

onInit

() => void

Callback executed when the library is initialized and ready to use.

onSignedIn

() => void

Callback executed when the user signed in.

onSignedOut

() => void

Callback executed when the user signed out.

Methods

addEvent

(calendarId: string, event: MbscCalendarEvent, callback: (addedEvent: MbscCalendarEvent) => void ) => Promise

Adds an event to the specified calendar.

Example usage
googleCalendarSync.addEvent(
'MY_CALENDAR_ID',
{
start: new Date(2022, 1, 15, 12),
end: new Date(2022, 1, 16, 14),
title: 'My new event',
googleEvent: {
description: 'My new event description'
}
});

Parameters:

  • calendarId - The ID of the calendar

  • event - The event to add. You can pass Google specific event properties through the googleEvent property. The rest of custom properties will be passed to the extendedProperties field.

  • callback - Callback function which is executed when the request is complete. Receives the added event.

deleteEvent

(calendarId: string, event: MbscCalendarEvent, callback: (deletedEvent: MbscCalendarEvent) => void ) => Promise

Removes an event in the specified calendar.

Parameters:

  • calendarId - The ID of the calendar

  • event - The event to delete

  • callback - Callback function which is executed then the request is complete. Receives the deleted event.

getCalendars

(callback: (calendars: Array<any>) => void ) => Promise

Queries the available calendars of the signed in user. Calls the callback function, if specified.

Parameters:

  • callback - A callback function to call with the calendars as parameters, when the query finished.

getEvents

(calendarIds: string | Array<string>, start: Date, end: Date, callback: (events: Array<MbscCalendarEvent>) => void ) => Promise

Queries the events of the specified calendars between two dates.

Parameters:

  • calendarIds - Array of the calendar IDs.

  • start - Start date of the specified interval.

  • end - End date of the specified interval.

  • callback - Callback function which is executed then the request is complete. Receives the list of events as parameter.

init

(config: MbscGoogleCalendarSyncConfig) => void

Makes the necessary initializations for the 3rd party. Triggers the onInit event when the initialization is ready, if specified.

Parameters:

  • config - The configuration object for the calendar integration

isSignedIn

() => boolean

Checks if the user is signed in or not.

signIn

() => Promise

If the user is not signed in, starts the sign in flow. On success, triggers the onSignedIn event.

signOut

() => Promise

If the user is signed in, signs out. On success triggers the onSignedOut event.

updateEvent

(calendarId: string, event: MbscCalendarEvent, callback: (updatedEvent: MbscCalendarEvent) => void ) => Promise

Updates an event in the specified calendar.

Example usage
googleCalendarSync.updateEvent(
'MY_CALENDAR_ID',
{
start: new Date(2022, 1, 20, 10),
end: new Date(2022, 1, 11, 15),
title: 'My updated event',
id: 1,
googleEvent: {
description: 'My updated event description'
}
});

Parameters:

  • calendarId - The ID of the calendar

  • event - The event to update. You can pass Google specific event properties through the googleEvent property. The rest of custom properties will be passed to the extendedProperties field.

  • callback - Callback function which is executed then the request is complete. Receives the updated event.

Outlook calendar integration

The Outlook Calendar Integration is a part of the third party calendar integrations plugin that manages the synchronization with your Outlook calendar services.

Outlook calendars

Calling the init function will do the necessary initializations for the third party. For this step you need to use a client ID. After the init, you can sign in, list your calendars and events and create, update or delete the events on the calendars you have permission to.

import { outlookCalendarSync} from "@mobiscroll/calendar-integration";

const calInst = mobiscroll.eventcalendar('#myDiv'. {
view: { schedule: { type: 'week' }},
});

// init outlook client
outlookCalendarSync.init({
clientId: 'YOUR_CLIENT_ID',
onSignedIn: () => {
outlookCalendarSync.getEvents(
['MY_FIRST_CALENDAR_ID', 'MY_SECOND_CALENDAR_ID'],
new Date(2022, 1, 1),
new Date(2022, 3, 0)
).then((events) => {
calInst.setEvents(events);
});
},
onSignedOut: () => {
calInst.setEvents([]);
},
});

API

Configuration options

clientId

string

The client ID obtained from the Outlook web app.

msal

any

The Microsoft Authentication Library, if already loaded. If not specified, the library will load it.

msalClient

any

The instance of the client application, if already loaded. If not specified, the library will load it.

pageSize

number

The maximum number of events to retrieve with one request. Default value is 1000.

redirectUri

string

The location where the authorization server sends the user once the app has been successfully authorized. Default value is 'http://localhost:3000'.

timezone

string

If specified, the event dates will be returned in this timezone.

timezonePlugin

MbscTimezonePlugin

The timezone plugin, needed if timezone is specified.

The MbscTimezonePlugin type has the following properties:

  • createDate: (s: any, year: string | number | Date | MbscTimezonedDate, month: number, date: number, h: number, min: number, sec: number, ms: number) => MbscTimezonedDate -
  • parse: (date: string | number, s: any) => MbscTimezonedDate -

Events

onInit

() => void

Callback executed when the library is initialized and ready to use.

onSignedIn

() => void

Callback executed when the user signed in.

onSignedOut

() => void

Callback executed when the user signed out.

Methods

addEvent

(calendarId: string, event: MbscCalendarEvent, callback: (addedEvent: MbscCalendarEvent) => void ) => Promise

Adds an event to the specified calendar.

Example usage
outlookCalendarSync.addEvent(
'MY_CALENDAR_ID',
{
start: new Date(2022, 1, 15, 12),
end: new Date(2022, 1, 16, 14),
title: 'My new event',
outlookEvent: {
isReminderOn: true,
}
});

Parameters:

  • calendarId - The ID of the calendar

  • event - The event to add. You can pass Outlook specific event properties through the outlookEvent property.

  • callback - Callback function which is executed when the request is complete. Receives the added event.

deleteEvent

(calendarId: string, event: MbscCalendarEvent, callback: (deletedEvent: MbscCalendarEvent) => void ) => Promise

Removes an event in the specified calendar.

Parameters:

  • calendarId - The ID of the calendar

  • event - The event to delete

  • callback - Callback function which is executed then the request is complete. Receives the deleted event.

getCalendars

(callback: (calendars: Array<any>) => void ) => Promise

Queries the available calendars of the signed in user. Calls the callback function, if specified.

Parameters:

  • callback - A callback function to call with the calendars as parameters, when the query finished.

getEvents

(calendarIds: string | Array<string>, start: Date, end: Date, callback: (events: Array<MbscCalendarEvent>) => void ) => Promise

Queries the events of the specified calendars between two dates.

Parameters:

  • calendarIds - Array of the calendar IDs.

  • start - Start date of the specified interval.

  • end - End date of the specified interval.

  • callback - Callback function which is executed then the request is complete. Receives the list of events as parameter.

init

(config: MbscOutlookCalendarSyncConfig) => void

Makes the necessary initializations for the 3rd party. Triggers the onInit event when the initialization is ready, if specified.

Parameters:

  • config - The configuration object for the calendar integration

isSignedIn

() => boolean

Checks if the user is signed in or not.

signIn

() => Promise

If the user is not signed in, starts the sign in flow. On success, triggers the onSignedIn event.

signOut

() => Promise

If the user is signed in, signs out. On success triggers the onSignedOut event.

updateEvent

(calendarId: string, event: MbscCalendarEvent, callback: (updatedEvent: MbscCalendarEvent) => void ) => Promise

Updates an event in the specified calendar.

Example usage
outlookCalendarSync.updateEvent(
'MY_CALENDAR_ID',
{
start: new Date(2022, 1, 20, 10),
end: new Date(2022, 1, 11, 15),
title: 'My updated event',
id: 1,
outlookEvent: {
isReminderOn: false,
}
});

Parameters:

  • calendarId - The ID of the calendar

  • event - The event to update. You can pass Outlook specific event properties through the outlookEvent property.

  • callback - Callback function which is executed when the request is complete. Receives the updated event.