Packages

A Slack Web & Real Time Messaging API client.

Current section

Files

Jump to
slack_kit lib slack web client.ex
Raw

lib/slack/web/client.ex

defmodule Slack.Web.Client do
@moduledoc """
Behaviour for a pluggable Slack Web API HTTP client.
Every function generated under `Slack.Web.*` calls `post!/2` on the module
configured as `:web_http_client` (default: `Slack.Web.DefaultClient`).
Implementing this behaviour lets you inject auth headers, add retries,
decorate responses, route requests through a proxy, or instrument calls
for telemetry without touching the generated code.
The return value of `post!/2` is handed back to the caller of the
`Slack.Web.*` function unchanged — there is no required shape, so a custom
client is free to wrap the response in `{:ok, _}` / `{:error, _}` tuples
or in a struct of its choosing.
## Example
defmodule MyApp.SlackClient do
@behaviour Slack.Web.Client
@impl true
def post!(url, {:form, params}) do
url
|> Req.post!(form: params, retry: :transient)
|> Map.fetch!(:body)
|> JSON.decode!()
|> wrap()
end
def post!(url, {:multipart, _parts} = body) do
# Fall back to the default client for multipart uploads.
Slack.Web.DefaultClient.post!(url, body)
end
defp wrap(%{"ok" => true} = body), do: {:ok, body}
defp wrap(%{"error" => reason} = body), do: {:error, reason, body}
end
# config/runtime.exs
config :slack, :web_http_client, MyApp.SlackClient
See `Slack.Web.DefaultClient` for the stock implementation built on `Req`.
"""
@type url :: String.t()
@type form_body :: {:form, Keyword.t()}
@type multipart_form_body :: {:multipart, nonempty_list(tuple())}
@type body :: form_body() | multipart_form_body()
@doc """
Performs a POST against `url` with `body`.
`body` is either `{:form, params}` for most endpoints or
`{:multipart, parts}` for file uploads. The return value is passed
through to the caller of the generated `Slack.Web.*` function verbatim
and may be any term.
"""
@callback post!(url :: url, body :: body) :: term()
end