A generic Slack bot framework written in Ruby on top of slack-ruby-client. This library does all the heavy lifting, such as message parsing, so you can focus on implementing slack bot commands. It also attempts to introduce the bare minimum number of requirements or any sorts of limitations. It's a Slack bot boilerplate.
If you are not familiar with Slack bots or Slack API concepts, you might want to watch this video.
- If you are just trying to send messages to Slack, use slack-ruby-client, which this library is built on top of.
- If you're trying to roll out a full service with Slack button integration, check out slack-ruby-bot-server, which uses this library.
- Otherwise, this piece of the puzzle will help you create a single bot instance for one team.
You're reading the documentation for the next release of slack-ruby-bot. Please see the documentation for the last stable release, v0.8.0 unless you're integrating with HEAD. See CHANGELOG for a history of changes and UPGRADING for how to upgrade to more recent versions.
source 'https://rubygems.org'
gem 'slack-ruby-bot'
gem 'celluloid-io'require 'slack-ruby-bot'
class PongBot < SlackRubyBot::Bot
command 'ping' do |client, data, match|
client.say(text: 'pong', channel: data.channel)
end
end
PongBot.runAfter registering the bot, run with SLACK_API_TOKEN=... bundle exec ruby pongbot.rb. Have the bot join a channel and send it a ping.
A typical production Slack bot is a combination of a vanilla web server and a websocket application that talks to the Slack Real Time Messaging API. See our Writing a Production Bot tutorial for more information.
The following examples of bots based on slack-ruby-bot are listed in growing order of complexity.
- slack-bot-on-rails: A bot running on Rails and using React to display Slack messages on a website.
- slack-mathbot: Slack integration with math.
- slack-google-bot: A Slack bot that searches Google, including CSE.
- slack-aws: Slack integration with Amazon Web Services.
- slack-gamebot: A game bot service for ping pong, chess, etc, hosted at playplay.io.
Bots are addressed by name, they respond to commands and operators. You can combine multiple commands.
class CallBot < SlackRubyBot::Bot
command 'call', '呼び出し' do |client, data, match|
client.say(channel: data.channel, text: 'called')
end
endCommand match data includes match['bot'], match['command'] and match['expression']. The bot match always checks against the SlackRubyBot::Config.user and SlackRubyBot::Config.user_id values obtained when the bot starts.
Operators are 1-letter long and are similar to commands. They don't require addressing a bot nor separating an operator from its arguments. The following class responds to =2+2.
class MathBot < SlackRubyBot::Bot
operator '=' do |client, data, match|
# implementation detail
end
endOperator match data includes match['operator'] and match['expression']. The bot match always checks against the SlackRubyBot::Config.user setting.
A bot will always respond to its name (eg. rubybot) and Slack ID (eg. @rubybot), but you can specify multiple aliases via the SLACK_RUBY_BOT_ALIASES environment variable or via an explicit configuration.
SLACK_RUBY_BOT_ALIASES=:pp: table-tennis
SlackRubyBot.configure do |config|
config.aliases = [':pong:', 'pongbot']
endThis is particularly fun with emoji.
Bots also will respond to a direct message, with or without the bot name in the message itself.
Commands and operators are generic versions of bot routes. You can respond to just about anything by defining a custom route.
class Weather < SlackRubyBot::Bot
match /^How is the weather in (?<location>\w*)\?$/ do |client, data, match|
client.say(channel: data.channel, text: "The weather in #{match[:location]} is nice.")
end
endYou can also capture multiple matchers with scan.
class Market < SlackRubyBot::Bot
scan(/(\[A-Z]{2,5})/) do |client, data, stocks|
# lookup stock market price
end
endSee examples/market for a working example.
You can specify help information for bot or commands with help block, for example:
in case of bot:
class WeatherBot < SlackRubyBot::Bot
help do
title 'Weather Bot'
desc 'This bot tells you the weather.'
command 'clouds' do
desc 'Tells you how many clouds there\'re above you.'
end
command 'What\'s the weather in <city>?' do
desc 'Tells you the weather in a <city>.'
long_desc "Accurate 10 Day Weather Forecasts for thousands of places around the World.\n" \
'Bot provides detailed Weather Forecasts over a 10 day period updated four times a day.'
end
end
# commands implementation
endin case of your own command:
class Deploy < SlackRubyBot::Commands::Base
help do
title 'deploy'
desc 'deploys your app'
long_desc 'command format: *deploy <branch> to <env>* where <env> is production or staging'
end
endThe SlackRubyBot::Bot class is DSL sugar deriving from SlackRubyBot::Commands::Base. For more involved bots you can organize the bot implementation into subclasses of SlackRubyBot::Commands::Base manually. By default a command class responds, case-insensitively, to its name. A class called Phone that inherits from SlackRubyBot::Commands::Base responds to phone and Phone and calls the call method when implemented.
class Phone < SlackRubyBot::Commands::Base
command 'call'
def self.call(client, data, match)
client.say(channel: data.channel, text: 'called')
end
endTo respond to custom commands and to disable automatic class name matching, use the command keyword. The following command responds to call and 呼び出し (call in Japanese).
class Phone < SlackRubyBot::Commands::Base
command 'call'
command '呼び出し'
def self.call(client, data, match)
client.say(channel: data.channel, text: 'called')
end
endThe SlackRubyBot::Client implementation comes with GIF support.
Sends text and/or a random GIF that matches a keyword using a RealTime client to a channel.
Slack-ruby-bot comes with several built-in commands. You can re-define built-in commands, normally, as described above.
This is also known as the default command. Shows bot version and links.
Politely says 'hi' back.
Get help.
Hooks are event handlers and respond to Slack RTM API events, such as hello or message. You can implement your own in a couple of ways:
A Hook Handler is any object that respond to a call message, like a proc, instance of an object, class with a call class method, etc.
Hooks are registered onto the SlackRubyBot::Server instance, by way of a configuration hash
SlackRubyBot::Server.new(hook_handlers: {
hello: MyBot::Hooks::UserChange.new
})or at any time by pushing it to the HookSet
# Push an object that implements the
server.hooks.add(:hello, MyBot::Hooks::UserChange.new)
# Push a lambda to handle the event
server.hooks.add(:hello, ->(client, data) { puts "Hello!" })For example, the following hook handles user_change, an event sent when a team member updates their profile or data. This can be useful to update the local user cache when a user is renamed.
module MyBot
module Hooks
class UserChange
def call(client, data)
# data['user']['id'] contains the user ID
# data['user']['name'] contains the new user name
...
end
end
end
endHooks can also be written as blocks inside the SlackBotRuby::Server class, for example
module MyBot
class MyServer < SlackRubyBot::Server
on 'hello' do |client, data|
# data['user']['id'] contains the user ID
# data['user']['name'] contains the new user name
end
end
endThese will get pushed into the hook set on initialization.
Either by configuration, explicit assignment or hook blocks, multiple handlers can exist for the same event type.
By default bots send animated GIFs in default commands and errors. To disable animated GIFs set send_gifs or ENV['SLACK_RUBY_BOT_SEND_GIFS'] to false.
SlackRubyBot.configure do |config|
config.send_gifs = false
endBy default bots do not respond to their own messages. If you wish to change that behavior, set allow_message_loops to true.
SlackRubyBot.configure do |config|
config.allow_message_loops = true
endBy default bots set a logger to STDOUT with DEBUG level. The logger is used in both the RealTime and Web clients. Silence logger as follows.
SlackRubyBot::Client.logger.level = Logger::WARNYou may want to integrate a bot or multiple bots into other systems, in which case a globally configured bot may not work for you. You may create instances of SlackRubyBot::Server which accepts token, aliases and send_gifs.
EM.run do
bot1 = SlackRubyBot::Server.new(token: token1, aliases: ['bot1'])
bot1.start_async
bot2 = SlackRubyBot::Server.new(token: token2, send_gifs: false, aliases: ['bot2'])
bot2.start_async
endFor an example of advanced integration that supports multiple teams, see slack-gamebot and playplay.io that is built on top of it.
Slack-ruby-bot ships with a number of shared RSpec behaviors that can be used in your RSpec tests. Require 'slack-ruby-bot/rspec' in your spec_helper.rb.
- behaves like a slack bot: A bot quacks like a Slack Ruby bot.
- respond with slack message: The bot responds with a message.
- respond with error: An exception is raised inside a bot command.
- newrelic-slack-ruby-bot: NewRelic instrumentation for slack-ruby-bot.
See CONTRIBUTING.
See CHANGELOG for a history of changes and UPGRADING for how to upgrade to more recent versions.
Copyright (c) 2015-2016, Daniel Doubrovkine, Artsy and Contributors.
This project is licensed under the MIT License.






