Skip to main content

I'm trying to build an automation that, based on a set of input values specified by a user, will output a set of available dates to create timeblocks in a calendar. The user specifies what date to start with, how many weeks to create these blocks for, as well as start & end times for the day, break time & duration, and how long each timeblock can be for (including some follow-up time). The code I've worked up seems to generate the output I am hoping for when compiled, but output.set and the console.log seem null when this runs in Airtable.

Here's my script:

 

let inputConfig = input.config();

let daysOfWeek = inputConfig.daysOfWeek;

let sessionDuration = inputConfig.sessionDuration;

let startTime = inputConfig.startTime;

let endTime = inputConfig.endTime;

let followUpTime = inputConfig.followUpTime;

let startDate = inputConfig.startDate;

let numWeeks = inputConfig.numWeeks;

let breakStartTime = inputConfig.breakStartTime;

let breakDuration = inputConfig.breakDuration;



// Helper function to add minutes to a Date object

function addMinutes(date, minutes) {

return new Date(date.getTime() + minutes * 60000);

}



// Helper function to get the day of the week index from a string (e.g., 'Monday' -> 1)

function getDayIndex(day) {

const daysOfWeek = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];

return daysOfWeek.indexOf(day);

}



// Function to convert 'YYYY-MM-DD' string to Date object

function parseDateString(dateString) {

const dateParts = dateString.split("-");

const year = parseInt(dateParts[0], 10);

const month = parseInt(dateParts[1], 10) - 1; // JavaScript months are 0-based

const day = parseInt(dateParts[2], 10);

return new Date(year, month, day);

}



// Main function to generate calendar entries

function generateCalendarEntries(startDateStr, numWeeks, daysOfWeek, startTime, endTime, sessionDuration, followUpTime, breakStartTime, breakDuration) {

// Parse the startDateStr to a Date object

const startDate = parseDateString(startDateStr);



const entries = [];

const msInAWeek = 7 * 24 * 60 * 60 * 1000; // Milliseconds in one week



// Loop through each week

for (let week = 0; week < numWeeks; week++) {

// Loop through the specified days of the week

daysOfWeek.forEach(day => {

const dayIndex = getDayIndex(day);

if (dayIndex === -1) return; // Invalid day name, skip



// Calculate the actual date for this day in the current week

const dayDate = new Date(startDate); // Clone the startDate

dayDate.setDate(startDate.getDate() + (7 * week) + (dayIndex - startDate.getDay()));



// Set the start and end time for the entire day

const start = new Date(dayDate);

start.setHours(startTime.split(":")[0], startTime.split(":")[1], 0, 0);



const end = new Date(dayDate);

end.setHours(endTime.split(":")[0], endTime.split(":")[1], 0, 0);



// Break period start and dynamically calculated end time

const breakStart = new Date(dayDate);

breakStart.setHours(breakStartTime.split(":")[0], breakStartTime.split(":")[1], 0, 0);



const breakEnd = addMinutes(breakStart, breakDuration);



// Handle sessions before the break

let sessionStart = start;

while (sessionStart < breakStart) {

const sessionEnd = addMinutes(sessionStart, sessionDuration + followUpTime);



// Skip session if it doesn't fit before the break

if (sessionEnd > breakStart) break;



entries.push({

title: "Session",

start: sessionStart,

end: sessionEnd

});



sessionStart = sessionEnd; // Move to the next session slot

}



// Handle sessions after the break

sessionStart = breakEnd;

while (sessionStart < end) {

const sessionEnd = addMinutes(sessionStart, sessionDuration + followUpTime);



// Skip session if it doesn't fit before the end of the day

if (sessionEnd > end) break;



entries.push({

title: "Session",

start: sessionStart,

end: sessionEnd

});



sessionStart = sessionEnd; // Move to next session slot

}

});

}

return entries;

}



const calendarEntries = generateCalendarEntries(startDate, numWeeks, daysOfWeek, startTime, endTime, sessionDuration, followUpTime, breakStartTime, breakDuration);

console.log(calendarEntries);

output.set("Entries", calendarEntries);

 

 And here's the output I get running this through an online compiler:

 

