Created
April 12, 2022 07:31
-
-
Save seshness/9c2b4a53b78c29da314ade9965bd0702 to your computer and use it in GitHub Desktop.
Syncs your personal calendar with your work calendar as 'busy' events
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Syncs your personal calendar with your work calendar as 'busy' events. | |
*/ | |
// WARNING: This script has the potential to delete events! Audit the code and run with care. | |
// The script *should* only delete events it has previously created, but bugs are possible! | |
// How to use | |
// ========== | |
// 1. Share your personal calendar with your work account using the free/busy option. | |
// 2. Visit https://script.google.com/ and create a new project eg. "Personal calendar sync". | |
// 3. Uncomment, fill in, and run the line below. | |
// 4. Set up a scheduled trigger to run the `syncEvents` script every hour. | |
// Uncomment this line and run to set up state. | |
// PropertiesService.getUserProperties().setProperty('PERSONAL_EMAIL', '<INSERT PERSONAL EMAIL HERE>'); | |
const daysToSyncPropertyValue = PropertiesService.getUserProperties().getProperty('DAYS_TO_SYNC') | |
const DAYS_TO_SYNC = daysToSyncPropertyValue ? Number.parseInt(daysToSyncPropertyValue, 10) : 7; | |
function isWeekend(someDate) { | |
return someDate.getDay() < 1 || someDate.getDay() > 5; | |
} | |
function syncEvents() { | |
const personalEmail = PropertiesService.getUserProperties().getProperty('PERSONAL_EMAIL'); | |
if (personalEmail == null) { | |
console.error('No PERSONAL_EMAIL user property set. Save a property in https://developers.google.com/apps-script/reference/properties/properties-service#getUserProperties().') | |
return; | |
} | |
const personalCalendar = CalendarApp.getCalendarById(personalEmail); | |
const workCalendar = CalendarApp.getDefaultCalendar(); | |
const now = new Date(); | |
const futureDate = new Date( | |
now.getTime() + DAYS_TO_SYNC * 86400 /* seconds in a day */ * 1000 /* milliseconds in a second */); | |
const eventsToSync = personalCalendar.getEvents(now, futureDate) | |
.filter(event => !event.isAllDayEvent()) | |
.filter(event => !isWeekend(event.getStartTime())); | |
let workEvents = workCalendar.getEvents(now, futureDate); | |
workEvents = workEvents.filter(workEvent => workEvent.getTag('source') === 'personal-calendar-sync'); | |
const workEventsBySourceId = Object.fromEntries(workEvents.map(workEvent => [workEvent.getTag('source_id'), workEvent])); | |
let eventsAdded = 0; | |
let eventsChanged = 0; | |
let eventsDeleted = 0; | |
for (let eventToSync of eventsToSync) { | |
if (workEventsBySourceId.hasOwnProperty(eventToSync.getId())) { | |
const correspondingWorkEvent = workEventsBySourceId[eventToSync.getId()]; | |
delete workEventsBySourceId[eventToSync.getId()] | |
if (correspondingWorkEvent.getStartTime() === eventToSync.getStartTime() && | |
correspondingWorkEvent.getEndTime() === eventToSync.getEndTime()) { | |
continue; | |
} | |
correspondingWorkEvent.setTime(eventToSync.getStartTime(), eventToSync.getEndTime()); | |
eventsChanged += 1; | |
} else { | |
const newEvent = workCalendar.createEvent('busy', eventToSync.getStartTime(), eventToSync.getEndTime()); | |
newEvent.setTag('source', 'personal-calendar-sync'); | |
newEvent.setTag('source_id', eventToSync.getId()); | |
eventsAdded += 1; | |
} | |
} | |
const remainingEventsToDelete = Object.values(workEventsBySourceId); | |
remainingEventsToDelete.forEach(remainingEventToDelete => { | |
// Switch to this line for testing to prevent deleting events | |
// remainingEventToDelete.setColor(CalendarApp.EventColor.RED); | |
remainingEventToDelete.deleteEvent(); | |
eventsDeleted += 1 | |
}); | |
console.log(`${eventsAdded} events added, ${eventsChanged} events changed, ${eventsDeleted} deleted.`) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment