How to Use Google Calendar API to Retrieve Available Time Slots for a Given Day

Is there a way to extract the list of available time slots from my Google Calendar? Currently, I am only able to retrieve the list of scheduled events. I am utilizing the Google Calendar npm package.

google_calendar.events.list(calObj.name,{
    timeMin: "2018-03-02T08:00:00.000Z",
    timeMax: "2018-03-02T16:00:00.000Z",
    singleEvents: true,
    orderBy: "startTime"
}, function (err, eventList) {
    // code to generate output similar to
    // freeSlots -> [{
    //     "startDate": "2018-03-02T08:00:00.000Z",
    //     "endDate": "2018-03-02T09:00:00.000Z"
    // },{
    //     "startDate": "2018-03-02T07:00:00.000Z",
    //     "endDate": "2018-03-02T08:00:00.000Z"
    // }]

    // check if there are events between 10:00 and 16:00 on this day (indicating calendar is busy)
})

Answer №1

If you are looking to access free slots on your Google Calendar, it can be done in just two simple steps. Utilizing npm google-calendar

Firstly, retrieve all the free/busy time slots from your calendar.

var startDateTime = new Date(),
    endDateTime = new Date();

var rootStartTime = startDateTime,
    rootEndTime = endDateTime;

gcal(<accessToken>).freebusy.query({
    "items":[{
        "id": calendarObjectName.name
    }],
    "timeMin": startDateTime.toISOString(),
    "timeMax": endDateTime.toISOString(),
    "timeZone": "GMT+0100"
},{
    fields: "calendars,groups,kind,timeMax,timeMin", 
    alt:"json"
}, function(err, responseData) {
    if(err) return console.log(err)

    // further process and identify free slots
    return determineSlotsFromEvents(startDateTime, responseData.calendars[<calendarName>].busy)
})

var interval = 2, // duration of a single slot (in this case, set to 2 hours) 
freeSlotsArr = []; 

