# `Noizu.Slack`
[🔗](https://github.com/noizu-labs-sdks/elixir-slack/blob/v0.1.0/lib/noizu/slack.ex#L1)

Slack Web API client for Elixir.

`Req`-based, explicit-client design (no global state): build a
`Noizu.Slack.Client` and pass it as the first argument to every Web API call. Every
call returns `{:ok, map}` or `{:error, %Noizu.Slack.Error{}}` — never raises
(except `*_stream` enumeration, which raises the error mid-stream).

## Quick start

    # config/runtime.exs (optional — SLACK_BOT_TOKEN is read as a fallback)
    config :noizu_slack, :client, token: System.get_env("SLACK_BOT_TOKEN")

    client = Noizu.Slack.client()

    {:ok, %{"user_id" => bot}} = Noizu.Slack.Auth.test(client)

    {:ok, %{"ts" => ts}} =
      Noizu.Slack.Chat.post_message(client, "C0123456", "Deploy *finished*")

    blocks = Noizu.Slack.Mrkdwn.to_blocks("# Release\n\n- **api** shipped\n- see [run](https://example.com)")
    {:ok, _} = Noizu.Slack.Chat.post_message(client, "C0123456", %{text: "Release", blocks: blocks}, thread_ts: ts)

    Noizu.Slack.Conversations.history_stream(client, "C0123456", limit: 200) |> Enum.take(1000)

    {:ok, _} = Noizu.Slack.Files.upload(client, "C0123456", %{filename: "r.csv", content: csv})

    :ok = Noizu.Slack.Signature.verify(signing_secret, ts_header, raw_body, sig_header)

## Architecture

| Module | Role |
|---|---|
| `Noizu.Slack.Client` | token / base URL / user agent / Req passthrough / retry config |
| `Noizu.Slack.Request` | GET/POST engine, ok-envelope decoding, bounded 429 retry |
| `Noizu.Slack.Pagination` | lazy `response_metadata.next_cursor` streams |
| `Noizu.Slack.Error` | structured error (`tag`, `reason`, `status`, `body`) |
| `Noizu.Slack.Auth` | `auth.test` |
| `Noizu.Slack.Chat` | `chat.postMessage` / `update` / `delete` / `postEphemeral` |
| `Noizu.Slack.Conversations` | `conversations.list` / `info` / `history` / `replies` / `join` / `members` |
| `Noizu.Slack.Users` | `users.list` / `info` / `lookupByEmail` |
| `Noizu.Slack.Search` | `search.messages` (user token) |
| `Noizu.Slack.Reactions` | `reactions.add` / `remove` |
| `Noizu.Slack.Pins` | `pins.add` |
| `Noizu.Slack.Files` | external upload flow (`getUploadURLExternal` → bytes → `completeUploadExternal`) |
| `Noizu.Slack.Webhook` | incoming webhooks (no client) |
| `Noizu.Slack.Signature` | v0 request signature verification |
| `Noizu.Slack.Blocks` | Block Kit builders + limit validation |
| `Noizu.Slack.Mrkdwn` | GitHub markdown → mrkdwn / section blocks |

# `client`

```elixir
@spec client(keyword()) :: Noizu.Slack.Client.t()
```

Builds a client from options / application config / `SLACK_BOT_TOKEN`. See `Noizu.Slack.Client.new/1`.

---

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