# `Ussd`
[🔗](https://github.com/spesohq/ussd/blob/main/lib/ussd.ex#L1)

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`.

# `t`

```elixir
@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() -&gt; String.t()),
  initial_state: module() | nil,
  response: (Ussd.Context.t(), String.t(), boolean() -&gt; term()),
  store: module() | nil
}
```

# `build`

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

Starts a builder for the given request context.

# `run`

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

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

# `use_configurator`

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

Applies shared setup from a `Ussd.Configurator` module.

# `use_continuing_state`

```elixir
@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`

```elixir
@spec use_exception_handler(t(), module() | (Exception.t() -&gt; 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`

```elixir
@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`

```elixir
@spec use_response(
  t(),
  module() | (Ussd.Context.t(), String.t(), boolean() -&gt; term())
) :: t()
```

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

# `use_store`

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

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

---

*Consult [api-reference.md](api-reference.md) for complete listing*
