Replace existing docs with fresh documentation built entirely from source code analysis. OpenAPI 3.1 spec as source of truth, plus human-readable Markdown with curl examples, response samples, and workflow guides. - OpenAPI 3.1 spec covering all 42 endpoints (validated against source) - 7 endpoint reference docs (auth, games, sessions, picker, stats, votes, webhooks) - WebSocket protocol documentation (auth, subscriptions, 4 event types) - 4 guide documents (getting started, session lifecycle, voting, webhooks) - API README with overview, auth docs, and quick reference table - Old docs archived to docs/archive/ Made-with: Cursor
362 lines
9.7 KiB
Markdown
362 lines
9.7 KiB
Markdown
# Session Start WebSocket Event
|
|
|
|
This document describes the `session.started` WebSocket event that is broadcast when a new game session is created.
|
|
|
|
## 📋 Event Overview
|
|
|
|
When a new session is created, the backend broadcasts a `session.started` event to all subscribed WebSocket clients. This allows bots and other integrations to react immediately to new game sessions.
|
|
|
|
## 🔌 WebSocket Connection
|
|
|
|
**Endpoint:** `ws://localhost:5000/api/sessions/live`
|
|
|
|
**Authentication:** Required (JWT token)
|
|
|
|
## 📨 Event Format
|
|
|
|
### Event Type
|
|
```
|
|
session.started
|
|
```
|
|
|
|
### Full Message Structure
|
|
|
|
```json
|
|
{
|
|
"type": "session.started",
|
|
"timestamp": "2025-11-01T20:00:00.123Z",
|
|
"data": {
|
|
"session": {
|
|
"id": 17,
|
|
"is_active": 1,
|
|
"created_at": "2025-11-01T20:00:00.123Z",
|
|
"notes": "Friday Game Night"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Field Descriptions
|
|
|
|
| Field | Type | Description |
|
|
|-------|------|-------------|
|
|
| `type` | string | Always `"session.started"` |
|
|
| `timestamp` | string | ISO 8601 timestamp when the event was generated |
|
|
| `data.session.id` | number | The ID of the newly created session |
|
|
| `data.session.is_active` | number | Always `1` (active) for new sessions |
|
|
| `data.session.created_at` | string | ISO 8601 timestamp when the session was created |
|
|
| `data.session.notes` | string/null | Optional notes for the session |
|
|
|
|
## 🚀 Implementation
|
|
|
|
### Backend Implementation
|
|
|
|
The `session.started` event is automatically broadcast when:
|
|
|
|
1. **New Session Created**: Admin creates a session via `POST /api/sessions`
|
|
|
|
**Code Location:** `backend/routes/sessions.js` - `POST /` endpoint
|
|
|
|
```javascript
|
|
// Broadcast session.started event via WebSocket
|
|
const wsManager = getWebSocketManager();
|
|
if (wsManager) {
|
|
const eventData = {
|
|
session: {
|
|
id: newSession.id,
|
|
is_active: 1,
|
|
created_at: newSession.created_at,
|
|
notes: newSession.notes
|
|
}
|
|
};
|
|
|
|
wsManager.broadcastEvent('session.started', eventData, parseInt(newSession.id));
|
|
}
|
|
```
|
|
|
|
### Client Implementation Example
|
|
|
|
#### Node.js with `ws` library
|
|
|
|
```javascript
|
|
const WebSocket = require('ws');
|
|
|
|
const ws = new WebSocket('ws://localhost:5000/api/sessions/live');
|
|
|
|
ws.on('open', () => {
|
|
// Authenticate
|
|
ws.send(JSON.stringify({
|
|
type: 'auth',
|
|
token: 'your-jwt-token'
|
|
}));
|
|
});
|
|
|
|
ws.on('message', (data) => {
|
|
const message = JSON.parse(data.toString());
|
|
|
|
switch (message.type) {
|
|
case 'auth_success':
|
|
// Subscribe to the new session (or subscribe when you receive session.started)
|
|
ws.send(JSON.stringify({
|
|
type: 'subscribe',
|
|
sessionId: 17
|
|
}));
|
|
break;
|
|
|
|
case 'session.started':
|
|
console.log('New session started!');
|
|
console.log(`Session ID: ${message.data.session.id}`);
|
|
console.log(`Created at: ${message.data.session.created_at}`);
|
|
if (message.data.session.notes) {
|
|
console.log(`Notes: ${message.data.session.notes}`);
|
|
}
|
|
|
|
// Auto-subscribe to the new session
|
|
ws.send(JSON.stringify({
|
|
type: 'subscribe',
|
|
sessionId: message.data.session.id
|
|
}));
|
|
break;
|
|
}
|
|
});
|
|
```
|
|
|
|
#### Python with `websockets` library
|
|
|
|
```python
|
|
import asyncio
|
|
import json
|
|
import websockets
|
|
|
|
async def listen_for_session_start():
|
|
uri = "ws://localhost:5000/api/sessions/live"
|
|
|
|
async with websockets.connect(uri) as websocket:
|
|
# Authenticate
|
|
await websocket.send(json.dumps({
|
|
"type": "auth",
|
|
"token": "your-jwt-token"
|
|
}))
|
|
|
|
async for message in websocket:
|
|
data = json.loads(message)
|
|
|
|
if data["type"] == "auth_success":
|
|
print("Authenticated, waiting for sessions...")
|
|
|
|
elif data["type"] == "session.started":
|
|
session = data["data"]["session"]
|
|
print(f"🎮 New session started! ID: {session['id']}")
|
|
print(f"📅 Created: {session['created_at']}")
|
|
if session.get('notes'):
|
|
print(f"📝 Notes: {session['notes']}")
|
|
|
|
# Auto-subscribe to the new session
|
|
await websocket.send(json.dumps({
|
|
"type": "subscribe",
|
|
"sessionId": session["id"]
|
|
}))
|
|
|
|
asyncio.run(listen_for_session_start())
|
|
```
|
|
|
|
## 🧪 Testing
|
|
|
|
### Manual Testing Steps
|
|
|
|
1. **Start the backend server:**
|
|
```bash
|
|
cd backend
|
|
npm start
|
|
```
|
|
|
|
2. **Connect a WebSocket client** (use the test script or your own):
|
|
```bash
|
|
# You can modify ../tests/test-session-end-websocket.js to listen for session.started
|
|
```
|
|
|
|
3. **Create a new session** in the Picker UI or via API:
|
|
```bash
|
|
curl -X POST http://localhost:5000/api/sessions \
|
|
-H "Authorization: Bearer <your-jwt-token>" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"notes": "Friday Game Night"}'
|
|
```
|
|
|
|
4. **Verify the event is received** by your WebSocket client
|
|
|
|
### Expected Event
|
|
|
|
```json
|
|
{
|
|
"type": "session.started",
|
|
"timestamp": "2025-11-01T20:00:00.123Z",
|
|
"data": {
|
|
"session": {
|
|
"id": 18,
|
|
"is_active": 1,
|
|
"created_at": "2025-11-01T20:00:00.123Z",
|
|
"notes": "Friday Game Night"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## 🤖 Bot Integration
|
|
|
|
### IRC/Kosmi Bot Example
|
|
|
|
When the bot receives a `session.started` event, it should:
|
|
|
|
1. **Announce the new game session** to users
|
|
2. **Auto-subscribe to the session** to receive game.added and session.ended events
|
|
3. **Optionally display session info** (notes, ID, etc.)
|
|
|
|
Example bot response:
|
|
```
|
|
🎮 Game Night has started! Session #18
|
|
📝 Friday Game Night
|
|
🗳️ Vote with thisgame++ or thisgame-- during games!
|
|
```
|
|
|
|
### Implementation Example
|
|
|
|
```javascript
|
|
ws.on('message', (data) => {
|
|
const msg = JSON.parse(data.toString());
|
|
|
|
if (msg.type === 'session.started') {
|
|
const { id, notes, created_at } = msg.data.session;
|
|
|
|
// Announce to IRC/Discord/etc
|
|
bot.announce(`🎮 Game Night has started! Session #${id}`);
|
|
if (notes) {
|
|
bot.announce(`📝 ${notes}`);
|
|
}
|
|
bot.announce('🗳️ Vote with thisgame++ or thisgame-- during games!');
|
|
|
|
// Auto-subscribe to this session
|
|
ws.send(JSON.stringify({
|
|
type: 'subscribe',
|
|
sessionId: id
|
|
}));
|
|
}
|
|
});
|
|
```
|
|
|
|
## 🔍 Debugging
|
|
|
|
### Check WebSocket Logs
|
|
|
|
The backend logs WebSocket events:
|
|
|
|
```
|
|
[Sessions] Broadcasted session.started event for session 18
|
|
[WebSocket] Broadcasted session.started to 1 client(s) for session 18
|
|
```
|
|
|
|
### Common Issues
|
|
|
|
1. **Event not received:**
|
|
- Verify the client is authenticated (`auth_success` received)
|
|
- Check backend logs for broadcast confirmation
|
|
- **No subscription required** - All authenticated clients automatically receive `session.started` events
|
|
- Make sure your WebSocket connection is open and authenticated
|
|
|
|
2. **Missing session data:**
|
|
- Check if the session was created successfully
|
|
- Verify the API response includes all fields
|
|
|
|
3. **Duplicate events:**
|
|
- Normal if multiple clients are connected
|
|
- Each client receives its own copy of the event
|
|
|
|
## 📚 Related Documentation
|
|
|
|
- [Session End WebSocket Event](SESSION_END_WEBSOCKET.md)
|
|
- [WebSocket Testing Guide](WEBSOCKET_TESTING.md)
|
|
- [Bot Integration Guide](BOT_INTEGRATION.md)
|
|
- [API Quick Reference](API_QUICK_REFERENCE.md)
|
|
|
|
## 🔗 Session Lifecycle Events
|
|
|
|
```
|
|
session.started
|
|
↓
|
|
game.added (multiple times)
|
|
↓
|
|
vote.received (during each game)
|
|
↓
|
|
session.ended
|
|
```
|
|
|
|
## 📝 Notes
|
|
|
|
- The `session.started` event is broadcast to **all authenticated clients** (not just subscribed ones)
|
|
- **No subscription required** - All authenticated clients automatically receive this event
|
|
- Clients should auto-subscribe to the new session to receive subsequent `game.added` and `vote.received` events
|
|
- The `is_active` field will always be `1` for new sessions
|
|
- The `notes` field may be `null` if no notes were provided
|
|
- The timestamp is in ISO 8601 format with timezone (UTC)
|
|
|
|
## 💡 Use Cases
|
|
|
|
1. **Bot Announcements** - Notify users when game night starts
|
|
2. **Auto-Subscription** - Automatically subscribe to new sessions
|
|
3. **Session Tracking** - Track all sessions in external systems
|
|
4. **Analytics** - Log session creation times and frequency
|
|
5. **Notifications** - Send push notifications to users
|
|
|
|
## 🎯 Best Practices
|
|
|
|
1. **Auto-subscribe** to new sessions when you receive `session.started`
|
|
2. **Store the session ID** for later reference
|
|
3. **Handle reconnections** gracefully (you might miss the event)
|
|
4. **Use polling as fallback** to detect sessions created while disconnected
|
|
5. **Validate session data** before processing
|
|
|
|
## 🔄 Complete Event Flow Example
|
|
|
|
```javascript
|
|
const WebSocket = require('ws');
|
|
const ws = new WebSocket('ws://localhost:5000/api/sessions/live');
|
|
|
|
let currentSessionId = null;
|
|
|
|
ws.on('message', (data) => {
|
|
const msg = JSON.parse(data.toString());
|
|
|
|
switch (msg.type) {
|
|
case 'session.started':
|
|
currentSessionId = msg.data.session.id;
|
|
console.log(`🎮 Session ${currentSessionId} started!`);
|
|
|
|
// Auto-subscribe
|
|
ws.send(JSON.stringify({
|
|
type: 'subscribe',
|
|
sessionId: currentSessionId
|
|
}));
|
|
break;
|
|
|
|
case 'game.added':
|
|
console.log(`🎲 New game: ${msg.data.game.title}`);
|
|
break;
|
|
|
|
case 'vote.received':
|
|
console.log(`🗳️ Vote: ${msg.data.vote.type}`);
|
|
break;
|
|
|
|
case 'session.ended':
|
|
console.log(`🌙 Session ${msg.data.session.id} ended!`);
|
|
console.log(`📊 Games played: ${msg.data.session.games_played}`);
|
|
currentSessionId = null;
|
|
break;
|
|
}
|
|
});
|
|
```
|
|
|
|
## ✨ Conclusion
|
|
|
|
The `session.started` WebSocket event provides instant notification when new game sessions are created, allowing bots and integrations to react immediately and provide a seamless user experience.
|
|
|