Setting up a Slack webhook for simple notifications
July 11, 2021tl;dr
Goal
To set up a Slack webhook so we can send text and simple HTML notifications to receive in a Slack channel.
Process Overview
- Setting up a Slack webhook URL in your Slack workspace to post to a channel
- Posting a notification to our webhook
- Creating a simple HTML parser to match the custom Slack markdown flavor
Python Dependencies
Assumptions
I'll assume you have a Slack account, a Slack workspace setup, Slack is installed, and you have knowledge of Python with a basic understanding of webhooks.
If you haven't heard of it before, Slack is a very popular team/workplace communication tool. In addition to direct messaging, it allows you to separate discussion into various topics or channels for more focused team communication.
Another great feature of Slack is that you can add 3rd party apps (or integrations) from your existing stack, or even develop your own! I have seen this streamline my own productivity, and I personally use a number of Slack apps.
To name a few, you may want to check out the following (assuming you use these tools) which I've found a lot of value in:
- Sentry - for application monitoring
- Google Calendar - to stay on top of my meetings schedule
- GitHub - getting notified of pull requests and meaningful changes to important repositories
- Jira Cloud - staying on top of changes to Jira tickets
- AWS Chatbot - alerts from CloudWatch alarms
You can browse the Slack app directory for more integrations.
However, not every integration is going to provide the functionality you need. This post will focus on creating our own custom Slack app with the goal of posting simple notifications to a Slack channel.
A common use case where we can apply our app will be sending notifications when any sort of user activity happens on a platform. As a developer, being notified of when a user completes a certain task can provide a lot of transparency and understanding into the usage of our application, while also keeping a sales teams informed on relevant activity on the platform. This is the use case we'll focus on.
We will do this by posting to a webhook hosted by Slack. For more information on webhooks, you can check out this article by Zapier.
Let's get started!
Setting up the Slack App
Open Slack, click Add channels, and create a new channel called notifications
. This is where our Slack app will post to once we set it up.
Now go to a web browser and head to https://api.slack.com/apps/.
Click on Create an App
Select From scratch
Create a name for your app and select the workspace you just created your notifications
channel in.
This will redirect you to the Basic Information tab for your app. Here, we'll enable Incoming Webhooks. As it states, this will enable us to post messages from an external source. In this case, our platform.
Turn on Activate Incoming Webhooks and you will see additional details appear. Towards the bottom, click on Add New Webhook to Workspace.
You will be redirected again to select which channel to post to. Select the notifications
channel that we previously created and press Allow.
This will redirect you back to your app configuration and you will see a webhook URL you can now post to. This will also include a simple curl POST request you can test with if you'd like. Copy the webhook URL for later, and remember to keep it private. This is a public URL that anyone can post to.
You can return to the Basic Information of your app settings in Slack to view more API credentials and also edit the look and feel of your new Slack bot.
Now we're ready to dive into the code to communicate with our webhook!
Communicating with our Webhook
To communicate with our webhook, we'll use the requests
Python library. This is a third party library, so you'll want to have a Python virtual environment set up to handle your dependencies. Virtual environments are out of the scope of this article, but you can read more on them here.
Inside your virtual environment, you can run the following to install the library.
Now, we'll set up a class to communicate with our Slack endpoint. We'll start by just sending a plain text message to Slack.
Above is the basic setup for communicating with the Slack webhook. We can run a quick test by moving this code to a script and adding the following.
Make sure to set your Slack webhook URL to the SLACK_WEBHOOK_URL
environment variable, and make sure you're in your virtual environment with the requests
package installed before running the script. This can be done on MacOS with the following.
When you run this, you should see a message from you Slack bot appear in the notifications
channel!
For our notifications to be more helpful, we may want to add links or other formatting. To do this, we will write our notifications with HTML tags, and then parse these tags and convert them to the Slack flavored Markdown called mrkdwn
.
Adding a simple HTML parser to our class
From the Slack formatting guide for messages, we can see all of the ways to format text in our messages. For our purposes, we will focus on a primary list.
- Making text
_italicized_
(<i>
) - Making text
*bold*
(<b>
) - Striking through ~
~ (text
<strike>
) - Adding line breaks (
<br>
) - Adding
one-line code blocks
using the backtick character (<code>
) - Adding unordered lists (line broken dashes) (
<ul><li>
) - Adding external links
<[external link]|[display text]>
(<a>
)
Also note that the Slack documentation says that certain characters need to be escaped.
There are a few more styles that could be implemented, but we'll focus on just this list for this post.
To do this, we will utilize the html
module in the Python standard library to parse HTML tags, attributes, and values.
Let's write a class (we need to inherit functions for the HTMLParser
class) where we will parse all of the tags and attributes, and escape the message text when needed. The idea here is that we can construct a string from scratch and for each tag we care about we can "replace" the HTML tags with the relevant mrkdwn syntax.
We can test our class out with the following code.
Now we can test our formatter in an actual Slack message! Import your formatter class or add it to your existing code so you're able to do the following.
You should see the following message in your notifications channel.
Looks pretty good! Note that you can still send plain text messages, you don't need to use HTML.
For some final adjustments, you may have noticed that the message preview on the notification that popped up showed the actual mrkdwn
characters as opposed to a formatted notification. This looks a little sloppy, so let's make a new notification title that is similar to an email subject line.
We will briefly look at the basics of Slack's Block Kit, which is a powerful way to add lots of customization to your Slack messages. You can also explore Block Kit with Slack's Block Kit Builder which provides a preview of your Slack message.
Without diving too much into the details on the Block Kit, let's update our SlackWebhookBot
class and add a method that adds a title block and a body block for our message. Our subject line will appear in the notification itself, and also in the actual Slack message.
Now we can tweak our send
method to format a new message and accept a subject string as a Kwarg.
And we can test our notification with a new subject line.
You should see a notification appear with the following preview
and the following message in your channel.
We have a custom Slack notification app! You can place the send
message calls all across your applications with related messages and now you can have a better pulse on user activity that developers and any other employees/stakeholders can easily access.
For those wanting additional challenges or to continue developing their custom app, Slack has added a lot of really cool tools to the Block Kit. There are a ton of really cool possibilities that can be added on by updating the format_message
method in our SlackWebhookBot
class.
Explore the Slack's Block Kit Builder and see what you can make!