Wardrik.Channel behaviour (wardrik_protocol v0.1.0-rc.1)

Copy Markdown

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

Summary

Types

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

The response sent back to the chat app.

Callbacks

Returns the child spec the channel runs as.

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

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

Functions

Deliver a chat app's request to a channel

Types

request()

@type request() :: %{
  path: String.t(),
  body: String.t(),
  headers: %{required(String.t()) => String.t()}
}

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

response()

@type response() :: %{
  status: pos_integer(),
  headers: %{required(String.t()) => String.t()},
  body: String.t()
}

The response sent back to the chat app.

Callbacks

child_spec(opts)

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

Returns the child spec the channel runs as.

notify(opts, room, t, approvers)

(optional)
@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(opts, request)

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

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

Functions

deliver(scope, channel, path, input \\ [])

@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}