Note: This post has been updated with Slack Button integration since the launch of the Slack Developer Platform.
The slack-ruby-bot gem lets you roll out a bot for your team, but used to recommend a global Slack token configuration. How do we turn it into a full Slack bot service for multiple teams? How can we get a Slack Button to let teams install our service?
tl;dr Check out github.com/dblock/slack-bot-server.
Concurrency in Slack-Ruby-Client
The initial implementation of Slack Real Time API support in slack-ruby-client used EventMachine and embedded the run loop deeply inside the client itself. That helped users not worry about simple integration scenarios, but prevented you from instantiating multiple instances of
Slack::RealTime::Client, which would require one global run loop. With the 0.5.0 release slack-ruby-client support for different concurrency models was added, including Celluloid or no concurrency at all. The latter effectively defers the implementation to the caller, which is what you want for a bot service, we initialize an EventMachine loop in
Multiple Slack Bots
The next hurdle is instantiating multiple instances of actual bots. Until now the implementation of slack-ruby-bot defined an easy-to-use
SlackRubyBot::App, a singleton. I’ve extracted
SlackRubyBot::Server in 0.5.0, that can be instantiated multiple times.
Furthermore, the implementation now relies on websocket events to keep the bot up, restarting it as necessary. This means any single instance of
SlackRubyBot::Server will survive everything from disconnects to having an integration disabled in the Slack UI, retrying a connection every 60 seconds or so without ever giving up.
A Service to add Tokens
In order to maintain multiple bot servers you need a registry. I chose to make something simple,
SlackRubyBot::Service that uses a lock for thread safety and adds instances of
SlackRubyBot::Service to a
Hash, with the API token as key. You can
SlackRubyBot::Service.stop!(token). The tokens are stored in MongoDB as
A Web Interface and an API
The bot server isn’t useful without a bit of UI. I implemented a Grape API with some basic CRUD to store teams with their API tokens, along with an HTML (ERB) page that uses JQuery to add and remove new integrations.
Slack Button Integration
To enable Slack button integration, I followed Create a New Application on Slack, noting the client ID and secret. The UI gives you the HTML code for a slack button. When a user clicks on the button they and OAuth completes successfully they are redirected back to your application with a
code in the query string. That code is POSTed to Slack via the Web API’s oauth.access which returns an actual API token that can be used with a Real Time API client.
You can use slack-bot-server as a boilerplate to roll out a full Slack bot service to multiple teams, just fork the project. I chose not to package this as a library, I want you to use this as a boilerplate to get you started, but then sail on your own to make something useful.
Everything can be found at github.com/slack-ruby/slack-bot-server.
- github.com/exciting-io/slack-bot-server: A server for running multiple slack bots using a Redis queue.