18 KiB
18 KiB
WebSocket Event Flow Diagram
🔄 Complete Session Lifecycle
┌─────────────────────────────────────────────────────────────────┐
│ BOT CONNECTS │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ Bot → Server: { type: "auth", token: "..." } │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ Server → Bot: { type: "auth_success" } │
│ ✅ Bot is now AUTHENTICATED │
│ ⏳ Bot waits... (no subscription yet) │
└─────────────────────────────────────────────────────────────────┘
↓
↓
┌─────────────────────────────────────────────────────────────────┐
│ ADMIN CREATES SESSION │
│ POST /api/sessions { notes: "Friday Game Night" } │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ Server → ALL AUTHENTICATED CLIENTS: │
│ { │
│ type: "session.started", │
│ data: { │
│ session: { id: 22, is_active: 1, ... } │
│ } │
│ } │
│ 📢 Broadcast to ALL (no subscription needed) │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ Bot receives session.started │
│ 🎮 Bot announces: "Game Night #22 has started!" │
│ │
│ Bot → Server: { type: "subscribe", sessionId: 22 } │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ Server → Bot: { type: "subscribed", sessionId: 22 } │
│ ✅ Bot is now SUBSCRIBED to session 22 │
└─────────────────────────────────────────────────────────────────┘
↓
↓
┌─────────────────────────────────────────────────────────────────┐
│ ADMIN ADDS GAME │
│ POST /api/sessions/22/games { game_id: 45 } │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ Server → SUBSCRIBED CLIENTS (session 22): │
│ { │
│ type: "game.added", │
│ data: { │
│ game: { title: "Quiplash 3", ... } │
│ } │
│ } │
│ 📢 Only to subscribers of session 22 │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ Bot receives game.added │
│ 🎲 Bot announces: "Now playing: Quiplash 3" │
│ 🗳️ Bot announces: "Vote with thisgame++ or thisgame--" │
└─────────────────────────────────────────────────────────────────┘
↓
↓
┌─────────────────────────────────────────────────────────────────┐
│ USER VOTES │
│ POST /api/votes/live { username: "Alice", vote: "up" } │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ Server → SUBSCRIBED CLIENTS (session 22): │
│ { │
│ type: "vote.received", │
│ data: { │
│ vote: { username: "Alice", type: "up" } │
│ } │
│ } │
│ 📢 Only to subscribers of session 22 │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ Bot receives vote.received │
│ 🗳️ Bot tracks vote (may announce later) │
└─────────────────────────────────────────────────────────────────┘
↓
(more games and votes...)
↓
↓
┌─────────────────────────────────────────────────────────────────┐
│ ADMIN CLOSES SESSION │
│ POST /api/sessions/22/close │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ Server → SUBSCRIBED CLIENTS (session 22): │
│ { │
│ type: "session.ended", │
│ data: { │
│ session: { id: 22, is_active: 0, games_played: 5 } │
│ } │
│ } │
│ 📢 Only to subscribers of session 22 │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ Bot receives session.ended │
│ 🗳️ Bot announces: "Final votes for Quiplash 3: 5👍 1👎" │
│ 🌙 Bot announces: "Game Night ended! 5 games played" │
│ ⏳ Bot waits for next session.started... │
└─────────────────────────────────────────────────────────────────┘
📊 Broadcast Scope Comparison
session.started (Global Broadcast)
┌─────────────────────────────────────────────────────────────────┐
│ SERVER │
│ │
│ broadcastToAll('session.started', data) │
└─────────────────────────────────────────────────────────────────┘
↓ ↓ ↓
┌──────────┴───────────┴───────────┴──────────┐
↓ ↓ ↓
┌────────┐ ┌────────┐ ┌────────┐
│ Bot A │ │ Bot B │ │ Bot C │
│ ✅ │ │ ✅ │ │ ✅ │
└────────┘ └────────┘ └────────┘
ALL authenticated clients receive it
(no subscription required)
game.added, vote.received, session.ended (Session-Specific)
┌─────────────────────────────────────────────────────────────────┐
│ SERVER │
│ │
│ broadcastEvent('game.added', data, sessionId: 22) │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────┴─────────┐
↓ ↓
┌────────┐ ┌────────┐ ┌────────┐
│ Bot A │ │ Bot B │ │ Bot C │
│ ✅ │ │ ❌ │ │ ✅ │
│subscr. │ │ not │ │subscr. │
│sess 22 │ │subscr. │ │sess 22 │
└────────┘ └────────┘ └────────┘
ONLY subscribers to session 22 receive it
🎯 Bot State Machine
┌─────────────┐
│ DISCONNECTED│
└──────┬──────┘
│ connect()
↓
┌─────────────┐
│ CONNECTED │
└──────┬──────┘
│ send auth
↓
┌─────────────┐
│AUTHENTICATED│ ← Wait here for session.started
└──────┬──────┘ (no subscription yet)
│
│ receive session.started
↓
┌─────────────┐
│ WAITING │
│ TO │
│ SUBSCRIBE │
└──────┬──────┘
│ send subscribe
↓
┌─────────────┐
│ SUBSCRIBED │ ← Now receive game.added, vote.received, session.ended
└──────┬──────┘
│
│ receive session.ended
↓
┌─────────────┐
│AUTHENTICATED│ ← Back to waiting for next session.started
└─────────────┘ (still authenticated, but not subscribed)
🔍 Event Flow by Subscription Status
Before Subscription (Just Authenticated)
Server Events: Bot Receives:
───────────── ─────────────
session.started ✅ YES (broadcast to all)
game.added ❌ NO (not subscribed yet)
vote.received ❌ NO (not subscribed yet)
session.ended ❌ NO (not subscribed yet)
After Subscription (Subscribed to Session 22)
Server Events: Bot Receives:
───────────── ─────────────
session.started ✅ YES (still broadcast to all)
game.added ✅ YES (subscribed to session 22)
vote.received ✅ YES (subscribed to session 22)
session.ended ✅ YES (subscribed to session 22)
🎮 Multiple Sessions Example
Time Event Bot A (sess 22) Bot B (sess 23)
──── ───── ─────────────── ───────────────
10:00 session.started (sess 22) ✅ Receives ✅ Receives
10:01 Bot A subscribes to sess 22 ✅ Subscribed ❌ Not subscribed
10:02 game.added (sess 22) ✅ Receives ❌ Doesn't receive
10:05 session.started (sess 23) ✅ Receives ✅ Receives
10:06 Bot B subscribes to sess 23 ✅ Still sess 22 ✅ Subscribed
10:07 game.added (sess 22) ✅ Receives ❌ Doesn't receive
10:08 game.added (sess 23) ❌ Doesn't receive ✅ Receives
10:10 session.ended (sess 22) ✅ Receives ❌ Doesn't receive
10:15 session.ended (sess 23) ❌ Doesn't receive ✅ Receives
📝 Quick Reference
| Event | Broadcast Method | Scope | Subscription Required? |
|---|---|---|---|
session.started |
broadcastToAll() |
All authenticated clients | ❌ NO |
game.added |
broadcastEvent() |
Session subscribers only | ✅ YES |
vote.received |
broadcastEvent() |
Session subscribers only | ✅ YES |
session.ended |
broadcastEvent() |
Session subscribers only | ✅ YES |
🔗 Related Documentation
- WEBSOCKET_SUBSCRIPTION_GUIDE.md - Detailed subscription guide
- SESSION_START_WEBSOCKET.md - session.started event
- SESSION_END_WEBSOCKET.md - session.ended event
- BOT_INTEGRATION.md - Bot integration guide