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);
        }
    });
}

Custom Events

Custom events are events that you create and add into the agent event stream. It gives you a method of communicating or passing data from the VC to services that consume the event stream. This is a useful option if the existing events don't quite fit your use case.

An agent event stream is established with an agent session. An agent session begins when the agent launches their agent application.

View simple example

You ask contacts their favorite color in the IVR. You package and pass this selection as a custom event named FavoriteColor. You also have a companion service running with your agent application that listens for the FavoriteColor event. This lets you pass the contact's color selection to the companion service. The service then displays the color inside the agent application.

The following are highlights about custom events:

  • You can pass data as a string in the event.

  • You can create custom events using either an API or the CustomEvent action in a Studio script.

  • You can generate custom events in response to actions like OnAnswer or during pre-agent actions (if the agent ID is supplied).

  • You can consume the agent event stream with the get-next-event API or Get Next Event Studio action.

  • Because services typically already consume the agent event stream, this can be a convenient method of sharing data without needing to stand up your own custom endpoint.

  • Custom events are often used for small scope apps or microservices.

  • You can find custom events by opening the browser's developer tools in CXone Agent.

Create Custom Events

To create a custom event via API or Studio action, both options have the same requirements:

  • Name the event.

  • Assign a target agent in the agentId parameter or Target Agent property of the Studio action. You can use the ID from the AgentId variable. This is automatically populated after the OnAnswer event. If you want to send a custom event before an agent is assigned, you must still supply an agent ID.
  • Set the persistInMemory field. If the agent is logged out, this determines whether they will receive the event after logging back in.
  • Populate the Data field, which is the payload as a string.

Below is an example of creating a custom event using the custom-event API. For an example of using the CustomEvent action in a Studio script, see the online help.

Example curl:

curl -X PUT "https://api-$AREA.$DOMAIN/incontactapi/services/v30.0/agents/$AGENT_ID/custom-event?eventName=From_Postman&persistInMemory=false&data=Sent_from_Postman"

Request Type: PUT

Fields:

Parameter Type Details
agentId String The agent ID value that identifies the target agent.
eventName String The name of the event. This must be used by any consumers of the event.
persistInMemory Boolean If the agent identified by agentId is not currently logged in, the event will either be ignored or remain for the agent once they log back in.
data String Any string of data.

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