Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save kappa4/9e100b5ac018ba6d5e201ff7e118ef28 to your computer and use it in GitHub Desktop.
Save kappa4/9e100b5ac018ba6d5e201ff7e118ef28 to your computer and use it in GitHub Desktop.
Sync a schedule from another calendar as a block schedule with a fixed title
function syncToday() {
for (const calendarInfo of setting.sourceCalendars) {
syncEventsWithOtherCalendar(calendarInfo, 1);
}
}
function syncThisWeek() {
for (const calendarInfo of setting.sourceCalendars) {
syncEventsWithOtherCalendar(calendarInfo, 7);
}
}
function syncOneMonth() {
for (const calendarInfo of setting.sourceCalendars) {
syncEventsWithOtherCalendar(calendarInfo, 30);
}
}
function syncThreeMonth() {
for (const calendarInfo of setting.sourceCalendars) {
syncEventsWithOtherCalendar(calendarInfo, 90);
}
}
const setting = {
targetCalendarId: 'xxxx@example.com',
sourceCalendars: [
{
eventTitle: '[yyyy] Busy',
id: 'aaaaaaaaaa',
email: 'yyyy@example.com'
},
{
eventTitle: '[zzzz] Busy',
id: 'bbbbbbbbbb',
email: 'zzzz@example.com'
}
]
}
const identifyKeyName = 'sourceCalendarId'

Usage

  1. Create new Google Apps Script
  2. Paste files here
  3. Set your calendar id and source calendar's ids and their titles in setting.gs
  4. Add Google Calendar API as a service from left side of the editor
  5. Share calendars with target calendar at Google Calendar
  6. Test and authorization
  7. Set trigger on GAS

Example

  • syncToday() for 15 minutes
  • syncThisMonth() for 1 hour
  • syncThreeMonth() for 4 hours
function syncEventsWithOtherCalendar(calendarInfo, days) {
let date = new Date();
for (let i = 0; i < days; i++) {
deleteTargetCalendarForDay(calendarInfo.id, date);
const sourceCalendarEvents = getEventsForDay(calendarInfo.id, date)
for (const event of sourceCalendarEvents) {
if (getEventSource(event) != null || event.eventType != 'default' || isDeclined(calendarInfo.email, event) || event.transparency == 'transparent') {
continue;
}
addAnotherCalendarEvent(calendarInfo, event);
}
date.setDate(date.getDate() + 1);
}
}
function deleteTargetCalendarForDay(sourceCalendarId, date) {
const targetCalendarEvents = getEventsForDay(setting.targetCalendarId, date);
for (const event of targetCalendarEvents) {
if (getEventSource(event) != sourceCalendarId) {
continue;
}
try {
Calendar.Events.remove(setting.targetCalendarId, event.id);
}
catch(e) {
console.log("setting.targetCalendarId: " + setting.targetCalendarId);
console.log("event: " + JSON.stringify(event));
console.log("Error message: " + e.message);
}
}
}
function isDeclined(email, event) {
if (typeof event.attendees == 'undefined') {
return false;
}
for (const attendee of event.attendees) {
if (attendee.email != email) {
continue;
}
if (attendee.responseStatus == "declined") {
return true;
}
else {
return false;
}
}
return false;
}
function addAnotherCalendarEvent(calendarInfo, event) {
let reservedEvent = {
summary: calendarInfo.eventTitle,
start: event.start,
end: event.end,
extendedProperties: {
private: {
[identifyKeyName]: calendarInfo.id
}
},
colorId: 8
};
try {
Calendar.Events.insert(reservedEvent, setting.targetCalendarId);
}
catch(e) {
console.log("sourceCalendarId: " + calendarInfo.id);
console.log("event: " + JSON.stringify(event));
console.log("reservedEvent: " + JSON.stringify(reservedEvent));
console.log("Error message: " + e.message);
}
}
function getEventsForDay(calendarId, date) {
const endOfDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59);
const timeMin = new Date(date.setHours(0, 0, 0, 0)).toISOString();
const timeMax = endOfDate.toISOString();
const events = Calendar.Events.list(calendarId, {
timeMin: timeMin,
timeMax: timeMax,
singleEvents: true
});
if (!events.items || events.items.length === 0) {
return [];
}
return events.items;
}
function getEventSource(event) {
if ('extendedProperties' in event && 'private' in event.extendedProperties) {
return event.extendedProperties.private[identifyKeyName];
}
return null;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment