by slack-ruby

A library that enables you to write a complete Slack bot service with Slack button integration, in R...

218 Stars 69 Forks Last release: Not found MIT License 247 Commits 21 Releases

Available items

No Items, yet!

The developer of this repository has not created any items for sale yet. Need a bug fixed? Help with integration? A different license? Create a request here:

Slack Ruby Bot Server

Gem Version Build Status Code Climate

Build a complete Slack bot service with Slack button integration, in Ruby.

If you are not familiar with Slack bots or Slack API concepts, you might want to watch this video.

A good open-source demo of a service built on top of this library is Strava integration with Slack.

Table of Contents

What is this?

A library that contains a Grape API serving a Slack Ruby Bot to multiple teams. This gem combines a web server, a RESTful API and multiple instances of slack-ruby-bot. It integrates with the Slack Platform API. Your customers can use a Slack button to install the bot.

Stable Release

You're reading the documentation for the next release of slack-ruby-bot-server. Please see the documentation for the last stable release, v0.12.2 unless you're integrating with HEAD. See UPGRADING when upgrading from an older version.

Try Me

A demo version of the sample app with mongoid is running on Heroku at Use the Add to Slack button. The bot will join your team as @slackbotserver.

Once a bot is registered, you can invite to a channel with

/invite @slackbotserver
interact with it. DM "hi" to it, or say "@slackbotserver hi".

Run Your Own

You can use one of the sample applications to bootstrap your project and start adding slack command handlers on top of this code. A database is required to store teams.


Use MongoDB with Mongoid as ODM. Configure the database connection in

. Add the
gem in your Gemfile.
gem 'mongoid'
gem 'kaminari-mongoid'
gem 'mongoid-scroll'
gem 'slack-ruby-bot-server'

See the sample app using Mongoid for more information.


Use ActiveRecord with, for example, PostgreSQL via pg. Configure the database connection in

. Add the
gems to your Gemfile.
gem 'pg'
gem 'activerecord', require: 'active_record'
gem 'slack-ruby-bot-server'
gem 'otr-activerecord'
gem 'cursor_pagination'

See the sample app using ActiveRecord for more information.


Start with one of the samples above, which contain a couple of custom commands, necessary dependencies and tests, then create a new Slack App.

Follow Slack's instructions, note the app client ID and secret, give the bot a default name, etc. The redirect URL should be the location of your app. For local testing purposes use a public tunneling service such as ngrok to expose local port 9292.

Within your application, edit your

file and add
in it.


bundle install
foreman start
to boot the app. Navigate to localhost:9292. You should see an "Add to Slack" button. Use it to install the app into your own Slack team.

OAuth Code Grant

The "Add to Slack" button uses the standard OAuth code grant flow as described in the Slack docs.

The button itself contains a link that looks like this:

Once clicked, the user is taken through the authorization process at Slack's site. Upon successful completion, a callback containing a temporary code is sent to the redirect URL you specified. The endpoint at that URL contains code that looks like this:

# Instantiate a web client
client =

Request a token using the temporary code

rc = client.oauth_access( client_id: ENV['SLACK_CLIENT_ID'], client_secret: ENV['SLACK_CLIENT_SECRET'], code: params[:code] )

Pluck the token from the response

token = rc['bot']['bot_access_token']

The token is stored in persistent storage and used each time a Slack client is instantiated for the specific team.


This library implements an app, SlackRubyBotServer::App, a service manager, SlackRubyBotServer::Service that creates multiple instances of a bot server class, SlackRubyBotServer::Server, one per team. It also provides default HTML templates and JS scripts for Slack integration.


The app instance checks for a working database connection, ensures indexes, performs migrations, sets up bot aliases and log levels. You can introduce custom behavior into the app lifecycle by subclassing

and creating an instance of the child class in
class MyApp < SlackRubyBotServer::App
  def prepare!


def deactivate_sleepy_teams! do |team| next unless team.sleepy? team.deactivate! end end end


Service Manager

Lifecycle Callbacks

You can introduce custom behavior into the service lifecycle via callbacks. This can be useful when new team has been registered via the API or a team has been deactivated from Slack.

instance = SlackRubyBotServer::Service.instance

instance.on :started, :stopped do |team|

team has been started or stopped


instance.on :created do |team, error, options|

a new team has been registered


instance.on :deactivated do |team, error, options|

an existing team has been deactivated in Slack


instance.on :error do |team, error, options|

an error has occurred


The following callbacks are supported. All callbacks receive a

, except
, which receives a

| callback | description | |:--------------:|:-----------------------------------------------------------------| | error | an error has occurred | | creating | a new team is being registered | | created | a new team has been registered | | booting | the service is starting and is connecting a team to Slack | | booted | the service is starting and has connected a team to Slack | | stopping | the service is about to disconnect a team from Slack | | stopped | the service has disconnected a team from Slack | | starting | the service is (re)connecting a team to Slack | | started | the service has (re)connected a team to Slack | | deactivating | a team is being deactivated | | deactivated | a team has been deactivated |

The Add to Slack button also allows for an optional

parameter that will be returned on completion of the request. The
callbacks include an options hash where this value can be accessed (to check for forgery attacks for instance).
auth = OpenSSL::HMAC.hexdigest("SHA256", "key", "data")
instance = SlackRubyBotServer::Service.instance
instance.on :creating do |team, error, options|
  raise "Unauthorized response" unless options[:state] == auth
Service Timers

You can introduce custom behavior into the service lifecycle on a timer. For example, check whether a team's trial has expired, or periodically cleanup data.

Note that unlike callbacks, timers are global for the entire service.

instance = SlackRubyBotServer::Service.instance

instance.every :hour do Team.each do |team| begin # do something with every team once an hour rescue StandardError end end end

instance.every :minute do

called every minute


instance.every :second do

called every second


instance.every 30 do

called every 30 seconds



A number of extensions use service manager callbacks and service timers to implement useful functionality.

Server Class

You can override the server class to handle additional events, and configure the service to use it.

class MyServer < SlackRubyBotServer::Server
  on :hello do |client, data|
    # connected to Slack

on :channel_joined do |client, data| # the bot joined a channel in['id'] end end

SlackRubyBotServer.configure do |config| config.server_class = MyServer end

Service Class

You can override the service class to handle additional methods.

class MyService < SlackRubyBotServer::Service
  def url

SlackRubyBotServer.configure do |config| config.service_class = MyService end

SlackRubyBotServer::Service.instance # MyService SlackRubyBotServer::Service.instance.url #

HTML Templates

This library provides a default HTML template and JS scripts that implement the "Add to Slack" button workflow. Customize your pages by adding a

directory in your application and starting with a index.html.erb template. The application's
folders are loaded by default.

You can add to or override template paths as follows.

SlackRubyBotServer.configure do |config|
  config.view_paths << File.expand_path(File.join(__dir__, 'public'))

Access Tokens

By default the implementation of Team stores a

that grants a certain amount of privileges to the bot user as described in Slack OAuth Docs along with
that represents the token of the installing user. You may not want a bot user at all, or may require different auth scopes, such as
to access user profile information via
. To change required scopes make the following changes.

1) Configure your app to require additional scopes in Slack API under OAuth, Permissions 2) Change the Add to Slack buttons to require the additional scope, eg.,users.profile:read&client_id=...
3) The access token with the requested scopes will be stored as

You can see a sample implementation in slack-sup#3a497b.

Example Bots Using Slack Ruby Bot Server

Copyright & License

Copyright Daniel Doubrovkine and Contributors, 2015-2020

MIT License

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.