lib/slack-ruby-bot/commands/base.rb in slack-ruby-bot-0.10.5 vs lib/slack-ruby-bot/commands/base.rb in slack-ruby-bot-0.11.0
- old
+ new
@@ -1,10 +1,12 @@
+require_relative 'support/match'
+require_relative 'support/help'
+
module SlackRubyBot
module Commands
class Base
include Loggable
- class_attribute :routes
class << self
attr_accessor :command_classes
def inherited(subclass)
@@ -30,11 +32,11 @@
logger.warn '[DEPRECATION] `send_gif` is deprecated. Please use `client.say` instead.'
client.say(options.merge(channel: channel, text: '', gif: keywords))
end
def help(&block)
- CommandsHelper.instance.capture_help(self, &block)
+ Support::Help.instance.capture_help(self, &block)
end
def command_name_from_class
name ? name.split(':').last.downcase : object_id.to_s
end
@@ -44,49 +46,68 @@
match Regexp.new("^(?<operator>#{values})(?<expression>.*)$", Regexp::IGNORECASE), &block
end
def command(*values, &block)
values = values.map { |value| value.is_a?(Regexp) ? value.source : Regexp.escape(value) }.join('|')
- match Regexp.new("^#{bot_matcher}[\\s]+(?<command>#{values})([\\s]+(?<expression>.*)|)$", Regexp::IGNORECASE), &block
+ match Regexp.new("^#{bot_matcher}[\\s]+(?<command>#{values})([\\s]+(?<expression>.*)|)$", Regexp::IGNORECASE | Regexp::MULTILINE), &block
end
def invoke(client, data)
finalize_routes!
expression, text = parse(client, data)
- return false unless expression
+ return false unless expression || data.attachments
routes.each_pair do |route, options|
match_method = options[:match_method]
case match_method
when :match
+ next unless expression
match = route.match(expression)
match ||= route.match(text) if text
next unless match
next if match.names.include?('bot') && !client.name?(match['bot'])
+ match = Support::Match.new(match)
when :scan
+ next unless expression
match = expression.scan(route)
next unless match.any?
+ when :attachment
+ next unless data.attachments && !data.attachments.empty?
+ match, attachment, field = match_attachments(data, route, options[:fields_to_scan])
+ next unless match
+ match = Support::Match.new(match, attachment, field)
end
call_command(client, data, match, options[:block])
return true
end
false
end
def match(match, &block)
- self.routes ||= ActiveSupport::OrderedHash.new
- self.routes[match] = { match_method: :match, block: block }
+ routes[match] = { match_method: :match, block: block }
end
def scan(match, &block)
- self.routes ||= ActiveSupport::OrderedHash.new
- self.routes[match] = { match_method: :scan, block: block }
+ routes[match] = { match_method: :scan, block: block }
end
+ def attachment(match, fields_to_scan = nil, &block)
+ fields_to_scan = [fields_to_scan] unless fields_to_scan.nil? || fields_to_scan.is_a?(Array)
+ routes[match] = {
+ match_method: :attachment,
+ block: block,
+ fields_to_scan: fields_to_scan
+ }
+ end
+
def bot_matcher
'(?<bot>\S*)'
end
+ def routes
+ @routes ||= ActiveSupport::OrderedHash.new
+ end
+
private
def call_command(client, data, match, block)
if block
block.call(client, data, match) if permitted?(client, data, match)
@@ -118,9 +139,21 @@
end
def finalize_routes!
return if routes && routes.any?
command command_name_from_class
+ end
+
+ def match_attachments(data, route, fields_to_scan = nil)
+ fields_to_scan ||= %i[pretext text title]
+ data.attachments.each do |attachment|
+ fields_to_scan.each do |field|
+ next unless attachment[field]
+ match = route.match(attachment[field])
+ return match, attachment, field if match
+ end
+ end
+ false
end
# Intended to be overridden by subclasses to hook in an
# authorization mechanism.
def permitted?(_client, _data, _match)