Archive for the ‘TSAPI’ Category

ctiSVR Open CTI for Salesforce

Posted: August 13, 2016 in TSAPI

Introduction

This post is about the configuration of CtiSVR (also known as ivrSVR)  with Salesforce Open CTI architecture. I have created a CtiSVR Open CTI package which contains a call center definition file and a sample html file, the two files allow you to integrate CtiSVR with Salesforece and enable Salesforce’s Click to Dial and ScreenPop features. Also a sample Softphone is implemented by the html file, you can use the Softphone to login Avaya ACD and perform CTI call controls. After you understand the logic behind, you can change the html file to fit your call center operation.

Creating A Call Center 

  • Click Setup->Customize->Call Center->Call Centers
  • callcentersetup
  • Click Call Centers->Import->Choose File->Select ctiSVROpenCTI.xml->Import
  • Click Manage Call Center Users->Add More Users->Find->Select your users->Add to Call Center
  • You can see the following screen after the Call Center definition file is imported and your users are added to the Call Center
  • importsuccess
  • You can move the ctiSVROpenCTI folder and the files to your WEB server, you need to change the CTI Adapter URL after you have changed the location

CtiSVR Configuration 

  • Firstly, you need to follow this guide to install and configure CtiSVR
  • In order to support “free seating”, we need to use an IP address to map to an agent extension, you can add the mapping of IP address to extension by CtiSVR tcpgate console command, for example
    • add ipextnmap 192.168.1.101 2611
    • You can display the mapping by the following tcpgate console command, for example
    • disp ipextnmap 
    • ipextnmap
  • You also need a WebSocket port for the integration of CtiSVR and Salesforce, to add a WebSocket port, enter the following tcpgate console commands
    • add tcp 9006 * * custom ivrsvrws
    • You can display all the listening ports of CtiSVR by the following tcpgate console command
    • disp tcp all
    • ipextnmap

CtiSVR Salesforce Sample Softphone

  • After Login Salesforce, the browser will prevent loading and execution of unsafe script (the CTI Adapter URL) from unauthorized site , for example
  • scriptexception
  • If you are using Chrome, click the Load Unsafe Script to load the Sample Softphone script.
  • loadunsafescripts
  • The Sample Softphone is appeared on the left hand side of the Salesforce
  • softphone

