# `WardrikSlack.Install`

Adds one Slack app to many workspaces, one for each org.

    slack:
      {WardrikSlack,
       client_id: "...",
       client_secret: "...",
       redirect_uri: "https://app.example.com/slack/installed",
       signing_secret: "...",
       installations: :stored,
       approvers: ["@maria"]}

`:client_id` and `:client_secret` are under **Basic Information**. Set the app's **Redirect URL**,
under **OAuth & Permissions**, to a route in your app, and pass the same URL as `:redirect_uri`.
Stored tokens are sealed with Wardrik's `:keys`.

Reach these through `Wardrik.Channels`:

    # 1. Send someone acting for the org to Slack
    {:ok, url} = Wardrik.Channels.install_url(MyApp.AgentRuntime, "slack", "acme", return_to: "/settings")

    # 2. In the route Slack sends them back to
    case Wardrik.Channels.installed(MyApp.AgentRuntime, "slack", "acme", conn.query_params) do
      {:ok, _installation, return_to} -> redirect(conn, external: return_to || "/")
      {:error, message} -> send_resp(conn, 400, message)
    end

The URL lasts ten minutes. It carries the owner it was made for, signed with the client secret,
so nobody else's URL can add a workspace for that owner. A new workspace gets the channel's
`:approvers`.

# `installed`

```elixir
@spec installed(WardrikChannel.Channel.t(), String.t(), map()) ::
  {:ok, Wardrik.Channel.Installation.t(), String.t() | nil}
  | {:error, String.t()}
```

Adds the app to a workspace for `owner`, from the `query` Slack redirects back with.

Returns the installation and the `:return_to` given to `url/3`. Returns `{:error, message}` if
the URL was made for another owner, has expired, or Slack refused.

# `scopes`

```elixir
@spec scopes() :: [String.t()]
```

Returns the bot scopes the app asks for.

# `url`

```elixir
@spec url(WardrikChannel.Channel.t(), String.t(), keyword()) ::
  {:ok, String.t()} | {:error, String.t()}
```

Returns the Slack URL where someone adds the app for `owner`.

Returns `{:error, message}` if the channel has no `:client_id` and `:client_secret`.

## Options

  * `:return_to` - where to send them once it's added. Returned by `installed/3`.

---

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