Slack Notifications Filter

I use Slack a lot. Besides team communication, it is great for richly formatted log messages emitted by microservices. For example, you can embed images and links.

Unfortunately, slack’s notification options are pretty limited and features like “highlight” words don’t work with bots or integrations (which are an important source of my Slack messages).

I want to only receive notifications for certain conditions, such as messages from a particular user or if the message’s text contains specific keywords, like “donuts” and “kitchen”. 😋

Thankfully, with the various serverless/FaaS options, setting up a custom filter isn’t too hard.

Slack Notifications Filter using webtask.io

An outline of our approach is as follows:

  1. On Slack,
  2. Define a slack channel that is configured to send you notifications for all messages, the notification channel
  3. Define an outgoing webhook for a channel whose messages you wish to filter
  4. Define an incoming webhook to “repost” the message to the notification channel for which you want a notification
  5. On webtask.io
  • create a webtask that will receive slack messages, filter these messages and “repost” the messages that satisfy the filter, using the webhooks created on Slack

As you can guess, you should disable notifications for the channels you wish to filter. You probably also shouldn’t manually post to the notification channel directly, as it may cause some confusion (but that’s up to you).

NOTE: Slack doesn’t have (that I know of) a “repost” method in its API. The UI has a share button, but it seems we’ll need to mimic this behavior by posting part of the original message and a link to the message.

Nuts and Bolts Setup

It isn’t too bad; the written instructions are probably more effort to read than actually do.

Download Gist from GitHub for the webtask

Here is a simple webtask (in Javascript) that I created to do the filtering. There are a few things to configure.

  • Slack token and incoming webhook url (to do after Slack setup)
  • define your filter rules
  • customize the “repost”

Filter Rules

There is a method, shouldNotify, that needs to be defined. You can specify whatever logic you like, such as looking at the user name or message text. This method should evaluate to a truthy or falsy value.

You can read about the available fields on Slack Outgoing Webhooks docs.

Customizing the Repost

Since this really is just a new message post, you can do whatever you want. The existing format, in the webtask in the gist, assumes you’ll add some comment to the repost and a link to the original message.

You could get fancy, such as using the Slack API to fetch the entire original message (the webhook only provides it’s text, username and timestamp) and repost all links, attachments, etc. But since there is a link to the original, this might be overkill.

Initial Configuration in webtask.io

You’ll need to do some initial setup for the webtask and then add some details after the Slack configuration.

First, you’ll need a webtask.io account and the wt cli installed. You can find instructions for doing this here.

Next, you’ll create a new webtask. Using the wt cli,

wt create name=slack-notification-filter path/to/webtask_from_gist.js

it should show you something like this

Webtask created

You can access your webtask at the following url:

https://webtask.it.auth0.com/api/run/rest-of-the-url

Make a note of this url. You’ll need to enter it in Slack.

Slack Setup

Notifications Channel

(Note these steps are not provided in detail, as I am going to assume, as a Slack user, you’ve created a Slack channel. Links to Slack’s documentation are provided.)

Create a new channel in slack. I suggest you name it something such as “notifications” or similar.

Configure Notifications. I suggest setting both desktop and mobile, but that is up to you.

Outgoing Webhook

This is for sending the messages to the webtask for filtering.

You’ll need to do this part for each channel you wish to filter.

In your Slack team, go to the Menu and select “Configure Apps”

slack_menu

Then, click “Build” on the upper-right.

slack_build_menu

Then click “Make a Custom Integration”

slack_build

Click “Outgoing Webhook” and “Add Outgoing Webhooks Integration”

slack_add_outgoing

In the form, select the Channel you wish to filter. In the URL, paste the webtask.io url from earlier.

Copy the Token. You’ll need this for webtask.io later.

slack_token

Incoming Webhook

This is for posting back the messages that pass the filter check. Unlike the outgoing webook, you only need to do this once.

As with the steps for the Outgoing Webhook, select “Incoming Webhook” and add one.

Select the Channel that you created earlier.

Copy the Webhook URL. You’ll add this to webtask.io

Back to webtask.io: adding secrets

We are treating the Outgoing Webhook token and Incoming Webhook url as sensitive information. webtask.io allows you to specify secrets that it encrypts. It injects their values into the context of your webtask.

Using the wt cli,

wt edit slack-notification-filter

This will load the webtask editor in your browser. From here, you can click the secrets button on the right.

webtask_secrets

Click “+Add Secret” and enter EXPECTED_TOKEN as the name. Enter the value from earlier (Outgoing Webhook token).

This is used by the webtask to verify that it is indeed Slack that is sending messages.

Click “+Add Secret” again and enter WEBHOOK_URL as the name. Enter the value from earlier (Incoming Webhook url).

Congratulations!

You are done.

Errata

If you configure multiple outgoing webhooks, you’ll either

  • need to change token verification to use an array

or

  • create a webtask per channel (so that you verify its token)

I think the array is easier, but you’ll probably need to encode the array of secrets as a JSON string and parse it in the task.

Furthermore, this approach is most effective for filter rules that apply for the team, not individuals. You can add criteria/logic to the webtasks and/or register additional webtasks to accommodate individual preferences, but that doesn’t scale.

If you want/need individual filtering control, I’d consider creating a Slack app that uses the Events API or Real Time Messaging API. The same pattern outlined here could work, though I would probably repost the filtered messages as direct messages to individuals, for example.