Developers Guide

Here is an example project with xuc authentication, both CTI and SIP websocket up and running, and an echo test plus a few examples of cti messages API. https://gitlab.com/xivo.solutions/cti-stack-example

Integration Principles

  • Download the javascript API files from the project xucserver on our gitlab repository

wget https://gitlab.com/xivo.solutions/xucserver/raw/master/app/assets/javascripts/cti.js
wget https://gitlab.com/xivo.solutions/xucserver/raw/master/app/assets/javascripts/callback.js
wget https://gitlab.com/xivo.solutions/xucserver/raw/master/app/assets/javascripts/membership.js
wget https://gitlab.com/xivo.solutions/xucserver/raw/master/app/assets/javascripts/xc_webrtc.js
wget https://gitlab.com/xivo.solutions/xucserver/raw/master/app/assets/javascripts/SIPml-api.js
  • Include the files in your projects

<!-- jquery needed as a dependency CDN from https://code.jquery.com/ -->
<script src="https://code.jquery.com/jquery-2.2.4.min.js"
    integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
    crossorigin="anonymous"></script>

<script src="http://<xucserver>:<xucport>/assets/javascripts/shotgun.js" type="text/javascript"></script>
<script src="cti.js" type="text/javascript"></script>
<script src="callback.js" type="text/javascript"></script>
<script src="membership.js" type="text/javascript"></script>

<!--  Optionnaly Include also the xc_webrtc and SIPml5 javascript APIs for the webRTC support -->

<script src="xc_webrtc.js" type="text/javascript"></script>
<script src="SIPml-api.js" type="text/javascript"></script>
var wsurl = "ws://"+server+"/xuc/api/2.0/cti?token="+token;
Cti.WebSocket.init(wsurl,username,phoneNumber);
  • Setup event handlers to be notified on
    • Phone state changes

    • Agent state changes

    • Statistics

  • Eventually also webRTC handlers
    • general

    • register

    • incoming

    • outgoing

  • Once web socket communication is established you are able to call XuC Cti javascript methods.
    • Place a call, log an agent ….

...
$('#login_btn').click(function(event){
   Cti.loginAgent($('#agentPhoneNumber').val());
});
$('#logout_btn').click(function(event){
   Cti.logoutAgent();
});
$('#xuc_dial_btn').click(function(event){
   Cti.dial($("#xuc_destination").val());
});
...

Sample Application

A sample application is provided by the XuC server. This application allows to display events and using different methods exposed by the XuC

http://<sucserver>:<xucport>/sample
../../../_images/sampleapp.png

You may browse and use the sample.js javascript file as an example

  • Calling Cti methods :

.$('#xuc_login_btn').click(function(event) {
     Cti.loginAgent($('#xuc_agentPhoneNumber').val());
 });

 $('#xuc_logout_btn').click(function(event) {
     Cti.logoutAgent();
 });
 $('#xuc_pause_btn').click(function(event) {
     Cti.pauseAgent();
 });
 $('#xuc_unpause_btn').click(function(event) {
     Cti.unpauseAgent();
 });
 $('#xuc_subscribe_to_queue_stats_btn').click(function(event) {
     Cti.subscribeToQueueStats();
 });
 $('#xuc_answer_btn').click(function(event) {
     Cti.answer();
 });
 $('#xuc_hangup_btn').click(function(event) {
     Cti.hangup();
 });
 $('#xuc_login_btn').click(function(event) {
     Cti.loginAgent($('#xuc_agentPhoneNumber').val());
 });
 $('#xuc_logout_btn').click(function(event) {
     Cti.logoutAgent();
 });
 $('#xuc_togglelogin_btn').click(function(event) {
     Cti.toggleAgentLogin();
 });
 $('#xuc_pause_btn').click(function(event) {
     Cti.pauseAgent();
 });
 $('#xuc_unpause_btn').click(function(event) {
     Cti.unpauseAgent();
 });
 $('#xuc_subscribe_to_queue_stats_btn').click(function(event) {
     Cti.subscribeToQueueStats();
 });
 $('#xuc_answer_btn').click(function(event) {
     Cti.answer();
 });
 $('#xuc_hangup_btn').click(function(event) {
     Cti.hangup();
 });
 $('#xuc_get_agent_call_history').click(function() {
     Cti.getAgentCallHistory(7);
 });
 $('#xuc_get_user_call_history').click(function() {
     Cti.getUserCallHistory(7);
 });
 $('#xuc_get_user_call_history_by_days').click(function() {
     Cti.getUserCallHistoryByDays(7);
 });

