class Stealth::Controller

Attributes

action_name[R]
current_flow[R]
current_message[R]
current_service[R]
current_session_id[R]
current_user_id[R]
flow_controller[R]

Public Class Methods

new(service_message:, current_flow: nil) click to toggle source
# File lib/stealth/controller/controller.rb, line 17
def initialize(service_message:, current_flow: nil)
  @current_message = service_message
  @current_service = service_message.service
  @current_user_id = @current_session_id = service_message.sender_id
  @current_flow = current_flow
  @progressed = false
end

Public Instance Methods

action(action: nil) click to toggle source
# File lib/stealth/controller/controller.rb, line 59
def action(action: nil)
  @action_name = action
  @action_name ||= current_session.state_string

  # Check if the user needs to be redirected
  if current_session.flow.current_state.redirects_to.present?
    Stealth::Logger.l(
      topic: "redirect",
      message: "From #{current_session.session} to #{current_session.flow.current_state.redirects_to.session}"
    )
    step_to(session: current_session.flow.current_state.redirects_to)
    return
  end

  run_callbacks :action do
    begin
      flow_controller.send(@action_name)
      run_catch_all(reason: 'Did not send replies, update session, or step') unless flow_controller.progressed?
    rescue StandardError => e
      Stealth::Logger.l(topic: "catch_all", message: e.backtrace.join("\n"))
      run_catch_all(reason: e.message)
    end
  end
end
current_session() click to toggle source
# File lib/stealth/controller/controller.rb, line 51
def current_session
  @current_session ||= Stealth::Session.new(user_id: current_session_id)
end
has_attachments?() click to toggle source
# File lib/stealth/controller/controller.rb, line 29
def has_attachments?
  current_message.attachments.present?
end
has_location?() click to toggle source
# File lib/stealth/controller/controller.rb, line 25
def has_location?
  current_message.location.present?
end
previous_session() click to toggle source
# File lib/stealth/controller/controller.rb, line 55
def previous_session
  @previous_session ||= Stealth::Session.new(user_id: current_session_id, previous: true)
end
progressed?() click to toggle source
# File lib/stealth/controller/controller.rb, line 33
def progressed?
  @progressed.present?
end
route() click to toggle source
# File lib/stealth/controller/controller.rb, line 37
def route
  raise(Stealth::Errors::ControllerRoutingNotImplemented, "Please implement `route` method in BotController")
end
step_to(session: nil, flow: nil, state: nil) click to toggle source
# File lib/stealth/controller/controller.rb, line 106
def step_to(session: nil, flow: nil, state: nil)
  flow, state = get_flow_and_state(session: session, flow: flow, state: state)
  step(flow: flow, state: state)
end
step_to_at(timestamp, session: nil, flow: nil, state: nil) click to toggle source
# File lib/stealth/controller/controller.rb, line 95
def step_to_at(timestamp, session: nil, flow: nil, state: nil)
  flow, state = get_flow_and_state(session: session, flow: flow, state: state)

  unless timestamp.is_a?(DateTime)
    raise ArgumentError, "Please specify your step_to_at `timestamp` parameter as a DateTime"
  end

  Stealth::ScheduledReplyJob.perform_at(timestamp, current_service, current_session_id, flow, state)
  Stealth::Logger.l(topic: "session", message: "User #{current_session_id}: scheduled session step to #{flow}->#{state} at #{timestamp.iso8601}")
end
step_to_in(delay, session: nil, flow: nil, state: nil) click to toggle source
# File lib/stealth/controller/controller.rb, line 84
def step_to_in(delay, session: nil, flow: nil, state: nil)
  flow, state = get_flow_and_state(session: session, flow: flow, state: state)

  unless delay.is_a?(ActiveSupport::Duration)
    raise ArgumentError, "Please specify your step_to_in `delay` parameter using ActiveSupport::Duration, e.g. `1.day` or `5.hours`"
  end

  Stealth::ScheduledReplyJob.perform_in(delay, current_service, current_session_id, flow, state)
  Stealth::Logger.l(topic: "session", message: "User #{current_session_id}: scheduled session step to #{flow}->#{state} in #{delay} seconds")
end
update_session_to(session: nil, flow: nil, state: nil) click to toggle source
# File lib/stealth/controller/controller.rb, line 111
def update_session_to(session: nil, flow: nil, state: nil)
  flow, state = get_flow_and_state(session: session, flow: flow, state: state)
  update_session(flow: flow, state: state)
end

Private Instance Methods

get_flow_and_state(session: nil, flow: nil, state: nil) click to toggle source
# File lib/stealth/controller/controller.rb, line 133
def get_flow_and_state(session: nil, flow: nil, state: nil)
  if session.nil? && flow.nil? && state.nil?
    raise(ArgumentError, "A session, flow, or state must be specified")
  end

  if session.present?
    return session.flow_string, session.state_string
  end

  if flow.present?
    if state.blank?
      state = FlowMap.flow_spec[flow.to_sym].states.keys.first.to_s
    end

    return flow.to_s, state.to_s
  end

  if state.present?
    return current_session.flow_string, state.to_s
  end
end
step(flow:, state:) click to toggle source
# File lib/stealth/controller/controller.rb, line 124
def step(flow:, state:)
  update_session(flow: flow, state: state)
  @progressed = :stepped
  @flow_controller = nil
  @current_flow = current_session.flow

  action(action: state)
end
update_session(flow:, state:) click to toggle source
# File lib/stealth/controller/controller.rb, line 118
def update_session(flow:, state:)
  @current_session = Stealth::Session.new(user_id: current_session_id)
  @progressed = :updated_session
  @current_session.set(flow: flow, state: state)
end