Hey y’all. Hope everyone is doing well. Today we’ll walk through writing a little bot for Slack using Golang. This is pretty straightforward, so this post will also be short and sweet. That said, a good bot can absolutely be a fun and interesting way to add some extra value to Slack for your org. We have one at Solinea that responds to our requests with pics of bacon. Clearly priceless.
Use What’s Already Out There
I spent some time looking at the different golang options out there for the Slack API. I landed on this one as the one that most folks seem to be using for go. Let’s setup what we need.
- Create a development directory. I called mine testbot.
mkdir testbot; cd testbot;
- Touch a couple of different files that we’ll use for our bot.
touch testbot.go Dockerfile
- Open up
touchbot.go
for editing.
Setup Slack##
Before we get any further, we need to get Slack setup properly.
- Head to
https://$YOUR_ORG.slack.com/apps/A0F7YS25R-bots
to get to the Bots app page. - Hit “Add Configuration”
- Once it’s created, copy the API Token somewhere safe. We’ll need that to connect to Slack.
This should be the minimum that’s necessary for Slack. Feel free to populate the other fields like name, description, etc.
Get Going
The slack library we’re using has some good getting started examples (for all kinds of Slack stuff!), but I just wanted the bare minimum to get a bot to respond.
- Let’s populate
touchbot.go
with the following:
Let’s walk through some of this. The general flow goes:
- Retrieve a Slack API token from our environment variables.
- Connect to Slack using the token and loop endlessly.
- When we receive an event, take action depending on what type of an event it is.
Now, there’s other types of events that can be present, but these are the ones that give enough quick feedback to troubleshoot an error.
There’s a couple of other important bits when a “MessageEvent” occurs:
- Get some basic info about our Slack session, just so we can fish our bot’s user name out of it.
- Set a prefix that should be met in order to warrant a response from us. This will look like
@testbot<space>
for me. - If the original message wasn’t posted by our bot AND it contains our prefix
@testbot
, then we’ll respond to the channel. For now, we’ll only respond with “What’s up buddy!?!?”
Bring On The Bots
That’s actually enough to get a bot connected and responding. Let’s check it out and then we’ll make it better.
- From your terminal, set a SLACK_TOKEN env variable with the value we got earlier from the bot configuration.
export SLACK_TOKEN="xxxyyyzzz111222333"
- Run your bot with
go run testbot.go
. This should show some terminal output that looks like it’s connecting to slack and reading some early events. -
In your slack client, invite testbot to a channel of your choosing.
/invite @testbot
- Now, let’s see if our buddy responds. Type something like
@testbot hey!
. You should see:
But Wait, There’s More
Sweet! It works! But you’ll probably notice pretty quick that if the only thing you’re looking for is the prefix, testbot is going to respond to ANYTHING you say to it. That can get a bit annoying. Let’s draft a responder and we can filter things out a bit.
- Create a function below your main function called “respond”. This code block should look like this:
- Looking through this code block. We’re basically just receiving the message that came through and, from here, we’ll determine if it warrants a response.
- There’s two maps that contain some accepted strings. For this example, we’re just accepting some greetings and some “how are you?” type or questions.
- If those strings are matched, a message is sent in response.
Now, we want to update our main function to use the respond function instead of posting messages directly. Your whole file should look like this:
Final Test
- Fire up your bot again with
go run testbot.go
- The bot should already be connected to your previous channel
- Greet your bot with
@testbot hey!
- Your bot will respond with our greeting response.
- Test out the second response:
@testbot how's it going?
Build and Run
This section will be quick. Let’s build a container image with our go binary in it. We’ll then be able to run it with Docker.
- Add the following to your Dockerfile:
- Build the go binary with
GOOS=linux GOARCH=amd64 go build
in the directory we created. - Create the container image:
docker build -t testbot .
- We can now run our container (anywhere!) with
docker run -d -e SLACK_TOKEN=xxxyyyzzz111222333 testbot