..............
  • Declaring events handlers :

Cti.setHandler(Cti.MessageType.USERSTATUSES, usersStatusesHandler);
Cti.setHandler(Cti.MessageType.USERSTATUSUPDATE, userStatusHandler);
Cti.setHandler(Cti.MessageType.USERCONFIGUPDATE, userConfigHandler);
Cti.setHandler(Cti.MessageType.LOGGEDON, loggedOnHandler);
Cti.setHandler(Cti.MessageType.PHONESTATUSUPDATE, phoneStatusHandler);
Cti.setHandler(Cti.MessageType.VOICEMAILSTATUSUPDATE, voiceMailStatusHandler);
Cti.setHandler(Cti.MessageType.LINKSTATUSUPDATE, linkStatusHandler);
Cti.setHandler(Cti.MessageType.QUEUESTATISTICS, queueStatisticsHandler);
Cti.setHandler(Cti.MessageType.QUEUECONFIG, queueConfigHandler);
Cti.setHandler(Cti.MessageType.QUEUELIST, queueConfigHandler);
Cti.setHandler(Cti.MessageType.QUEUEMEMBER, queueMemberHandler);
Cti.setHandler(Cti.MessageType.QUEUEMEMBERLIST, queueMemberHandler);
Cti.setHandler(Cti.MessageType.DIRECTORYRESULT, directoryResultHandler);

Cti.setHandler(Cti.MessageType.AGENTCONFIG, agentConfigHandler);
Cti.setHandler(Cti.MessageType.AGENTLIST, agentConfigHandler);
Cti.setHandler(Cti.MessageType.AGENTGROUPLIST, agentGroupConfigHandler);
Cti.setHandler(Cti.MessageType.AGENTSTATEEVENT, agentStateEventHandler);
Cti.setHandler(Cti.MessageType.AGENTERROR, agentErrorHandler);
Cti.setHandler(Cti.MessageType.ERROR, errorHandler);
Cti.setHandler(Cti.MessageType.AGENTDIRECTORY, agentDirectoryHandler);

Cti.setHandler(Cti.MessageType.CONFERENCES, conferencesHandler);
Cti.setHandler(Cti.MessageType.CALLHISTORY, callHistoryHandler);

xc_webrtc.setHandler(xc_webrtc.MessageType.GENERAL, webRtcGeneralEventHandler);
xc_webrtc.setHandler(xc_webrtc.MessageType.REGISTRATION, webRtcRegistrationEventHandler);
xc_webrtc.setHandler(xc_webrtc.MessageType.INCOMING, webRtcIncomingEventHandler);
xc_webrtc.setHandler(xc_webrtc.MessageType.OUTGOING, webRtcOutgoingEventHandler);

Throttling

The websocket server integrates a throttling mechanism to prevent flooding.

If you exceed more than 90 request messages in 30 seconds (with a burst of 180), your messages will be throttled and you will receive an error :

`{msgType: "Error", ctiMessage: {Error: "Maximum throttle throughput exceeded."}}`

By default, the server applies theses limits:

websocket.messagePerDuration = 90
websocket.maxBurst = 180

They can be adjusted if the default settings are not suitable due to a high volume of messages on a machine with heavy traffic. To adjust these values you have to set WS_THROTTLING_NB_MESSAGES and WS_THROTTLING_NB_MESSAGES_BURST environment variables in the /etc/docker/compose/custom.env

Example:

WS_THROTTLING_NB_MESSAGES=120
WS_THROTTLING_NB_MESSAGES_BURST=240

Then you need to recreate the xucserver container with xivocc-dcomp up -d to apply the changes. If these environment variables are not defined in the custom.env file, the default throttling limits will be applied.

This mechanism is analog to the rate-limiting from nginx, and concepts such as burst are explained there.

Debugging

Cti features

Cti events can be logged in the console if the Cti.debugMsg variable is set to true, you can do it directly in the developer tools console:

Cti.debugMsg=true;

You’ll then get send and received events in the console log (prefixed by S>>> and R<<< respectively):

2016-11-23 14:48:59.180 S>>> {"claz":"web","command":"dial","destination":"111","variables":{}}
2016-11-23 14:48:59.557 R<<< {"msgType":"PhoneStatusUpdate","ctiMessage":{"status":"CALLING"}}