Skip to main content

Real-Time Events Guide

Connect to real-time events using WebSockets for instant updates.

Overview

Semaswift uses Centrifugo for real-time communication. Connect once and subscribe to channels for live updates on calls, agents, tickets, and more.

Connection Setup

Get Connection Token

POST /api/v1/realtime/token
Authorization: Bearer YOUR_TOKEN
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_at": "2024-01-15T11:30:00Z"
}

Connect to WebSocket

import { Centrifuge } from 'centrifuge';

const centrifuge = new Centrifuge('wss://realtime.semaswift.com/connection/websocket', {
token: connectionToken
});

centrifuge.on('connected', (ctx) => {
console.log('Connected:', ctx);
});

centrifuge.on('disconnected', (ctx) => {
console.log('Disconnected:', ctx);
});

centrifuge.connect();

Available Channels

Voice Channels

ChannelEvents
voice:callsAll call events
voice:agentsAgent status changes
voice:queue:{id}Specific queue events

Ticketing Channels

ChannelEvents
tickets:allAll ticket updates
tickets:mineAssigned ticket updates
tickets:{id}Specific ticket

User Channels

ChannelEvents
user:{id}Personal notifications
presence:onlineOnline/offline status

Subscribing to Channels

// Subscribe to call events
const callsSub = centrifuge.newSubscription('voice:calls');

callsSub.on('publication', (ctx) => {
const event = ctx.data;
switch (event.type) {
case 'call.started':
console.log('New call:', event.data);
break;
case 'call.ended':
console.log('Call ended:', event.data);
break;
}
});

callsSub.subscribe();

Event Types

Call Events

{
"type": "call.started",
"data": {
"call_id": "call_123",
"direction": "inbound",
"from": "+1-555-123-4567",
"to": "+1-555-987-6543",
"queue_id": "queue_support",
"started_at": "2024-01-15T10:30:00Z"
}
}

Agent Events

{
"type": "agent.status_changed",
"data": {
"agent_id": "agent_123",
"previous_status": "available",
"new_status": "on_call",
"timestamp": "2024-01-15T10:30:00Z"
}
}

Ticket Events

{
"type": "ticket.updated",
"data": {
"ticket_id": "tkt_123",
"changes": {
"status": {"from": "open", "to": "pending"},
"assignee_id": {"from": null, "to": "usr_456"}
},
"updated_by": "usr_789",
"updated_at": "2024-01-15T10:30:00Z"
}
}

Presence

Track who's online:

const presenceSub = centrifuge.newSubscription('presence:online');

presenceSub.on('join', (ctx) => {
console.log('User joined:', ctx.info);
});

presenceSub.on('leave', (ctx) => {
console.log('User left:', ctx.info);
});

// Get current presence
presenceSub.presence().then((result) => {
console.log('Online users:', result.clients);
});

Error Handling

centrifuge.on('error', (ctx) => {
console.error('Connection error:', ctx);

if (ctx.code === 109) {
// Token expired - refresh and reconnect
refreshToken().then((newToken) => {
centrifuge.setToken(newToken);
});
}
});

callsSub.on('error', (ctx) => {
console.error('Subscription error:', ctx);
});

Best Practices

  1. Handle reconnection - Auto-reconnect is built-in
  2. Refresh tokens - Before expiry
  3. Unsubscribe - When leaving a page
  4. Batch updates - Don't update UI on every event
  5. Use presence sparingly - It has higher overhead