[

{

title: 'Session',

start: 2024-10-15T10:00:00.000Z,

end: 2024-10-15T11:00:00.000Z

},

{

title: 'Session',

start: 2024-10-15T11:00:00.000Z,

end: 2024-10-15T12:00:00.000Z

},

{

title: 'Session',

start: 2024-10-15T13:00:00.000Z,

end: 2024-10-15T14:00:00.000Z

},

{

title: 'Session',

start: 2024-10-15T14:00:00.000Z,

end: 2024-10-15T15:00:00.000Z

},

{

title: 'Session',

start: 2024-10-17T10:00:00.000Z,

end: 2024-10-17T11:00:00.000Z

},

{

title: 'Session',

start: 2024-10-17T11:00:00.000Z,

end: 2024-10-17T12:00:00.000Z

},

{

title: 'Session',

start: 2024-10-17T13:00:00.000Z,

end: 2024-10-17T14:00:00.000Z

},

{

title: 'Session',

start: 2024-10-17T14:00:00.000Z,

end: 2024-10-17T15:00:00.000Z

},

{

title: 'Session',

start: 2024-10-22T10:00:00.000Z,

end: 2024-10-22T11:00:00.000Z

},

{

title: 'Session',

start: 2024-10-22T11:00:00.000Z,

end: 2024-10-22T12:00:00.000Z

},

{

title: 'Session',

start: 2024-10-22T13:00:00.000Z,

end: 2024-10-22T14:00:00.000Z

},

{

title: 'Session',

start: 2024-10-22T14:00:00.000Z,

end: 2024-10-22T15:00:00.000Z

},

{

title: 'Session',

start: 2024-10-24T10:00:00.000Z,

end: 2024-10-24T11:00:00.000Z

},

{

title: 'Session',

start: 2024-10-24T11:00:00.000Z,

end: 2024-10-24T12:00:00.000Z

},

{

title: 'Session',

start: 2024-10-24T13:00:00.000Z,

end: 2024-10-24T14:00:00.000Z

},

{

title: 'Session',

start: 2024-10-24T14:00:00.000Z,

end: 2024-10-24T15:00:00.000Z

},

{

title: 'Session',

start: 2024-10-29T10:00:00.000Z,

end: 2024-10-29T11:00:00.000Z

},

{

title: 'Session',

start: 2024-10-29T11:00:00.000Z,

end: 2024-10-29T12:00:00.000Z

},

{

title: 'Session',

start: 2024-10-29T13:00:00.000Z,

end: 2024-10-29T14:00:00.000Z

},

{

title: 'Session',

start: 2024-10-29T14:00:00.000Z,

end: 2024-10-29T15:00:00.000Z

},

{

title: 'Session',

start: 2024-10-31T10:00:00.000Z,

end: 2024-10-31T11:00:00.000Z

},

{

title: 'Session',

start: 2024-10-31T11:00:00.000Z,

end: 2024-10-31T12:00:00.000Z

},

{

title: 'Session',

start: 2024-10-31T13:00:00.000Z,

end: 2024-10-31T14:00:00.000Z

},

{

title: 'Session',

start: 2024-10-31T14:00:00.000Z,

end: 2024-10-31T15:00:00.000Z

},

{

title: 'Session',

start: 2024-11-05T10:00:00.000Z,

end: 2024-11-05T11:00:00.000Z

},

{

title: 'Session',

start: 2024-11-05T11:00:00.000Z,

end: 2024-11-05T12:00:00.000Z

},

{

title: 'Session',

start: 2024-11-05T13:00:00.000Z,

end: 2024-11-05T14:00:00.000Z

},

{

title: 'Session',

start: 2024-11-05T14:00:00.000Z,

end: 2024-11-05T15:00:00.000Z

},

{

title: 'Session',

start: 2024-11-07T10:00:00.000Z,

end: 2024-11-07T11:00:00.000Z

},

{

title: 'Session',

start: 2024-11-07T11:00:00.000Z,

end: 2024-11-07T12:00:00.000Z

},

{

title: 'Session',

start: 2024-11-07T13:00:00.000Z,

end: 2024-11-07T14:00:00.000Z

},

{

title: 'Session',

start: 2024-11-07T14:00:00.000Z,

end: 2024-11-07T15:00:00.000Z

}

]

 

And here's what I get when it runs in Airtable:

I'd welcome any guidance as to what I am missing. Thanks in advance!

If you could DM me an invite link to your base I could try helping you troubleshoot this?  I'd suggest just dumping a bunch of logging inside your functions to see what's happening.  May I know how much development experience you have?


Thanks, I followed up with you directly.


Turns out the solution here was that I had some issues caused by `sessionDuration` and `followupTime` being strings instead of ints. After converting them that solved part of the issue:

let sessionDuration = +inputConfig.sessionDuration;

let followUpTime = +inputConfig.followUpTime;

I also needed to convert dates to ISO strings :

function toISOString(date){

return new Date(date).toISOString()

}
entries.push({

title: "Session",

start: toISOString(sessionStart),

end: toISOString(sessionEnd)

});

After making those changes and some other adjustments to the date fields in my table to all use the same TZ, my script now generates the expected output. Many thanks to @TheTimeSavingCo for the assist!


Reply