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 handshake
    • token in query parameters
    • Authorization: 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',
});