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

Submitting a form using jquery

I am working on a project that involves using a jquery fancyzoom box. Within this box, there is a contact form that should send an email upon submission. However, I am encountering issues with calling the form submit function due to the fancyzoom feature. ...

Prevent selection of future dates in JavaScript by using the user's chosen StartDate

Here is the code I currently have: var today = new Date().toISOString().split('T')[0]; document.getElementsByName("StartDate")[0].setAttribute('min', today); $('#StartDate').change(function myfunction() { var endDate = ...

Setting up vue-apollo 3.0.0 Beta

Seeking guidance as a newcomer in this field. I have experience with Authentication using Apollo client, but I'm stuck when trying to integrate the new vue-apollo-plugin into my Vue-cli-3 generated project. Specifically, I'm confused about how an ...

Querying MongoDB with a JavaScript file for formatting datetime values

I am utilizing mongodb3.0.5 and my database collection appears as follows: { "_id" : "xxxxxxxxxxxxxxx", "SchoolId" : 1, "ActivationTimestamp" : ISODate("2015-09-22T13:01:58.000Z"), "PersonDetails" : [ { "Name" : "John" ...

Mirror the input text to another input within a for loop

I have a list of questions displayed, each with an input field for entering a phone number. How can I use jQuery or JavaScript in a for-loop to mirror the text entered in the first phone input box to all subsequent phone input boxes? ..Enter your phone... ...

Issue with passing props to screen not displaying on initial load

Greetings, I'm a newcomer to the world of react native and currently facing an issue: const Tab = createMaterialTopTabNavigator(); export const CurriculumMenu = ({navigation, item}) => { const data = item.Title; console.log(data) return ( ...

The Chrome extension takes control of the new tab feature by redirecting it to a custom newtab.html

I have a website https://example.com where users can adjust their site preferences, including enabling night mode. To enhance the user experience, I developed a Chrome extension for https://example.com that transforms Chrome's new tab with a custom ne ...

Issue with form array patching causing value not to be set on material multiple select

When attempting to populate a mat-select with multiple options using an array of ids from Firestore, I encountered an issue. The approach involved looping through the array, creating a new form control for each id, and then adding it to the formArray using ...

What are some ways to adjust the size of the option field in a select menu?

In my ionic popup, I have a HTML property called select with nested options. Below is the code snippet along with the applied CSS. My query is how can I set the white space to occupy the entire area of the select? https://i.stack.imgur.com/iPqAa.png http ...

I am looking to include both the type and maxLength attributes in a MUI TextField

<TextField value={ele.mobile} helperText={ferrors[id]?.mobile} name="mobile" classes={{ root: classes.textField }} InputProps={{ clas ...

What is the reason Angular is unable to locate a controller for a directive in an external file?

As a newcomer to Angular, I'm struggling to comprehend John Papa's recommendations. His guidelines suggest placing controller logic inside directives, but this approach doesn't seem intuitive to me. Despite my efforts to implement it myself, ...

Encountering issues while trying to install create-react-app globally using npm

Encountering Issues I am currently facing errors when trying to run npm install -g create-react-app. The app I am working on is called robofriend. Thank you for your assistance in advance. ...

The installation of npm was successful, however, the node version is not displaying on Windows 10

After checking the node version, I received the following response: PS C:\WINDOWS\system32> node -v Node Commands Syntax: node {operator} [options] [arguments] Parameters: /? or /help - Display this help message. list ...

Incorrect Tooltip DisplayWhat could be causing the issue with

I am facing an issue when trying to add a tooltip to a glyphicon within a tile. It doesn't seem to work correctly when it should. However, placing the tooltip outside of the tile works fine. I'm quite perplexed and would greatly appreciate any as ...

Automatically redirect to a different page upon clicking the jquery popup button

I integrated a jQuery popup feature on my website to display messages. Now, I am looking to implement a redirect to another page when the user clicks a button within the jQuery popup. However, I am unsure of how to achieve this. <script type="text/ja ...

Mastering ReactJS: Error Encountered - Unexpected import Token

Just getting started with ReactJS and trying out some code from egghead.io. Unfortunately, I keep running into this error: Uncaught SyntaxError: Unexpected token import I've tried loading babel again and making sure to follow the lesson step by step ...

Incorporate a CSS class name with a TypeScript property in Angular version 7

Struggling with something seemingly simple... All I need is for my span tag to take on a class called "store" from a variable in my .ts file: <span [ngClass]="{'flag-icon': true, 'my_property_in_TS': true}"></span> I&apos ...

Retrieving the value from a concealed checkbox

I have been searching everywhere, but I can't seem to find a solution to this particular issue. There is a hidden checkbox in my field that serves as an identifier for the type of item added dynamically. Here's how I've set it up: <inpu ...

Error unfound: [CLIENT_MISSING_INTENTS]: The Client requires valid intents to function properly

I've gone through multiple tutorials, but I keep encountering an uncaught TypeError. Despite following the suggested solutions, the error persists. I even tried implementing the "intent" solution, but it's prompting a change in "const client = ne ...

The slideshow fails to show correctly after being loaded from an external JavaScript file

Utilizing standard code, I have set up a Slideshow at the top of a website: HTML: <body id="Top" onload="showSlides()"> ... <div id="slides"> <div id="slide1" class="slides fade"></div> <div id="s ...