Skip to content

Instantly share code, notes, and snippets.

@mburtscher
Last active April 2, 2024 16:01
Show Gist options
  • Save mburtscher/50bbd8ed0a62334d8cee81837d4e23d4 to your computer and use it in GitHub Desktop.
Save mburtscher/50bbd8ed0a62334d8cee81837d4e23d4 to your computer and use it in GitHub Desktop.
Slack "Google Calendar for Teams" replacement
var webhookUrl = 'https://hooks.slack.com/services/…/…/…'; // Webhook URL
var calendarId = '…@group.calendar.google.com'; // Id of the calendar
var slackChannel = '#events'; // Name of Slack channel to post updates to
var threshold = 30; // Seconds to look back after "onEventUpdated" event was received
var messageWeeklySingle = 'There is *1 event* this week:';
var messageWeeklyMultiple = 'There are *{events} events* this week:';
var messageCreated = 'A *new event* has been created:';
function sendWeeklyEventsSummary()
{
var start = new Date();
start.setHours(0, 0, 0, 0);
var end = new Date(start.getTime() + 7 * 24 * 60 * 60 * 1000);
var events = CalendarApi.Events.list(calendarId, {
timeMin: start.toISOString(),
timeMax: end.toISOString(),
singleEvents: true,
orderBy: 'startTime'
}).items;
if (events.length === 0) {
Logger.log('No events found.');
return;
}
// Build the message
var message = events.length === 1 ? messageWeeklySingle : messageWeeklyMultiple.replace('{events}', events.length);
for (var event of events) {
message += `\n\n` + formatEvent(event);
}
sendMessage(message);
}
function onEventUpdated(e)
{
var syncStartTime = new Date(new Date() - threshold * 1000);
var events = CalendarApi.Events.list(calendarId, {
updatedMin: syncStartTime.toISOString()
}).items;
for (var event of events) {
if (event.status === 'cancelled') {
// Event has been cancelled / deleted.
continue;
}
var created = new Date(event.created);
if (created < syncStartTime) {
// Event has been created earlier and was only updated.
continue;
}
sendMessage(messageCreated + '\n\n' + formatEvent(event));
}
}
function formatEvent(event) {
var result = `> *<${event.htmlLink}|${event.summary}>*\n`;
result += `> ${(new Date(event.start.dateTime)).toLocaleString('de-AT', {dateStyle: 'full', timeStyle: 'short'})}`;
if (event.location) {
result += `\n> <https://maps.google.com/maps?q=${encodeURIComponent(event.location)}|${event.location}>`;
}
return result;
}
function sendMessage(message) {
return UrlFetchApp.fetch(webhookUrl, {
"method" : "post",
"contentType" : "application/json",
"payload" : JSON.stringify({
"channel": "#events",
"username": "Events",
"text": message,
"icon_emoji": ":calendar:"
})
});
}
@ogoldberg
Copy link

@mburtscher thanks for this!
I forked your code and made some minor update

  • I added a daily summary function.
  • I fixed a bug where it wasn't handling date vs dateTime properly`
  • I made the message creation a little bit more dynamic

You can see it here if you are interested:
https://gist.github.com/ogoldberg/9a807342ed1c508800e62a64b75ba623

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