Skip to content

Instantly share code, notes, and snippets.

@alranel
Forked from ttrahan/block_personal_appts
Last active January 23, 2023 15:10
Show Gist options
  • Save alranel/f1c9b7abb9013f4a39aa4fb12f6de4ef to your computer and use it in GitHub Desktop.
Save alranel/f1c9b7abb9013f4a39aa4fb12f6de4ef to your computer and use it in GitHub Desktop.
Google Apps Script to automatically create, edit and delete events on work calendar for personal calendar events. Inspired by @willroman's work but heavily changed. Instructions on how to set up can be found in the original post: https://medium.com/@willroman/auto-block-time-on-your-work-google-calendar-for-your-personal-events-2a752ae91dab
var source_calendars = [
'xxx',
];
function sync() {
var today = new Date();
var enddate = new Date();
enddate.setDate(today.getDate()+90); // how many days in advance to monitor and block off time
var sourceEvents = [];
source_calendars.forEach(function(id) {
var secondaryCal = CalendarApp.getCalendarById(id);
sourceEvents = sourceEvents.concat(secondaryCal.getEvents(today,enddate));
});
var thisCal = CalendarApp.getDefaultCalendar();
var offEventTitle = "off"; // update this to the text you'd like to appear in the new events created in primary calendar
var thisCalEventsUpdated = []; // to contain primary calendar events that were updated from secondary calendar
var thisCalEventsCreated = []; // to contain primary calendar events that were created from secondary calendar
var thisCalEventsDeleted = []; // to contain primary calendar events previously created that have been deleted from secondary calendar
// create filtered list of events from this calendar that were previously created from the source calendar
var thisCalOffEvents = [];
for (var pEvent of thisCal.getEvents(today,enddate)) {
if (pEvent.getTitle() == offEventTitle)
thisCalOffEvents.push(pEvent);
}
// process all events in source calendar
for (var sev of sourceEvents) {
// skip events in secondary calendar that were already created by a script similar to this one
if (sev.getTitle() == offEventTitle)
continue;
// ignore declined events
if (sev.getMyStatus() == CalendarApp.GuestStatus.NO || sev.getMyStatus() == CalendarApp.GuestStatus.MAYBE)
continue;
// ignore all-day events
if (sev.isAllDayEvent())
continue;
/*
// Unfortunately, the GSuite API does not provide access to the Transparency property
if (sev.getTransparency() == 'transparent')
continue; // Ignore events whose transparency is set to transparent
*/
// Ignore events in the weekend
if (![1,2,3,4,5].includes(sev.getStartTime().getDay()))
continue;
Logger.log("Processing: " + sev.getTitle());
// Does an "off" event already exist in this calendar?
var offEvent = null;
for (var pEvent of thisCalOffEvents) {
if (pEvent.getStartTime().getTime() == sev.getStartTime().getTime()
&& pEvent.getEndTime().getTime() == sev.getEndTime().getTime()
&& pEvent.getTitle() == offEventTitle)
{
offEvent = pEvent;
break;
}
}
if (!offEvent) {
offEvent = thisCal.createEvent(offEventTitle, sev.getStartTime(), sev.getEndTime());
thisCalEventsCreated.push(offEvent.getId());
Logger.log(' off event created');
} else {
thisCalEventsUpdated.push(offEvent.getId());
Logger.log(' off event updated');
}
//offEvent.setDescription(sev.getTitle() + '\n\n' + sev.getDescription());
offEvent.setVisibility(CalendarApp.Visibility.DEFAULT);
offEvent.removeAllReminders();
}
// if an off event previously created no longer exists in the secondary calendar, delete it
for (var pev of thisCalOffEvents) {
if (!thisCalEventsUpdated.includes(pev.getId())) {
thisCalEventsDeleted.push(pev.getId());
Logger.log('OFF EVENT DELETED: ' + pev.getId());
pev.deleteEvent();
}
}
Logger.log('Off events previously created: ' + thisCalOffEvents.length);
Logger.log('Off events updated: ' + thisCalEventsUpdated.length);
Logger.log('Off events deleted: ' + thisCalEventsDeleted.length);
Logger.log('Off events created: ' + thisCalEventsCreated.length);
// Delete past events in primary calendar
var olddate = new Date();
olddate.setDate(today.getDate()-10);
var pastthisCalEvents = thisCal.getEvents(olddate, today);
var deletedPastEvents = 0;
for (var pEvent of pastthisCalEvents) {
if (pEvent.getEndTime() > today)
continue;
if (pEvent.getTitle() == offEventTitle) {
pEvent.deleteEvent();
deletedPastEvents++;
}
}
Logger.log('Past off events deleted: ' + deletedPastEvents);
}
@JohnLockeNJ
Copy link

The new version has been working great and I've been using it since you uploaded!

For anyone interested, I've found a way to use the script to sync an Outlook Exchange calendar to a Google Calendar.

If you publish your Outlook Exchange calendar and set it to "Can view all details", you then get an ICS link that you can add as an Other Calendar in one of your Google Calendar accounts. Instructions: https://www.alphr.com/sync-outlook-calendar-google-calendar/

Those instructions say it sets up syncing, but it really just lets you view the calendar in Google and doesn't include it in Google Calendar free/busy without more steps.

Once it's added as an Other Calendar, you can get the Google Calendar ID for that new calendar per Will Roman's original Medium article and put it into the script. Pick different text for the "off" blocked off time than your other Google Cal to Google Cal scripts. You now have Outlook Exchange meetings blocked off in your Google Calendar and it will replicate to other Google Calendars for which you've set up sync scripts and everyone who looks at the Google Calendar free/busy times.

Rather than find a way to sync the other direction (Google Calendar to Outlook Exchange) using client software or setting up a personal server, I just added one of my Google Calendars (that already syncs with all my other work Google Calendars) as a Personal Calendar in Outlook for the Web which lets you include those entries when people look at your free/busy time.
https://office365itpros.com/2020/02/27/adding-your-personal-calendar-owa/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment