If you have not been living under a rock for the past year, you’ll have heard about Slack or are most probably using it in your company. For those who did actually live under one, Slack is a team communication platform that is an integral part of thousands of companies’ workflows. Launched in 2013, the product’s adoption rate has been nothing short of phenomenal. There are a number of new things that Slack has to offer that the existing communication tools failed to, which in a way led to its meteoric growth.
One of its unique offerings is the ability to build extensions called bots for fun and for productivity. With the recent launch of the Slack platform, it’s high time to build all sorts of extensions and apps for Slack.
Today we’re going to look into how to build one of those fun slack bots in Ruby. This bot “might” be useful to you, but the main focus of this article is to introduce you to Slack’s incoming webhook and slash command APIs. Without further ado, let’s get started.
Our bot, let’s call it anonbot, lets people post anonymous messages in Slack. We will implement this using Slack’s slash command API and incoming webhook API. We are using slash commands, because those messages are private and only shown to the recipient even inside a channel. Then, using an incoming webhook, we’ll post back the content that was sent to us through a slash command to the respective channel from which it was sent.
Setting Up the Project
As noted, we are going to build this in Ruby and Sinatra. It’s a simple app that could be built on plain Ruby, but we’re using Sinatra to simplify it further. Sinatra is a lightweight web framework for Ruby that’s very useful for building simple web applications like ours.
Let’s start by creating the necessary files for our app, which are only two. Start by creating a folder for our project and create the below mentioned two files inside it:
anonbot | |-------- app.rb |-------- Gemfile |-------- config.ru
app.rb
is where the logic goes, and Gemfile
is for specifying the gem requisites. config.ru
is required for hosting in Heroku, but it is not mandatory for the app’s functionality.
Add the below lines to our Gemfile and we’re ready to commit the project into git.
source "https://rubygems.org" gem "sinatra" gem "httparty"
The sinatra gem is for the framework, and we need httparty to post the anonymous message to Slack’s incoming webhoook. After the gems are added, run bundle install
from inside the project directory.
A new file Gemfile.lock
will have been created now. Nice—let’s initialize our project into git and commit the changes.
git init git add -A git commit -m "Initial commit with gem requisites"
Code It Up
Let’s get to the business. We are going to have only one API endpoint which Slack calls when our slash command is invoked. Open up app.rb
and add the below lines to it.
require 'sinatra' require 'httparty' require 'json' get '/anonymize' do postback params[:text], params[:channel_id] status 200 end def postback message, channel slack_webhook = ENV['SLACK_WEBHOOK_URL'] HTTParty.post slack_webhook, body: {"text" => message.to_s, "username" => "John Doe", "channel" => params[:channel_id]}.to_json, headers: {'content-type' => 'application/json'} end
So I guess the code is pretty self-explanatory, but let’s quickly skim over it. We’re first requiring the necessary libraries, and initializing our first and only API endpoint. This is the endpoint that Slack calls whenever our custom slash command is invoked.
We will get a list of parameters along with the message, but we are only interested in two parameters:
-
text
: the message that was typed in following the slash command -
channel_id
: the channel from which the user has invoked the command; we need it to post it back to that channel
The postback
method takes care of posting the message using the webhook URL to Slack. We’re specifying the text, and overriding the username and channel which will be set while configuring the webhook. There’s a new option that Slack introduced in the slash command which is a quick and easy way to do this in just two lines—we’ll see it later.
By doing that, we are all done with the app’s functionality. Add the below lines to config.ru
before committing the changes and deploying our app.
require './app' run Sinatra::Application
This file is required for Heroku to recognize the app type and to start serving requests. Let’s commit the changes:
git add -A git commit -m "Add app functionality"
If you don’t have the Heroku toolbelt, it’s time to install it now. If it’s already installed, create a Heroku app and deploy our shiny new bot.
heroku create appbot-name heroku deploy
So we have successfully created our bot and deployed it. Yay! It’s time to finish the Slack side of things.
Configuring the Slack Extension
We are using two types of extensions here—slash command and incoming webhook—so we have to configure the two of them separately. Go to Configure Apps and click on the slash commands and Add Configuration on the next page.
Give a slash command of your choice—you can be as mischievous as possible. I have chosen the obvious /anonbot
. Once you have typed in the slash command, on the next page fill in the URL field with the newly deployed Heroku URL.
https://<appbot-name>.herokuapp.com/anonymize
Note that we have specified a https
endpoint. It’s important that you check it since Slack recommends the communication endpoints to be https
. Also set the Method as GET
, and then you can save the integration.
Next, go to the same Configure Apps endpoint and this time select Incoming WebHooks, and on the Configuration page, select whatever channel you want, since anyway we are going to override it in our message. On the resulting page, make a note of the Webhook URL
.
Now that we have the webhook url, set it as Heroku’s environment variable so that we can start the show. From the command line inside the project directory, run:
heroku config:set SLACK_WEBHOOK_URL=https://hooks.slack.com/services/your-webhook-url
And for the happy news, we are done! Let’s test our mischievous new bot. Type up your slash command followed by a message to startle your team members.
This is how the response would be in the channel.
Well, no one could guess it right!
The Short Way
As I mentioned already, there is a simple alternative way to do this. We have to get rid of the incoming webhook part altogether and instead respond to the initial call that Slack makes with the text and the response_type
as in_channel
. This is how app.rb will look by using that method:
get '/anonymize' do content_type :json {:text => params[:text], :response_type => "in_channel"}.to_json end
This feature was introduced recently by Slack. By specifying the response_type
as in_channel
, we are displaying the response publicly, which is private otherwise. I didn’t go ahead with this method because the intention is to show how easy the two extensions are.
Conclusion
So simple, right? The intention of this tutorial is to give you a glimpse of a couple of extensions that Slack has to offer, and I think it’s satisfied. All the sample code used in this tutorial is hosted on GitHub.
I thank you for reading this article, and I hope it served your purposes. Until next time!
Comments