Sample Softphone Programming Details 

  • The source code of the sample Softphone is on here, most of the code can be found in the index.html file
  • When the page is load, it gets the configuration string that contains all details of the call center 
    // the page is loaded
    window.addEventListener("load", sforce.interaction.cti.getCallCenterSettings(getCallCenterSettingsCallback), false);
  • In the getCallCenterSettingsCallback function, the configString is in JSON format. Since the Softphone is connected to CtiSVR using WebSocket, the following is to get the production and backup WebSocket URIs
    var jsonObj = JSON.parse(configString);
    wsUriA = jsonObj["/ServerInfo/wsURIA"];
    wsUriB = jsonObj["/ServerInfo/wsURIB"];
  • In the getCallCenterSettingsCallback function, we also get the international, long distance and outside dialing prefix by the following 
    internationalPrefix = jsonObj["/reqDialingOptions/reqInternationalPrefix"];
    longDistPrefix = jsonObj["/reqDialingOptions/reqLongDistPrefix"];
    outsidePrefix = jsonObj["/reqDialingOptions/reqOutsidePrefix"];
  • After that, a WebSocket is created to connect to CtiSVR. Also set the callback functions for the WebSocket
    webSocket = new WebSocket(wsUriA);
    webSocket.onopen = function(evt) {
        onWebSocketOpen(evt)
    };
    webSocket.onclose = function(evt) {
        onWebSocketClose(evt)
    };
    webSocket.onmessage = function(evt) {
        onWebSocketMessage(evt)
    };
    webSocket.onerror = function(evt) {
        onWebSocketError(evt)
    };
  • When the WebSocket is connected to the CtiSVR, the callback function onWebSocketOpen will be invoked. We then submit a request (myextension) to CtiSVR to query the agent extension based on the IP address of the browser
    // Callback of WebSocket onOpen
    function onWebSocketOpen(evt) {
        webSocket.send(JSON.stringify({
            id: MSGID_GETEXTENSION,
            request: "myextension"
        }));
    }
  • If there is reply from CtiSVR, callback function onWebSocketMessage will be invoked. The response message also in JSON format. If the myextension command is successful, the extension number can be found in the response message. We then store the extension number and submit another command (startmonitor) to monitor the agent extension for unsolicited telephony events. 
    if (id==MSGID_GETEXTENSION) {
        if (jsonObj["result"]=='success') {
            myExtension = jsonObj["extension"];
            webSocket.send(JSON.stringify({
                id: MSGID_STARTMONITOR,
                request: "startmonitor",
                extension: myExtension
            }));
        } else {
            alert('SoftPhone get CTI extension failed.');
        }
    }
  • If the startmonitor command is successful, querydeviceinfo command is sent to CtiSVR
    } else if (id==MSGID_STARTMONITOR) {
        if (jsonObj["result"]=='success') {
            webSocket.send(JSON.stringify({
                id: MSGID_QUERYDEVICEINFO,
                request: "querydeviceinfo",
                extension: myExtension
            }));
        } else {
            alert('SoftPhone monitor CTI extension failed.');
        }
    }
  • We then set the state of the Softphone by the result of querydeviceinfo. Also register Click to Dial callback function and enable Click to Dial with Salesforce
    } else if (id==MSGID_QUERYDEVICEINFO) {
        if (jsonObj["result"]=='success') {
            myAgentId = jsonObj["associateddevice"];
            if (myAgentId) {
                document.getElementById('txtAgentId').value = myAgentId;
                document.getElementById('txtPasswd').value = "*****";
                document.getElementById('btnSubmitLogin').disabled = true;
                document.getElementById('btnSubmitLogout').disabled = false;
                document.getElementById('txtAgentId').disabled = true;
                document.getElementById('txtPasswd').disabled = true;
                webSocket.send(JSON.stringify({
                    id: MSGID_QUERYAGENTSTATE,
                    request: "queryagentstate",
                    extension: myExtension
                }));
            } else {
                document.getElementById('btnSubmitLogin').disabled = false;
                document.getElementById('btnSubmitLogout').disabled = true;
                document.getElementById('txtAgentId').disabled = false;
                document.getElementById('txtPasswd').disabled = false;
                document.getElementById('btnAuto').disabled = true;
                document.getElementById('btnManual').disabled = true;
                document.getElementById('btnAcw').disabled = true;
                document.getElementById('btnAux').disabled = true;
                webSocket.send(JSON.stringify({
                    id: MSGID_SNAPSHOT,
                    request: "snapshot",
                    extension: myExtension
                }));
            }
            // Register Click to Dial Callback
            sforce.interaction.cti.onClickToDial(onClickToDialCallback);
            // Enable Click to Dial
          sforce.interaction.cti.enableClickToDial(enableClickToDialCallback);
        }
    }
  • The Softphone is now ready for Click to Dial and ScreenPop. When user clicks a telephone number, callback function onClickToDialCallback is invoked. Before a number is submitted to CtiSVR, we need to format a prefix number and remove all characters such as “+()” and SPACE, then makecall or consultation command is sent to CtiSVR which depends on agent state 
    var onClickToDialCallback = function (response) {
        if (response.result) {
            var prefix;
            var jsonObj = JSON.parse(response.result);
            var number = jsonObj["number"];
            if (number.indexOf("+")>=0) {
                prefix = outsidePrefix + internationalPrefix;
            } else if (number.indexOf("(")>=0 && number.indexOf(")")>=0) {
                prefix = outsidePrefix + longDistPrefix;
            }
            number = number.replace(/\+/g, '');
            number = number.replace(/\s+/g, '');
            number = number.replace(/\(/g, '');
            number = number.replace(/\)/g, '');
            number = number.replace(/-/g, '');
            if (prefix) {
                number = prefix + number;
            } else {
                if (number.length > myExtension.length) {
                    number = outsidePrefix + number;
                }
            }
            if (myAgentIdle==true) {
                // idle, make call
                webSocket.send(JSON.stringify({
                    id: MSGID_MAKECALL,
                    request: "makecall",
                    extension: myExtension,
                    destination: number
                }));
            } else {
                // has call, consultation call
                webSocket.send(JSON.stringify({
                    id: MSGID_CONSULTATION,
                    request: "consultation",
                    extension: myExtension,
                    destination: number
                }));
            }
        }
    }
  • When there is an incoming call, the Softphone receives telephony offer event and Salesforce ScreenPop function is invoked
    if (jsonObj["eventtype"]=='offer') {
        // agent is not idle
        myAgentIdle = false;
        // inbound screen pop
        if (jsonObj["origcalling"]) {
            document.getElementById('txtCLI').value = jsonObj["origcalling"];
            document.getElementById('txtDNIS').value = jsonObj["called"];
            sforce.interaction.searchAndScreenPop(jsonObj["origcalling"], '',
                'inbound', searchAndScreenPopCallback);
        } else {
            document.getElementById('txtCLI').value = jsonObj["calling"];
            document.getElementById('txtDNIS').value = jsonObj["called"];
            sforce.interaction.searchAndScreenPop(jsonObj["calling"], '',
                'inbound', searchAndScreenPopCallback);
        }
    }
  • When Login button is clicked, jQuery function $(‘#btnSubmitLogin’).click is invoked
    $('#btnSubmitLogin').click(function(e) {
        e.preventDefault(); //prevent form from submitting
        myAgentId = $('#loginForm').find('[id=txtAgentId]').val();
        myPasswd = $('#loginForm').find('[id=txtPasswd]').val();
        if (myAgentId) {
            webSocket.send(JSON.stringify({
                id: MSGID_LOGIN,
                request: "login",
                extension: myExtension,
                agentid: myAgentId,
                passwd: myPasswd
            }));
        }
    });
  • When Logout button is clicked, jQuery function $(‘#btnSubmitLogout’).click is invoked
    $('#btnSubmitLogout').click(function(e) {
        e.preventDefault(); //prevent form from submitting
        if (myAgentId) {
            webSocket.send(JSON.stringify({
                id: MSGID_LOGOUT,
                request: "logout",
                extension: myExtension,
                agentid: myAgentId
            }));
        }
    });
  • When AUTO button is clicked, the function changeAUTO is invoked
    function changeAUTO() {
        if (myAgentId) {
            webSocket.send(JSON.stringify({
                id: MSGID_CHANGEAUTO,
                request: "setstate",
                extension: myExtension,
                agentid: myAgentId,
                passwd: myPasswd,
                state: "auto"
            }));
        }
    }
  • When MANUAL button is clicked, the function changeMANUAL is invoked
    function changeMANUAL() {
        if (myAgentId) {
            webSocket.send(JSON.stringify({
                id: MSGID_CHANGEMANUAL,
                request: "setstate",
                extension: myExtension,
                agentid: myAgentId,
                passwd: myPasswd,
                state: "manual"
            }));
        }
    }
  • When ACW button is clicked, the function changeACW is invoked
    function changeACW() {
        if (myAgentId) {
            webSocket.send(JSON.stringify({
                id: MSGID_CHANGEACW,
                request: "setstate",
                extension: myExtension,
                agentid: myAgentId,
                passwd: myPasswd,
                state: "acw"
            }));
        }
    }
  • When AUX button is clicked, the function changeAUX is invoked
    function changeAUX() {
        if (myAgentId) {
            var reason = document.getElementById('selReasonCode');
            var code = reason.options[reason.selectedIndex].value;
            webSocket.send(JSON.stringify({
                id: MSGID_CHANGEAUX,
                request: "setstate",
                extension: myExtension,
                agentid: myAgentId,
                passwd: myPasswd,
                state: "aux",
                reasoncode: code
            }));
        }
    }
  • When Answer button is clicked, jQuery function $(‘#btnSubmitAnswer’).click is invoked
    $('#btnSubmitAnswer').click(function(e) {
        e.preventDefault(); //prevent form from submitting
        webSocket.send(JSON.stringify({
            id: MSGID_ANSWER,
            request: "answer",
            extension: myExtension
        }));
    });
  • When Call button is clicked, jQuery function $(‘#btnSubmitCall’).click is invoked
    $('#btnSubmitCall').click(function(e) {
        e.preventDefault(); //prevent form from submitting
        var phoneNumber =
            $('#phoneNumberForm').find('[id=txtPhoneNumber]').val();
        if (phoneNumber) {
            webSocket.send(JSON.stringify({
                id: MSGID_MAKECALL,
                request: "makecall",
                extension: myExtension,
                destination: phoneNumber
            }));
        }
    });
  • When Hold button  is clicked, the function pressHold is invoked
    function pressHold() {
        webSocket.send(JSON.stringify({
            id: MSGID_HOLD,
            request: "hold",
            extension: myExtension
        }));
    }
  • When Retrieve button is clicked, the function pressRetrieve is invoked
    function pressRetrieve() {
        webSocket.send(JSON.stringify({
            id: MSGID_RETRIEVE,
            request: "retrieve",
            extension: myExtension
        }));
    }
  • When Hangup button is clicked, the function pressHangup is invoked
    function pressHangup() {
        webSocket.send(JSON.stringify({
            id: MSGID_HANGUP,
            request: "hangup",
            extension: myExtension
        }));
    }
  • When DropParty button is clicked, the function pressDrop is invoked
    function pressDrop() {
        var phoneNumber =
            $('#phoneNumberForm').find('[id=txtPhoneNumber]').val();
        if (phoneNumber) {
            webSocket.send(JSON.stringify({
                id: MSGID_DROPPARTY,
                request: "dropparty",
                extension: myExtension,
                party: phoneNumber
            }));
        }
    }
  • When Consultation button is clicked, the function pressConsultation is invoked
    function pressConsultation() {
        var phoneNumber =
            $('#phoneNumberForm').find('[id=txtPhoneNumber]').val();
        if (phoneNumber) {
            webSocket.send(JSON.stringify({
                id: MSGID_CONSULTATION,
                request: "consultation",
                extension: myExtension,
                destination: phoneNumber
           }));
        }
    }
  • When Reconnect button is clicked, the function is pressReconnect invoked
    function pressReconnect() {
        webSocket.send(JSON.stringify({
            id: MSGID_RECONNECT,
            request: "reconnect",
            extension: myExtension
        }));
    }
  • When Transfer button is clicked, the function pressTransfer is invoked
    function pressTransfer() {
        var phoneNumber =
            $('#phoneNumberForm').find('[id=txtPhoneNumber]').val();
        webSocket.send(JSON.stringify({
            id: MSGID_TRANSFER,
            request: "transfer",
            extension: myExtension,
            destination: phoneNumber
        }));
    }
  • When Conference button is clicked, the function pressConference is invoked
    function pressConference() {
        var phoneNumber =
            $('#phoneNumberForm').find('[id=txtPhoneNumber]').val();
        webSocket.send(JSON.stringify({
            id: MSGID_CONFERENCE,
            request: "conference",
            extension: myExtension,
            destination: phoneNumber
        }));
    }

CTI Tools Updated

Posted: August 2, 2016 in News, TSAPI

Some CTI tools such as CtiSVR, AstLogger and ScreenPop use uuiSVR for data passing during call control. The data read write procedures are changed to support user data in XML format and some tools are updated for this reason. Please find the details below

CtiSVR Version 1.2.3
1. The user data is encoded in base64 format before storing in uuiSVR. Also the data is decoded before sending to related applications.
2. calltoui is modified to support call with user data.

AstLogger 1.4.9
1. Supports agent triggered trunk recording.
2. Fixed a bug in the WebSocket interface, the closing of websocket will crash the application.
3. The user data is encoded in base64 format before storing in uuiSVR. Also the data is decoded before sending to related applications.

ScreenPop Version 1.4.5
1. The user data is encoded in base64 format before storing in uuiSVR. Also the data is decoded before sending to related applications.

ScreenPop 1.4.4 Released

Posted: July 21, 2016 in News, TSAPI

21 July 2016, screenPop 1.4.4 just released. This version

1. Fixed a bug in the WebSocket interface, the closing of websocket will crash the application.
2. Supports DropParty() function.

ctiSVR 1.2.2 Released

Posted: July 19, 2016 in News, TSAPI

19 Jul 2016, ctiSVR (also known as ivrSVR) 1.2.2 just released. This version

1. More trace messages are added.
2. Fixed a bug in the WebSocket module, the tool crashed when an open socket is closed.
3. Supports callto protocol, the tool callto.exe and calltoui.exe are modified for this tool. Click-to-call feature for CRM products such as Salesforce, SugarCRM are supported.

AstLogger 1.4.8 Released

Posted: June 23, 2016 in Asterisk, News, TSAPI

23 Jun 2016, AstLogger 1.4.8 just released. This version 

1. Supports call log centralization by integration with CallAban.
2. The logic for application data logging is modified. Only the modified data item will be saved to database.
3. Fixed a bug that AstLogger will not startup successfully before AES startup.
4. Fixed a bug that AstLogger will not startup successfully before Asterisk startup.
5. Supports pauserecording and unpauserecording function by the REST interface.

ivrSVR 1.2.1 Released

Posted: June 17, 2016 in News, TSAPI

17 June 2016, ivrSVR 1.2.1 just released. This version

1. Supports monitor “all” device by the ActiveX and WebSocket interfaces.
2. Supports DropParty() API.

ivrSVR 1.2.0 Released

Posted: May 21, 2016 in News, TSAPI

21 May 2016, ivrSVR 1.2.0 just released. This version

1. Supports SelectiveListeningHold() and SelectiveListeningRetrieve() API
2. Supports permanent connection between ivrSVR and uuiSVR to make the add, update and delete of user data more efficient.
3. Fixed a bug that ivrSVR will not startup successfully before AES startup.

ivrSVR 1.1.9 Released

Posted: May 1, 2016 in News, TSAPI

1 May 2016, ivrSVR 1.1.9 just released. This version included the following updates:

1. The Answer() API supports answer call by callid.
2. The Retrieve() API supports retrieve call by callid.
3. The ClearCall() API supports clear call by callid.
4. New API SingleStepConference() is supported.
5. New admin command “bulkadd extension” and “bulkdelete extension” are supported via tcpgate console.
6. The MakeCall() API returns additonal UCID field to application.
7. The Consultation() API returns additional UCID field to application.

For details, please refer to the support page.

ivrSVR 1.1.8 Released

Posted: March 25, 2016 in News, TSAPI

25 Mar 2016, ivrSVR 1.1.8 just released. This version supports more CTI functions 

  • QueryDeviceInfo
  • DeflectCall
  • PickupCall
  • QueryAgentLogin
  • QueryAgentState
  • QueryCallClassifier
  • QueryDeviceName
  • QueryDoNotDisturb
  • QueryForwarding
  • QueryMsgWaitingInd
  • QueryStationStatus
  • QueryTimeOfDay
  • QueryTrunkGroup
  • QueryUCID
  • SetDoNotDisturb
  • SetForwarding
  • SetMsgWaitingInd

ctiSVR / CTI Server for Avaya

Posted: March 25, 2016 in TSAPI

Introduction

architecture

The ctiSVR (also known as ivrSVR, the two names are interchangeable) is a CTI server for IVR systems and agent front-end applications. The ctiSVR is part of the CTI Architecture, it uses TSAPI library to monitor IVR and agent extensions, it hides the technical details of TSAPI and provides simple ActiveX, REST and WebSocket interfaces for the development of IVR systems and front-end applications. The ctiSVR program supports passing of customized user data between different kinds of CTI software when a customized DLL is developed. Currently, the ctiSVR program supports the following call control functions:

  • ACD Login – Login ACD
  • ACD Logout – Logout ACD
  • ACD SetState – Set AUX, ACW, MANUAL or AUTO mode
  • MakeCall – Make a call
  • Answer – Answer a call
  • Hangup – Hangup a call
  • DropParty – Drop a specific party from a call
  • Hold – Hold a call
  • Retrieve – Retrieve a call
  • Transfer – Single step or two steps transfer which depends on extension state
  • Conference – Single step or two steps conference which depends on extension state
  • Consultation – Make a consultation call
  • Reconnect – Reconnect from a consultation call
  • Alternate – Alternate a hold and a connected call
  • SingleStepConference – Join a new device into an existing call
  • SingleStepTransfer – Transfers an existing connection to another device
  • SelectiveListeningHold – Prevent a specific party on a call from hearing anything said by another specific party or all other parties on the call
  • SelectiveListeningRetrieve – Retrieve a party from listen-hold to another party or all parties that were previously being listen-held
  • DTMF – Send a DTMF tone or a string of DTMF tones
  • UserData – Get user data when a call alert or hangup
  • ClearCall – Clear a call or all calls of an extension
  • DeflectCall – Redirects an alerting call at a device with the connection to a new destination, either on-PBX or off-PBX
  • PickupCall – Redirects an alerting call at a device to another on-PBX device
  • Snapshot – Snapshot a device
  • QueryACDSplit – Query ACD split and provides number of available agents, number of calls in queue and number of logon agents
  • QueryAgentLogin – Query the extension of each ACD agent logged into the specified ACD split
  • QueryAgentState – Query the agent state of an ACD agent
  • QueryCallClassifier – Query the number of “idle” and “in-use” ports of call classifier cards
  • QueryTimeOfDay – Query the switch information for the year, month, day, hour, minute, and second
  • QueryDeviceName – Query the associated name of the device
  • QueryDoNotDisturb – Query the status of the send all calls feature expressed as on or off at a device
  • QueryDeviceInfo – Query the class and type of a device
  • QueryForwarding – Query the forwarding status of the device
  • QueryMsgWaitingInd – Query status of the message waiting indicator expressed as on or off for a device
  • QueryStationStatus – Query the idle and/or busy state of a station
  • QueryTrunkGroup – Query the number of idle trunks and the number of in-use trunks
  • QueryUCID – Query the Universal Call ID (UCID) for a normal callID
  • SetDoNotDisturb – Turns on or off the G3 Send All Calls (SAC) feature for a user station
  • SetForwarding – Sets the G3 Call Forwarding feature on or off for a user station
  • SetMsgWaitingInd – Sets the G3 Message Waiting Indicator (MWI) on or off for a user station
  • MyExtension – Query extension number by IP address
  • ListExtension – List all extensions that monitored by ctiSVR
  • AddExtension – Add extension and start monitoring by ctiSVR
  • DelExtension – Delete extension and stop monitoring by ctiSVR
  • MakePhantomCall – Use a phantom device that is controlled by ctiSVR to make call, waits Connect or Disconnect event in a provided duration
  • PinVer – Conference a IVR extension and waits for Disconnect event which the PinVer result is contained in the hangup data of the Disconnect event
  • SvrInfo – Get version and license information
  • SplitSkillStatus – Display login status of a split/skill
  • GetLinkStatus – Get DMCC link status
  • GetButtonInformation – Get button information of an extension by DMCC API
  • GetLampMode – Get lamp mode of an extension by DMCC API
  • GetDisplay – Get display of an extension by DMCC API
  • GetHookSwitchStatus – Get hook switch status of an extension by DMCC API
  • GetRingerStatus – Get ringer status of an extension by DMCC API
  • GetRegistrationState – Get registration state of an extension by DMCC API
  • ValidateDeviceSecurityCode – Validate device security code of an extension by DMCC API
  • ChangeDeviceSecurityCode – Change device security code of an extension by DMCC API
  • ButtonPress – Press a button of an extension by DMCC API
  • SetHookSwitchStatus – Set hook switch status by DMCC API

Web Softphone

Web Softphone is supported by ctiSVR now! The softphone is crated simply by a PHP page and uses WebSocket to communicate with ctiSVR. If you have CRM application, you can include this page and customize it as CTI application. Have Fun!

Pricing Details

Check the pricing from this URL

Reference Manual

Upgrade Procedure

Docker Implementation 

Supported Environment

  • Avaya AES 6.x, 7.x, 8.x, 10.x
  • Latest version Windows Server
  • Latest version of RedHat/Rocky Linux

Supported Integration Interfaces

Testing using Docker Image

Please follow this guide to test CtiSVR using Docker Container.

Testing using OVA File

centos

We also create a OVA file which you can deploy it to VirtualBox or VMware for testing.  After deploying the OVA file, please modify the following for your own environment:

  • Reference this guide to delete the file /etc/udev/rules.d/70-persistent-net.rules
  • Change the MAC address and IP address of the VM in the file /etc/sysconfig/network-scripts/ifcfg-eth0
  • Edit /usr/lib/tslibrc, change 127.0.0.1 to the IP address of your Avaya AES
  • Telnet to ctiSVR console port 14012, update the parameters ivr_tlink_01 and ivr_tlink_02. The ivr_tlink_01 and ivr_tlink_02 string contain three fields and they are separated by comma (,). For example “AVAYA#AVAYA_ECS#CSTA#XXXXXX,username,encrypted_password
    • AVAYA#AVAYA_ECS#CSTA#XXXXXX is the tlink, you can get the name by command /usr/lib/tstest
    • username is the AES cti user
    • encrypted_password can be obtained by tcpgate console command genpass, enter your AES cti user password two times you will get the encrypted password
  • Once the changes are completed, reboot the VM
  • Contact service@upinget.com for a trial license

The username and password of the OVA VM is

  • OS : root/P@ssw0rd
  • MySQL: root/P@ssw0rd
  • ivrSVR console: tcpgate/tcpgate01
  • uuiSVR console: tcpgate/tcpgate01

Windows Installation – Preparation and Password Encryption

  • The access MDB file stored the username and password of AE server. For security reason, a tool called encryptpasswd.exe is provided to generate an encrypted password for the installation and configuration of the software
  • Execute the program, generate an encrypted passwords for the user of AE server, then paste the encrypted password to parameter ivr_tlink. For example, the encrypted password for “p@ssword” is “R3NIw1yJMLlnPFzEQtuh2A==”
  • encryptpasswd

Windows Installation – ODBC Administration

  • For 64 bit Windows system, please follow the steps below
    • For CtiSVR 64bit version, configure ODBC System DSN using
      • C:\Windows\System32\odbcad32.exe
    • Stop the Windows firewall because it enables by default and telnet port 14012 is required for the application.

Windows Installation Guide

  • Download the TSAPI client for Windows 64-bit from Avaya web site, it contains the library files. DevConnect registration is required before you can access the download page.
  • Download the ivrSVR zip file here or backup site.
  • Follow the installation steps below to install the software.
    • Extract all the files into directory c:\program files\ivrSVR
    • Open Windows Command Prompt, enter the following commands to register the program as Windows Service
      • cd c:\program files\ivrSVR
      • ivrSVR64 -i
      • sc description ivrSVR64 “Provides CTI functions for Avaya CM”
      • uuiSVR64 -i
      • sc description uuiSVR64 “Provides userdata functions for ctiSVR”
    • If you cannot find the Microsoft Access Driver when using the ODBC Data Source Administrator (64-bit), please download and install Microsoft Access Database Engine 2016 Redistributable
    • Open ODBC Setting, create a System DSN called IVRSVRCFG for Microsoft Access Driver and point to ivrsvr.mdb which is located in the directory c:\program files\ivrSVR
    • Open ODBC Setting, create a System DSN called UUISVRCFG for Microsoft Access Driver and point to uuisvr.mdb which is located in the directory c:\program files\ivrSVR
    • Start the Windows Service ivrSVR
    • Telnet to localhost and port number 14012, enter username tcpgate and password tcpgate01 to access the program console
    • Enter the following command to setup the ctiSVR
      • setup
      • setup api
    • Enter the following command to add extension, the ivrSVR can control the extension once it is added to the database
      • add extension 60123
    • Enter the following command in the program console, you will receive debug information
      • trace on asc
    • Enter the following command in the program console, you will get the help message
      • help
    • To support passing of user data between applications, please install uuiSVR which is described in ScreenPop page. Then modify the ivr_uuisvr parameter to have the IP address and port number of the uuiSVR.

RedHat/CentOS 7.x Installation Guide

  • centosredhat
  • The following is for RedHat/CentOS 7 (64 bit only), other Linux distributions are not supported
  • The ctiSVR is built using Avaya TSAPI 32bit library, the ctiSVR executable is also a 32bit application
  • Login as root and execute the following commands
  • yum update
  • reboot
  • Install the MySQL 8.x
  • sudo rpm -Uvh https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm
    sudo yum --enablerepo=mysql80-community install mysql-community-server
    sudo service mysqld start
    grep "A temporary password" /var/log/mysqld.log
    mysql_secure_installation
  • Install the following packages
  • yum install glibc.i686 libstdc++.i686 expat.i686 unixODBC.i686 openssl-libs.i686 telnet wget telnet
  • wget https://dev.mysql.com/get/Downloads/Connector-ODBC/8.0/mysql-connector-odbc-setup-8.0.22-1.el7.i686.rpm
    wget https://dev.mysql.com/get/Downloads/Connector-ODBC/8.0/mysql-connector-odbc-8.0.22-1.el7.i686.rpm
    yum install mysql-connector-odbc*
    ln -s /usr/lib/libmyodbc8a.so /usr/lib/libmyodbc5.so
  • Download Avaya Aura AE Services 8.1.3 TSAPI Client for RHEL 7 from DevConnect
  • chmod +x tsapi-client-linux-8.1.3-25.i386.bin
  • Execute the installation file tsapi-client-linux-8.1.3-25.i386.bin
    • ./tsapi-client-linux-8.1.3-25.i386.bin
  • Edit /usr/lib/tslibrc, change 127.0.0.1 to the IP address of your Avaya AES
  • Config and start MySQL
  • chkconfig mysqld on
  • service mysqld start
  • Create database and user
  • mysql -u root -p
  • create database ivrsvr;
  • create database uuisvr;
  • create user 'tcpgate'@'localhost' identified by 'P@ssw0rd';
  • grant all on ivrsvr.* to 'tcpgate'@'localhost';
  • grant all on uuisvr.* to 'tcpgate'@'localhost';
  • flush privileges;
  • quit
  • mysql -h localhost -u tcpgate -p ivrsvr < ivrsvr.sql
  • mysql -h localhost -u tcpgate -p uuisvr < uuisvr.sql
  • Copy the following to /etc/odbc.ini file
    • [IVRSVRCFG]
      Description = MySQL connection to ivrSVR
      Driver = MySQL
      Server = localhost
      Port = 3306
      Database = ivrsvr
    • [UUISVRCFG]
      Description = MySQL connection to uuiSVR
      Driver = MySQL
      Server = localhost
      Port = 3306
      Database = uuisvr
  • Create user and copy files
  • useradd upinget
  • mkdir /usr/local/ctisvr
  • cp ivrSVR /usr/local/ctisvr
  • cp uuiSVR /usr/local/ctisvr
  • chmod +x /usr/local/ctisvr/ivrSVR
  • chmod +x /usr/local/ctisvr/uuiSVR
  • chown -R upinget.upinget /usr/local/ctisvr
  • mkdir -p /var/log/ivrsvr
  • mkdir -p /var/log/uuisvr
  • chown -R upinget.upinget /var/log/ivrsvr
  • chown -R upinget.upinget /var/log/uuisvr
  • Auto start the daemon after server reboot
  • echo "rm /tmp/ivrsvr.log" >> /etc/rc.local
  • echo "su upinget -c '/usr/local/ctisvr/ivrSVR -u tcpgate -p 40UIt9O3PqtwsSn+Wx6pig=='" >> /etc/rc.local
  • echo "rm /tmp/uuisvr.log" >> /etc/rc.local
  • echo "su upinget -c '/usr/local/ctisvr/uuiSVR -u tcpgate -p 40UIt9O3PqtwsSn+Wx6pig=='" >> /etc/rc.local
  • chmod +x /etc/rc.local

Change of License Key

  • Once you obtained a license key, please enter the following tcpgate console commands to activate the license. For example, if your license key is Bbshtj3sohqSKqqY41wM/qG6zSKvJNh+nrxy4zGXfDM=
    • update parameter ivr_licensekey Bbshtj3sohqSKqqY41wM/qG6zSKvJNh+nrxy4zGXfDM=
    • reload
  • To check your license status, the command is
    • disp license 

Failover of Avaya AES

  • The ctiSVR supports multiple Avaya AES, it switches to another AES  automatically when it detects active stream is failure. The ctiSVR has internal polling thread, it checks Avaya AES status every 30 seconds. When it detects Avaya AES failure, it failover to another Avaya AES automatically.

Change of Avaya AES

  • The ivrSVR supports multiple Avaya AES, it switches to another AES  automatically when it detects active stream is failure.
  • The default configuration database (ivrSVR.mdb) contains two entries of AES information, to change the AES information, please enter the follwoing tcpgate console commands
    • genpass
      • Enter the AES CTI user password twice to generate an encrypted password
    • update parameter ivr_tlink_01 AVAYA#AVAYA_ECS#CSTA#XXXXXX,username,encrypted_password
  • Service restart is needed after the change of AES informaiton

White list or Black list Servers 

  • To protect ivrSVR from unauthorized access, enter the following tcpgate console commands to add white list servers
    • add whitelist 10.10.1.220 webServerA
      • Add webServerA in white list and its IP address is 10.10.1.220
  • If you want to add an IP address in black list, enter the following tcpgate console commands
    • add blacklist 10.10.1.221 webServerB
      • Add webServerB in black list and its IP address is 10.10.1.221

Process and Port Monitoring

  • If you have NMS and want to monitor the status of ivrSVR, please monitor the following
  • Process Monitoring
    • ivrSVR.exe 
    • uuiSVR.exe
  • Port Monitoring
    • Please make sure firewall open for the following ports
    • ivrSVR
      • 14012 – tcpgate console port 
      • 9001 – REST interface port, you can change it by the “update tcp” command 
      • 9002 – ctiClient.ocx API port
      • 9003 – WebSocket interface port 
    • uuiSVR
      • 14014 – tcpgate console port 
      • 5100 – User data exchange port

System Logging

  • The ivrSVR only logs critical error messages, you can find these message on Event Viewer
  • For system monitoring purpose, suggest monitoring these information and error messages on Event Viewer
    • “QueryDeviceInfo returned error code, please check device…”
    • “MonitorDevice returned error code, please check device…”
    • “Received Monitor Ended Event, caused by…”
    • “Received Universial Failure Event…”
    • “Received TSAPI Stream ReOpen event. Active TLINK is…”
    • “CIVRSvrMgr::Initialize failed, possibly initialize TSAPI failed.”
  • To view real time debug messages, please enter the following tcpgte console commands
    • trace on asc

Load Balance and Redundant Configuration

loadbalancereddundancy

  • The ivrSVR is designed as a stateless CTI server especially the REST interface which the client connections can be persistent or temporary with the server.
  • You can use Linux Virtual Servers to form a Virtual IP (VIP) for ivrSVR instances. If you configure the LVS as round robin, then load balance of ivrSVR can be implemented very easily.
  • If one of the ivrSVR server instance is failure, LVS can detect it and route the subsequent traffic to other healthy ivrSVR instances.
  • If you want to remove a particular ivrSVR instance from the LVS, you can do it very easily by the following tcpgate console command
    • add blacklist 10.10.1.231 activeLVS
      • Hint: this adds the active LVS as blacklist IP address to ivrSVR, the polling messages from the LVS will not be entertained and LVS will remove the ivrSVR from the connection pool.
    • delete blacklist 10.10.1.231
      • Hint: After maintenance, please remove the blacklist so LVS polling messages will be entertained and LVS will add the ivrSVR to the connection pool.

Customized DLL for Passing of User Data 

  • Edit the parameters to enable passing of user data. A customized DLL is used to set or get of user data from UUI key
    • ivr_custdataconfigstring, the configuration string of your customized DLL
    • ivr_custdatadll, the path and name of the DLL
    • ivr_custdatamaxsize, the maximum size of user data

ActiveX

  • Register the ActiveX control ctiClient.ocx by the following Windows command
    • regsvr32 ctiClient.ocx
  • Enter the following command in the program console to add an API interface port
    • add tcp 9002 * * custom ivrsvrapi

REST interface 

Installation for WebSocket interface Call Control

  • Enter the following command in the program console to add a WebSocket interface port
    • add tcp 9003 * * custom ivrsvrws
  • WebSocket interface accepts JSON request, returns JSON response and delivers unsolicited JSON events
  • The JSON strings for MakeCall request and response are
    {
    “id”: “1”,
    “request”: “makecall”,
    “extension”: “101”,
    “destination”: “67896789”,
    “data”: “hello world”
    }
    {
    “msgtype”: “response”,
    “id”: “1”,
    “result”: “success”,
    “callid”: “12345”,
    “ucid”: “00001148011456795778”
    }
  • The JSON strings for Hold call request and response are
    {
    “id”: “2”,
    “request”: “hold”,
    “extension”: “101”
    }
    {
    “msgtype”: “response”,
    “id”: “2”,
    “result”: “success”,
    “error”: “”
    }
  • The JSON strings for Retrieve call request and response are
    {
    “id”: “3”,
    “request”: “retrieve”,
    “extension”: “101”
    }
    {
    “id”: “3”,
    “request”: “retrieve”,
    “extension”: “101”,
    “destination”: “T1234#1”
    }
    {
    “msgtype”: “response”,
    “id”: “3”,
    “result”: “success”,
    “error”: “”
    }
  • The JSON strings for Hangup call request and response are
    {
    “id”: “4”,
    “request”: “hangup”,
    “extension”: “101”,
    “data”: “hello world”
    }
    {
    “msgtype”: “response”,
    “id”: “4”,
    “result”: “success”,
    “error”: “”
    }
  • The JSON strings for DropParty call request and response are
    {
    “id”: “5“,
    “request”: “dropparty”,
    “extension”: “101”,
    “party”: “60123”,
    “data”: “hello world”
    }
    {
    “msgtype”: “response”,
    “id”: “5“,
    “result”: “success”,
    “error”: “”
    }
  • The JSON strings for Answer call request and response are
    {
    “id”: “6“,
    “request”: “answer”,
    “extension”: “101”,
    “destination”: “67896789”
    }
    {
    “msgtype”: “response”,
    “id”: “6“,
    “result”: “success”,
    “callid”: “12345”
    }
  • The JSON strings for Consultation call request and response are
    {
    “id”: “7“,
    “request”: “consultation”,
    “extension”: “101”,
    “destination”: “67896789”,
    “data”: “hello world”
    }
    {
    “msgtype”: “response”,
    “id”: “7“,
    “result”: “success”,
    “primarycallid”: “123”,
    “secondarycallid”: “456”,
    “ucid”: “00001148011456795778”
    }
  • The JSON strings for Reconnect call request and response are
    {
    “id”: “8“,
    “request”: “reconnect”,
    “extension”: “101”
    }
    {
    “msgtype”: “response”,
    “id”: “8“,
    “result”: “success”,
    “error”: “”
    }
  • The JSON strings for Alternate call request and response are
    {
    “id”: “9“,
    “request”: “alternate”,
    “extension”: “101”
    }
    {
    “msgtype”: “response”,
    “id”: “9“,
    “result”: “success”,
    “error”: “”
    }
  • The JSON strings for Transfer call request and response are
    {
    “id”: “10“,
    “request”: “transfer”,
    “extension”: “101”,
    “destination”: “67896789”
    }
    {
    “msgtype”: “response”,
    “id”: “10“,
    “result”: “success”,
    “error”: “”
    }
  • The JSON strings for Conference call request and response are
    {
    “id”: “11“,
    “request”: “conference”,
    “extension”: “101”,
    “destination”: “67896789”
    }
    {
    “msgtype”: “response”,
    “id”: “11“,
    “result”: “success”,
    “error”: “”
    }
  • The JSON strings to send DTMF request and response are
    {
    “id”: “12“,
    “request”: “dtmf”,
    “extension”: “101”,
    “dtmf”: “1”
    }
    {
    “msgtype”: “response”,
    “id”: “12“,
    “result”: “success”,
    “error”: “”
    }
  • The JSON strings for ACD Login request and response are
    {
    “id”: “13“,
    “request”: “login”,
    “extension”: “101”,
    “agentid”: “12345”,
    “passwd”: “67890”
    }
    {
    “msgtype”: “response”,
    “id”: “13“,
    “result”: “success”,
    “error”: “”
    }
  • The JSON strings for ACD Logout request and response are
    {
    “id”: “14“,
    “request”: “logout”,
    “extension”: “101”,
    “agentid”: “12345”,
    “passwd”: “67890”
    }
    {
    “msgtype”: “response”,
    “id”: “14“,
    “result”: “success”,
    “error”: “”
    }
  • The JSON strings for ACD SetState request and response are, add parameter “enablepending”: “true” to enable pending mode while in call
    {
    “id”: “15“,
    “request”: “setstate”,
    “extension”: “101”,
    “state”: “aux”,
    “reasoncode”: “1”
    }
    {
    “id”: “15“,
    “request”: “setstate”,
    “extension”: “101”,
    “state”: “acw”
    }
    {
    “id”: “15“,
    “request”: “setstate”,
    “extension”: “101”,
    “state”: “manual
    }
    {
    “id”: “15“,
    “request”: “setstate”,
    “extension”: “101”,
    “state”: “auto
    }
    {
    “msgtype”: “response”,
    “id”: “15“,
    “result”: “success”,
    “error”: “”
    }
  • The JSON strings for StartMonitor extension
    {
    “id”: “16“,
    “request”: “startmonitor”,
    “extension”: “101”
    }
    {
    “msgtype”: “response”,
    “id”: “16“,
    “result”: “success”,
    “error”: “”
    }
  • The JSON strings for StopMonitor extension
    {
    “id”: “17“,
    “request”: “stopmonitor”,
    “extension”: “101”
    }
    {
    “msgtype”: “response”,
    “id”: “17“,
    “result”: “success”,
    “error”: “”
    }
  • The JSON strings for Alert UserData request and response are
    {
    “id”: “18“,
    “request”: “userdata”,
    “extension”: “101”,
    “type”: “alert”
    }
    {
    “msgtype”: “response”,
    “id”: “18“,
    “result”: “success”,
    “callid”: 1361,
    “calling”: “101”,
    “called”: “102”,
    “alerting”: “102”,
    “cli”: “101”,
    “dnis”: “102”,
    “uec”: “”,
    “ucid”: “00001013551428290972”,
    “split”: “”,
    “trunkgroup”: “5”,
    “trunkmember”: “20”,
    “userdata”: “”
    }
  • The JSON strings for Hangup UserData request and response are
    {
    “id”: “19“,
    “request”: “userdata”,
    “extension”: “101”,
    “type”: “hangup”
    }
    {
    “msgtype”: “response”,
    “id”: “19“,
    “result”: “success”,
    “callid”: 1361,
    “releasing”: “101”,
    “ucid”: “00001013551428290972”,
    “userdata”: “”
    }
  • The JSON strings for Get, Set and Update UserData requests are
    {
    “id”: “20“,
    “request”: “userdata”,
    “extension”: “101”,
    “type”: “get”,
    “uui”: “FCCCCCCC0000000156A853617F00000113EC00000005”
    }
    {
    “msgtype”: “response”,
    “id”: “20“,
    “result”: “success”,
    “data”: “get data”
    }
    {
    “id”: “20“,
    “request”: “userdata”,
    “extension”: “101”,
    “type”: “set”,
    “data”: “set data”
    }
    {
    “msgtype”: “response”,
    “id”: “20“,
    “result”: “success”,
    “uui”: “FCCCCCCC0000000156A853617F00000113EC00000005”
    }
    {
    “id”: “20“,
    “request”: “userdata”,
    “extension”: “101”,
    “type”: “update”,
    “uui”: “FCCCCCCC0000000156A853617F00000113EC00000005”,
    “data”: “upate data”
    }
    {
    “msgtype”: “response”,
    “id”: “20“,
    “result”: “success”,
    “error”: “”
    }
  • The JSON strings for ClearCall request and response are
    {
    “id”: “21“,
    “request”: “clearcall”,
    “extension”: “101”,
    “destination”: “102”
    }
    {
    “msgtype”: “response”,
    “id”: “21“,
    “result”: “success”,
    “error”: “”
    }
  • The JSON strings for DeflectCall request and response are
    {
    “id”: “22“,
    “request”: “deflectcall”,
    “extension”: “101”,
    “destination”: “102”
    }
    {
    “msgtype”: “response”,
    “id”: “22“,
    “result”: “success”,
    “error”: “”
    }
  • The JSON strings for PickupCall request and response are
    {
    “id”: “23“,
    “request”: “pickupcall”,
    “extension”: “101”,
    “destination”: “102”
    }
    {
    “msgtype”: “response”,
    “id”: “23“,
    “result”: “success”,
    “error”: “”
    }
  • The JSON strings for Snapshot request and response are
    {
    “id”: “24“,
    “request”: “snapshot”,
    “extension”: “101”
    }
    {
    “msgtype”: “response”,
    “id”: “24“,
    “result”: “success”,
    “error”: “”,
    “extension”: “101”,
    “numcall”: 1,
    “list”: [
    {
    “callid”: 13815,
    “state”: “connect”,
    “numparty”: 2,
    “party”: [
    {
    “extension”: “101”
    },
    {
    “extension”: “T13815#2”
    }
    ]
    }
    ]
    }
  • The JSON strings for SingleStepConference request and response are
    {
    “id”: “25“,
    “request”: “singlestepconference”,
    “extension”: “101”,
    “devicetojoin”: “102”,
    “type”: “passive”
    }
    {
    “msgtype”: “response”,
    “id”: “25“,
    “result”: “success”,
    “callid”: “12345”,
    “ucid”: “00001000481428289124”
    }
  • The JSON strings for SingleStepTransfer request and response are
    {
    “id”: “25“,
    “request”: “singlesteptransfer”,
    “extension”: “101”,
    “destination”: “102”
    }
    {
    “msgtype”: “response”,
    “id”: “25“,
    “result”: “success”,
    “callid”: “12345”,
    “ucid”: “00001000481428289124”
    }
  • The JSON strings for SelectiveListeningHold request and response are
    {
    “id”: “26“,
    “request”: “selectivelisteninghold”,
    “extension”: “101”,
    “party”: “102”
    }
    {
    “id”: “26“,
    “request”: “selectivelisteninghold”,
    “extension”: “101”,
    “party”: “all
    }
    {
    “msgtype”: “response”,
    “id”: “27“,
    “result”: “success”
    }
  • The JSON strings for SelectiveListeningRetrieve request and response are
    {
    “id”: “27“,
    “request”: “selectivelisteningretrieve”,
    “extension”: “101”,
    “party”: “102”
    }
    {
    “id”: “27“,
    “request”: “selectivelisteningretrieve”,
    “extension”: “101”,
    “party”: “all
    }
    {
    “msgtype”: “response”,
    “id”: “27“,
    “result”: “success”
    }
  • The JSON strings for QueryACDSplit request and response are
    {
    “id”: “28“,
    “request”: “queryacdsplit”,
    “split”: “201”
    }
    {
    “msgtype”: “response”,
    “id”: “28“,
    “result”: “success”,
    “agentsavailable”: 5,
    “callsqueue”: 0,
    “agentslogon”: 26
    }
  • The JSON strings for QueryAgentLogin request and response are
    {
    “id”: “29“,
    “request”: “queryagentlogin”,
    “split”: “201”
    }
    {
    “msgtype”: “response”,
    “id”: “29“,
    “result”: “success”,
    “split”: “201”,
    “numextension”: 5,
    “list”: [
    {
    “extension”: “101”
    },
    {
    “extension”: “102”
    },
    {
    “extension”: “103”
    },
    {
    “extension”: “104”
    },
    {
    “extension”: “105”
    }
    ]
    }
  • The JSON strings for QueryAgentState request and response are
    {
    “id”: “30“,
    “request”: “queryagentstate”,
    “extension”: “101”
    }
    {
    “msgtype”: “response”,
    “id”: “30“,
    “result”: “success”,
    “skillmode”: “null”,
    “talkstate”: “idle”,
    “reasoncode”: 0
    }
  • The JSON string for QueryCallClassifier request and response are
    {
    “id”: “31“,
    “request”: “querycallclassifier”
    }
    {
    “msgtype”: “response”,
    “id”: “31“,
    “result”: “success”,
    “availport”: 439,
    “usedport”: 5
    }
  • The JSON string for QueryTimeOfDay request and response are
    {
    “id”: “32“,
    “request”: “querytimeofday”
    }
    {
    “msgtype”: “response”,
    “id”: “32“,
    “result”: “success”,
    “year”: 16,
    “month”: 3,
    “day”: 23,
    “hour”: 22,
    “minute”: 24,
    “second”: 16
    }
  • The JSON string for QueryDeviceName request and response are
    {
    “id”: “33“,
    “request”: “querydevicename”,
    “extension”: “101”
    }
    {
    “msgtype”: “response”,
    “id”: “33“,
    “result”: “success”,
    “name”: “Peter”
    }
  • The JSON string for QueryDoNotDisturb request and response are
    {
    “id”: “34“,
    “request”: “querydonotdisturb”,
    “extension”: “101”
    }
    {
    “msgtype”: “response”,
    “id”: “34“,
    “result”: “success”,
    “dnd”: “false”
    }
  • The JSON string for QueryDeviceInfo request and response are
    {
    “id”: “35“,
    “request”: “querydeviceinfo”,
    “extension”: “101”
    }
    {
    “msgtype”: “response”,
    “id”: “35“,
    “result”: “success”,
    “associatedclass”: “other”,
    “associateddevice”: “”
    }
  • The JSON string for QueryForwarding request and response are
    {
    “id”: “36“,
    “request”: “queryforwarding”,
    “extension”: “101”
    }
    {
    “msgtype”: “response”,
    “id”: “36“,
    “result”: “success”,
    “destination”: “102”
    }
  • The JSON string for QueryMsgWaitingInd request and response are
    {
    “id”: “37“,
    “request”: “querymsgwaitingind”,
    “extension”: “101”
    }
    {
    “msgtype”: “response”,
    “id”: “37“,
    “result”: “success”,
    “indicator”: “false”
    }
  • The JSON string for QueryStationStatus request and response are
    {
    “id”: “38“,
    “request”: “querystationstatus”,
    “extension”: “101”
    }
    {
    “msgtype”: “response”,
    “id”: “38“,
    “result”: “success”,
    “busy”: “false”
    }
  • The JSON string for QueryTrunkGroup request and response are
    {
    “id”: “39“,
    “request”: “querytrunkgroup”,
    “tag”: “410”
    }
    {
    “msgtype”: “response”,
    “id”: “39“,
    “result”: “success”,
    “idletrunks”: 91,
    “usedtrunks”: 1
    }
  • The JSON string for QueryUCID request and response are
    {
    “id”: “40“,
    “request”: “queryucid”,
    “callid”: “123”
    }
    {
    “msgtype”: “response”,
    “id”: “40“,
    “result”: “success”,
    “ucid”: “00001148011456795778”
    }
  • The JSON string for SetDoNotDisturb request and response are
    {
    “id”: “41“,
    “request”: “setdonotdisturb”,
    “extension”: “101”,
    “dnd”: “true”
    }
    {
    “msgtype”: “response”,
    “id”: “41“,
    “result”: “success”,
    “error”: “”
    }
  • The JSON string for SetForwarding request and response are
    {
    “id”: “42“,
    “request”: “setforwarding”,
    “extension”: “101”,
    “destination”: “102”,
    “fwd”: “true”
    }
    {
    “msgtype”: “response”,
    “id”: “42“,
    “result”: “success”,
    “error”: “”
    }
  • The JSON string for SetMsgWaitingInd request and response are
    {
    “id”: “43“,
    “request”: “setmsgwaitingind”,
    “extension”: “101”,
    “ind”: “true”
    }
    {
    “msgtype”: “response”,
    “id”: “43“,
    “result”: “success”,
    “error”: “”
    }
  • The JSON string for MyExtension request and response are
    {
    “id”: “44“,
    “request”: “myextension”
    }
    {
    “msgtype”: “response”,
    “id”: “44“,
    “result”: “success”,
    “extension”: “66711”
    }
  • The JSON string for ListExtension request and response are
    {
    “id”: “45“,
    “request”: “listextension”
    }
    {
    “msgtype”: “response”,
    “id”: “45“,
    “result”: “success”,
    “numextension”: 5,
    “list”: [
    {
    “extension”: “61450”
    },
    {
    “extension”: “61451”
    },
    {
    “extension”: “66711”
    },
    {
    “extension”: “66820”
    },
    {
    “extension”: “66910”
    }
    ]
    }
  • The JSON string for AddExtension request and response are
    {
    id: “46”,
    request: “addextension”,
    username: “tcpgate”,
    passwd: “encrypted_passwd_by_genpass”,
    extension: “66711”

    }
    {
    “msgtype”: “response”,
    “id”: “46”,
    “result”: “success”,
    “error”: “The command completed successfully.”
    }
  • The JSON string for DelExtension request and response are
    {
    id: “47”,
    request: “delextension”,
    username: “tcpgate”,
    passwd: “encrypted_passwd_by_genpass”,
    extension: “66711”

    }
    {
    “msgtype”: “response”,
    “id”: “47”,
    “result”: “success”,
    “error”: “The command completed successfully.”
    }
  • The JSON string for MakePhantomCall request and response are
    {
    id: “48”,
    request: “makephantomcall”,
    destination: “912345678”,
    duration: 20,
    waitevent: “connect”,
    data: “hello”

    }
    {
    “msgtype”: “response”,
    “id”: “48”,
    “result”: “success”,
    “callid”: 13562,
    “ucid”: “00001135621477779601”,
    “phantom”: “41103”,
    “answering”: “T13562#2”,
    “releasing”: “”,
    “hangupdata”: “”
    }
  • The JSON string for PinVer request and response are
    {
    id: “49”,
    request: “pinver”,
    extension: “61451”,
    destination: “66711”,
    druation: 20,
    data: “hello”

    }
    {
    “msgtype”: “response”,
    “id”: “49”,
    “result”: “success”,
    “callid”: 13693,
    “ucid”: “00001136931477780159”,
    “answering”: “66711”,
    “releasing”: “66711”,
    “hangupdata”: “ok”
    }
  • The JSON string for SvrInfo request and response are
    {
    id: “50”,
    request: “svrinfo”
    }
    {
    “msgtype”: “response”,
    “id”: “50”,
    “result”: “success”,
    “ver”: “ivrSVR 1.2.8”,
    “licensecompany”: “abc”,
    “licensecount”: “100”,
    “licensetype”: “permanent”,
    “licensestartdate”: “”,
    “licenseenddate”: “”
    }
  • The JSON strings for incoming Call Offer event is
    {
    “msgtype”: “event”,
    “eventtype”: “offer”,
    “referenceid”: 1,
    “origcalling”: “101”,
    “origcalled”: “102”,
    “calling”: “101”,
    “called”: “102”,
    “alerting”: “102”,
    “ucid”: “00001094861421138402”,
    “uui”: “”,
    “uec”: “”,
    “split”: “”,
    “custdata”: “”,
    “time”: 1424044800,
    “trunkgroup”: “10”,
    “trunkmember”: “12”,
    “lastredirection”: “”,
    “callid”: 48
    }
  • The JSON string for outgoing Call Alert event is
    {
    “msgtype”: “event”,
    “eventtype”: “alert”,
    “referenceid”: 1,
    “origcalling”: “101”,
    “origcalled”: “102”,
    “calling”: “101”,
    “called”: “102”,
    “alerting”: “102”,
    “ucid”: “00001000481428289124”,
    “uui”: “”,
    “custdata”: “”,
    “time”: 1428289128,
    “trunkgroup”: “5”,
    “trunkmember”: “118”,
    “callid”: 48
    }
  • The JSON string for Call Connect event is
    {
    “msgtype”: “event”,
    “eventtype”: “connect”,
    “referenceid”: 1,
    “origcalling”: “101”,
    “origcalled”: “102”,
    “calling”: “101”,
    “called”: “102”,
    “answering”: “102#2”,
    “ucid”: “00001000481428289124”,
    “uui”: “”,
    “uec”: “”,
    “split”: “”,
    “custdata”: “”,
    “time”: 1428289134,
    “trunkgroup”: “5”,
    “trunkmember”: “118”,
    “lastredirection”: “”,
    “callid”: 48
    }
  • The JSON string for Call Fail event is
    {
    “msgtype”: “event”,
    “eventtype”: “fail”,
    “referenceid”: 1,
    “failing”: “101”,
    “called”: “102”,
    “cause”: 23,
    “time”: 1424044800,
    “callid”: 48
    }
  • The JSON string for Call Hold event is
    {
    “msgtype”: “event”,
    “eventtype”: “hold”,
    “referenceid”: 1,
    “holding”: “101”,
    “time”: 1428289135,
    “callid”: 48
    }
  • The JSON string for Call Retrieve event is
    {
    “msgtype”: “event”,
    “eventtype”: “retrieve”,
    “referenceid”: 1,
    “retrieving”: “101”,
    “time”: 1428289135,
    “callid”: 48
    }
  • The JSON string for Call Disconnect event is
    {
    “msgtype”: “event”,
    “eventtype”: “disconnect”,
    “referenceid”: 1,
    “releasing”: “101”,
    “uui”: “”,
    “custdata”: “”,
    “time”: 1428289136,
    “callid”: 48
    }
  • The JSON string for Call Transfer event is
    {
    “msgtype”: “event”,
    “eventtype”: “transfer”,
    “referenceid”: 1,
    “transferring”: “101”,
    “transferred”: “102”,
    “ucid”: “00001094861421138402”,
    “uui”: “”,
    “cusdata”: “”,
    “time”: 1424044800,
    “trunkgroup”: “10”,
    “trunkmember”: “12”,
    “primarycallid”: 123,
    “secondarycallid”: 124,
    “party1”: “101”,
    “party2”: “102”,
    “party3”: “”,
    “party4”: “”,
    “party5”: “”,
    “party6”: “”
    }
  • The JSON string for Call Conference event is
    {
    “msgtype”: “event”,
    “eventtype”: “conference”,
    “referenceid”: 1,
    “controller”: “101”,
    “addedparty”: “102”,
    “ucid”: “00001094861421138402”,
    “uui”: “”,
    “cusdata”: “”,
    “time”: 1424044800,
    “trunkgroup”: “10”,
    “trunkmember”: “12”,
    “primarycallid”: 123,
    “secondarycallid”: 124,
    “party1”: “101”,
    “party2”: “102”,
    “party3”: “”,
    “party4”: “”,
    “party5”: “”,
    “party6”: “”
    }
  • The JSON string for Call Idle event is
    {
    “msgtype”: “event”,
    “eventtype”: “idle”,
    “referenceid”: 1,
    “time”: 1424044800,
    “extension”: “101”
    }

Uninstallation

  • Stop the Window Service ivrSVR
  • Open Windows Command Prompt, enter the following commands to uninstall the program from Windows Service
    • cd c:\program files\ivrsvr
    • ivrSVR -u

Support and License