Class: Slackbotsy::Bot
- Inherits:
-
Object
- Object
- Slackbotsy::Bot
- Defined in:
- lib/slackbotsy/bot.rb
Instance Attribute Summary collapse
-
#api ⇒ Object
Returns the value of attribute api.
-
#last_description ⇒ Object
Returns the value of attribute last_description.
-
#listeners ⇒ Object
Returns the value of attribute listeners.
Instance Method Summary collapse
-
#attach(ary, options = {}) ⇒ Object
simple wrapper on post to send attachment(s).
-
#desc(command, description = nil) ⇒ Object
record a description of the next hear block, for use in help.
-
#eval_scripts(*files) ⇒ Object
pass list of files containing hear statements, to be opened and evaled.
-
#get_responses(msg, text) ⇒ Object
run on msg all hear blocks matching text.
-
#handle_item(msg) ⇒ Object
alias for backward compatibility.
-
#handle_outgoing_webhook(msg) ⇒ Object
check message and run blocks for any matches.
- #handle_slash_command(msg) ⇒ Object
-
#hear(regex, &block) ⇒ Object
add regex to things to hear.
-
#initialize(options, &block) ⇒ Bot
constructor
A new instance of Bot.
-
#parse_outgoing_tokens(tokens) ⇒ Object
use set of tokens for (more or less) O(1) lookup on multiple channels.
-
#post(options) ⇒ Object
raw post of hash to slack webhook.
-
#post_message(text, options = {}) ⇒ Object
simple wrapper on api.post_message (which calls chat.postMessage).
-
#say(text, options = {}) ⇒ Object
simple wrapper on post to send text.
-
#setup_incoming_webhook ⇒ Object
setup http connection for sending async incoming webhook messages to slack.
-
#setup_web_api ⇒ Object
use api_token to setup Web API authentication.
-
#upload(options) ⇒ Object
simple wrapper on api.upload (which calls files.upload) pass ‘channel’ as a csv list of channel names, otherwise same args as files.upload.
-
#users ⇒ Object
simple wrapper on api.users (which calls users.list).
Constructor Details
#initialize(options, &block) ⇒ Bot
Returns a new instance of Bot.
12 13 14 15 16 17 18 19 |
# File 'lib/slackbotsy/bot.rb', line 12 def initialize(, &block) = @listeners = [] ['outgoing_token'] = parse_outgoing_tokens(['outgoing_token']) setup_incoming_webhook # http connection for async replies setup_web_api # setup slack Web API instance_eval(&block) if block_given? # run any hear statements in block end |
Instance Attribute Details
#api ⇒ Object
Returns the value of attribute api.
10 11 12 |
# File 'lib/slackbotsy/bot.rb', line 10 def api @api end |
#last_description ⇒ Object
Returns the value of attribute last_description.
10 11 12 |
# File 'lib/slackbotsy/bot.rb', line 10 def last_description @last_description end |
#listeners ⇒ Object
Returns the value of attribute listeners.
10 11 12 |
# File 'lib/slackbotsy/bot.rb', line 10 def listeners @listeners end |
Instance Method Details
#attach(ary, options = {}) ⇒ Object
simple wrapper on post to send attachment(s)
69 70 71 72 |
# File 'lib/slackbotsy/bot.rb', line 69 def attach(ary, = {}) = ary.is_a?(Array) ? ary : [ ary ] #force first arg to array post({ attachments: }.merge()) end |
#desc(command, description = nil) ⇒ Object
record a description of the next hear block, for use in help
110 111 112 |
# File 'lib/slackbotsy/bot.rb', line 110 def desc(command, description = nil) @last_desc = [ command, description ] end |
#eval_scripts(*files) ⇒ Object
pass list of files containing hear statements, to be opened and evaled
121 122 123 124 125 |
# File 'lib/slackbotsy/bot.rb', line 121 def eval_scripts(*files) files.flatten.each do |file| self.instance_eval(File.open(file).read) end end |
#get_responses(msg, text) ⇒ Object
run on msg all hear blocks matching text
156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/slackbotsy/bot.rb', line 156 def get_responses(msg, text) = Slackbotsy::Message.new(self, msg) @listeners.map do |listener| text.match(listener.regex) do |mdata| begin .instance_exec(mdata, *mdata[1..-1], &listener.proc) rescue => err # keep running even with a broken script, but report the error err end end end end |
#handle_item(msg) ⇒ Object
alias for backward compatibility
141 142 143 |
# File 'lib/slackbotsy/bot.rb', line 141 def handle_item(msg) handle_outgoing_webhook(msg) end |
#handle_outgoing_webhook(msg) ⇒ Object
check message and run blocks for any matches
128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/slackbotsy/bot.rb', line 128 def handle_outgoing_webhook(msg) return nil unless ['outgoing_token'].include?(msg[:token]) # ensure messages are for us from slack return nil if msg[:user_name] == 'slackbot' # do not reply to self return nil unless msg[:text].is_a?(String) # skip empty messages responses = get_responses(msg, msg[:text].strip) if responses { text: responses.compact.join("\n") }.to_json # webhook responses are json end end |
#handle_slash_command(msg) ⇒ Object
145 146 147 148 149 150 151 152 153 |
# File 'lib/slackbotsy/bot.rb', line 145 def handle_slash_command(msg) return nil unless ['slash_token'].include?(msg[:token]) responses = get_responses(msg, "#{msg[:command]} #{msg[:text]}".strip) if responses responses.join("\n") # plain text responses end end |
#hear(regex, &block) ⇒ Object
add regex to things to hear
115 116 117 118 |
# File 'lib/slackbotsy/bot.rb', line 115 def hear(regex, &block) @listeners << OpenStruct.new(regex: regex, desc: @last_desc, proc: block) @last_desc = nil end |
#parse_outgoing_tokens(tokens) ⇒ Object
use set of tokens for (more or less) O(1) lookup on multiple channels
22 23 24 25 26 27 28 29 30 31 |
# File 'lib/slackbotsy/bot.rb', line 22 def parse_outgoing_tokens(tokens) case tokens when NilClass [] when String tokens.split(/[,\s]+/) when Array tokens end.to_set end |
#post(options) ⇒ Object
raw post of hash to slack webhook
51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/slackbotsy/bot.rb', line 51 def post() payload = { username: ['name'], channel: ['channel'] }.merge() payload[:channel] = payload[:channel].gsub(/^#?/, '#') #slack api needs leading # on channel request = Net::HTTP::Post.new(@uri.request_uri) request.set_form_data(payload: payload.to_json) @http.request(request) return nil # so as not to trigger text in outgoing webhook reply end |
#post_message(text, options = {}) ⇒ Object
simple wrapper on api.post_message (which calls chat.postMessage)
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/slackbotsy/bot.rb', line 75 def (text, = {}) payload = { username: ['name'], channel: ['channel'], text: text, as_user: true }.merge() unless (payload[:channel]) payload[:channel] = enforce_leading_hash(payload[:channel]) @api.join(payload[:channel]) end @api.(payload) return nil # be quiet in webhook reply end |
#say(text, options = {}) ⇒ Object
simple wrapper on post to send text
64 65 66 |
# File 'lib/slackbotsy/bot.rb', line 64 def say(text, = {}) post({ text: text }.merge()) end |
#setup_incoming_webhook ⇒ Object
setup http connection for sending async incoming webhook messages to slack
34 35 36 37 38 39 40 41 |
# File 'lib/slackbotsy/bot.rb', line 34 def setup_incoming_webhook ## incoming_webhook will be used if provided, otherwise fallback to old-style url with team and token url = .fetch('incoming_webhook', false) || "https://#{@options['team']}.slack.com/services/hooks/incoming-webhook?token=#{@options['incoming_token']}" @uri = URI.parse(url) @http = Net::HTTP.new(@uri.host, @uri.port) @http.use_ssl = true @http.verify_mode = OpenSSL::SSL::VERIFY_PEER end |
#setup_web_api ⇒ Object
use api_token to setup Web API authentication
44 45 46 47 48 |
# File 'lib/slackbotsy/bot.rb', line 44 def setup_web_api if ['api_token'] @api = Api.new(['api_token']) end end |
#upload(options) ⇒ Object
simple wrapper on api.upload (which calls files.upload) pass ‘channel’ as a csv list of channel names, otherwise same args as files.upload
94 95 96 97 98 99 100 101 102 |
# File 'lib/slackbotsy/bot.rb', line 94 def upload() payload = channels = @api.channels # list of channel objects payload[:channels] ||= (.fetch(:channel, ['channel'])).split(/[\s,]+/).map do |name| channels.find { |c| name.match(/^#?#{c['name']}$/) }.fetch('id') # convert channel id to name end.join(',') @api.upload(payload) return nil # be quiet in webhook reply end |
#users ⇒ Object
simple wrapper on api.users (which calls users.list)
105 106 107 |
# File 'lib/slackbotsy/bot.rb', line 105 def users @api.users end |