Contact Center WebSocket Events Channel¶
The WebSocket Events Channel provides real-time event streaming for contact center operations. This channel allows clients to receive live updates about call events, agent state changes, and other contact center activities.
Overview¶
The Events Channel is designed to stream contact center events in real-time through WebSocket connections. It supports:
- Real-time event streaming from contact center operations
- Account-based filtering to receive events from specific accounts
- Event type filtering to subscribe to specific types of events
- JWT-based authentication for secure access
- Automatic reconnection and error handling
Available Endpoints¶
The Events Channel provides two sets of endpoints for different use cases:
API Endpoints (/api/v2/cc_events_channel)¶
These endpoints follow the standard REST API pattern and are recommended for most integrations:
- Login:
POST https://your-domain.com:9443/api/v2/cc_events_channel/login - WebSocket:
wss://your-domain.com:9443/api/v2/cc_events_channel/ws - Health Check:
GET https://your-domain.com:9443/api/v2/cc_events_channel/health - Statistics:
GET https://your-domain.com:9443/api/v2/cc_events_channel/stats
WebSocket Endpoints (/ws/v1/cc_events)¶
These endpoints are part of the WebSocket subrouter and provide the same functionality:
- Login:
POST https://your-domain.com:9443/ws/v1/cc_events/login - WebSocket:
wss://your-domain.com:9443/ws/v1/cc_events - Health Check:
GET https://your-domain.com:9443/ws/v1/cc_events/health - Statistics:
GET https://your-domain.com:9443/ws/v1/cc_events/stats
Note: Both endpoint sets provide identical functionality. Choose the one that best fits your integration pattern.
Authentication¶
Step 1: Obtain Authentication Token¶
Before connecting to the WebSocket, you need to obtain a JWT authentication token by making a POST request to the login endpoint.
Endpoint: POST https://your-domain.com:9443/api/v2/cc_events_channel/login
Request Body:
{
"username": "your_username",
"password": "your_password",
"domain": "your_account_domain",
"account_ids": ["account_id_1", "account_id_2"],
"event_types": ["fonouc_cc_queue_on_call_event", "fonouc_cc_queue_on_agent_state_event"]
}
Note: The account_ids and event_types fields are optional. If not provided, you will receive events from all accounts you have access to and all available event types.
Response:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_in": 86400
}
Step 2: Use the Token¶
The returned token must be included in the WebSocket connection request as either:
- Authorization header: Authorization: Bearer <token>
- Query parameter: ?token=<token>
WebSocket Connection¶
Connection URL¶
wss://your-domain.com:9443/api/v2/cc_events_channel/ws
Connection Examples¶
JavaScript/Node.js¶
const WebSocket = require('ws');
const token = 'your_jwt_token_here';
const ws = new WebSocket(`wss://your-domain.com:9443/api/v2/cc_events_channel/ws`, {
headers: {
'Authorization': `Bearer ${token}`
}
});
ws.on('open', function open() {
console.log('Connected to Events Channel');
});
ws.on('message', function message(data) {
const event = JSON.parse(data);
console.log('Received event:', event);
});
ws.on('error', function error(err) {
console.error('WebSocket error:', err);
});
Python¶
import websocket
import json
def on_message(ws, message):
event = json.loads(message)
print(f"Received event: {event}")
def on_error(ws, error):
print(f"WebSocket error: {error}")
def on_open(ws):
print("Connected to Events Channel")
token = "your_jwt_token_here"
ws = websocket.WebSocketApp(
f"wss://your-domain.com:9443/api/v2/cc_events_channel/ws",
header={"Authorization": f"Bearer {token}"},
on_message=on_message,
on_error=on_error,
on_open=on_open
)
ws.run_forever()
cURL (using wscat)¶
## Install wscat first: npm install -g wscat
wscat -c "wss://your-domain.com:9443/api/v2/cc_events_channel/ws" -H "Authorization: Bearer your_jwt_token_here"
Event Filtering¶
Account Filtering¶
To receive events from specific accounts, include the account_ids parameter in your login request:
{
"username": "your_username",
"password": "your_password",
"domain": "your_account_domain",
"account_ids": ["account_id_1", "account_id_2"]
}
Note: If no account_ids are specified, you will receive events from all accounts you have access to.
Event Type Filtering¶
To subscribe to specific event types, include the event_types parameter in your login request:
{
"username": "your_username",
"password": "your_password",
"domain": "your_account_domain",
"event_types": ["fonouc_cc_queue_on_call_event", "fonouc_cc_queue_on_agent_state_event"]
}
Available Event Types:
- fonouc_cc_queue_on_call_event - Call-related events (call start, end, transfer, etc.)
- fonouc_cc_queue_on_agent_state_event - Agent state changes (idle, busy, on-call, etc.)
Note: If no event_types are specified, you will receive all available event types.
Combined Filtering¶
You can combine both account and event type filtering:
{
"username": "your_username",
"password": "your_password",
"domain": "your_account_domain",
"account_ids": ["account_id_1"],
"event_types": ["fonouc_cc_queue_on_call_event"]
}
WebSocket Message Format¶
All messages sent through the WebSocket follow a standardized format. The system processes events from RabbitMQ and transforms them into a consistent structure before broadcasting to clients.
Message Structure¶
{
"id": "cc_evt_1758808138000000000",
"type": "fonouc_cc_queue_on_call_event",
"account_id": "b02d27af637452b70ac6abbd8385f491",
"timestamp": 1758808138,
"data": { /* Complete original event data from RabbitMQ */ },
"metadata": { /* Processing information */ }
}
Field Descriptions¶
id: Unique identifier for the event (format:cc_evt_<nanoseconds>)type: Event type identifier (e.g.,fonouc_cc_queue_on_call_event)account_id: Account ID that generated the eventtimestamp: Unix timestamp when the event occurreddata: Complete original event data from the contact center systemmetadata: Additional processing information (optional)
Event Types¶
The system supports two main event categories:
Contact Center Events¶
fonouc_cc_queue_on_call_event: Call-related events (call start, end, transfer, etc.)fonouc_cc_queue_on_agent_state_event: Agent state changes (idle, busy, on-call, etc.)
Generic Events (Fallback)¶
AGENT_LOGIN: Agent login eventsAGENT_LOGOUT: Agent logout eventsAGENT_STATUS_CHANGE: Agent status changesAGENT_QUEUE_JOIN: Agent joining a queueAGENT_QUEUE_LEAVE: Agent leaving a queueAGENT_CALL_START: Agent call startAGENT_CALL_END: Agent call endAGENT_BREAK_START: Agent break startAGENT_BREAK_END: Agent break endAGENT_TRANSFER: Agent transfer eventsAGENT_CONFERENCE: Agent conference eventsAGENT_DEVICE_REGISTER: Device registrationAGENT_DEVICE_UNREGISTER: Device unregistrationAGENT_PERFORMANCE: Performance metricsAGENT_CUSTOM_EVENT: Custom agent events
Complete Message Example¶
{
"id": "cc_evt_1758808138000000000",
"type": "fonouc_cc_queue_on_call_event",
"account_id": "b02d27af637452b70ac6abbd8385f491",
"timestamp": 1758808138,
"data": {
"Account-ID": "b02d27af637452b70ac6abbd8385f491",
"Queue-ID": "4157c203-c027-44d0-ab94-14107fa1fa00",
"Type": "fonouc_cc_queue_on_call_event",
"CDR": {
"channel": {
"Conference-Channel-Vars": {
"Energy-Level": 20,
"Member-Ghost": false,
"Member-Type": "member",
"Member-ID": 10165
},
"Custom-Channel-Vars": {
"Account-ID": "b02d27af637452b70ac6abbd8385f491",
"Bridge-ID": "71f97488-7719-4bb7-901e-ce3d5bb5cf75"
}
},
"Call-ID": "c29d3944-27ad-4fe4-b029-784af886102e",
"Conference-ID": "fe14be7f6e3205b9e6f96e9186bc0797",
"Event": "add-member"
},
"customer_info": {
"customer_callerid_name": "John Doe",
"customer_callerid_number": "15140000001",
"customer_uuid": "1-23921@178.128.227.190"
},
"history": [
{
"type": "agent",
"ext": "2256",
"event": "agent_enter",
"email": "agent@example.com",
"first_name": "Agent",
"last_name": "Name"
}
]
},
"metadata": {
"source": "contact_center",
"original_format": "contact_center_event",
"processed_at": 1758808138,
"queue_id": "4157c203-c027-44d0-ab94-14107fa1fa00"
}
}
Message Fields¶
id: Unique identifier for the eventtype: Event type (e.g.,fonouc_cc_queue_on_call_event)account_id: Account ID that generated the eventtimestamp: Unix timestamp when the event occurreddata: Complete event data from the contact center systemmetadata: Additional processing information
Error Handling¶
Connection Errors¶
The WebSocket connection may fail for various reasons:
- Authentication failure: Invalid or expired token
- Network issues: Connection timeout or network problems
- Server errors: Internal server errors
Reconnection Strategy¶
Implement automatic reconnection with exponential backoff:
function connectWithRetry(maxRetries = 5, baseDelay = 1000) {
let retryCount = 0;
function connect() {
const ws = new WebSocket(`wss://your-domain.com:9443/api/v2/cc_events_channel/ws`, {
headers: {
'Authorization': `Bearer ${token}`
}
});
ws.on('open', function() {
console.log('Connected successfully');
retryCount = 0; // Reset retry count on successful connection
});
ws.on('error', function(error) {
console.error('Connection error:', error);
if (retryCount < maxRetries) {
retryCount++;
const delay = baseDelay * Math.pow(2, retryCount - 1);
console.log(`Retrying connection in ${delay}ms (attempt ${retryCount}/${maxRetries})`);
setTimeout(connect, delay);
} else {
console.error('Max retry attempts reached');
}
});
return ws;
}
return connect();
}
Health Check¶
You can check the status of the Events Channel using the health check endpoint:
Endpoint: GET https://your-domain.com:9443/api/v2/cc_events_channel/health
Response:
{
"status": "healthy",
"total_connections": 5,
"timestamp": 1758808138
}
Statistics¶
Get connection statistics using the stats endpoint:
Endpoint: GET https://your-domain.com:9443/api/v2/cc_events_channel/stats
Response:
{
"total_connections": 5,
"clients": [
{
"id": "client_123",
"account_id": "account_1",
"connected_at": 1758808000,
"last_ping": 1758808130
}
],
"timestamp": 1758808138
}
Best Practices¶
1. Token Management¶
- Store tokens securely
- Implement token refresh before expiration
- Handle token expiration gracefully
2. Connection Management¶
- Implement proper connection lifecycle management
- Use heartbeat/ping mechanisms to detect connection issues
- Implement automatic reconnection with backoff
3. Event Processing¶
- Process events asynchronously to avoid blocking the connection
- Implement proper error handling for malformed events
- Use event queuing for high-volume scenarios
4. Resource Management¶
- Close connections properly when no longer needed
- Implement connection pooling for multiple clients
- Monitor connection count and resource usage
Troubleshooting¶
Common Issues¶
Connection Refused - Check if the Events Channel is enabled - Verify the WebSocket URL is correct - Ensure proper authentication token
Authentication Failed - Verify username/password are correct - Check if the account domain is valid - Ensure the token hasn't expired
No Events Received - Verify account filtering settings - Check event type filtering - Ensure the account has active events
Frequent Disconnections - Check network stability - Implement proper reconnection logic - Monitor server logs for errors
Debug Mode¶
Enable debug logging to troubleshoot connection issues:
const ws = new WebSocket(url, {
headers: {
'Authorization': `Bearer ${token}`
}
});
ws.on('open', () => console.log('WebSocket opened'));
ws.on('message', (data) => console.log('Message received:', data));
ws.on('error', (error) => console.error('WebSocket error:', error));
ws.on('close', (code, reason) => console.log('WebSocket closed:', code, reason));
Support¶
For technical support or questions about the Events Channel:
- Check the health endpoint for service status
- Review server logs for error details
- Contact your system administrator for configuration issues
Note: Replace your-domain.com with your actual domain name in all examples. The port :9443 should be included in all URLs.