🗓️ Calendar Slots
Find availability for a user based on their calendar. Works with Google Calendar or any iCalendar URL.
💡 Usage
Install the package from npm:
npm install calendar-slots
Import and use:
import { findSlots } from "calendar-slots";
const today = new Date();
const tomorrow = new Date();
tomorrow.setDate(today.getDate() + 1);
const slots = await findSlots({
slotDuration: 30, // Find 30 minute slots
slots: 3, // Recommend 3 slots
from: today, // Starting now
to: tomorrow, // Until tomorrow
});
console.log(slots);
/* [
{ from: "Tue May 05 2020 12:00:00 GMT-0800 (PST)", to: "Tue May 05 2020 12:30:00 GMT-0800 (PST)" },
{ from: "Wed May 06 2020 09:30:00 GMT-0800 (PST)", to: "Wed May 06 2020 10:00:00 GMT-0800 (PST)" },
{ from: "Wed May 06 2020 14:30:00 GMT-0800 (PST)", to: "Wed May 06 2020 15:00:00 GMT-0800 (PST)" }
] */
Each Slot has two Date objects, start and end. The from and to properties accept native Date objects, moment objects, or other values that moment understands like date strings and UNIX timestamp numbers.
⚒️ Configuration
| Key | Type | Description |
|---|---|---|
slotDuration |
number | Duration in minutes |
slots |
number | Number of slots to find |
from (required) |
Date or similar | Start time |
to (required) |
Date or similar | End time |
days |
number[] | Days of the week to use |
daily.timezone |
string | Timezone for time restrictions |
daily.from |
[number, number?, number?] | Start [hours, minutes, seconds] |
daily.to |
[number, number?, number?] | End [hours, minutes, seconds] |
strategies |
string | Recommendation strategies |
padding |
number | Time (min) between events |
slotFilter |
(slot: Slot) => boolean | Custom filter for available slots |
url. |
string | iCalendar URL |
calendarId |
string | Specific Google Calender ID |
auth |
Google API OAuth2 client | API client to use |
user.accessToken |
string | User’s access token |
user.refreshToken |
string | User’s refresh token |
log |
boolean | Whether to console.log steps |
logger |
(…args: any[]) => void | Custom function for logging |
iCalendar
Any iCalendar-compliant URL is supported; all major calendar providers (Google Calendar, Apple Calendar, Microsoft Outlook, Yahoo! Calendar, etc.) support iCalendar URLs.
You can specify the url:
const slots = await findSlots({
from: new Date(),
to: nextWeek,
url: "webcal://your-example-url.ics"
});
Authentication with Google Calendar
You can either specify auth, calendar, and user:
import { google } from "googleapis";
import { OAuth2Client } from "google-auth-library";
const oauth2Client = new google.auth.OAuth2(
"Client ID",
"Client Secret",
"Redirect URL"
);
oauth2Client.setCredentials({
access_token: "Access token",
refresh_token: "Refresh token",
});
const calendar = google.calendar("v3");
const slots = await findSlots({
from: new Date(),
to: nextWeek,
auth: oauth2Client,
calendar: calendar,
});
Alternately, you can set the following environment variables and we’ll setup the authentication:
GOOGLE_CALENDAR_CLIENT_IDGOOGLE_CALENDAR_CLIENT_SECRETGOOGLE_CALENDAR_REDIRECT_URLGOOGLE_CALENDAR_ACCESSGOOGLE_CALENDAR_REFRESH
🗜️ Examples
Slots on specific days
You might want to skip weekends when finding slots. Add the days property with an array of numbers (0 for Sunday, 6 for Saturday):
/**
* Find 3 slots, 30 minutes, from today until next week
* but only between Monday and Friday
*/
const slots = await findSlots({
slotDuration: 30,
slots: 3,
from: new Date(),
to: nextWeek,
days: [1, 2, 3, 4, 5],
});
Slots between specific times every day
You might want to find slots only between specific times of the day. Add the daily property:
/**
* Find 3 slots, 30 minutes, from today until next week
* but only between Monday and Friday
* and only from 9:00 am to 5:30 pm, Pacific Time
*/
const slots = await findSlots({
slotDuration: 30,
slots: 3,
from: new Date(),
to: nextWeek,
days: [1, 2, 3, 4, 5],
daily: {
timezone: "America/Los_Angeles",
from: [9],
to: [17, 30],
},
});
Prefer morning slots
You may want to increase the probability of getting certain slots, using strategies.
/**
* Find 3 slots, 30 minutes, from today until next week
* but only between Monday and Friday
* and prefer morning slots rather than later in the day
*/
const slots = await findSlots({
slotDuration: 30,
slots: 3,
from: new Date(),
to: nextWeek,
days: [1, 2, 3, 4, 5],
strategies: ["heavy-mornings"],
});
Available strategies are:
linear(default)heavy-firsts(prefer beginning of all slots)heavy-lasts(prefer ending of all slots)heavy-centers(prefer middle of all slots)heavy-mornings(prefer mornings)heavy-afternoons(prefer afternoons)heavy-evenings(prefer evenings)heavy-mondays(prefer Mondays)heavy-tuesdays(prefer Tuesdays)heavy-wednesdays(prefer Wednesdays)heavy-fridays(prefer Fridays)heavy-saturday(prefer Saturday)heavy-sundays(prefer Sundays)
There are no strategies for preference of light rather than heavy; however, this works: If you want light mornings, you can pass the strategies ["heavy-afternoons", "heavy-evenings"]. Similarly, if you want light Fridays, you can pass heavy- other days.
👩💻 Development
Build TypeScript:
npm run build
Run unit tests and view coverage:
npm run test-without-reporting

