chat-realtime-flow
Support System Endpoints
Socket.IO Namespace: /support
Port: 3002
Connection URL
http://localhost:3002/support
Authentication
- Optional: Guests can connect without authentication
- Token: Pass JWT token via:
auth.token
in handshaketoken
in query parametersAuthorization: Bearer <token>
in headers
Events (Client → Server)
1. JOIN_ROOM
{ "ticketId": "optional-ticket-id" }
2. LEAVE_ROOM
{ "ticketId": "optional-ticket-id" }
3. CREATE_TICKET (Authenticated users only)
{ "title": "Issue title", "category": "GENERAL|TECHNICAL|BILLING|ACCOUNT|SECURITY|FEATURE_REQUEST|BUG_REPORT", "message": "Description of the issue", "priority": "LOW|MEDIUM|HIGH|URGENT", "attachments": ["url1", "url2"] }
4. CREATE_GUEST_TICKET (Guests)
{ "title": "Issue title", "category": "GENERAL|TECHNICAL|BILLING|ACCOUNT|SECURITY|FEATURE_REQUEST|BUG_REPORT", "message": "Description of the issue", "priority": "LOW|MEDIUM|HIGH|URGENT", "attachments": ["url1", "url2"], "guestName": "Guest Name", "guestEmail": "guest@example.com" }
5. SEND_MESSAGE (Authenticated users only)
{ "ticketId": "ticket-id", "message": "Message content", "attachments": ["url1", "url2"] }
6. TYPING_START
{ "ticketId": "ticket-id" }
7. TYPING_END
{ "ticketId": "ticket-id" }
8. MARK_AS_READ (Authenticated users only)
{ "ticketId": "ticket-id", "messageId": "message-id" }
9. LOAD_MORE_MESSAGES (Authenticated users only)
{ "ticketId": "ticket-id", "page": 1, "limit": 20 }
Events (Server → Client)
1. TICKET_LIST
[ { "id": "ticket-id", "title": "Issue title", "category": "GENERAL", "status": "OPEN|IN_PROGRESS|WAITING_FOR_USER|WAITING_FOR_ADMIN|CLOSED|RESOLVED", "priority": "HIGH", "created_at": "2024-01-01T00:00:00.000Z", "updated_at": "2024-01-01T00:00:00.000Z", "admin_name": "Admin Name", "user_id": "user-id" } ]
2. NEW_TICKET
{ "id": "ticket-id", "title": "Issue title", "category": "GENERAL", "status": "OPEN", "priority": "HIGH", "created_at": "2024-01-01T00:00:00.000Z", "updated_at": "2024-01-01T00:00:00.000Z", "user_id": "user-id" }
3. NEW_MESSAGE
{ "ticketId": "ticket-id", "messages": [ { "id": "message-id", "message": "Message content", "ticket_id": "ticket-id", "user_id": "user-id", "admin_id": "admin-id", "current_status": "OPEN", "attachments": "url1,url2", "created_at": "2024-01-01T00:00:00.000Z", "user_name": "User Name", "admin_name": "Admin Name" } ] }
4. STATUS_CHANGED
{ "ticketId": "ticket-id", "oldStatus": "OPEN", "currentStatus": "IN_PROGRESS" }
5. TICKET_UPDATED
{ "id": "ticket-id", "status": "IN_PROGRESS", "admin_name": "Admin Name" }
6. TYPING_START
{ "ticketId": "ticket-id", "userType": "USER|ADMIN", "userName": "User Name", "userId": "user-id" }
7. TYPING_END
{ "ticketId": "ticket-id", "userType": "USER|ADMIN", "userId": "user-id" }
8. READ_RECEIPT
{ "ticketId": "ticket-id", "messageId": "message-id", "userId": "user-id" }
9. ERROR
{ "code": 400, "message": "Error message", "area": "SUPPORT_TICKET" }
10. UNREAD_COUNT
{ "ticketId": "ticket-id", "unreadCount": 1, "isNew": true }
Room Structure
- User Room:
SUPPORT_TICKET_USER_{userId}
- for user-specific notifications - Ticket Room:
SUPPORT_TICKET_{ticketId}
- for ticket-specific messages - Guest Room:
SUPPORT_TICKET_GUEST_{socketId}
- for guest users
Redis Channels
- User to Admin:
SUPPORT_TICKET_USER_TO_ADMIN
- Admin to User:
SUPPORT_TICKET_ADMIN_TO_USER
- Background Processor:
SUPPORT_TICKET_BACKGROUND_PROCESSOR
Test với Socket.IO Client
const io = require('socket.io-client'); // Connect với authentication const socket = io('http://localhost:3002/support', { auth: { token: 'your-jwt-token', }, }); // Connect như guest const guestSocket = io('http://localhost:3002/support'); // Listen for events socket.on('TICKET_LIST', tickets => { console.log('Tickets:', tickets); }); socket.on('NEW_MESSAGE', data => { console.log('New message:', data); }); // Join room socket.emit('JOIN_ROOM', { ticketId: 'optional-ticket-id' }); // Create ticket (authenticated users) socket.emit('CREATE_TICKET', { title: 'Test Issue', category: 'TECHNICAL', message: 'This is a test ticket', priority: 'HIGH', }); // Create guest ticket guestSocket.emit('CREATE_GUEST_TICKET', { title: 'Guest Issue', category: 'GENERAL', message: 'This is a guest ticket', guestName: 'John Doe', guestEmail: 'john@example.com', });