Class: Bianchi::USSD::Engine

Inherits:
Object
  • Object
show all
Includes:
ProviderConfigurations
Defined in:
lib/bianchi/ussd/engine.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ProviderConfigurations

#parse_params, #parser_prompt_data

Methods included from ProviderParsers::Appsnmobile

#appsnmobile_params_parser, #appsnmobile_prompt_data_parser, #return_activity_state

Methods included from ProviderParsers::Africastalking

#africastalking_params_parser, #africastalking_prompt_data_parser

Constructor Details

#initialize(params, options) ⇒ Engine

Returns a new instance of Engine.



10
11
12
13
14
15
16
17
18
# File 'lib/bianchi/ussd/engine.rb', line 10

def initialize(params, options)
  validate_engine_options(options)

  @provider = options[:provider]&.to_sym || :none
  @params = parse_params(params)
  @session = Session.new @params
  @menus = []
  @prompt_data = nil
end

Instance Attribute Details

Returns the value of attribute menus.



8
9
10
# File 'lib/bianchi/ussd/engine.rb', line 8

def menus
  @menus
end

#paramsObject

Returns the value of attribute params.



8
9
10
# File 'lib/bianchi/ussd/engine.rb', line 8

def params
  @params
end

#prompt_dataObject

Returns the value of attribute prompt_data.



8
9
10
# File 'lib/bianchi/ussd/engine.rb', line 8

def prompt_data
  @prompt_data
end

#providerObject

Returns the value of attribute provider.



8
9
10
# File 'lib/bianchi/ussd/engine.rb', line 8

def provider
  @provider
end

#sessionObject

Returns the value of attribute session.



8
9
10
# File 'lib/bianchi/ussd/engine.rb', line 8

def session
  @session
end

Class Method Details

.start(params, options = {}, &block) ⇒ Object

Raises:



20
21
22
23
24
25
26
27
28
# File 'lib/bianchi/ussd/engine.rb', line 20

def self.start(params, options = {}, &block)
  raise ArgumentError, "block required to start the engine" unless block_given?

  new(params, options).tap do |e|
    validate_params(e.params)
    e.instance_eval(&block)
    e.process_activity_state
  end
end

.validate_params(params) ⇒ Object

Raises:



40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/bianchi/ussd/engine.rb', line 40

def self.validate_params(params)
  raise ArgumentError, "params expected to be a hash to start engine" unless params.is_a? Hash

  required_params = %w[session_id mobile_number input_body activity_state]

  left_required_params = required_params - params.keys.map(&:to_s)
  unless left_required_params.empty?
    raise ArgumentError, "#{left_required_params} required in params to start engine"
  end

  return if %w[initial subsequent].include? params[:activity_state]

  raise ArgumentError, "activity_state has to either be initial or subsequent"
end

Instance Method Details

#ensure_initial_menuObject

Raises:



65
66
67
68
69
# File 'lib/bianchi/ussd/engine.rb', line 65

def ensure_initial_menu
  return if initial_menu

  raise PageLoadError, "an initial menu is required to proceed"
end

#initial_menuObject



89
90
91
# File 'lib/bianchi/ussd/engine.rb', line 89

def initial_menu
  menus.find { |menu| menu.options[:initial] }
end

#initial_menu_pageObject



84
85
86
87
# File 'lib/bianchi/ussd/engine.rb', line 84

def initial_menu_page
  session.menu = initial_menu
  menu_page("Page1", :request)
end

Raises:



55
56
57
58
59
60
61
62
63
# File 'lib/bianchi/ussd/engine.rb', line 55

def menu(menu_name, options = {})
  unless [String, Symbol].include? menu_name.class
    raise ArgumentError, "menu_name expected to either be string/symbol to define menus"
  end

  raise ArgumentError, "menu_options expected to be a hash to start engine" unless options.is_a? Hash

  @menus << Menu.new(menu_name, options)
end


104
105
106
107
108
109
110
111
112
113
114
# File 'lib/bianchi/ussd/engine.rb', line 104

def menu_page(page_number, action)
  constant_name = "USSD::#{session.menu.name.camelize}Menu::#{page_number}"
  page = constant_name.safe_constantize

  unless page
    raise PageLoadError,
          "#{constant_name} is supposed to be defined to process #{session.menu.name} menu #{page_number}"
  end

  page.call(session, action)
end

#process_activity_stateObject



71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/bianchi/ussd/engine.rb', line 71

def process_activity_state
  ensure_initial_menu

  page = case session.activity_state.to_sym
         when :initial
           initial_menu_page
         when :subsequent
           subsequent_menu_page
         end

  @prompt_data = parser_prompt_data page.session_prompt_data
end

#subsequent_menu_pageObject



93
94
95
96
97
98
99
100
101
102
# File 'lib/bianchi/ussd/engine.rb', line 93

def subsequent_menu_page
  previous_session = session.store.previous_session
  unless previous_session
    raise PageLoadError, "Previous session not found to load subsequent page restart from initial menu"
  end

  session.menu = previous_session.menu

  menu_page(previous_session.page_number, :response)
end

#validate_engine_options(options) ⇒ Object

Raises:



30
31
32
33
34
35
36
37
38
# File 'lib/bianchi/ussd/engine.rb', line 30

def validate_engine_options(options)
  raise ArgumentError, "options expected to be a hash to start engine" unless options.is_a? Hash
  return if options.empty?

  allowed_options = %i[provider]
  return if (options.keys.map(&:to_sym) - allowed_options).empty?

  raise ArgumentError, "#{allowed_options} are the only valid option keys"
end