# `WardrikChannel.Rooms`

Keeps which agent answers in each room, and the threads it has answered in.

    # The bot was invited into the room
    WardrikChannel.Rooms.joined(workspace, room, member)
    #=> {:bound, binding, offer}  # one agent offered; it now answers when mentioned
    #=> {:choose, offers}         # several offered; show them to pick from
    #=> :none                     # none offered

    # Someone picked an agent
    {:ok, binding, offer} = WardrikChannel.Rooms.chose(workspace, room, "acme/triage", member)

    # Answer every message, not only mentions
    {:ok, binding} = WardrikChannel.Rooms.answers(workspace, room, :everything, member)

    # The bot left the room
    :ok = WardrikChannel.Rooms.left(workspace, room, member)

Each change is recorded in the audit as `wardrik.room.bound` or `wardrik.room.unbound`. Pass the
`member` who made it, or `nil` if the adapter doesn't know.

# `shown`

```elixir
@type shown() ::
  {:bound, WardrikChannel.Binding.t(), WardrikChannel.Offer.t()}
  | {:choose, [WardrikChannel.Offer.t()]}
  | :none
```

What a room shows once its bot joins: its agent, agents to pick from, or none.

# `answers`

```elixir
@spec answers(
  WardrikChannel.Workspace.t(),
  String.t(),
  WardrikChannel.Binding.answers(),
  WardrikChannel.Member.t() | nil
) :: {:ok, WardrikChannel.Binding.t()} | {:error, :not_bound}
```

Sets whether `room`'s agent answers `:mentions` or `:everything`. Returns `{:error, :not_bound}` if no agent is bound.

# `choices`

```elixir
@spec choices(WardrikChannel.Workspace.t()) ::
  {:choose, [WardrikChannel.Offer.t()]} | :none
```

Returns the agents someone may switch `room` to, or `:none`.

# `chose`

```elixir
@spec chose(
  WardrikChannel.Workspace.t(),
  String.t(),
  String.t(),
  WardrikChannel.Member.t() | nil
) ::
  {:ok, WardrikChannel.Binding.t(), WardrikChannel.Offer.t()}
  | {:error, :not_offered}
```

Binds `room` to `agent`, answering when mentioned. Returns `{:error, :not_offered}` if the workspace doesn't offer it.

# `get`

```elixir
@spec get(WardrikChannel.Workspace.t(), String.t()) ::
  WardrikChannel.Binding.t() | nil
```

Returns `room`'s binding, or `nil` if it has none.

Returns `nil` too if the agent isn't the installation owner's. So a workspace added again for
another owner keeps none of its rooms' agents.

# `joined`

```elixir
@spec joined(
  WardrikChannel.Workspace.t(),
  String.t(),
  WardrikChannel.Member.t() | nil
) :: shown()
```

Binds `room` to the agent the workspace offers, if there's one. Else returns the choices.

# `left`

```elixir
@spec left(WardrikChannel.Workspace.t(), String.t(), WardrikChannel.Member.t() | nil) ::
  :ok
```

Unbinds `room`. No agent answers there, and nothing more is posted in its threads.

# `start`

```elixir
@spec start(WardrikChannel.Workspace.t(), String.t(), String.t()) :: :ok
```

Marks `thread` as one the room's agent answers in.

# `started?`

```elixir
@spec started?(WardrikChannel.Workspace.t(), String.t(), String.t()) :: boolean()
```

Returns whether the room's agent has answered in `thread`.

---

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