class Telegram::Rails::ActionDispatcher

Constants

COMMAND_ARGS_SEPARATOR
COMMAND_START_SYMBOL
DEFAULT_ACTION_NAME
ENDPOINT_DELIMETER
ROUTE_DELIMETER

Public Class Methods

new(adapters) click to toggle source
# File lib/telegram/rails/action_dispatcher.rb, line 15
def initialize adapters
  @adapters = adapters
  @routes   = []
end

Public Instance Methods

dispatch_message(bot_name, message) click to toggle source
# File lib/telegram/rails/action_dispatcher.rb, line 27
def dispatch_message bot_name, message
  adapter = find_adapter_for bot_name
  return unless adapter

  command, args = extract_command_from message
  route = find_route_for bot_name, command
  return unless route

  process_message message, with: route, args: args, command: command
end
register_route(route_data) click to toggle source
# File lib/telegram/rails/action_dispatcher.rb, line 21
def register_route route_data
  route = parse_route(route_data)
  @routes << route
end

Private Instance Methods

extract_command_from(payload) click to toggle source

TEST get command name from payload

# File lib/telegram/rails/action_dispatcher.rb, line 105
def extract_command_from payload
  command_str = payload.text
  if command_str && command_str.starts_with?(COMMAND_START_SYMBOL)
    command_str.slice!(0)
    command,*args = command_str.split COMMAND_ARGS_SEPARATOR
    return [command.to_sym, args] if command && command.length
  end
  return [nil,nil]
end
find_adapter_for(name) click to toggle source
# File lib/telegram/rails/action_dispatcher.rb, line 41
def find_adapter_for name
  @adapters[name]
end
find_route_for(bot_name, command) click to toggle source
# File lib/telegram/rails/action_dispatcher.rb, line 46
def find_route_for bot_name, command
  @routes.find do |route|
    route_match? bot_name, command, route
  end
end
parse_route(route_data) click to toggle source

TEST

# File lib/telegram/rails/action_dispatcher.rb, line 78
def parse_route route_data
  route_string = route_data[:route]
  options      = route_data[:options]

  segments = route_string.split ROUTE_DELIMETER, 2
  bot_name, command = segments

  bot_name = bot_name.to_sym if bot_name
  command  = command.to_sym  if command

  endpoint = options[:to]
  controller_name, action_name = endpoint.to_s.split ENDPOINT_DELIMETER, 2

  controller_class = "#{controller_name}_controller".classify.constantize
  action_name      = action_name ? action_name.to_sym : DEFAULT_ACTION_NAME

  {
    bot_name:         bot_name,
    command:          command,
    controller_class: controller_class,
    action_name:      action_name,
  }
end
process_message(message, opts) click to toggle source
# File lib/telegram/rails/action_dispatcher.rb, line 59
def process_message message, opts
  route = opts[:with]

  controller = route[:controller_class].new
  controller.tap do |c|
    c.bots     = @adapters
    c.bot_name = route[:bot_name]
    c.message  = message
    c.params   = {
      command: opts[:command],
      args:    opts[:args],
    }
  end

  controller.dispatch route[:action_name]
end
route_match?(bot_name, command, route) click to toggle source
# File lib/telegram/rails/action_dispatcher.rb, line 53
def route_match? bot_name, command, route
  bot_name == route[:bot_name] &&
  (command == route[:command] || route[:command].nil?)
end