How Can I Add Features To This Slack Bot to replace 'Google Calendar for Team Events' which is going away
Asked Answered
L

1

7

CONTEXT: Read Reddit thread here

This Slack integration with Google Calendar is sunsetting on March 1, 2023 and there are currently no alternatives

https://slack.com/help/articles/360047938054-Google-Calendar-for-Team-Events-for-Slack

I was able to hack together a rudimentary bot using Google Scripts + Slack's Incoming Web Hooks functionality however it is missing a few features I couldn't figure out:

Features it has:

  • Weekly summaries [I set an event trigger on Sunday night]

Features it lacks:

  • Post reminders 2 days before an event
  • Post a reminder the day-of the event at a specified time
  • Get notified when an event is created or updated [an event's title, time, or location is updated] and ONLY post that event
  • Slackbot sends each event as a separate category [currently, they are all bundled]

Steps to get setup:

Create a Webhook

  1. Create an incoming webhook in Slack.
  2. Go to Slack custom integrations directory > Search for “Incoming WebHooks” > Click “Add configuration”. Fill out the details for the Slack channel to which your Slackbot will post, a description of your Slackbot, etc. (the script can override these fields, just name the webhook something you'll remember.)
  3. Copy and save the webhook url for use later.

Then create a Google Script here

  1. Click 'Services' and add the 'AdSense' and 'Calendar' services

Now, copy in the below code and add your custom webhook for the WebhookURL variable

// Resources https://www.kutil.org/2016/02/integrate-google-apps-and-slack-with.html
// Slack messages formatting reference https://app.slack.com/block-kit-builder/T0247NYLG9Y

// This is the code for updating the vacations channel with upcoming PTO

function UpcomingPTO() {

  var WebhookURL = "https://hooks.slack.com/services/XXX/YYYY/ZZZZZZZ";
  
// Define PTO Calendar ID variables 
  var PTOCal = '[email protected]'
  var cal = CalendarApp.getCalendarById(PTOCal);

// Sets how far in the future to look for events and get the color of the calendar
  var StartTime = new Date();
  var EndTime = new Date(StartTime.getTime() + 7776000000); //90 days from today
  var color = cal.getColor(); 

  var events = cal.getEvents(StartTime, EndTime);

  var EventTitles = [];
      for (var i= 0; i < events.length; i++) {
          
          var NextEvent = [];
          NextEvent.push(events[i].getTitle())
          
          var NextEventStartDate = [];
          NextEventStartDate.push(events[i].getStartTime())
          
          var NextEventEndDate = [];
          NextEventEndDate.push(events[i].getEndTime())

          var StartDate = new Date(NextEventStartDate).toLocaleDateString('en-us', { weekday: 'short', month: 'short', day: 'numeric' })
          var EndDate = new Date(NextEventEndDate).toLocaleDateString('en-us', { weekday: 'short', month: 'short', day: 'numeric', year: 'numeric' })
          
          EventTitles.push("\n\n *" + NextEvent + "* \n" + StartDate + " to " + EndDate);
      }

  var payload = {
     "channel" : "#1-vacations",          // <-- optional parameter, use if you want to override default channel
     "username" : "Team PTO",               // <-- optional parameter, use if you want to override default "robot" name 
     "text" : 'There are ' + events.length + ' upcoming PTO events soon',
     "icon_emoji": ":palm_tree:",           // <-- optional parameter, use if you want to override default icon, 
     "attachments":[
      {
         "color": color,
         "fields":[
            {
               "title": EventTitles,                                                // The title may not contain markup and will be escaped for you
               "value": String(EventTitles),                                        // Text value of the field. May contain standard message markup and must be escaped as normal and multi-line
               "short":false                                                        // Optional flag indicating whether the `value` is short enough to be displayed side-by-side with other values
            }
         ]
      }
    ]
  }
  
  Logger.log(events)
  Logger.log(NextEvent)
  Logger.log(EventTitles)
  sendToSlack_(WebhookURL,payload)
}


function sendToSlack_(WebhookURL,payload) {
   var options =  {
    "method" : "post",
    "contentType" : "application/json",
    "payload" : JSON.stringify(payload)
  };
  return UrlFetchApp.fetch(WebhookURL, options)
}
Lactescent answered 22/2, 2023 at 20:43 Comment(2)
Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer.Diacid
Thanks for this! I was able to implement getting notifications "for when an event is created or updated [an event's title, time, or location is updated] and ONLY post that event" by also using the Google Sheets API and storing the payload in a sheet. Then I created a trigger on my calendar being modified, and only sent the difference between payloads to SlackPelagias
F
3

Based on Shant's implementation (thx by the way!), I have created a version that supports both weekly notifications and event created notifications.

  1. Create an incoming webhook for Slack here.
  2. Create a new Google Script here.
  3. Copy the code from here to your new Google Script.
  4. Replace the values for webhookUrl, calendarId and slackChannel.
  5. (Optional) Create a time-based trigger for the sendWeeklyEventsSummary() function.

Image showing the time-based trigger configuration for sendWeeklyEventsSummary

  1. (Optional) Create a event based trigger for the onEventUpdated() function.

Image showing the event based trigger configuration for onEventUpdated

Disclaimer: The event based trigger will just look back 30 seconds and send all events created in this time period. If you have a lot of action on your calendar, this may result in multiple notifications for the same event.

Fradin answered 28/7, 2023 at 9:41 Comment(1)
thanks for this! I forked your code and made some minor updates - 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: gist.github.com/ogoldberg/9a807342ed1c508800e62a64b75ba623Equipage

© 2022 - 2025 — McMap. All rights reserved.