Expand description
Slack Web API REST client — apps.connections.open (Socket Mode URL
fetch) + chat.postMessage for outbound delivery.
Rate limiting: v1 implements only per-channel ~1msg/s spacing (enforced
by the caller in socket.rs’s outbound loop) and reactive
429/Retry-After backoff. Full token-bucket accounting for every
documented Slack API tier is explicitly out of scope (spec §2.6) —
mirrors Discord’s and Telegram’s rest.rs, neither of which does
header-driven throttling beyond reacting to a rate-limit signal.
Secret-in-error-message hygiene: both Slack tokens (xoxb-/xapp-) are
sent as Authorization: Bearer headers, never embedded in request URLs —
unlike Telegram’s bot{token} path convention — so reqwest::Error’s
Display (which can embed request URLs on connection failures) does not
leak either token via that vector, and no redact()-style scrubbing of
reqwest::Error text is needed here the way telegram/rest.rs needs it.
The one Slack-specific value that is both URL-embedded and secret is
the Socket Mode WS URL’s ticket= query param returned by
apps.connections.open: it’s a single-use, short-lived credential (spec
§2.1, §9.6). We never pass that URL through this module’s error paths
(the WS connect happens in socket.rs), but we still provide
redact_ticket here so any code that logs the URL (today: one debug!
call in socket.rs) redacts it first — unnecessary exposure in a log
that can persist long past the ticket’s few-seconds validity window is
not worth the convenience of an unredacted log line.
Structs§
- Slack
ApiError - Error from a Slack Web API call, carrying the
Retry-Afterseconds when present (429 responses only — Slack signals rate limits via the HTTP header, not a response-body field like Telegram’sparameters.retry_after— spec §2.6).
Constants§
Functions§
- open_
connection - POST apps.connections.open —
Authorization: Bearer {app_token}. Returns the ephemeral Socket Mode WS URL. Must be called before the initial connect and before every reconnect (spec §2.1) — the URL is single-use and short-lived; never cache/reuse it. - parse_
retry_ 🔒after - Parses an HTTP
Retry-Afterheader value (seconds, per RFC 9110 — Slack always sends the delta-seconds form, never the HTTP-date form). - post_
message - POST chat.postMessage —
Authorization: Bearer {bot_token}. MUST checkbody.ok, not just HTTP status: Slack’s REST responses are HTTP 200 even on many logical failures (e.g.channel_not_found,not_in_channel) — spec §2.4. - post_
response_ url - POST to a slash-command
response_url. Stub for the deferred-response path (spec §2.5, §4.3) — not called anywhere in v1 scope; slash commands are explicitly out of scope for this PR. Kept so the module shape doesn’t need rework when they land. - redact_
ticket - Redacts the single-use
ticketquery param from a Socket Mode WS URL before it’s ever logged (spec §9.6). Leaves the rest of the URL (host,app_id, path) intact since that part isn’t secret and is useful for debugging connection issues.