Build a USSD (Unstructured Supplementary Service Data) request/response cycle out of Ussd.State modules.

alias Ussd.Context

context = Context.new(session_id, phone_number, input)

Ussd.build(context)
|> Ussd.use_initial_state(MyApp.States.Welcome)
|> Ussd.use_response(&Ussd.Responses.AfricasTalking.respond/3)
|> Ussd.run()

Each call into run/1 resolves exactly one screen: it looks up (or starts) the session behind context, asks the current Ussd.State which transition/2 (or back/2/paginate/1) matches context.input, renders the resulting state's menu, and formats it via whatever was passed to use_response/2.

Summary

Functions

Starts a builder for the given request context.

Resolves one screen and returns whatever use_response/2's formatter produces.

Applies shared setup from a Ussd.Configurator module.

Configures resumable-session behavior for redials

Sets how an unhandled exception becomes a caller-visible message: a Ussd.ExceptionHandler module, or a 1-arity (exception -> message) function.

Sets the state (or action) a brand-new session starts in. Required before run/1 unless the session is already live.

Sets how the final message is formatted: a Ussd.Response module, or a 3-arity (context, message, terminating? -> term) function.

Overrides which Ussd.Cache implementation backs this session's Ussd.Record (defaults to config :ussd, :cache).

Types

t()

@type t() :: %Ussd{
  context: Ussd.Context.t(),
  continuing_mode: Ussd.ContinuingMode.t(),
  continuing_state: module() | nil,
  continuing_ttl: pos_integer() | nil,
  exception_handler: (Exception.t() -> String.t()),
  initial_state: module() | nil,
  response: (Ussd.Context.t(), String.t(), boolean() -> term()),
  store: module() | nil
}

Functions

build(context)

@spec build(Ussd.Context.t()) :: t()

Starts a builder for the given request context.

run(ussd)

@spec run(t()) :: term()

Resolves one screen and returns whatever use_response/2's formatter produces.

use_configurator(ussd, module)

@spec use_configurator(t(), module()) :: t()

Applies shared setup from a Ussd.Configurator module.

use_continuing_state(ussd, mode, ttl \\ nil, continuing_state \\ nil)

@spec use_continuing_state(
  t(),
  Ussd.ContinuingMode.t(),
  pos_integer() | nil,
  module() | nil
) :: t()

Configures resumable-session behavior for redials:

  • :start (default) - every dial is a brand-new session.
  • :continue - a redial silently resumes the previous session, kept alive for ttl after each response.
  • :confirm - a redial is routed to continuing_state (a module using Ussd.State, continue: true), which asks the caller whether to resume.

use_exception_handler(ussd, handler)

@spec use_exception_handler(t(), module() | (Exception.t() -> String.t())) :: t()

Sets how an unhandled exception becomes a caller-visible message: a Ussd.ExceptionHandler module, or a 1-arity (exception -> message) function.

use_initial_state(ussd, module)

@spec use_initial_state(t(), module()) :: t()

Sets the state (or action) a brand-new session starts in. Required before run/1 unless the session is already live.

use_response(ussd, response)

@spec use_response(
  t(),
  module() | (Ussd.Context.t(), String.t(), boolean() -> term())
) :: t()

Sets how the final message is formatted: a Ussd.Response module, or a 3-arity (context, message, terminating? -> term) function.

use_store(ussd, cache_module)

@spec use_store(t(), module()) :: t()

Overrides which Ussd.Cache implementation backs this session's Ussd.Record (defaults to config :ussd, :cache).