Skip to content

Instantly share code, notes, and snippets.

@glacials
Last active November 23, 2024 17:54
Show Gist options
  • Save glacials/af791509b845303ef3999bd0d5445ba3 to your computer and use it in GitHub Desktop.
Save glacials/af791509b845303ef3999bd0d5445ba3 to your computer and use it in GitHub Desktop.
Sync personal events to your work calendar
// WHAT DOES THIS DO?
//
// If you follow the instructions below, your work calendar will show you as busy during events on
// your personal calendar.
//
//
// NOTES
//
// This code is based on [Jeremy Hon's code][1].
//
// The events this code creates on your work calendar will not be edited or removed
// if the original event on your personal calendar is edited or removed.
//
// You can synchronize any two calendars in this way, but these instructions assume
// you are copying events from your personal calendar to your work calendar. If needed,
// substitute PERSONAL and WORK to fit your situation.
//
//
// INSTRUCTIONS
//
// 1. On your PERSONAL Google account, go to calendar.google.com.
// 2. Click on the cog -> Settings.
// 3. In the sidebar go to 'Settings for my calendars' -> click your PERSONAL calendar.
// 4. Scroll to 'Share with specific people or groups'.
// 5. Click "+ Add people and groups" and type in your WORK Google account email.
// You can select any permissions you want; they all work.
// No matter which you select, your synced events will only show "busy" to your coworkers.
// 6. Scroll to 'Integrate calendar' and make note of your Calendar ID (if this is your
// account's primary calendar then the ID is exactly your email address).
// 7. Open a new tab. On your WORK Google account, go to calendar.google.com. In the sidebar,
// click the '+' next to 'Other calendars', click 'Subscribe to calendar' and subscribe to
// your PERSONAL Google account's calendar you just shared by typing its email address.
// 8. On your WORK Google account, go to script.google.com.
// 9. Click 'New project'. Delete the default contents and paste THIS FILE that you are
// reading into the textarea. It's easier to copy-paste if you click "Raw" in the top-right.
// 10. Below these instructions you'll see some text that says "CHANGEME"; change this to your
// calendar ID you noted from step 5.
// 11. Click 'Save project' (small button near the Undo/Redo buttons; do NOT click deploy)
// then click 'Run'. Grant permission if asked.
// 12. You should see its progress in the log at the bottom.
// When you see "Execution completed",
// check your calendars to make sure it worked
// (events in the next 30 days on your personal calendar
// should appear on your work calendar as "busy").
// YOU ARE NOT DONE YET!
// 13. In the left nav bar go to Triggers, then click Add Trigger.
// 1. Set 'Select event source' to 'From calendar'.
// 2. Write your PERSONAL email in the box.
// 3. Leave everything else default and click Save. Grant permission if asked.
// 14. Go to your PERSONAL Google Calendar and create an event to test; it should appear
// within ~30 seconds on your work calendar as 'busy'!
//
// PS. If and when you leave your job, you can force undo this by repeating steps 1–4
// then clicking the "X" by your work account.
//
// [1]: https://gist.github.com/jeremyhon/60b7be41273a04b98c339014804d3e28
function sync() {
personalCalendarIds = [
"CHANGEME",
]
// How many days in advance to monitor and block off time for?
const daysForward = 30
// What should the copied events on your work calendar be called?
const twinEventTitle = "busy"
const workCal = CalendarApp.getDefaultCalendar()
const personalCals = personalCalendarIds.map(id => CalendarApp.getCalendarById(id))
if (personalCals.some(cal => cal === null)) {
console.error("Couldn't fetch personal calendar. Did you remember to subscribe to it on your work account?")
return
}
const today = new Date()
const enddate = new Date()
enddate.setDate(today.getDate() + daysForward)
const workEvents = workCal.getEvents(today, enddate)
const personalEvents = personalCals.map(cal => cal.getEvents(today, enddate)).flat()
console.log(`Sifting through ${personalEvents.length} personal events over the next ${daysForward} days`)
for (personalEvent of personalEvents) {
if (workEvents.some(workEvent => (
workEvent.getStartTime().getTime() == personalEvent.getStartTime().getTime() &&
workEvent.getEndTime().getTime() == personalEvent.getEndTime().getTime()
)
)) {
continue
}
const d = personalEvent.getStartTime()
const n = d.getDay()
// Skip all-day events. Delete this if you want to include all-day events.
if (personalEvent.isAllDayEvent()) {
continue
}
// Skip weekends. Delete this if you want to include weekends.
if (n == 0 || n == 6) {
continue
}
const newEvent = workCal.createEvent(twinEventTitle, personalEvent.getStartTime(), personalEvent.getEndTime())
// alternative version below that copies the exact secondary event information into the primary calendar event
// const newEvent = workCal.createEvent(personalEvent.getTitle(), personalEvent.getStartTime(), personalEvent.getEndTime(), {location: personalEvent.getLocation(), description: personalEvent.getDescription()})
// Prevent the copies from sending "starts soon" notifications.
newEvent.removeAllReminders()
}
}
@bjesus
Copy link

bjesus commented Mar 26, 2022

As the above seem to work for Google Calendars only, check out https://github.com/bjesus/callibella if you're looking for something non-Google :)

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