Skip to content

Instantly share code, notes, and snippets.

@ericchansen
Last active April 15, 2026 03:36
Show Gist options
  • Select an option

  • Save ericchansen/6987e49130c8b7b99c57fa9238e1d348 to your computer and use it in GitHub Desktop.

Select an option

Save ericchansen/6987e49130c8b7b99c57fa9238e1d348 to your computer and use it in GitHub Desktop.
Import events from one calendar into another
/**
* Google Calendar Sync — Import events from one calendar into another.
*
* Copies upcoming events from a secondary calendar into your primary calendar
* as private "Personal Appointment" blocks (title and times only). Keeps them
* in sync: creates new blocks, updates moved events, and deletes stale ones.
*
* Setup:
* 1. Replace SECONDARY_CALENDAR_ID with the calendar you want to import from.
* 2. Add a time-driven trigger to run sync() on your preferred schedule.
*/
const SECONDARY_CALENDAR_ID = "your-email@gmail.com";
const BLOCK_TITLE = "Personal Appointment";
function sync() {
const today = new Date();
const endDate = new Date();
endDate.setDate(today.getDate() + 7);
const secondaryCal = CalendarApp.getCalendarById(SECONDARY_CALENDAR_ID);
const secondaryEvents = secondaryCal.getEvents(today, endDate);
const primaryCal = CalendarApp.getDefaultCalendar();
const primaryEvents = primaryCal.getEvents(today, endDate);
const primaryEventsFiltered = [];
const primaryEventsUpdated = [];
const primaryEventsCreated = [];
const primaryEventsDeleted = [];
Logger.log('Number of primaryEvents: ' + primaryEvents.length);
Logger.log('Number of secondaryEvents: ' + secondaryEvents.length);
for (const pEvent of primaryEvents) {
if (pEvent.getTitle() == BLOCK_TITLE) { primaryEventsFiltered.push(pEvent); }
}
for (const evi of secondaryEvents) {
let alreadyExists = false;
for (const pEvent of primaryEventsFiltered) {
const secondaryTitle = evi.getTitle();
const secondaryDesc = evi.getDescription();
if ((pEvent.getStartTime().getTime() == evi.getStartTime().getTime()) && (pEvent.getEndTime().getTime() == evi.getEndTime().getTime())) {
alreadyExists = true;
pEvent.setTitle(BLOCK_TITLE);
pEvent.setDescription(secondaryTitle + '\n\n' + secondaryDesc);
pEvent.setVisibility(CalendarApp.Visibility.PRIVATE);
primaryEventsUpdated.push(pEvent.getId());
Logger.log('PRIMARY EVENT UPDATED'
+ '\nprimaryId: ' + pEvent.getId() + ' \nprimaryTitle: ' + pEvent.getTitle() + ' \nprimaryDescription: ' + pEvent.getDescription());
}
}
if (alreadyExists) continue;
if (evi.isAllDayEvent()) {
continue;
}
// else if ([1,2,3,4,5].includes(evi.getStartTime().getDay())) // Uncomment for weekday-only sync.
else {
const newEvent = primaryCal.createEvent(BLOCK_TITLE, evi.getStartTime(), evi.getEndTime());
// newEvent.setDescription(evi.getTitle() + '\n\n' + evi.getDescription()); // Uncomment to add a description.
newEvent.setVisibility(CalendarApp.Visibility.PRIVATE);
// newEvent.removeAllReminders(); // Uncomment if you don't want reminders for these imported events.
primaryEventsCreated.push(newEvent.getId());
Logger.log('PRIMARY EVENT CREATED'
+ '\nprimaryId: ' + newEvent.getId() + '\nprimaryTitle: ' + newEvent.getTitle() + '\nprimaryDescription: ' + newEvent.getDescription() + '\n');
}
}
for (const pEvent of primaryEventsFiltered) {
if (primaryEventsUpdated.indexOf(pEvent.getId()) == -1) {
Logger.log(pEvent.getId() + ' deleted');
primaryEventsDeleted.push(pEvent.getId());
pEvent.deleteEvent();
}
}
Logger.log('Primary events previously created: ' + primaryEventsFiltered.length);
Logger.log('Primary events updated: ' + primaryEventsUpdated.length);
Logger.log('Primary events deleted: ' + primaryEventsDeleted.length);
Logger.log('Primary events created: ' + primaryEventsCreated.length);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment