Slink.SocketMode (Slink v0.6.0)

Copy Markdown View Source

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

Summary

Functions

Returns a specification to start this module under a supervisor.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

start_link(opts)