Voice Management Guide

The Voice Management user guide

API notifications Voice Management

1 - Introduction

This API allows you to receive a real-time stream of events related to all aspects of the Voice Management function: agents, queues, routing, etc. It can be used for various purposes, including the production of monitoring dashboards.
It’s based on the Socket.IO protocol

2 - How it works

Using the API requires two steps:
1. a first authentication step, in the form of a normal HTTP request
2. the actual use via the Socket.IO library, using the authentication created in the previous step

3 - Authentication

3.1 - Authentication

Before being allowed to connect to our notification server, you’ll need to obtain an authentication token, which will be valid for two hours. The request must be made from the device where the notifications will be processed. Verification is done via the token and the IP.
Authentication requires the use of a “supervisor” login/password.
A POST request will be carried out by configuring a JSON header with these credentials in order to obtain the token to be used to authenticate to the notification server.
Data to be included in the JSON:

  • requete: init
  • header:
    • count_type: supervisor
    • login: « login »
    • password: « password »
  • msg: (vide)

Example of an authentication request with CURL:

				
					curl -X POST -H "X-JSON: {\"requete\":\"init\",\"header\": 
{\"login\":\"xxxxx\",\"password\":\"xxx\",\"account_type\":\"supervisor\"},\"msg\":{}}" 
https://voice-management.axialys.com/ws/
				
			

This request returns all the information needed to receive notifications, configure groups and agents in a JSON object.
The main relevant information includes:

  • ops (id, nom, groupes[])
  • groupes (id, nom)
  • trunks (id, nom)
  • pauses (id, value)
  • target (id du superviseur)
  • expire (date d’expiration au format yyyy-mm-ddthh-mm-ss.000000+GMT)
  • id_session

The last two parameters are the supervisory account ID (target) and the token (id_session) needed for authentication. See below.

3.2 - Renewal of the authentication token

Instead of waiting for the token to expire before renewing it (at the risk of possibly losing events), you can do it via the following method:

				
					curl -X POST -H ‘X-JSON: {\”requete\”:\”refresh_token\”,\”header\”:{\”id_session\”:\”XXXXXXXXXX\”},\”msg\”:{}}’ ‘https://voice-management.axialys.com/ws/’
				
			

This query returns the id_session as well as expires as “//” in a JSON object.

4 - Notification feeds

4.1 - Connection

The notification flow uses the Socket.IO Javascript library protocol. The following examples are in Javascript, but any library compatible with this protocol should work.
Once authentication has been completed and the authentication token has been received, you can connect to the notification server to receive real-time events.
It’s best to set a callback for update events and then request the start of the flow via an init message.

				
					socket = io.connect() ;

socket.on(‘update’, function(data) { // traitement de l’événement })

socket.emit(‘init’, ‘supervisor’, <id_superviseur>, <id_session>);
				
			

4.2 - Events

The data is transmitted as a JSON object, with the name of the event, which will always be “update” and a structure in the following form:


● cpt: event number
● elapse: time since the event
● event:

    • event: insert_call
    • type_notification: queue |operator |UI |trunk


● ts: timestamp for when the event is sent

There are five types of events, as detailed below:


● operator: concerns the status of an agent’s communications
● UI: concerns the state of the agent’s interface, login/breaks, etc
● PUSHCALL: a request has been made to ask an agent to make an outgoing call
● queue: information on an agent queue
● trunk: information on a routing queue

Allows you to obtain information on the status of an agent:


Example:

				
					{“msg”: {“status”: “connected”, “rec”: 1, “call_duration”: 0, “caller_id_num”: “3363441111”, “step”: 1, “id_queue”: 0, “id_call”: -17137, “id_operator”: 8, “id_client”: 3}, “type_notification”: “operator”, “event”: “status”}
				
			

Available values for the main variables:


● call_duration: duration of the call
● caller_id_num: caller’s number
● id_call: caller’s identification
● id_operator: ID of the relevant agent
● id_queue: ID of the queue associated with the current call
● rec: call recorded
● catchup: catchup time after call (only provided at the end of a call)
● service: service number when ringing (ascertained only when ringing)
● status

    • available: agent is available
    • ringing: agent is ringing
    • calling: call made
    • connected: call in progress
    • unavailable: unknown status
    • transfert_start: start of a call transfer
    • transfert_end: end of a call transfer


4.2.2 UI Event


Allows you to obtain login/logout/break information or other types of information related to the agent interface.
Login example:

				
					{“msg”: {“supp”: “”, “id_operator”: 1, “id_client”: 1}, “type_notification”: “UI”, “event”: “login”}
				
			

Available values for the main variables:

  • event:
    • login: agent logs in
    • logout: agent logs out
    • pause: break event
    • unpause: break ended
    • push: call pushed to the operator’s interface
    • push_cancel: attempt to cancel the various events pushed to the operator
  • id_operator: ID of the relevant agent
  • supp: additional information, including break type identifier

Specific variables contained in “msg” that relate to pushing events to the client interface

  • retry_timeout: time between two attempts
  • auto_timeout: timeout after which the call will be activated if the operator doesn’t activate it before then and there’s an “AUTO” request
  • vars: variables
  • ring_timeout: ring time
  • expire: expiration of allocation
  • unassign_timeout: timeout for call de-allocation
  • retries: number of retries remaining
  • priority: call priority (1 to 100)
  • e164: number to reach the operator
  • type:
    • AUTO: activate the call automatically after *auto_timeout* seconds if the operator has not activated the call and is in the field tab.
    • MANUAL: manual activation


4.2.3 “Queue” event


Allows you to obtain login/logout information or other types of information related to the interface, such as paused user .
Example of an incoming call:

				
					{“msg”: {“call_duration”: 43, “caller_id_num”: “33761433333”, “priority”: 100, “id_queue”: 391, “id_call”: 26, “vip_rate”: 1, “duration_in_queue”: 0, “id_client”: 174808}, “type_notification”: “queue”, “event”: “insert_call”}
				
			

Example of a connection:

				
					{“msg”: {“status”: “connected”, “call_duration”: 0, “caller_id_num”: “335497”, “step”: 1, “id_queue”: 8, “id_call”: -1713, “id_operator”: 2, “id_client”: 1}, “type_notification”: “queue”, “event”: “connect_call”}
				
			

Example of an exit from the queue:

				
					{“msg”: {“id_call”: 26901513, “id_queue”: 1023, “id_client”: “164645”}, “type_notification”: “queue”, “event”: “delete_call”}
				
			

Available values for the main variables:

  • call_duration: duration of the call
  • caller_id_num: caller’s number
  • duration_in_queue: wait time in the queue
  • event:
    • connect_call: connect
    • delete_call: call ended
    • insert_call: incoming call goes into the queue
  • id_call: call identifier
  • id_operator: ID of the relevant agent
  • id_queue: ID of the queue associated with the current call
  • rec: call recorded
  • status
    • available: agent available
    • ringing: agent ringing
    • calling: call made
    • connected: call in progress
    • unavailable: unknown status

Special notification (used by alerts): Available values for the main variables:

  • duration_in_queue: for how long
  • event:
    • alert_op: not enough operators
    • alert_file: call waiting threshold exceeded
  • id_call: call identifier
  • id_operator: ID of the relevant agent
  • id_queue: Id of the queue associated with the current call
  • validity: validity of the warning

4.2.4 “Trunk” Event


Provides information on routing calls
Add call example:

				
					{“msg”: {“call_duration”: 0, “id_trunk”: 346223, “caller_id_num”: “33783655555”, “id_call”: 269, “duration_in_queue”: 0}, “type_notification”: “trunk”, “event”: “insert_call”}
				
			

Connection example:

				
					{“msg”: {“status”: “connected”, “call_duration”: 0, “id_trunk”: “345940”, “caller_id_num”: “33980689888”, “id_call”: “26903925”}, “type_notification”: “trunk”, “event”: “connect_call”}
				
			

End of call example:

				
					{“msg”: {“id_call”: 2690, “id_trunk”: 34}, “type_notification”: “trunk”, “event”: “delete_call”}
				
			

Available values for the main variables:

  • caller_id_num: caller’s number
  • call_duration: duration of the call
  • id_call: call identifier
  • id_trunk: routing account identifier
  • event:
    • insert_call: adding a call to a queue
    • connect_call: connecting a call
    • delete_call: end a call

4.2.5 “Num” Event


Allows you to receive information on incoming calls (note that to receive this type of event, you must request it).
Example of an incoming call:

				
					{"msg":{"type_dest":"GROUPE","id_call":3819,"id_num":31,"id_client":666,"service":"33820620620","caller_id_num":"33612345678"},"type_notification":"num","srv":8,"event":"start"}
				
			

Example of pick-up (provided only if a sound is played):

				
					{"msg":{"type_dest":"GROUPE","id_call":3819,"id_num":31,"id_client":666,"service":"33820620620","caller_id_num":"33612345678"},"type_notification":"num","srv":8,"event":"answer"}
				
			

End of call example:

				
					{"msg":{"type_dest":"GROUPE","id_call":3819,"id_num":31,"id_client":666,"service":"33820620620","caller_id_num":"33612345678"},"type_notification":"num","srv":8,"event":"end"}
				
			

Available values for the main variables:

  • caller_id_num: caller’s number
  • service: service number
  • id_call: call identifier
  • type_dest : corresponds to the last destination type called (GROUP, TRUNK, NO)
  • event:
    • start: arrival of an incoming call
    • answer: call answered (provided only if answered before outbound call)
    • end: end of incoming call

4.2.6 “Input” Event


Allows you to receive information on input events. (Note: to receive this type of event, you must request it, as it currently only retrieves speech recognition data.)
Example of recognition event:

				
					{“ts”:1590431889,”elapse”:0,”event”:{“msg”:{“id_call”:40090062,”score”:97,”id”:96897,”id_client”:173778,”input”:”92″},”type_notification”:”input”,”event”:”asr”}}
				
			

Available values for the main variables:

  • id_call: call identifier
  • event:
    • ASR: voice recognition
  • score: evaluation of the relevance of the recognition 0→100

4.3 Example of a full message


Below is an example of a full message as the JSON is received.
Example:

				
					[“update”,{“ts”:1547651821,”elapse”:0,”event”:{“msg”:{“status”:”transfert_start”,”id_operator”:1,”stype”:3,”id_client”:164645,”id_call”:”26″},”type_notification”:”operator”,”event”:”status”},”cpt”:2297}]
				
			

4.4 Example of a call


A token must be generated beforehand in addition to adding the supervisor’s ID ([target]) to the “id_sup” variable and the session identifier ([id_session]) to the “id_session” variable.

				
					<!doctype html>
<html lang="fr">
<head>

<title>Demo socket.io</title>
<script type="rocketlazyloadscript" src="./socket.io.js" crossorigin="anonymous" defer></script>
<script type="rocketlazyloadscript" data-minify="1" src="https://guide.axialys.com/wp-content/cache/min/1/jquery-3.2.1.min.js?ver=1666989114" crossorigin="anonymous" defer></script>
<script type="rocketlazyloadscript">window.addEventListener('DOMContentLoaded', function() {
 
var id_sup = [target] ;
var id_session = [id_session] ;
 
$(document).ready(function () {
	var socket = io.connect("https://voice-management.axialys.com", {path:"/socket.io/"});
	socket.on('connect', function() {
		console.log("ready") ;
		$("#text").append("<p>ready</p>") ;
		socket.emit('init', 'supervisor', id_sup, id_session);
	});
 
	socket.on('update', function(data) {
		$("#text").append("<p>"+JSON.stringify(data)+"</p>") ;
		console.log(data) ;
	}) ;
 
	console.log([id_sup, id_session]) ;
    socket.emit('init', 'supervisor', id_sup, id_session);
}) ;
});</script>
</head>
<body>
Mon test:
<div id="text"></div>
<script>"use strict";function wprRemoveCPCSS(){var preload_stylesheets=document.querySelectorAll('link[data-rocket-async="style"][rel="preload"]');if(preload_stylesheets&&0<preload_stylesheets.length)for(var stylesheet_index=0;stylesheet_index<preload_stylesheets.length;stylesheet_index++){var media=preload_stylesheets[stylesheet_index].getAttribute("media")||"all";if(window.matchMedia(media).matches)return void setTimeout(wprRemoveCPCSS,200)}var elem=document.getElementById("rocket-critical-css");elem&&"remove"in elem&&elem.remove()}window.addEventListener?window.addEventListener("load",wprRemoveCPCSS):window.attachEvent&&window.attachEvent("onload",wprRemoveCPCSS);</script><script>class RocketElementorAnimation{constructor(){this.deviceMode=document.createElement("span"),this.deviceMode.id="elementor-device-mode",this.deviceMode.setAttribute("class","elementor-screen-only"),document.body.appendChild(this.deviceMode)}_detectAnimations(){let t=getComputedStyle(this.deviceMode,":after").content.replace(/"/g,"");this.animationSettingKeys=this._listAnimationSettingsKeys(t),document.querySelectorAll(".elementor-invisible[data-settings]").forEach(t=>{const e=t.getBoundingClientRect();if(e.bottom>=0&&e.top<=window.innerHeight)try{this._animateElement(t)}catch(t){}})}_animateElement(t){const e=JSON.parse(t.dataset.settings),i=e._animation_delay||e.animation_delay||0,n=e[this.animationSettingKeys.find(t=>e[t])];if("none"===n)return void t.classList.remove("elementor-invisible");t.classList.remove(n),this.currentAnimation&&t.classList.remove(this.currentAnimation),this.currentAnimation=n;let s=setTimeout(()=>{t.classList.remove("elementor-invisible"),t.classList.add("animated",n),this._removeAnimationSettings(t,e)},i);window.addEventListener("rocket-startLoading",function(){clearTimeout(s)})}_listAnimationSettingsKeys(t="mobile"){const e=[""];switch(t){case"mobile":e.unshift("_mobile");case"tablet":e.unshift("_tablet");case"desktop":e.unshift("_desktop")}const i=[];return["animation","_animation"].forEach(t=>{e.forEach(e=>{i.push(t+e)})}),i}_removeAnimationSettings(t,e){this._listAnimationSettingsKeys().forEach(t=>delete e[t]),t.dataset.settings=JSON.stringify(e)}static run(){const t=new RocketElementorAnimation;requestAnimationFrame(t._detectAnimations.bind(t))}}document.addEventListener("DOMContentLoaded",RocketElementorAnimation.run);</script><noscript><link rel="stylesheet" href="https://guide.axialys.com/wp-content/cache/min/1/24713921a416b8a0eefae05c9cde7368.css" media="all" data-minify="1" /><link rel='stylesheet' id='elementor-frontend-css' href='https://guide.axialys.com/wp-content/uploads/elementor/css/custom-frontend-lite.min.css?ver=1666958935' media='all' /><link rel='stylesheet' id='elementor-post-6-css' href='https://guide.axialys.com/wp-content/uploads/elementor/css/post-6.css?ver=1666958921' media='all' /><link rel='stylesheet' id='elementor-pro-css' href='https://guide.axialys.com/wp-content/uploads/elementor/css/custom-pro-frontend-lite.min.css?ver=1666958935' media='all' /><link rel='stylesheet' id='elementor-global-css' href='https://guide.axialys.com/wp-content/uploads/elementor/css/global.css?ver=1666958936' media='all' /><link rel='stylesheet' id='elementor-post-4151-css' href='https://guide.axialys.com/wp-content/uploads/elementor/css/post-4151.css?ver=1666989113' media='all' /><link rel='stylesheet' id='elementor-post-47-css' href='https://guide.axialys.com/wp-content/uploads/elementor/css/post-47.css?ver=1666958921' media='all' /><link rel='stylesheet' id='elementor-post-209-css' href='https://guide.axialys.com/wp-content/uploads/elementor/css/post-209.css?ver=1666958922' media='all' /><link rel='stylesheet' id='google-fonts-1-css' href='https://fonts.googleapis.com/css?family=Roboto%3A100%2C100italic%2C200%2C200italic%2C300%2C300italic%2C400%2C400italic%2C500%2C500italic%2C600%2C600italic%2C700%2C700italic%2C800%2C800italic%2C900%2C900italic&#038;display=auto&#038;ver=6.1.6' media='all' /><link rel="stylesheet" href="//fonts.googleapis.com/css?family=Open+Sans&display=swap" media="all" /><link rel="stylesheet" href="//fonts.googleapis.com/css?family=Open+Sans:300|Open+Sans:400|Open+Sans:700&display=swap" media="all" /><link rel="stylesheet" href="https://guide.axialys.com/wp-content/uploads/elementor/css/custom-widget-icon-list.min.css?ver=1666960324"><link rel='stylesheet' id='elementor-post-3699-css' href='https://guide.axialys.com/wp-content/uploads/elementor/css/post-3699.css?ver=1666964082' media='all' /></noscript></body>
</html>
				
			

5- Using the API to receive all the events

The API can be used in a different way to receive all the events, from the introduction of the call, including before it’s picked up, while it’s ringing or while the pre-answer message is playing.

5.1 How it works


Using the API also requires the two steps described above: authentication by generating a token, then calling the API using the previously created token.

5.2 Authentication


Before being allowed connect to the notification server, you’ll need to obtain an authentication token, which will be valid for two hours. The request must be made from the device where the notification processing will take place, the verification taking place via the token and the IP.


Authentication requires the use of a login/password corresponding to your API account (if you do not have one, please request one).


You can make a POST request by configuring a JSON header with the credentials in order to obtain the token to be used to authenticate to the notification server.
To retrieve the full data set:

				
					curl -X POST -u “<login>:<password>” -H “Content-Type: application/json” -d ‘{“user_type”:”api”}’ https://api.axialys.com/vm/token
				
			
To retrieve data for a single operator: 
				
					curl -X POST -u “<login>:<password>” -H “Content-Type: application/json” -d ‘{“user_type”:”agent”,”<id_agent>”}’ https://api.axialys.com/vm/token
				
			
To know the expiration date of the token, this query returns “expire” (expiration date in the format yyyy-mm-ddthh-mm-ss.000000+GMT).

5.3 Events
An example of its use:

https://voice-management.axialys.com/labo/index.htm?id_client=<id_client>&id_session=<id_session>

To test, just replace id_client with the one that was provided to you and id_session with the one that was sent to you through the generation of the token, to see all the events in your account.