Class: Ant::Bot::Base
- Inherits:
-
Object
- Object
- Ant::Bot::Base
- Includes:
- Logger, Storage::Datasource
- Defined in:
- lib/ant/bot/base.rb
Overview
Base class for bot implementation. It wraps the threads execution, the provider and the state storage inside an object.
Instance Method Summary collapse
-
#add_param(value) ⇒ Object
Stores a parameter into the status.
-
#ask_param(param) ⇒ Object
Sends a message to get the next parameter from the user.
-
#command=(cmd) ⇒ Object
stores the command into state.
-
#command_ready? ⇒ Boolean
Checks if the command is ready to be executed.
-
#current_channel ⇒ Object
returns the current_channel from where the message was sent.
-
#current_command_object ⇒ Object
Loads command from state.
-
#current_params ⇒ Object
loads parameters from state.
-
#initialize(configs) ⇒ Base
constructor
Configurations needed: - pool_size: number of threads created in execution - provider: a configuration for a thread provider.
-
#load_state(channel) ⇒ Object
Private implementation for load message.
-
#load_state!(channel) ⇒ Object
Loads the state from storage.
-
#next_missing_param ⇒ Object
validates which is the following parameter required.
-
#process_message(message) ⇒ Object
Process a single message, this method can be overwriten to enable more complex implementations of commands.
-
#register_command(name, params, &block) ⇒ Object
DSL method for adding simple commands.
-
#run ⇒ Object
Starts the bot execution, this is a blocking call.
-
#run_command! ⇒ Object
Method for triggering command.
-
#run_simple_command!(message) ⇒ Object
Executes a command with the easiest definition.
-
#save_state! ⇒ Object
Saves the state into storage.
- #session ⇒ Object
Constructor Details
#initialize(configs) ⇒ Base
Configurations needed:
-
pool_size: number of threads created in execution
-
provider: a configuration for a thread provider. See supported adapters
-
name: The bot name
-
repository: Configurations about the state storage
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/ant/bot/base.rb', line 23 def initialize(configs) @pool_size = configs['pool_size'] @provider = Ant::Bot::Adapter.from_config(configs['provider']) @commands = Ant::Bot::CommandDefinition.new # TODO: move this to config @repository = Ant::Storage::Repository.from_config( nil, configs['state_repository'] .merge('primary_key' => 'channel_id', 'table' => 'bot_sessions'), {} ) @factory = Ant::Storage::Factory.new(EmptyModel) @factory.register(:default, :json) @factory.register(:json, @repository) end |
Instance Method Details
#add_param(value) ⇒ Object
Stores a parameter into the status
141 142 143 144 145 146 147 |
# File 'lib/ant/bot/base.rb', line 141 def add_param(value) log_debug('Received new param', param: @state[:requested_param].to_sym, value: value) @state[:params][@state[:requested_param].to_sym] = value. end |
#ask_param(param) ⇒ Object
Sends a message to get the next parameter from the user
133 134 135 136 137 138 |
# File 'lib/ant/bot/base.rb', line 133 def ask_param(param) log_debug('I\'m going to ask the next param', param: param) @provider.(current_channel, "I need you to tell me #{param}") @state[:requested_param] = param.to_s end |
#command=(cmd) ⇒ Object
stores the command into state
120 121 122 123 124 125 |
# File 'lib/ant/bot/base.rb', line 120 def command=(cmd) log_debug('Message set as command', command: cmd) @state[:cmd] = cmd. @state[:params] = {} end |
#command_ready? ⇒ Boolean
Checks if the command is ready to be executed
98 99 100 101 |
# File 'lib/ant/bot/base.rb', line 98 def command_ready? cmd = current_command_object cmd.ready?(current_params) end |
#current_channel ⇒ Object
returns the current_channel from where the message was sent
115 116 117 |
# File 'lib/ant/bot/base.rb', line 115 def current_channel @state[:channel_id] end |
#current_command_object ⇒ Object
Loads command from state
109 110 111 112 |
# File 'lib/ant/bot/base.rb', line 109 def current_command_object command = @state[:cmd] @commands[command] end |
#current_params ⇒ Object
loads parameters from state
104 105 106 |
# File 'lib/ant/bot/base.rb', line 104 def current_params @state[:params] || {} end |
#load_state(channel) ⇒ Object
Private implementation for load message
155 156 157 158 159 160 161 |
# File 'lib/ant/bot/base.rb', line 155 def load_state(channel) data = @factory.get(channel) data[:params] = JSON.parse(data[:params], symbolize_names: true) data rescue Ant::Storage::Exceptions::ObjectNotFound @factory.create(channel_id: channel, params: {}.to_json) end |
#load_state!(channel) ⇒ Object
Loads the state from storage
150 151 152 |
# File 'lib/ant/bot/base.rb', line 150 def load_state!(channel) @state = load_state(channel) end |
#next_missing_param ⇒ Object
validates which is the following parameter required
128 129 130 |
# File 'lib/ant/bot/base.rb', line 128 def next_missing_param current_command_object.next_missing_param(current_params) end |
#process_message(message) ⇒ Object
Process a single message, this method can be overwriten to enable more complex implementations of commands. It receives a message object.
63 64 65 |
# File 'lib/ant/bot/base.rb', line 63 def () run_simple_command!() end |
#register_command(name, params, &block) ⇒ Object
DSL method for adding simple commands
88 89 90 |
# File 'lib/ant/bot/base.rb', line 88 def register_command(name, params, &block) @commands.register_command(name, params, block) end |
#run ⇒ Object
Starts the bot execution, this is a blocking call.
46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/ant/bot/base.rb', line 46 def run @pool = Array.new(@pool_size) do # TODO: Create a subclass with the context execution Ant::DRY::Daemon.new(@pool_size, true) do = @provider. () end end # TODO: Implement an interface for killing the process @pool.each(&:run) # :nocov: # @pool.each(&:await) # :nocov: # end |
#run_command! ⇒ Object
Method for triggering command
93 94 95 |
# File 'lib/ant/bot/base.rb', line 93 def run_command! current_command_object.execute(current_params) end |
#run_simple_command!(message) ⇒ Object
Executes a command with the easiest definition. It runs a state machine:
-
If the message is a command, set the status to asking params
-
If the message is a param, stores it
-
If the command is ready to be executed, trigger it.
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/ant/bot/base.rb', line 71 def run_simple_command!() load_state!(.channel_id) log_debug('loaded state', message: .to_h, state: @state.to_h) if .command? self.command = else add_param() end if command_ready? run_command! else ask_param(next_missing_param) end save_state! end |
#save_state! ⇒ Object
Saves the state into storage
164 165 166 167 168 169 |
# File 'lib/ant/bot/base.rb', line 164 def save_state! json = @state[:params] @state[:params] = json.to_json @state.store @state[:params] = json end |
#session ⇒ Object
41 42 43 |
# File 'lib/ant/bot/base.rb', line 41 def session @repository.connection end |