Skip to content

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 event
  • timestamp: Unix timestamp when the event occurred
  • data: Complete original event data from the contact center system
  • metadata: 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 events
  • AGENT_LOGOUT: Agent logout events
  • AGENT_STATUS_CHANGE: Agent status changes
  • AGENT_QUEUE_JOIN: Agent joining a queue
  • AGENT_QUEUE_LEAVE: Agent leaving a queue
  • AGENT_CALL_START: Agent call start
  • AGENT_CALL_END: Agent call end
  • AGENT_BREAK_START: Agent break start
  • AGENT_BREAK_END: Agent break end
  • AGENT_TRANSFER: Agent transfer events
  • AGENT_CONFERENCE: Agent conference events
  • AGENT_DEVICE_REGISTER: Device registration
  • AGENT_DEVICE_UNREGISTER: Device unregistration
  • AGENT_PERFORMANCE: Performance metrics
  • AGENT_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 event
  • type: Event type (e.g., fonouc_cc_queue_on_call_event)
  • account_id: Account ID that generated the event
  • timestamp: Unix timestamp when the event occurred
  • data: Complete event data from the contact center system
  • metadata: 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.