Slackbots for Fun and Profit
This is the general process/flow for creating Slack integrations, nothing groundbreaking here, just wanting to consolidate the info that I used when building bots. In the future (once I get approval) I will publish the details of a bot in Ruby and a slash command in Python.
Bot/Slash Command integrations are limited only by your imagination. There is a process for integrating with Slack, what you do with received messages and how you integrate that data with your other platforms is where the real power lies.
Details on integrating with Slack can be reviewed in detail at https://api.slack.com
Bot Types
There are two distinct types of Slack bots: bots and slash commands
Bots
At their core, bots are synonymous with users. This type of both interacts with Slack the same way as a normal user: they are added to channels, can read any messages posted to channels they are part of, and can respond to any room they are part of or is public. They can also interact in a Direct Message. The bot logs into Slack using a bot_id
and an API token.
The biggest consideration here is from a security perspective: this type of bot can read EVERYTHING that is public or posted to channels where the bot has been added.
This type of bot may also initiate communication which is useful when building integrations that need to trigger a Slack event based on external events.
Using the Slack Real-Time Messaging API and the Web API, bot creators can receive messages, parse the message based on their needs, and respond.
Slash Commands
Most Slack users are familiar with at least one slash command (probably /gifs
). Slash commands differ from bots in that they do not mimic user functionality. Instead of being added to channels they only get information from Slack when they are invoked.
From a technical perspective, when a slash command is created, the admin defines a listening server to service the slash command requests. When the command is invoked within Slack, an HTTP POST request is sent to the configured listening server with certain parameters such as user, channel, and a response URL. The response URL is valid for 30 minutes and allows an easy way to respond quickly to invocations.
The listener server can also be configured with a token that is compared to a token supplied in the POST requests to ensure that requests are valid.
General Bot Creation Flow
-
Determine what language you want to use for your integration. There are many integrations already built for most of the major programming/scripting languages listed here. The Slack API is also pretty well documented if you want to start from scratch; of note are the Real Time Messaging API and the Web API.
-
You must create a bot within your team's Slack and get a Slack Token and ID for the bot. This guide for a Python Bot does a great job of walking through the bot creation. Be sure to take not of the ID and Token.
-
Create a simple integration using the client of your choosing (from 1). They all should have simple test examples. I would recommend just starting with a "Hello World!" type bot that can respond to a specific message. One nice aspect of responding to Slack is that all Slack formatting is valid in response messages including Emoji.
-
Start a channel with your bot, ensure it is online, and start interacting.
-
Start building your logic on top of your working test integration. If you are interacting with another service that has a time constant (not instant responses) I would recommend using a queuing mechanism in your language to write the message data for out-of-band processing. For sure you will want to record the
user_name
,channel
, and thetext
from the message. -
Repeat steps 4 and 5 until you achieve your ~goal~ profit.
General Slash Command Creation Flow
-
Determine what language you want to use for your integration. There are many integrations already built for most of the major programming/scripting languages listed here. The Slack API is also pretty well documented if you want to start from scratch; of note are the Real Time Messaging API and the Web API.
-
You must create a Slash Command within your team's Slack and get a Client ID, Client Secret, and Verification Token for the command. Slash commands can be created here. Under "Add Features and Functionality" select "Slash Command". This is where you can configure the command and most importantly, configure the location of your listening server. HTTPS is not required for apps with a scope limited to your organization but it is required for apps that you plan to deploy publicly. Just make it HTTPS. NOTE: the POST requests will come from Slack, not user clients, so the listening server must be publicly accessible.
-
When you are ready, find the section for "Install App To Workspace". This will make the app available within your workspace, albeit with zero functionality.
-
Build a web server to handle the post requests (the same server you configured in step 2). At this point the command does not care what server you run as long as the server can receive and send POST requests.
- Web server ~should~ MUST validate the token sent against the one from the command creation. If this is not done, anyone on the internet could send commands to your handler.
- Process the POST request specifically recording the
user_id
,channel_id
, andresponse_url
parameters included in the POST. - Based on a recommendation from Slack, the initial response should look something like this to let your users know something is working:
# JSON response per Slack recommendation # Ephemeral indicates respones will only be visible to user content_type :json { :response_type => 'ephemeral', :text => "Some initial response test here", :attachements => [{}] }
- If responding within 3000ms, the response can just be in the response body to the POST request.
ephemeral
responses are only visible to the requesting user,in_channel
responses are visible to all users in the channel. Depending on your integration, this may be all you need. - If your integration requires more than 3000ms to respond (and less than 30 minutes) then further responses are done by POST the message with the same syntax as above to the
response_url
provided in the initial command message.
-
Continue to test/built your integration until you are happy.