module Boty class Bot include Boty::Logger attr_reader :id, :name def initialize(bot_info, session) @raw_info, @id, @name = bot_info, bot_info["id"], bot_info["name"] @events = {} load_default_scripts on :message, &method(:message_handler) end def event(data) return unless type = event_type(data) @events[type].each do |action| action.call data end end def on(event_type, &block) @events[event_type.to_sym] ||= [] @events[event_type.to_sym] << block end def message(regex, &block) @handlers ||= [] @handlers << create_action(regex, &block) end def respond(regex, &block) @commands ||= [] @commands << create_action(regex, &block) end def say(message, api_parameters = {}) channel = (@_message && @_message.channel) || "general" options = { channel: channel }.merge api_parameters post_response = Slack.chat.post_message message, options logger.debug { "post response: #{post_response}" } end def desc(command, description = nil) @current_desc = { command: command, description: description } end def know_how descriptions = (Array(@commands) + Array(@handlers)).compact.map(&:desc) descriptions.inject({}) { |hsh, desc| hsh.merge!(desc.command => desc.description) } end def im(message) logger.debug { "sending im messge to #{@_message.user.name}" } Slack.chat.post_im @_message.user.id, message end def brain @brain ||= {} end private def scripts_to_load default_scripts_path = File.expand_path("../../../script", __FILE__) paths = Dir["script/**/*.rb"] + Dir["#{default_scripts_path}/**/*.rb"] paths.map { |file| File.expand_path file }.uniq end def load_default_scripts scripts_to_load.each do |file| instance_eval File.read(file), file, 1 end end def event_type(data) type = data["type"].to_sym logger.debug { "bot specifc event[#{type}] arrived: #{data}" } unless @events[type] logger.debug "no action binded to #{type}" return end type end def create_action(regex, &block) Boty::Action.new(regex, @current_desc, &block).tap { @current_desc = nil } end def message_from_bot_itself?(data) data["user"] == self.id || data["user"] == self.name end def has_valid_mention?(data) return false if message_from_bot_itself? data !!(/(<@#{id}|#{name}>)/ =~ data["text"]) end def execute_command(command, message) @_message = message instance_exec @_message, &command.action @_message = nil end def message_handler(data) actions = has_valid_mention?(data) ? @commands : @handlers Array(actions).each do |command| next unless match = command.regex.match(data["text"]) #command.execute(self, match) #=> or something like that... execute_command command, Message.new(data, match: match) end end end end