Last active
January 31, 2025 23:04
-
-
Save dat-boris/8ead4769e34c620cf50ca8ff9c6169a6 to your computer and use it in GitHub Desktop.
Syncing pingboard calendar to my own calendar via Google app script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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