#!/usr/bin/env node /** * Test script for session.ended WebSocket event * * This script: * 1. Connects to the WebSocket server * 2. Authenticates with a JWT token * 3. Subscribes to a session * 4. Listens for session.ended events * * Usage: * node test-session-end-websocket.js * * Example: * node test-session-end-websocket.js 17 your-jwt-token-here */ const WebSocket = require('ws'); // Configuration const WS_URL = process.env.WS_URL || 'ws://localhost:5000/api/sessions/live'; const SESSION_ID = process.argv[2] || '17'; const JWT_TOKEN = process.argv[3]; if (!JWT_TOKEN) { console.error('āŒ Error: JWT token is required'); console.error('Usage: node test-session-end-websocket.js '); process.exit(1); } console.log('šŸš€ Testing session.ended WebSocket event'); console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'); console.log(`šŸ“” Connecting to: ${WS_URL}`); console.log(`šŸŽ® Session ID: ${SESSION_ID}`); console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'); // Create WebSocket connection const ws = new WebSocket(WS_URL); ws.on('open', () => { console.log('āœ… Connected to WebSocket server\n'); // Step 1: Authenticate console.log('šŸ” Authenticating...'); ws.send(JSON.stringify({ type: 'auth', token: JWT_TOKEN })); }); ws.on('message', (data) => { try { const message = JSON.parse(data.toString()); switch (message.type) { case 'auth_success': console.log('āœ… Authentication successful\n'); // Step 2: Subscribe to session console.log(`šŸ“» Subscribing to session ${SESSION_ID}...`); ws.send(JSON.stringify({ type: 'subscribe', sessionId: parseInt(SESSION_ID) })); break; case 'subscribed': console.log(`āœ… Subscribed to session ${message.sessionId}\n`); console.log('šŸ‘‚ Listening for session.ended events...'); console.log(' (Close the session in the Picker to trigger the event)\n'); break; case 'session.ended': console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'); console.log('šŸŽ‰ SESSION.ENDED EVENT RECEIVED!'); console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'); console.log('\nšŸ“¦ Event Data:'); console.log(JSON.stringify(message, null, 2)); console.log('\n✨ Event Details:'); console.log(` Session ID: ${message.data.session.id}`); console.log(` Active: ${message.data.session.is_active === 1 ? 'Yes' : 'No'}`); console.log(` Games Played: ${message.data.session.games_played}`); console.log(` Timestamp: ${message.timestamp}`); console.log('\nāœ… Test successful! The bot should now announce the session end.\n'); // Close connection after receiving the event setTimeout(() => { console.log('šŸ‘‹ Closing connection...'); ws.close(); }, 1000); break; case 'auth_error': case 'error': console.error(`āŒ Error: ${message.message}`); ws.close(); process.exit(1); break; case 'pong': // Ignore pong messages break; default: console.log(`šŸ“Ø Received message: ${message.type}`); console.log(JSON.stringify(message, null, 2)); } } catch (err) { console.error('āŒ Failed to parse message:', err); console.error('Raw data:', data.toString()); } }); ws.on('error', (err) => { console.error('āŒ WebSocket error:', err.message); process.exit(1); }); ws.on('close', (code, reason) => { console.log(`\nšŸ”Œ Connection closed (code: ${code})`); if (reason) { console.log(` Reason: ${reason}`); } process.exit(0); }); // Handle Ctrl+C gracefully process.on('SIGINT', () => { console.log('\n\nšŸ‘‹ Shutting down...'); ws.close(); process.exit(0); }); // Send periodic pings to keep connection alive const pingInterval = setInterval(() => { if (ws.readyState === WebSocket.OPEN) { ws.send(JSON.stringify({ type: 'ping' })); } }, 30000); // Clean up interval on close ws.on('close', () => { clearInterval(pingInterval); });