Using Events

Many things related to an agent session can occur on the platform, unprompted by your application. For example, the ACD can route a call to the agent. Or the agent phone can be disconnected. Or an active contact can end when the caller hangs up. You will want your agent application to know about these events so it can notify the agent by updating its UI, synchronize data with a third party system, etc.

Your application must request notification about events by polling the platform. You should begin polling for events as soon as the session is started. When the session is started, you will receive a "session ID". You will use this session ID in each event poll request. The polling model supported by the NICE CXone platform employs the "comet" pattern (a.k.a. "reverse ajax").

In this pattern, your application makes a REST-ful call (over HTTPS) to request new events. The server will only respond when there are new events related to the agent session, the agent leg, or any of its active contacts, or when the "timeout" period elapses without any new events. The timeout period is between 0 and 60 seconds, and is specified by your application in the new event poll request.

If there are new events, the API will return with an HTTP status of 200, and the response body will contain a JSON-encoded payload that contains one or more events.

If the timeout period elapses without any new events, the API will return an HTTP status code of 304, and a description that indicates that there were no new events.

Whether there are new events or not, your application should immediately request new events again when the API request returns, so there isn’t a lag when new events occur. In effect, your application will always be polling for new events. The comet pattern prevents your application from being very "chatty", and reduces the request-response cycle to a minimum of traffic.

There are a number of events that can occur on the platform. In step four, you can find links for each event type.

Most of the Agent API resources can only be accessed through an "Agent Session". An agent session is started by POST-ing a new session request to the "agent-sessions" collection resource. The context for the agent-sessions collection is specified in the API token that you receive from the platform when your application authenticates and requests a token. "Agent-sessions" applies to the user whose credentials were used to request the API token. When you start an agent session by POST-ing to the agent-sessions collection resource, the session is started for the agent whose credentials were used to retrieve the API token that is used when calling the "start session" method.

To start an agent session, you need to get an API Password (or Implicit) token from the token service. See the Getting Started tutorial for more details.

Once you have received a responce object with access token and other needed information, we can consider some code.

var auth_response;
var baseUrl = auth_response.resource_server_base_uri;
var sessionId;
var getEvents = false;

function startSession() {
    console.log("Starting session...");
    $.ajax({
        url: baseUrl + "services/v12.0/agent-sessions",
        type: "POST",
        contentType: "application/json",
        dataType: "json",
        data: JSON.stringify({
            "stationPhoneNumber": "4005150001"
        }),
        headers: {
            "Authorization": auth_response.token_type + " " +
            auth_response.access_token
        },
        success: function (data) {
            sessionId = data.sessionId;
            console.log("Session started");
            console.log("session id: " + sessionId);
            getEvents = true;//Get events. Timeout is set to 10 seconds
            getNextEvents(10);
        },
        error: function (xhr, status) {
            alert("start session failed: " + xhr.status);
        }
    });
}

function endSession() {
    $.ajax({
        type: "DELETE",
        url: baseUrl + 'services/v13.0/agent-sessions/' + sessionId,
        contentType: 'application/json',
        dataType: "json",
        headers: {
            "Authorization": auth_response.token_type + " " + auth_response.access_token
        },
        error:
        function (xhr, status) {
            eventLog("failed to end session: " + xhr.status + " - " + xhr.statusText);
        }
    });
}

Here we have two functions: startSession() and endSession() which will start and end our agent session respectively.

endSession() just sends DELETE XHR request to end current session.

The startSession() function sends the

{
    "stationPhoneNumber": "4005150001"
}

as a parameter. If our request will complete successfully and we have sessionId we can start requesting events immediately with getNextEvents().

The NICE CXone platform supports the "comet" design pattern (also known as "Ajax Push", "Reverse Ajax", "Two-way-web", "HTTP Streaming", and "HTTP Server Push".) This design pattern allows the agent client application to request events from the NICE CXone platform, and the HTTP request will not return until an event occurs on the platform. This can prevent the agent application from being very "chatty", and will greatly reduce the number of event polling requests needed. Because the event request is a "blocking" request (i.e. the API request doesn’t return until there is an event to retrieve), you should make these requests in a background thread.

When you request events from the platform, you must specify a "timeout" value (in seconds) after which the request will return, even if there are no events. Note that if an event occurs before the timeout period, the request will return the event immediately. Your application should dispatch a handler to handle the event, and immediately request new events again.

The timeout value must be between 0 and 60 seconds. A value of "0" causes the request to return immediately, whether there are events or not. Any value over 60, or any non-integer value, will result in an error response from the API.

Each request for events from the NICE CXone platform will return two things:

  1. A new session ID, which should be used in the subsequent event poll request
  2. A collection of events that have occurred since the previous event poll request, if any
function getNextEvents(timeout) {
    if (getEvents) {
        console.log("Getting events...");
        $.ajax({
            url: baseUrl + "services/v13.0/agent-sessions/" + sessionId +
            "/get-next-event?timeout=" + timeout,
            type: "GET",
            contentType: "application/json",
            dataType: "json",
            headers: {
                "Authorization": auth_response.token_type + " " +
                auth_response.access_token
            },
            success: function (data) {
                //Process events here
                processEvents(data);
                console.log("Events received");
            },
            error: function (xhr, status) {
                alert("get events failed: " + xhr.status + " - " + xhr.statusText);
                getEvents = false;
            },
            complete: function (xhr, status) {
                if (xhr.status == 304) {
                    //Do something if not modified
                }
            }
        });
    }
}

function processEvents(event) {
    // an undefined event typically means that a 304 was returned with
    // an empty body in the get-next-event request.  This is a "timeout",
    // which means there were no events... so nothing to log, we just
    // need to re-request events.
    if (typeof (event) != 'undefined') {
        sessionId = event.sessionId;
        var events = event.events;
        console.log("processing " + events.length + " events...");
        $.each(events, function (index, value) {
            console.log("event received: " + value.Type);
            if (value.Type == 'AgentSessionEnd') {
                getEvents = false;
            }
        });
    }
    getNextEvents();
}

Our getNextEvents() function requests events and calls processEvents() which process all coming events and calls cyclically getNextEvents() again. For example you can try to place a test call and see what events you will get

function callNumber() {
    console.log("Placing call...");
    $.ajax({
        url: baseUrl + "services/v13.0/agent-sessions/" + sessionId + "/dial-phone",
        type: "POST",
        contentType: "application/json",
        dataType: "json",
        data: JSON.stringify({
            "phoneNumber": "4005150002",
            "skillName": "sk_obphone1"
        }),
        headers: {
            "Authorization": auth_response.token_type + " " + auth_response.access_token
        },
        success: function (data) {
            console.log("Call request successful");
        },
        error: function (xhr, status) {
            alert("dial phone request failed: " + xhr.status);
        }
    });
}

There are a number of events that can occur on the platform. The links below will lead you to the JSON schema for each event type that you could receive.

Agent Events
Personal Connection Events
Call Contact Events
Work Item Contact Events
Indicator Events
Page Open Events
Chat Contact Events
Supervisor Events
Other Events