Skip to content

refactor: replace hand-rolled WebSocket gateway with discord.js#61

Open
justmaker wants to merge 6 commits intomoazbuilds:masterfrom
justmaker:pr/discordjs-migration
Open

refactor: replace hand-rolled WebSocket gateway with discord.js#61
justmaker wants to merge 6 commits intomoazbuilds:masterfrom
justmaker:pr/discordjs-migration

Conversation

@justmaker
Copy link
Copy Markdown
Contributor

Summary

Replaces the hand-rolled WebSocket gateway (~330 lines) with discord.js v14 Client, which automatically handles:

  • Gateway heartbeat, reconnect, and resume
  • Thread membership maintenance
  • Intent negotiation and payload parsing

What changed

  • Removed: sendWs, sendHeartbeat, startHeartbeat, stopHeartbeat, resetGatewayState, sendIdentify, sendResume, connectGateway, handleGatewayPayload, handleDispatch
  • Added: discord.js Client with event listeners for MessageCreate, InteractionCreate, GuildCreate, ThreadCreate, ThreadDelete, ThreadUpdate, ThreadListSync
  • Kept: All business logic (message handler, AI intent classifier, thread management, slash commands, attachment handling)
  • Net: -78 lines of code

Why

The hand-rolled gateway had persistent issues with thread liveness after reconnects — RESUMED events don't trigger GUILD_CREATE, causing thread membership loss. discord.js handles all of this automatically.

Dependencies

This PR builds on top of #60 (core fixes & multi-session support).

Testing

Running in production. Gateway reconnects, thread membership, and message delivery all working correctly.

justmaker and others added 6 commits March 26, 2026 13:15
- config.ts: Remove reference to undefined `discordUserIds` variable
  in parseSettings(). Use raw.discord.allowedUserIds directly instead.

- runner.ts: Keep `settings` variable in execClaude() scope so the
  later `(settings as any).sessionTimeoutMs` reference resolves.
  Previously, getSettings() was destructured directly, leaving
  `settings` undefined.

Co-authored-by: Rex Hsu <rexhsu@qnap.com>
* feat: multi-session thread support for Discord

- New sessionManager.ts: per-thread session lifecycle (CRUD, turn tracking, compact warnings)
- runner.ts: per-thread queues enabling parallel execution across threads
- discord.ts: thread detection via gateway events, auto-session routing, cleanup on archive/delete
- /status shows thread session count and details
- README.md: added multi-session threads section
- docs/MULTI_SESSION.md: full technical documentation

Backward compatible: non-thread messages use global session as before.

* feat: hire/fire thread commands

- 'hire <name>' creates a Discord thread with auto-session
- 'fire <name>' deletes thread and cleans up session
- Also supports Chinese: 建立/開, 刪除/關

---------

Co-authored-by: Rex Hsu <rexhsu@qnap.com>
Let Claude CLI create the session on first message, runner.ts
captures the real UUID and saves it to sessions.json.
Bot must be a thread member to receive messages. After restart,
bot loses thread membership. Now rejoins all threads from
sessions.json on GUILD_CREATE.
Discord gateway RESUMED events don't trigger GUILD_CREATE, so
thread membership was lost on lightweight reconnects. Now rejoin
threads on both GUILD_CREATE and RESUMED.
- Use discord.js Client for gateway management (heartbeat, reconnect,
  resume, thread membership) — all handled automatically
- Keep all business logic unchanged (handlers, intent classifier,
  thread management, slash commands)
- Auto-join new threads via ThreadCreate event
- Periodic 5-min thread rejoin still in place as safety net
- ~80 fewer lines of code
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