# `Slink.SocketMode`
[🔗](https://github.com/wkirschbaum/slink/blob/v0.6.0/lib/slink/socket_mode.ex#L1)

Socket Mode transport: a `GenServer` that keeps a WebSocket open to Slack.

It opens a connection URL via `apps.connections.open`, upgrades to a
WebSocket with `Mint.WebSocket`, acknowledges every envelope immediately
(Slack requires an ACK within 3 seconds), and dispatches the decoded event to
your module off-process. Slack's periodic `disconnect` refreshes and dropped
connections are handled by transparently reconnecting.

Add it to a supervision tree:

    {Slink.SocketMode,
     module: MyBot,
     app_token: System.fetch_env!("SLACK_APP_TOKEN"),
     bot_token: System.fetch_env!("SLACK_BOT_TOKEN")}

Options:

  * `:module` (required) — a module implementing the `Slink` behaviour.
  * `:app_token` (required) — app-level token (`xapp-…`, `connections:write`).
  * `:bot_token` — bot token (`xoxb-…`) passed to handlers for Web API calls.
  * `:name` — process name (defaults to `Slink.SocketMode`; pass `nil` to run
    unregistered, e.g. to run several clients at once).
  * `:connections` — how many parallel WebSocket connections to hold open
    (default `1`). Slack recommends **2+** in production so that when one
    drops (or Slack rolls its own reconnects) another is already live and no
    events are missed; deliveries are load-balanced across them. A delivery
    duplicated across sockets dispatches once: event callbacks dedup on
    Slack's `event_id`, slash commands and interactions on their
    `envelope_id` (`view_submission` is the exception — its synchronous ack
    must answer every delivery). With `connections: 2` the given `:name`
    belongs to the supervisor of the two clients. Slack allows at most 10
    open connections per app.
  * `:join` — a list of channel IDs to `conversations.join` once connected
    (requires the `channels:join` scope). Defaults to `[]`.
  * `:open_connection` — a 0-arity function returning `{:ok, ws_url}` used to
    obtain the WebSocket URL. Defaults to calling `apps.connections.open` with
    `:app_token`. Primarily a testing seam.
  * `:verbose` — when `true`, log every incoming WebSocket frame at `:info`
    (raw text for text frames). Useful for debugging what Slack actually
    delivers. Defaults to `false`.
  * `:idle_timeout_ms` — reconnect if no traffic (frames, pings, any TCP data)
    arrives for this long, catching connections that died without a close
    (NAT timeout, network partition). Slack pings every few seconds, so a
    quiet-but-healthy link never trips this. Milliseconds (or `:infinity` to
    disable); defaults to 2 minutes.

## Multiple workspaces

Run one client per workspace — each dials out with its own tokens and stamps
its own `:bot_token` into the handler context, so a single `MyBot` serves them
all. Give each a distinct `:name`:

    for w <- MyApp.workspaces() do
      {Slink.SocketMode,
       name: {:global, {MyBot, w.team_id}},
       module: MyBot,
       app_token: w.app_token,
       bot_token: w.bot_token}
    end

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `start_link`

---

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