Skip to content

Instantly share code, notes, and snippets.

@dat-boris
Last active January 31, 2025 23:04
Show Gist options
  • Save dat-boris/8ead4769e34c620cf50ca8ff9c6169a6 to your computer and use it in GitHub Desktop.
Save dat-boris/8ead4769e34c620cf50ca8ff9c6169a6 to your computer and use it in GitHub Desktop.
Syncing pingboard calendar to my own calendar via Google app script
/**
* To use:
* 1. customize the script (see CUSTOMIZE below)
* 2. Add this to your Google App Script dashboard https://script.google.com/a/xxx.org/
* 3. Test run and you should see new event added to your calendar
* 4. Add a trigger - e.g. to run every minute
*
* Originally from
* https://webapps.stackexchange.com/questions/108132/how-to-automatically-forward-events-from-one-google-calendar-to-another
*
* API doc:
* https://developers.google.com/apps-script/reference/calendar/calendar
*/
var GIST = 'Set by https://git.io/fNilG';
// get from https://api.slack.com/custom-integrations/legacy-tokens#
var SLACK_TOKEN = 'xoxp-xxxxxx';
// get from https://api.slack.com/methods/auth.test/test
var SLACK_USER = 'Uxxxxxx';
var NAME = 'Boris Lau';
function copyVacationEvents() {
// company pingboard calendar
var source = CalendarApp.getCalendarById('[email protected]');
// CUSTOMIZE: my own calendar ID
var target = CalendarApp.getCalendarById('[email protected]');
var now = new Date();
var endPeriod = new Date();
endPeriod.setDate(endPeriod.getDate() + 30); // 30 days from now
var events = findEventFromCalendar(source, NAME, now, endPeriod);
for (var i = 0; i < events.length; i++) {
var event = events[i];
// Since we dont see event after they finish, we need to reset status just before
var eventEndTimeJustBefore = new Date(event.getEndTime().getTime() - 3600 * 0.5 * 1000);
// Hack: bump to next day (normally 5pm end)
var eventEndTimeAndAFew = new Date(event.getEndTime().getTime() + 3600 * 7 * 1000);
/**
* Setting slack status
*/
if (event.getStartTime() <= now && now < eventEndTimeJustBefore) {
setSlackStatus(
// remove prefix with from title in pingboard
event.getTitle().split(':').pop() + ' till ' + eventEndTimeAndAFew.getDate() + '/' + (eventEndTimeAndAFew.getMonth()+1) + ' (' + GIST + ')',
':palm_tree:'
);
setDND(60);
} else if (eventEndTimeJustBefore <= now && now < eventEndTimeAndAFew) {
setSlackStatus(
'Back from vacation (' + GIST + ')',
':nerd_face:'
);
}
/**
* Copy to calendar if we did not find set event
*/
var matchedEvents = findEventFromCalendar(target, event.getId(), now, endPeriod);
if (matchedEvents.length === 0) {
var title = event.getTitle() + ' '+ event.getId();
if (event.isAllDayEvent()) {
//cal.createAllDayEvent(title, event.getAllDayStartDate());
// we want to block the date
var eventDate = event.getAllDayStartDate();
eventDate.setHours(0);
while (eventDate < event.getAllDayEndDate()) {
var nextDate = new Date(eventDate.getTime() + 60 * 60 * 24 * 1000);
var nextDateMinusOneSec = new Date(nextDate.getTime()-1000);
target.createEvent(title, eventDate, nextDateMinusOneSec, {
'description': GIST
});
eventDate = nextDate;
}
}
else {
target.createEvent(title, event.getStartTime(), event.getEndTime(), {
'description': GIST
});
}
Utilities.sleep(100);
}
}
}
function findEventFromCalendar(cal, substring, startPeriod, endPeriod) {
var foundEvents = [];
var events = cal.getEvents(startPeriod, endPeriod);
for (var i = 0; i < events.length; i++) {
var event = events[i];
var title = event.getTitle();
if (title.indexOf(substring) === -1) {
continue;
}
foundEvents.push(event);
}
return foundEvents;
}
/**
* https://tanaikech.github.io/2017/05/09/changing-slack-status-using-google-apps-script/
*/
function setSlackStatus(status_text, status_emoji) {
var result = UrlFetchApp.fetch(
'https://slack.com/api/users.profile.set',
{
method: 'post',
payload: {
token: SLACK_TOKEN,
user: SLACK_USER,
profile: JSON.stringify({status_text: status_text, status_emoji: status_emoji})
},
muteHttpExceptions: true
}
).getContentText();
var result_data = JSON.parse(result);
if (!result_data.ok) {
throw "Slack error: "+result;
}
return result_data;
}
function setDND(minutes) {
return UrlFetchApp.fetch(
'https://api.slack.com/api/dnd.setSnooze?token='+SLACK_TOKEN+'&num_minutes='+minutes
).getContentText();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment