Skip to content

feat(daemon): real Discord Gateway (WebSocket) + harden Telegram/Slack#76

Merged
Patel230 merged 1 commit into
mainfrom
feat/discord-gateway-websocket
Jun 28, 2026
Merged

feat(daemon): real Discord Gateway (WebSocket) + harden Telegram/Slack#76
Patel230 merged 1 commit into
mainfrom
feat/discord-gateway-websocket

Conversation

@Patel230

Copy link
Copy Markdown
Contributor

Summary

Replaces the Discord bridge's REST-polling design — which only watched hand-configured channels and, as wired, never fetched anything — with the official Discord Gateway over WebSocket via bwmarrin/discordgo (the industry-standard Go Discord library). Telegram (long-poll) and Slack (Events API + HMAC) keep their already-idiomatic designs but are hardened.

Discord (rewritten)

  • Real Gateway connection with intents GuildMessages | MessageContent | DirectMessages; library handles heartbeats, resume/reconnect, rate limits.
  • Real-time guild @mentions and DMs; bot user learned from READYno app/channel IDs to configure.
  • Lifecycle-clean: opens socket, blocks on ctx, drains in-flight handlers, closes.
  • Message filtering (wantsDiscordMessage, stripDiscordMention) and the pairing/allowlist forward policy (handleMessage) are pure and unit-tested without a live socket; openSession is injectable.

Cross-gateway hardening

  • Bounded, lifecycle-tracked goroutines (asyncDispatcher) drained on Stop; Slack handlers run under the gateway context (not context.Background).
  • Platform API errors checked & logged instead of swallowed (Slack ok=false, Discord/Telegram non-2xx, Telegram getUpdates ok=false).
  • Telegram: fail-closed bare constructor; context-aware exponential backoff.
  • setDaemonURL via a daemonURLSetter interface instead of a concrete type switch.

Dependency

Adds github.com/bwmarrin/discordgo v0.28.1 (+ gorilla/websocket indirect; x/crypto already satisfied). go work sync reconciled go.mod/go.sum/go.work.sum.

Notes

  • MessageContent is a privileged intent — enable it in the Discord developer portal or message text arrives empty.

Verification

go build ./..., go vet, go test -race ./internal/daemon, golangci-lint (0 issues); go work sync idempotent and go build -mod=readonly ./cmd/hawk clean.

Discord: replace the REST-poll bridge (which only watched hand-configured
channels and never actually fetched anything as wired) with the official
Discord Gateway over WebSocket via bwmarrin/discordgo. Receives guild
@mentions and DMs in real time; the bot user is learned from READY so no
app/channel IDs need configuring. Library handles heartbeats, resume,
reconnect, and rate limits. Message filtering and the pairing/allowlist
forward policy are split into pure, unit-tested helpers.

Cross-gateway hardening:
- Bounded, lifecycle-tracked goroutines (asyncDispatcher) drained on Stop;
  Slack handlers now run under the gateway context, not context.Background.
- Platform API errors are checked and logged instead of swallowed
  (Slack ok=false, Discord/Telegram non-2xx, Telegram getUpdates ok=false).
- Telegram: fail-closed bare constructor, context-aware exponential backoff.
- setDaemonURL via a daemonURLSetter interface instead of a type switch.

Adds github.com/bwmarrin/discordgo (+ gorilla/websocket indirect).
@Patel230 Patel230 merged commit dd7aef5 into main Jun 28, 2026
18 checks passed
@Patel230 Patel230 deleted the feat/discord-gateway-websocket branch June 28, 2026 03:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant