Class: SlackBotServer::Bot
- Inherits:
-
Object
- Object
- SlackBotServer::Bot
- Extended by:
- Logging
- Includes:
- Logging
- Defined in:
- lib/slack_bot_server/bot.rb
Overview
A superclass for integration bot implementations.
A simple example:
class MyBot < SlackBotServer::Bot
# Set the friendly username displayed in Slack
username 'My Bot'
# Set the image to use as an avatar icon in Slack
icon_url 'http://my.server.example.com/assets/icon.png'
# Respond to mentions in the connected chat room (defaults to #general).
# As well as the normal data provided by Slack's API, we add the `message`,
# which is the `text` parameter with the username stripped out. For example,
# When a user sends 'simple_bot: how are you?', the `message` data contains
# only 'how are you'.
on_mention do |data|
if data['message'] == 'who are you'
reply text: "I am #{bot_user_name} (user id: #{bot_user_id}, connected to team #{team_name} with team id #{team_id}"
else
reply text: "You said '#{data['message']}', and I'm frankly fascinated."
end
end
# Respond to messages sent via IM communication directly with the bot.
on_im do
reply text: "Hmm, OK, let me get back to you about that."
end
end
Direct Known Subclasses
Defined Under Namespace
Classes: ConnectionError
Constant Summary collapse
- SLACKBOT_USER_ID =
The user ID of the special slack user
SlackBot 'USLACKBOT'
Class Attribute Summary collapse
-
.mention_keywords ⇒ Object
readonly
Returns the value of attribute mention_keywords.
Instance Attribute Summary collapse
-
#key ⇒ Object
readonly
Returns the value of attribute key.
-
#token ⇒ Object
readonly
Returns the value of attribute token.
Class Method Summary collapse
-
.callbacks ⇒ Object
All callbacks defined on this class.
-
.callbacks_for(type) ⇒ Object
Returns all callbacks (including those in superclasses) for a given event type.
-
.default_message_options ⇒ Object
Holds default options to send with each message to Slack.
-
.icon_url(url) ⇒ Object
Sets the image to use as an avatar for this bot.
- .low_level_callbacks ⇒ Object
-
.mention_as(*keywords) ⇒ Object
Sets the keywords in messages that will trigger the
on_mentioncallback. -
.on(type, &block) ⇒ Object
Register a callback.
-
.on_im(&block) ⇒ Object
Define a callback to run when any a user sends a direct message to this bot.
-
.on_mention(&block) ⇒ Object
Define a callback to run when any of the mention keywords are present in a message.
-
.on_slack_event(name, &block) ⇒ Object
Define a callback to use when a low-level slack event is fired.
-
.username(name) ⇒ Object
Sets the username this bot should use.
Instance Method Summary collapse
-
#bot_user_id ⇒ Object
Returns the ID of the bot user we are connected as, e.g.
-
#bot_user_name ⇒ Object
Returns the username (for @ replying) of the bot user we are connected as, e.g.
-
#broadcast(options) ⇒ Object
Sends a message to every channel this bot is a member of.
-
#call(method, args) ⇒ Object
Call a method directly on the Slack web API (via Slack::Web::Client).
-
#connected? ⇒ Boolean
Returns
trueif this bot is currently connected to Slack. -
#initialize(token:, key: nil) ⇒ Bot
constructor
Create a new bot.
-
#reply(options) ⇒ Object
Sends a reply to the same channel as the last message that was received by this bot.
-
#running? ⇒ Boolean
Returns
trueif this bot is (or should be) running. -
#say(options) ⇒ Object
Send a message to Slack.
-
#say_to(user_id, options) ⇒ Object
Sends a message via IM to a user.
-
#start ⇒ Object
Starts the bot running.
-
#stop ⇒ Object
Stops the bot from running.
-
#team_id ⇒ Object
Returns the ID of the team we are connected to, e.g.
-
#team_name ⇒ Object
Returns the name of the team we are connected to, e.g.
-
#to_s ⇒ Object
Returns a String representation of this Bot.
-
#typing(options = {}) ⇒ Object
Sends a typing notification.
Methods included from Logging
debug, log, log_error, log_string
Constructor Details
#initialize(token:, key: nil) ⇒ Bot
Create a new bot. This is normally called from within the block passed to Server#on_add, which should return a new bot instance.
54 55 56 57 58 59 |
# File 'lib/slack_bot_server/bot.rb', line 54 def initialize(token:, key: nil) @token = token @key = key || @token @connected = false @running = false end |
Class Attribute Details
.mention_keywords ⇒ Object (readonly)
Returns the value of attribute mention_keywords.
205 206 207 |
# File 'lib/slack_bot_server/bot.rb', line 205 def mention_keywords @mention_keywords end |
Instance Attribute Details
#key ⇒ Object (readonly)
Returns the value of attribute key.
41 42 43 |
# File 'lib/slack_bot_server/bot.rb', line 41 def key @key end |
#token ⇒ Object (readonly)
Returns the value of attribute token.
41 42 43 |
# File 'lib/slack_bot_server/bot.rb', line 41 def token @token end |
Class Method Details
.callbacks ⇒ Object
All callbacks defined on this class
261 262 263 |
# File 'lib/slack_bot_server/bot.rb', line 261 def callbacks @callbacks ||= {} end |
.callbacks_for(type) ⇒ Object
Returns all callbacks (including those in superclasses) for a given event type
267 268 269 270 271 272 273 274 275 |
# File 'lib/slack_bot_server/bot.rb', line 267 def callbacks_for(type) if superclass.respond_to?(:callbacks_for) matching_callbacks = superclass.callbacks_for(type) else matching_callbacks = [] end matching_callbacks += callbacks[type.to_sym] if callbacks[type.to_sym] matching_callbacks end |
.default_message_options ⇒ Object
Holds default options to send with each message to Slack
256 257 258 |
# File 'lib/slack_bot_server/bot.rb', line 256 def @default_message_options ||= {type: 'message'} end |
.icon_url(url) ⇒ Object
Sets the image to use as an avatar for this bot
class MyBot < SlackBotServer::Bot
icon_url 'http://example.com/bot.png'
# etc
end
228 229 230 |
# File 'lib/slack_bot_server/bot.rb', line 228 def icon_url(url) [:icon_url] = url end |
.low_level_callbacks ⇒ Object
337 338 339 |
# File 'lib/slack_bot_server/bot.rb', line 337 def low_level_callbacks @low_level_callbacks ||= [] end |
.mention_as(*keywords) ⇒ Object
Sets the keywords in messages that will trigger the on_mention callback
class MyBot < SlackBotServer::Bot
mention_as 'hey', 'bot'
# etc
end
will mean the on_mention callback fires for messages like “hey you!” and “bot, what are you thinking”.
Mention keywords are only matched at the start of messages, so the text “I love you, bot” won’t trigger this callback. To implement general keyword spotting, use a custom on :message callback.
If this is not called, the default mention keyword is the bot username, e.g. simple_bot
251 252 253 |
# File 'lib/slack_bot_server/bot.rb', line 251 def mention_as(*keywords) @mention_keywords = keywords end |
.on(type, &block) ⇒ Object
Register a callback
class MyBot < SlackBotServer::Bot
on :message do
reply text: 'I heard a message, so now I am responding!'
end
end
Possible callbacks are:
+:start+ :: fires when the bot establishes a connection to Slack
+:finish+ :: fires when the bot is disconnected from Slack
+:message+ :: fires when any message is sent in any channel the bot is
connected to
Multiple blocks for each type can be registered; they will be run in the order they are defined.
If any block returns false, later blocks will not be fired.
295 296 297 298 |
# File 'lib/slack_bot_server/bot.rb', line 295 def on(type, &block) callbacks[type.to_sym] ||= [] callbacks[type.to_sym] << block end |
.on_im(&block) ⇒ Object
Define a callback to run when any a user sends a direct message to this bot
327 328 329 330 331 332 333 334 335 |
# File 'lib/slack_bot_server/bot.rb', line 327 def on_im(&block) on(:message) do |data| debug on_im: data, bot_message: (data), is_im_channel: is_im_channel?(data.channel) if !(data) && is_im_channel?(data.channel) @last_received_user_message.merge!(message: data.text) instance_exec(@last_received_user_message, &block) end end end |
.on_mention(&block) ⇒ Object
Define a callback to run when any of the mention keywords are present in a message.
Typically this will be for messages in open channels, where as user directs a message to this bot, e.g. “@simple_bot hello”
By default, the mention keyword is simply the bot’s username e.g. simple_bot
As well as the raw Slack data about the message, the data Hash yielded to the given block will contain a ‘message’ key, which holds the text sent with the keyword removed.
312 313 314 315 316 317 318 319 320 321 322 323 |
# File 'lib/slack_bot_server/bot.rb', line 312 def on_mention(&block) on(:message) do |data| debug on_message: data, bot_message: (data) if !(data) && (data.text =~ /\A(#{mention_keywords.join('|')})[\s\:](.*)/i || data.text =~ /\A(<@#{bot_user_id}>)[\s\:](.*)/) = $2.strip @last_received_user_message.merge!(message: ) instance_exec(@last_received_user_message, &block) end end end |
.on_slack_event(name, &block) ⇒ Object
Define a callback to use when a low-level slack event is fired
342 343 344 |
# File 'lib/slack_bot_server/bot.rb', line 342 def on_slack_event(name, &block) self.low_level_callbacks << [name, block] end |
.username(name) ⇒ Object
Sets the username this bot should use
class MyBot < SlackBotServer::Bot
username 'My Bot'
# etc
end
will result in the friendly name ‘My Bot’ appearing beside the messages in your Slack rooms
217 218 219 |
# File 'lib/slack_bot_server/bot.rb', line 217 def username(name) [:username] = name end |
Instance Method Details
#bot_user_id ⇒ Object
Returns the ID of the bot user we are connected as, e.g. ‘U123456’
68 69 70 |
# File 'lib/slack_bot_server/bot.rb', line 68 def bot_user_id client.self.id end |
#bot_user_name ⇒ Object
Returns the username (for @ replying) of the bot user we are connected as, e.g. ‘simple_bot’
63 64 65 |
# File 'lib/slack_bot_server/bot.rb', line 63 def bot_user_name client.self.name end |
#broadcast(options) ⇒ Object
Sends a message to every channel this bot is a member of
106 107 108 109 110 |
# File 'lib/slack_bot_server/bot.rb', line 106 def broadcast() client.channels.each do |id, _| say(.merge(channel: id)) end end |
#call(method, args) ⇒ Object
Call a method directly on the Slack web API (via Slack::Web::Client). Useful for debugging only.
142 143 144 145 |
# File 'lib/slack_bot_server/bot.rb', line 142 def call(method, args) args.symbolize_keys! client.web_client.send(method, args) end |
#connected? ⇒ Boolean
Returns true if this bot is currently connected to Slack
200 201 202 |
# File 'lib/slack_bot_server/bot.rb', line 200 def connected? @connected end |
#reply(options) ⇒ Object
Sends a reply to the same channel as the last message that was received by this bot.
116 117 118 119 |
# File 'lib/slack_bot_server/bot.rb', line 116 def reply() channel = @last_received_user_message.channel say(.merge(channel: channel)) end |
#running? ⇒ Boolean
Returns true if this bot is (or should be) running
195 196 197 |
# File 'lib/slack_bot_server/bot.rb', line 195 def running? @running end |
#say(options) ⇒ Object
Send a message to Slack
91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/slack_bot_server/bot.rb', line 91 def say() = symbolize_keys(.merge()) if () debug "Sending via Web API", client.web_client.chat_postMessage() else debug "Sending via RTM API", client.() end end |
#say_to(user_id, options) ⇒ Object
Sends a message via IM to a user
125 126 127 128 129 |
# File 'lib/slack_bot_server/bot.rb', line 125 def say_to(user_id, ) result = client.web_client.im_open(user: user_id) channel = result.channel.id say(.merge(channel: channel)) end |
#start ⇒ Object
Starts the bot running. You should not call this method; instead, the server will call it when it is ready for the bot to connect
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/slack_bot_server/bot.rb', line 151 def start @client = ::Slack::RealTime::Client.new(token: @token) @running = true client.on :open do |event| @connected = true log "connected to '#{team_name}'" run_callbacks(:start) end client.on :message do |data| begin debug message: data @last_received_user_message = data if (data) (data) rescue => e log_error e end end client.on :close do |event| log "disconnected" @connected = false run_callbacks(:finish) end register_low_level_callbacks client.start_async rescue Slack::Web::Api::Error => e raise ConnectionError.new(e., e.response) end |
#stop ⇒ Object
Stops the bot from running. You should not call this method; instead send the server a remote_bot message
187 188 189 190 191 192 |
# File 'lib/slack_bot_server/bot.rb', line 187 def stop log "closing connection" @running = false client.stop! log "closed" end |
#team_id ⇒ Object
Returns the ID of the team we are connected to, e.g. ‘T234567’
78 79 80 |
# File 'lib/slack_bot_server/bot.rb', line 78 def team_id client.team.id end |
#team_name ⇒ Object
Returns the name of the team we are connected to, e.g. ‘My Team’
73 74 75 |
# File 'lib/slack_bot_server/bot.rb', line 73 def team_name client.team.name end |
#to_s ⇒ Object
Returns a String representation of this SlackBotServer::Bot
353 354 355 |
# File 'lib/slack_bot_server/bot.rb', line 353 def to_s "<#{self.class.name} key:#{key}>" end |
#typing(options = {}) ⇒ Object
Sends a typing notification
134 135 136 137 138 |
# File 'lib/slack_bot_server/bot.rb', line 134 def typing(={}) last_received_channel = @last_received_user_message ? @last_received_user_message.channel : nil = {channel: last_received_channel} client.typing(.merge()) end |