Holds one connection to the Discord Gateway (v10, JSON encoding) and hands each dispatch frame to a caller-supplied function.
This is the Discord update feed, the counterpart of
Raxol.Telegram.UpdatePoller: sink-agnostic, :on_event decides what a
frame means. Pair it with Raxol.Gateway.Adapter.Discord.normalize_event/1
and authorize BEFORE routing:
{:ok, conn} = Raxol.Gateway.Adapter.Discord.connect(bot_token: token)
Raxol.Gateway.Adapter.Discord.GatewaySocket.start_link(
token: token,
on_event: fn frame ->
with {:ok, route, event} <- Raxol.Gateway.Adapter.Discord.normalize_event(frame),
:allow <- Raxol.Gateway.Pairing.authorize(MyPairing, route) do
Raxol.Gateway.SessionRouter.route(MyRouter, route, event)
else
:ignore -> :ok
:deny -> Logger.info("unauthorized discord chat denied")
end
end
)Options
:token(required) - the bot token, sent in identify/resume:on_event(required) - 1-arity function called per dispatch frame (op 0), in order, with the raw string-keyed frame (%{"t" => type, "d" => data, ...}). A crash inside it is caught and logged.:intents- intent bitfield (defaultRaxol.Gateway.Adapter.Discord.Protocol.default_intents/0; note MESSAGE_CONTENT is privileged and must also be enabled in the developer portal):gateway_url- default"wss://gateway.discord.gg"; the?v=10&encoding=jsonquery is appended, so pass it query-free:transport/:transport_opts- theRaxol.Gateway.Adapter.Discord.GatewaySocket.Transportmodule (defaultMintTransport, which needs the optional:mint_web_socketdependency) and its options:parent- optional pid receiving{:discord_socket, payload}lifecycle notifications (:ready,{:disconnected, reason},{:reconnecting, attempt, delay}):reconnect_base_ms/:reconnect_max_ms- backoff window (defaults 500 / 30_000):jitter_fn- 0-arity float source for the first-heartbeat jitter (default:rand.uniform/0); injectable so tests control when the heartbeat timer can fire:name- optional registered name
Semantics
Heartbeats are client-initiated at the HELLO interval (first beat
jittered per the gateway docs); a beat that is never acknowledged marks
the connection a zombie and forces a reconnect. After READY the socket
resumes interrupted sessions (session id + sequence + resume URL) so
missed dispatches replay; an unresumable session re-identifies from
scratch. Reconnects back off exponentially from
:reconnect_base_ms doubling to :reconnect_max_ms, resetting once a
session reaches READY/RESUMED. Frames are never logged whole - identify
and resume embed the token.
Summary
Functions
Returns a specification to start this module under a supervisor.
Gracefully close the connection and stop the socket.
Current connection phase. Mostly for tests and introspection.
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec close(GenServer.server()) :: :ok
Gracefully close the connection and stop the socket.
@spec phase(GenServer.server()) :: atom()
Current connection phase. Mostly for tests and introspection.