Skip to content

Instantly share code, notes, and snippets.

@ifuller1
Last active February 16, 2023 21:23
Show Gist options
  • Save ifuller1/5df2b3a0173b44b3be3ad56184fc0185 to your computer and use it in GitHub Desktop.
Save ifuller1/5df2b3a0173b44b3be3ad56184fc0185 to your computer and use it in GitHub Desktop.
For copying events between calendars
//import "google-apps-script";
const doCleanup = false;
const doSync = true;
const isProduction = true;
const debug = false;
const id = "[email protected]";
const tagName = "sourceId";
const copyTitle = true;
const preappendString = `Booked for ${id} - `;
const daysToCopy = 30;
const today = new Date();
const endDate = new Date();
endDate.setDate(today.getDate() + daysToCopy);
const sourceCalendar = CalendarApp.getCalendarById(id);
const targetCalendar = CalendarApp.getDefaultCalendar();
const sourceEvents = sourceCalendar.getEvents(today, endDate);
const targetEvents = targetCalendar.getEvents(today, endDate);
function cleanup() {
if (!doCleanup) {
return;
}
targetEvents.forEach((event) => {
if (debug) {
console.log(`Existing event: ${event.getTitle()}`);
}
const title = event.getTitle();
if (title.indexOf(preappendString) === 0) {
if (debug) {
console.log("title matches prefix");
}
if (isProduction) {
console.log(`Deleting event ${event.getTitle()}`);
event.deleteEvent();
}
}
});
}
function sync() {
if (!doSync) {
console.log("skipping sync");
return;
}
const findMatchingEvent = (newEvent, existingEvents) => {
return existingEvents.some((existingEvent) => {
const foundTag = existingEvent.getTag(tagName);
const newEventId = newEvent.getId();
const equal = newEventId === foundTag;
if (debug && false) {
console.log(`Found tag ${foundTag} new id ${newEventId}`);
if (equal) {
console.log(`Are equal!! ${newEvent.getTitle()}`);
} else {
console.log(`not equal ${newEvent.getTitle()}`);
}
}
return equal;
});
};
const outOfOfficeTitle = ["ooo", "out of office", "holiday"];
const checkIsOutOfOffice = (newEvent) => {
const title = newEvent.getTitle().toLowerCase();
return outOfOfficeTitle.indexOf(title) >= 0;
};
const existingCopiedEvents = targetEvents
.map((targetEvent) => {
return {
sourceId: targetEvent.getTag(tagName),
targetId: targetEvent.getId(),
};
})
.filter((copiedEvent) => {
return copiedEvent.sourceId !== null;
});
if (debug) {
console.log(`Existing copied events ${existingCopiedEvents.toString()}`);
}
// remove any sourceIds that are no longer found
existingCopiedEvents.forEach((copiedEvent) => {
const copiedEventIndex = sourceEvents.findIndex((sourceEvent) => {
return sourceEvent.getId() === copiedEvent.sourceId;
});
if (copiedEventIndex < 0) {
const targetEvent = targetCalendar.getEventById(copiedEvent.targetId);
if (!isProduction) {
console.log(
`${targetEvent.getTitle()} ${targetEvent.getTag(
tagName
)} index in source list is ${copiedEventIndex}`
);
}
console.log(`Will remove '${targetEvent.getTitle()}'`);
if (isProduction) {
targetEvent.deleteEvent();
}
}
});
sourceEvents.forEach((sourceEvent) => {
const eventIsNew = findMatchingEvent(sourceEvent, targetEvents) === false;
const isWithinDay = sourceEvent.isAllDayEvent() === false;
const myStatus = sourceEvent.getMyStatus();
const amAttending =
myStatus === null ||
myStatus.toString() === "YES" ||
myStatus.toString() === "MAYBE";
if (eventIsNew && isWithinDay && amAttending) {
const eventDay = sourceEvent.getStartTime().getDay();
const isWeekday = eventDay >= 1 && eventDay <= 5;
const isInOffice = checkIsOutOfOffice(sourceEvent) === false;
if (isWeekday && isInOffice && isProduction) {
const title = copyTitle ? sourceEvent.getTitle() : "";
const sourceId = sourceEvent.getId();
const location = sourceEvent.getLocation();
const greyColour = 8;
const newEvent = targetCalendar.createEvent(
`${preappendString} ${title}`,
sourceEvent.getStartTime(),
sourceEvent.getEndTime()
);
newEvent.setColor(greyColour);
newEvent.setLocation(location);
newEvent.setTag(tagName, sourceId);
newEvent.removeAllReminders();
if (isProduction === false) {
console.log(
`Event: ${sourceEvent.getTitle()} tag: ${sourceEvent.getTag(
tagName
)}`
);
}
console.log(
`Will add '${sourceEvent.getTitle()}' on ${sourceEvent.getStartTime()}`
);
}
} else {
// remove events if conditions have changed...
}
});
}
@ifuller1
Copy link
Author

ifuller1 commented Jan 5, 2023 via email

@scottblevitt
Copy link

just attempted this and i got the following error?

TypeError: Cannot read properties of null (reading 'getEvents') (anonymous) @ Code.gs:19

Suggestions?

@ifuller1
Copy link
Author

Did you change const id = "[email protected]"; to use the email address from the source account?

@scottblevitt
Copy link

scottblevitt commented Feb 16, 2023 via email

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