# `Wardrik.Channel`

A behaviour for chat apps, like Slack, that people reach agents through.

Give each channel a name of your own in Wardrik's `:channels` option:

    channels: [slack: {WardrikSlack, token: token, signing_secret: secret}]

Each channel runs under Wardrik's supervisor. Requests to `POST /v1/channels/{channel}/{path}`
reach `c:request/2` unchanged, so the channel can verify them, for example by a signature over
the body. To deliver one yourself:

    {:ok, answer} = Wardrik.Channel.deliver(scope, "slack", "events", body: body, headers: headers)

Every callback gets the channel's options, plus:

  * `:wardrik` - the instance the channel runs under.
  * `:channel` - the channel's name.
  * `:store` - Wardrik's store. Prefix keys with your package's name.

# `request`

```elixir
@type request() :: %{
  path: String.t(),
  body: String.t(),
  headers: %{required(String.t()) =&gt; String.t()}
}
```

A request from the chat app: its `path` within the channel, raw `body`, and `headers` by lowercase name.

# `response`

```elixir
@type response() :: %{
  status: pos_integer(),
  headers: %{required(String.t()) =&gt; String.t()},
  body: String.t()
}
```

The response sent back to the chat app.

# `child_spec`

```elixir
@callback child_spec(opts :: keyword()) :: Supervisor.child_spec()
```

Returns the child spec the channel runs as.

# `notify`
*optional* 

```elixir
@callback notify(
  opts :: keyword(),
  room :: String.t(),
  Wardrik.Notice.t(),
  approvers :: [String.t()]
) ::
  :ok | {:skip, String.t()} | {:error, term()}
```

Posts `notice` in `room`, asking `approvers` to decide the calls a parked turn waits on.

`approvers` are named as the chat app names people. Returns `{:skip, reason}` if there's nowhere
to post. Optional: a channel without it posts no notices. See `Wardrik.Notify`.

# `request`

```elixir
@callback request(opts :: keyword(), request()) :: response()
```

Handles a request from the chat app and returns the response.

# `deliver`

```elixir
@spec deliver(Wardrik.Scope.t(), String.t() | struct(), String.t() | struct(), term()) ::
  term() | :ok | {:error, Wardrik.Error.t()}
```

Deliver a chat app's request to a channel

Hands a request a chat app such as Slack sent to the channel of that name, as it came. The channel checks it by what it carries, such as a signature over the body, and answers it as the chat app expects. not_found where no channel of that name takes requests.

`POST /v1/channels/{channel}/{path}`

---

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