function determineSlotsFromEvents(dateTime, eventsData) {
    eventsData.forEach(function (singleEvent, index) { //calculate free slots based on busy times
        if (index == 0 && startDateTime < singleEvent.start) {
            freeSlotsArr.push({startDateTime: startDateTime, endDateTime: singleEvent.start});
        }
        else if (index == 0) {
            startDateTime = singleEvent.end;
        }
        else if (eventsData[index - 1].end < singleEvent.start) {
            freeSlotsArr.push({startDateTime: eventsData[index - 1].end, endDateTime: singleEvent.start});
        }

        if (eventsData.length == (index + 1) && singleEvent.end < endDateTime) {
            freeSlotsArr.push({startDateTime: singleEvent.end, endDateTime: endDateTime});
        }
    });

    if (eventsData.length == 0) {
        freeSlotsArr.push({startDateTime: startDateTime, endDateTime: endDateTime});
    }

    var tempObj = {}, hourBasedSlots = [];
    freeSlotsArr.forEach(function(freeTimeSlot, index) {
        var numHourDiff = new Date(freeTimeSlot.endDateTime).getHours() - new Date(freeTimeSlot.startDateTime).getHours(), startTime = new Date(freeTimeSlot.startDateTime), endTime = new Date(freeTimeSlot.endDateTime);
        while(startTime.getHours() + numHourDiff + interval >= 0) { // 11 + 4 + 2 >= 0
            if(numHourDiff >= interval) {
                tempObj.e = new Date(freeTimeSlot.startDateTime);
                tempObj.e.setHours(tempObj.e.getHours() + numHourDiff);
                tempObj.s = new Date(freeTimeSlot.startDateTime);
                tempObj.s.setHours(tempObj.s.getHours() + numHourDiff - interval);
                if(tempObj.s.getHours() >= rootStartTime.getHours() && tempObj.e.getHours() <= rootEndTime.getHours()) {
                    hourBasedSlots.push({calendarName: calendarObjectName.name, startDateTime:tempObj.s, endDateTime:tempObj.e});
                    tempObj = {};
                }
            }
            numHourDiff--;
        }
    })

    // callBack(freeSlotsArr, hourBasedSlots);
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue with NPM Scripts Post Hook Triggering

Currently, I am exploring the use of npm scripts to gradually phase out my dependency on Gulp. To begin, I have created a single custom script called watch. This script will eventually execute all other scripts prefixed with the name watch, such as watch:s ...

Utilize JavaScript and jQuery to locate a particular character within a string and move it one position back in the sequence

Can you locate a particular character within a string and move it to the position before? For instance: Consider the following string: Kù Iù Mù The desired output is: ùK ùI ùM ...

React 15 is found to be incompatible with React-redux due to certain compatibility

I'm currently working on upgrading to the newest version of [email protected] in my project, which also utilizes the react-redux@^4.4.0 package. However, I encountered issues when attempting to follow the upgrade instructions provided in the documenta ...

Progressing with JavaScript: Implementing Sound Controls and Dynamic Image Switching

I am looking to create a button that, when clicked, displays a small image and plays a sound. The button should change to a different image and stop the sound when clicked again. Essentially, it functions as a "start" button that loops the sound and change ...

Encountered a Node.js error "spawning git ENOENT" while attempting to clone a repository using simple

I'm currently working on an application that involves cloning a repository, parsing XML files in the repository, and displaying the information. I've successfully implemented this functionality on my local machine and the development test server. ...

Exploring NPM: Utilizing the Groan Module and Uncovering the PHP Session File Name Location

I am trying to figure out how to access PHP session data in Node.js After conducting some research, I came across a helpful thread on Stack Overflow titled "Read PHP Session data in node.js" Following the advice from the thread, I used a sample code prov ...

Using Sequelize and Express API for verification in the controller is an essential component of building

I'm currently working on building the API for my web app, utilizing Sequelize and Express. I have set up models with Sequelize and am in the process of developing controllers and endpoints. My main query is: Should I perform data validation checks be ...

`Navigating through database structures using node js`

When it comes to interpreting a Database {} object in JavaScript, I am currently working on back end scripts for validating a registration form. Specifically, I need to make sure that the username and email being used for registration are not already taken ...

Guide to setting up an automated process in PHP

When setting up a tournament interface on my page: Users utilize functions like fopen() and fwrite() to create tournaments. The created tournaments must only start after a specific time, for example, 1 hour. This delay allows other users to join the tour ...

Utilize jQuery and AJAX to refresh functions after each AJAX call for newly added items exclusively

I have encountered an issue with my jQuery plugins on my website. Everything functions smoothly until I load new elements via AJAX call. Re-initializing all the plugins then causes chaos because some are initialized multiple times. Is there a way to only i ...

There is no index signature that accepts a parameter of type 'string' in the type '{ [key: string]: AbstractControl; }'

I'm currently tackling a challenge in my Angular project where I am creating a custom validator for a reactive form. However, I've encountered an error within the custom validators function that I am constructing. Below you will find the relevan ...

Ways to implement StackNavigator along with Redux?

Is there anyone who can assist me in integrating StackNavigator and Redux? It seems straightforward, but I'm encountering issues. index.ios.js import React from 'react' import { AppRegistry } from 'react-native' import { Provi ...

Resolve Redux-Firestore issue #45: Possible Solutions?

I'm facing an issue where deleting a document from Firestore results in my Redux store showing it as null instead of removing it. Even though the document is deleted in Firestore, this inconsistency causes frontend issues because my .map functions can ...

What is the best way to transfer the "user" object from TopBar.js to App.js in my project?

In my project, TopBar.js functions as an AppBar component responsible for handling user authentication. When a user logs in, I receive an object called "user". My goal is to export this "user" object to App.js. If I am successful in exporting it to App.js ...

What techniques can be employed to utilize multiple JavaScript files?

Hey there, I am facing an issue while trying to execute multiple JavaScript codes. My first script is running smoothly with the change function, but the second one seems to be causing some trouble. Can anyone guide me on how to effectively run multiple J ...

Display a jQuery alert when an AJAX post request exceeds its timeout limit

I have been working on creating a feature to notify users when their $.post() request times out. To achieve this, I have implemented the following code snippet: //when ajax request start show overlay $(document).ajaxStart(function(){ ...

HTML experiences confusion as JSON tosses undefined data

Can someone assist me with API integration? I am new to this and trying to display the Poster, Title, and Year from an API URL. Here is the code I have been working on. When I log in, it shows JSON in an array but throws "undefined" in front-end. Your help ...

NodeJS closes the previous server port before establishing a new server connection

During my development and testing process, whenever I make changes, I find myself having to exit the server, implement the updates, and then start a new server. The first time I run the command node server.js, everything works perfectly. However, when I m ...

Encountering a "Failed to retrieve 'appData' path" error with Cypress (Electron) on OpenShift while running End-to-end tests

Running cypress end-to-end tests in OpenShift has presented a challenge. While it works locally, an error occurs in OpenShift after initiating the tests using the cypress run command. Error message in OpenShift > <a href="/cdn-cgi/l/email-protectio ...

Generate a JSON object based on the request.body information

Currently using NodeJs along with Express for building a REST API. The functionality is all set up and running smoothly, but I'm facing an issue in comprehending how to iterate through the request.body object and validate its fields for any undefined ...