class Pepito::Robot
The robot component of the bot.
Attributes
List of running adapters. @return [Hash] A map of adapter’s keys to classes.
Redis connection @return [Pepito::Database]
Default adapters that can’t be turned off @return [Array<String>]
Default handlers that can’t be turned off @return [Array<String>]
List of running handlers. @return [Hash] A map of handler’s keys to classes.
The running http_api. @return [Pepito::HTTPApi::RackApp]
The Puma::Server running the HTTP API @return [Puma::Server]
The thread running the HTTP API. @return [Thread]
Logger @return [Logger]
Name of the bot. @return [String]
The web app. @return [Pepito::WebApp::App]
The Puma::Server running the Web App @return [Puma::Server]
The thread running the web app. @return [Thread]
Public Class Methods
@return [void]
# File lib/pepito/robot.rb, line 79 def initialize @logger = Logger.new(ENV['LOG_FILE'] || STDOUT) @logger.info('Connecting to the database') @database = Database.new @http_api = HTTPApi::RackApp.new @web_app = WebApp::App @default_handlers = %w(Info Help Room ExtensionsCatalog Queenbee) @handlers = {} @default_adapters = [] @adapters = {} @name = @database.get('name') || 'pepito' end
Public Instance Methods
Checks if an adapter is running or not. @param adapter [String] Name of the adapter. @return [Boolean]
# File lib/pepito/robot.rb, line 323 def adapter?(adapter) @adapters.key?(adapter) end
Retrieve the list of possible adapters to install from server @return [Array<String>]
# File lib/pepito/robot.rb, line 139 def adapters_list catalog_url = 'https://raw.githubusercontent.com/yafoy/pepito-catalog/master/all.json' response = RestClient.get(catalog_url) integrations = MultiJson.load(response.body, symbolize_keys: true) integrations[:adapters] end
Checks if an handler is running or not. @param handler [String] Name of the handler. @return [Boolean]
# File lib/pepito/robot.rb, line 228 def handler?(handler) @handlers.key?(handler) end
Retrieve the list of possible handlers to install from server @return [Array<String>]
# File lib/pepito/robot.rb, line 130 def handlers_list catalog_url = 'https://raw.githubusercontent.com/yafoy/pepito-catalog/master/all.json' response = RestClient.get(catalog_url) integrations = MultiJson.load(response.body, symbolize_keys: true) integrations[:handlers] end
Helper to receive a message. @param message [Pepito::Message] A message received by an adapter. @return [void]
# File lib/pepito/robot.rb, line 115 def receive_message(message) match = @handlers.dup.map do |_, handler| handler.chat_routes.map do |route| next unless message.match_route?(route) strings = handler.public_send(route.func, message.source, route.pattern.match(message.command || message.body)) message.source.adapter.send_messages(message.source, strings) unless strings.nil? true end.any? end.any? message.source.adapter.send_messages(message.source, ['No match for command "' + message.command + '"']) if !match && message.command end
Runs the robot. @return [void]
# File lib/pepito/robot.rb, line 100 def run run_http_api run_web_app run_handlers run_adapters begin sleep rescue Interrupt @logger.info('Exiting') end end
Starts an adapter. @param adapter [String] Name of the adapter to start. Must match the adapter’s class name. @param gem_name [String] Name of the gem for the adapter @param config [Hash<String,String>] The config for the adapter @return [Integer]
0 - if adapter was started 1 - if adapter is already running 2 - if adapter can't be found 3 - if there are missing methods on the adapter 4 - if there are missing configuration values 5 - other errors
# File lib/pepito/robot.rb, line 243 def start_adapter(adapter, gem_name, config) @logger.info('"' + adapter.to_s + '" adapter starting') if @adapters.key?(adapter) @logger.warn('"' + adapter.to_s + '" adapter already running') return 1 else # Installing gem begin gem_load gem_name rescue => e @logger.error(e) return 2 end begin adp = Pepito::Adapters.const_get(adapter).new(self, config) rescue NameError => e @logger.error('"' + adapter.to_s + '" adapter could not be found') @logger.error(e) return 2 rescue Pepito::Errors::RequiredMethodsError => e @logger.error('"' + adapter.to_s + '" adapter failed to start. ' + e.message + ': ' + e.missing_methods.to_s) return 3 rescue Pepito::Errors::MissingConfigurationValueError => e @logger.error('"' + adapter.to_s + '" adapter failed to start. ' + e.message + ': ' + e.configuration_values.to_s) return 4 rescue => e @logger.error('"' + adapter.to_s + '" adapter failed to start. Error: ' + e.message.to_s) @logger.error(e) return 5 end # If it didnt fail, spawn adapter thread @adapters[adapter] = adp @database.sadd('adapters', adapter) # Clear old config in database @database.del(adapter) # Set gem name in database @database.set(adapter + ':gem', gem_name) # Setup new config in database config.each do |key, value| @database.hset(adapter + ':config', key, value) end Thread.new do adp.run end @logger.info('"' + adapter.to_s + '" adapter started successfully') return 0 end end
Starts an handler. @param handler [String] Name of the handler to start. @return [Integer]
0 - If success 1 - If failed because handler is already running 2 - If handler can't be found 3 - If handler is missing configuration values 4 - Other errors
# File lib/pepito/robot.rb, line 154 def start_handler(handler, gem_name, config) @logger.info('"' + handler.to_s + '" handler starting') if @handlers.key?(handler) @logger.warn('"' + handler.to_s + '" handler is already running') return 1 else # Installing gem begin gem_load gem_name rescue => e @logger.error(e) return 2 end begin @handlers[handler] = Handlers.const_get(handler).new(self, config) rescue NameError @logger.error('"' + handler.to_s + '" handler does not exist') return 2 rescue Pepito::Errors::MissingConfigurationValueError => e @logger.error('"' + handler.to_s + '" handler failed to start. ' + e.message + ': ' + e.configuration_values.to_s) return 3 rescue => e @logger.error('"' + handler.to_s + '" handler failed to start. Error: ' + e.message.to_s) @logger.error(e) return 4 end @http_api.router.uncompile @handlers[handler].run @handlers[handler].start @database.sadd('handlers', handler) @database.set(handler + ':gem', gem_name) # Setup new config in database config.each do |key, value| @database.hset(handler + ':config', key, value) end @logger.info('"' + handler.to_s + '" handler started successfully') return 0 end end
Stops an adapter. @param adapter [String] Name of the adapter to stop. Must match the adapter’s class name. @return [Integer]
0 - If successful 1 - If adapter is default 2 - If adapter is not running
# File lib/pepito/robot.rb, line 302 def stop_adapter(adapter) if @default_adapters.include?(adapter) @logger.error('Can\'t stop "' + adapter.to_s + '" adapter because it is a default adapter') return 1 elsif !@adapters.key?(adapter) @logger.warn('"' + adapter.to_s + '" adapter is not running') return 2 else @adapters[adapter].stop @adapters.delete(adapter) @database.del(adapter + ':config') @database.del(adapter + ':gem') @database.srem('adapters', adapter) @logger.info('"' + adapter.to_s + '" adapter stopped successfully') return 0 end end
Stops an handler. @param handler [String] Name of the handler to stop. Must match the handler’s class name. @return [Integer]
0 - If handler stopped 1 - If it is a default handler 2 - If it is not running
# File lib/pepito/robot.rb, line 203 def stop_handler(handler) @logger.info('Stopping "' + handler.to_s + '" handler') if @default_handlers.include?(handler) @logger.error('Can\'t stop "' + handler.to_s + '" because it is a default handler') return 1 elsif !@handlers.key?(handler) @logger.warn('"' + handler.to_s + '" handler is not running') return 2 else @handlers.delete(handler) @database.srem('handlers', handler) @database.del(handler + ':config') @database.del(handler + ':gem') @http_api.router.reset! @handlers.each do |_, h| h.start end @logger.info('"' + handler.to_s + '" handler stopped successfully') return 0 end end
Private Instance Methods
Runs the adapters saved in the database @return [void]
# File lib/pepito/robot.rb, line 373 def run_adapters @logger.info('Starting the adapters') @default_adapters.each do |adapter, gem_name, configs| start_adapter(adapter, gem_name, configs) end @database.smembers('adapters').each do |adapter| start_adapter(adapter, @database.get(adapter + ':gem'), @database.hgetall(adapter + ':config')) unless @default_adapters.include?(adapter) end end
Runs the handlers saved in the database @return [void]
# File lib/pepito/robot.rb, line 360 def run_handlers @logger.info('Starting the handlers') @default_handlers.each do |handler| start_handler(handler, 'pepito', []) end @database.smembers('handlers').each do |handler| start_handler(handler, @database.get(handler + ':gem'), @database.hgetall(handler + ':config')) unless @default_handlers.include?(handler) end end
Runs the http api in a new thread. @return [void]
# File lib/pepito/robot.rb, line 331 def run_http_api @logger.info('Starting the HTTP API') @http_api_thread = Thread.new do @http_api_server = Puma::Server.new(@http_api.app) @http_api_server.add_tcp_listener('127.0.0.1', 8080) @http_api_server.run end @http_api_thread.abort_on_exception = true end
Runs the web app in a new thread. @return [void]
# File lib/pepito/robot.rb, line 344 def run_web_app @logger.info('Starting the web app') @web_app_thread = Thread.new do @web_app.set(:robot, self) @web_app_server = Puma::Server.new(@web_app) @web_app_server.add_tcp_listener('127.0.0.1', 4567) @web_app_server.run end @web_app_thread.abort_on_exception = true end