Programatic message threading with your Slack Bot
Thread related messages & avoid being an automated spammer.
In part one I wrote about why and how we built a Slack bot. We use our bot as middleware to send notifications from a browser app. The bot exposes endpoints mapped to methods like chat.postMessage
in Slack’s web-api. We POST to the endpoint with a block-kit-builder formatted message. Each message to Slack returns a message ID (ts
) which we use to thread related messages. It’s a great way to avoid spamming our channels.
Drone pilots use our app to upload imagery to our services. We want to notify a channel when:
- an upload is started
- every 25% progress is reached
- the pilot pauses, resumes or cancels the upload
- a file fails upload
In this post I’ll walk though how we implemented this notification flow.
Setting up
To send messages to Slack I’ll need:
- Channel ID
- Url to the GCP function hosting the bot
- A way to cache message IDs so they survive page refreshes
You can get a channel Id by right licking the name of your channel, “then copy link”. Paste it anywhere, the ID is the characters on the end. Something like this: C21S4MN6C4
(👈🏻 Not an actual ID). Make sure you’ve added your bot to that channel too.
To find the url for the Cloud function go to the GCP console and look under the TRIGGER
tab. It’ll look something like: https://europe-west1-[project-name].cloudfunctions.net/slack-bot
. The name on the end is the same as the name we used when deploying the bot in part 1.
To cache the ts
key I’m using local storage. Nothing fancy here. Usually there are one or two keys live at anyone point. I use an upload Id to scope keys in the cache.
Sending the first message
I’ve structured my notifications as a series of async functions. I use a primary notifySlack
function which makes the request. Other notification specific functions with names like notifySlackUploadInit
, and notifySlackUploadComplete
call into it. The notifySlack
uses fetch for POSTing to the bot with the channel ID and message body. It returns a ts
key which I’ll use later to thread messages.
These two functions will send a message to Slack that looks like this:
Block Kit Builder is a great tool for designing messages. Copy the JSON and use it directly in the request function.
My storeUploadNotificationTs
function adds the ts
key to local storage. It uses the upload ID to scope it in case a user triggers other uploads from a different tab.
Threading messages
To send a message as a thread of another message we’ll add the ts
key to the request. This function sends an “Upload Completed” message:
I retrieve the ts
key from local storage and add it to the request’s thread_ts
property. Because it’s the end of the line, I clean up local storage. The resulting threaded message now looks like this:
That’s it. The hard part is getting a Slack bot setup and working. Then with this endpoint I can send messages to any channel in our workspace from any client app.