.. javascriptapi: ############## Javascript API ############## Introduction ============ The Xuc javascript API enables you to integrate enterprise communication functions to your business application. It exposes Cti functions using javascript methods calls. You may add your own handlers for your application to react to telephony / contact center events. This API is using websockets_, and therefore needs a modern browser supporting them (firefox_, chrome ...) .. _firefox: https://www.mozilla.org/en-US/firefox/desktop/ .. _websockets: http://en.wikipedia.org/wiki/WebSocket Integration Principles ====================== * Include the Cti and Callback javascript API from the Xuc Server :: * Include also the xc_webrtc and SIPml5 javascript APIs for the webRTC support: :: .. _cti_authentication: * Connect to the Xuc server using new Authentication token (see :ref:`rest_authentication`) :: var wsurl = "ws://"+server+"/xuc/api/2.0/cti?token="+token; Cti.WebSocket.init(wsurl,username,phoneNumber); * Connect to the Xuc server using XiVO client username and password (DEPRECATED) :: var wsurl = "ws://"+server+"/ctichannel?username="+username+"&agentNumber="+phoneNumber+"&password="+password; 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://:/sample .. figure:: sampleapp.png :scale: 90% 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); }); .............. * 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); Debugging ========= Cti features ------------ Cti messages 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 messages 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"}} WebRTC features --------------- The WebRTC debug can be activated separately by the following method: :: xc_webrtc.setDebug(sipml5level, event, handler) Where: * sipml5level refers to the SIPml5 library log level string as described on `SIPml5 log level documentation`_, * event is a boolean value activating event logging (each event is prefixed by ``RE<<<``), * handler is a boolean value activating logging of message handler subscription/unsubscription. .. _SIPml5 log level documentation: https://www.doubango.org/sipml5/docgen/symbols/SIPml.html#.setDebugLevel WebRTC on sample page --------------------- Once logged on the sample page, you can init the webRTC through the init button, follow events shown in the webRTC section and send and receive calls. You can terminate a call by the terminate button in the phone section. Direct and attended transfer can be performed using phone section methods. Hold and DTMF features are available via the webRTC API. Current implementation support just one simultaneous call. Current browsers doesn't allow media sharing without secure connections - https and wss. The xivoxc_nginx docker image contains the configuration required for loading the sample page over a secure connection using an auto-signed certificate. This certificate is automatically generated by the installation script. It is meant to be used only for test purposes, you should replace it by a signed certificate before switching to production. The sample page is available on the following address: https://MACHINE_IP:8443/sample Login ===== User login ---------- Users can connect using login, password and phone number: :: var wsurl = "ws://"+server+"/ctichannel?username="+username+"&agentNumber="+phoneNumber+"&password="+password; Cti.WebSocket.init(wsurl,username,phoneNumber); Agent login ----------- An agent can be logged in using `Cti.loginAgent(agentPhoneNumber, agentId)`. For the moment, the phone number used for agent login should be the same as the one used for user login, otherwise you will get many error messages "LoggedInOnAnotherPhone". Following cases are handled: - agent is not logged and requests a login to a known line: the agent is logged in - agent is not logged and requests a login to an unknown line: an error is raised: :: {"Error":"PhoneNumberUnknown"} - agent is already logged on the requested line: the agent stays logged - agent is already logged on another line: an error is raised and the agent stays logged (on the number where he was logged before the new request). It's up to the implementation to handle this case. :: {"Error":"LoggedInOnAnotherPhone","phoneNb":"1002","RequestedNb":"1001"} - agent is not logged and requests a login to a line already used by another agent: the agent takes over the line and the agent previously logged on the line is unlogged Generic CTI Messages ==================== Error ----- * Cti.MessageType.ERROR LoggedOn -------- * Cti.MessageType.LOGGEDON Directory And Favorites ======================= Cti.directoryLookUp: function(term) ----------------------------------- This command deprecates previously used `Cti.searchDirectory(pattern)`. This command deprecates previously used `Cti.searchDirectory(pattern)` removed in xuc xivo16 versions. Note: If dird is not configured, xivo.useDird should be configured to false, and search directory will fallback using the cti server Associated Handler ------------------ * Cti.MessageType.DIRECTORYRESULT Triggered by command `Cti.directoryLookUp(pattern)`. :: { "msgType": "DirectoryResult", "ctiMessage": { "entries": [ { "status": 0, "entry": [ "hawkeye", "pierce", "1002", "0761187406", "false"]}, { "status": -2, "entry": [ "peter", "pan", "1004", "", "false"]}], "headers": [""Firstname", "Lastname", "Number", "Mobile", "Favorite"]}} Cti.getFavorites: function() ---------------------------- Cti.addFavorite: function(contactId, source) -------------------------------------------- Cti.removeFavorite: function(contactId, source) ----------------------------------------------- Other Messages ============== Sheet ----- * Cti.MessageType.SHEET :: {"msgType":"Sheet","ctiMessage":{"timenow":1425055334,"compressed":true,"serial":"xml", "payload":{"profile":{"user":{"internal":[{"content":"xivo","name":"ipbxid"}, {"content":"link","name":"where"},{"content":"1425055330.23","name":"uid"}, {"content":"no","name":"focus"},{"content":"1","name":"zip"}], "sheetQtui":null,"sheetInfo":[{"value":"http://www.google.fr/","name":"popupUrl","order":10,"type":"url"}, {"value":"&folder=1234","name":"folderNumber","order":30,"type":"text"}, {"value":"http://www.google.fr/","name":"popupUrl1","order":20,"type":"url"}],"systrayInfo":[]}}},"channel":"SIP/1k4yj2-00000013"}} User Statuses ------------- * Cti.MessageType.USERSTATUSES : "UsersStatuses" User Status Update ------------------ * Cti.MessageType.USERSTATUSUPDATE : "UserStatusUpdate", User Config Update ------------------ * Cti.MessageType.USERCONFIGUPDATE : "UserConfigUpdate", :: {"msgType":"UserConfigUpdate", "ctiMessage":{"userId":9,"dndEnabled":false,"naFwdEnabled":false,"naFwdDestination":"","uncFwdEnabled":false,"uncFwdDestination":"","busyFwdEnabled":false,"busyFwdDestination":"", "firstName":"Alice","lastName":"Johnson","fullName":"Alice Johnson","mobileNumber":"064574512","agentId":22,"lineIds":[5],"voiceMailId":58,"voiceMailEnabled":true}} Phone Status Update ------------------- * Cti.MessageType.PHONESTATUSUPDATE .. _phoneevents: Phone Events ------------ * Cti.MessageType.PHONEEVENT Phone events are automatically sent when application is connected Format :: { "msgType":"PhoneEvent", "ctiMessage":{ "eventType":"EventRinging", "DN":"1118", "otherDN":"1058", "otherDName":"Jane Black", "linkedId":"1447670380.34", "uniqueId":"1447670382.37", "queueName":"blue", "userData":{ "XIVO_CONTEXT":"default","XIVO_USERID":"9","XIVO_SRCNUM":"1058","XIVO_DSTNUM":"3000" } } } +-------------+----------------------------------------+ | fields | Description | +=============+========================================+ | Event types | * EventReleased | | | * EventDialing | | | * EventRinging | | | * EventEstablished | +-------------+----------------------------------------+ | DN | The directory number of the event | +-------------+----------------------------------------+ | otherDN | Can be calling number of called number | +-------------+----------------------------------------+ | otherDName | Can be name of caller of called number | +-------------+----------------------------------------+ | queueName | Optional, the queue name for inbound | | | acd calls | +-------------+----------------------------------------+ | UserData | Contains a list of attached data, | | | system data XIVO\_ or data attached | | | to the call key beginning by USR\_ | +-------------+----------------------------------------+ If you use the following preprocess subroutine :: [user_data_test] exten = s,1,Log(DEBUG,**** set user data ****) same = n,SET(USR_DATA1=hello) same = n,SET(USR_DATA2=24) same = n,SET(USR_DATA3=with space) same = n,Return() you will get these data in the events. Data can also be attached using the `Cti.dial`_ command. Voice Mail Status Update ------------------------ * VOICEMAILSTATUSUPDATE : "VoiceMailStatusUpdate", :: {"msgType":"VoiceMailStatusUpdate","ctiMessage":{"voiceMailId":58,"newMessages":2,"waitingMessages":1,"oldMessages":1}} Link Status Update ------------------ * Cti.MessageType.LINKSTATUSUPDATE User Right Profile ------------------- * Cti.MessageType.RIGHTPROFILE: "RightProfile" :: {"msgType":"RightProfile","ctiMessage":{"profile":"Supervisor"}} This message is sent upon connection to the xuc websocket. The profile can be one of: "Supervisor", "Admin", "NoRight". Queue Statistics ---------------- * Handler on : Cti.MessageType.QUEUESTATISTICS The handler is executed when a notification of new statistic values is received. Each message contains one or more counters for one queue. The queue is identified by its queueId. See example below for reference. The queue's id can be used to retrieve queue's configuration, see `Queue Configuration`_. Following counters are available: * TotalNumberCallsEntered * TotalNumberCallsAnswered * PercentageAnsweredBefore15 * TotalNumberCallsAbandonned * TotalNumberCallsAbandonnedAfter15 * PercentageAbandonnedAfter15 * WaitingCalls * LongestWaitingTime * EWT * AvailableAgents * TalkingAgents :: { "msgType":"QueueStatistics", "ctiMessage":{ "queueId":11,"counters":[{"statName":"AvailableAgents","value":0},{"statName":"LoggedAgents","value":0},{"statName":"TalkingAgents","value":0},{"statName":"EWT","value":0}] } } Some messages contain a queueRef with a queue's name instead of the queueId. This issue should be eliminated in future versions. :: {"queueRef":"travels","counters":[{"statName":"TotalNumberCallsAbandonned","value":19}]} Queue Calls ----------- * Handler on: Cti.MessageType.QUEUECALLS Awaiting calls in a queue. Subscription to the events with : `Cti.subscribeToQueueCalls(9)` (9 being the queueId). Unsubscription with: `Cti.unSubscribeToQueueCalls(9)`. :: {"queueId":9,"calls":[{"position":1,"name":"John Doe","number":"33356782212","queueTime":"2015-07-16T10:40:16.626+02:00"}]} Queue Configuration ------------------- * QUEUECONFIG : "QueueConfig", :: {"id":8,"context":"default","name":"blue","displayName":"blue sky","number":"3506"} Queue List ---------- * QUEUELIST : "QueueList", :: { "msgType":"QueueList", "ctiMessage":[ {"id":170,"context":"default","name":"bluesky","displayName":"Bl Record","number":"3012"}, {"id":5,"context":"default","name":"noagent","displayName":"noagent","number":"3050"}, {"id":6,"context":"default","name":"__switchboard_hold","displayName":"Switchboard hold","number":"3005"}, {"id":173,"context":"default","name":"outbound","displayName":"outbound","number":"3099"}, {"id":2,"context":"default","name":"yellow","displayName":"yellow stone","number":"3001"}, {"id":7,"context":"default","name":"green","displayName":"green openerp","number":"3006"}, {"id":3,"context":"default","name":"red","displayName":"red auto polycom","number":"3002"}, {"id":11,"context":"default","name":"pool","displayName":"Ugips Pool","number":"3100"}, {"id":4,"context":"default","name":"__switchboard","displayName":"Switchboard","number":"3004"} ] } Queue Member ------------ * Handler on : Cti.MessageType.QUEUEMEMBER Received when an agent is associated to a queue or a penalty is updated. Penalty is -1 when agent is removed from a queue :: {"agentId":19,"queueId":3,"penalty":12} Queue Member List ----------------- * Handler on : Cti.MessageType.QUEUEMEMBERLIST :: { "msgType":"QueueMemberList", "ctiMessage":[ {"agentId":129,"queueId":8,"penalty":2}, {"agentId":139,"queueId":168,"penalty":2}, {"agentId":129,"queueId":10,"penalty":0}, {"agentId":129,"queueId":11,"penalty":0} ] } Agent State Event ----------------- * Cti.MessageType.AGENTSTATEEVENT * AgentLogin :: {"name":"AgentLogin","agentId":19,"phoneNb":"1000","since":1423839787,"queues":[8,14,170,4,1],"cause":""} * AgentReady :: {"name":"AgentReady","agentId":19,"phoneNb":"1000","since":0,"queues":[8,14,170,4,1],"cause":"available"} * AgentOnPause :: {"name":"AgentOnPause","agentId":19,"phoneNb":"1000","since":0,"queues":[8,14,170,4,1],"cause":"available"} * AgentOnWrapup :: {"name":"AgentOnWrapup","agentId":19,"phoneNb":"1000","since":2,"queues":[8,14,170,4,1],"cause":"available"} * AgentRinging :: {"name":"AgentRinging","agentId":19,"phoneNb":"1000","since":0,"queues":[8,14,170,4,1],"cause":"available"} * AgentDialing :: {"name":"AgentDialing","agentId":19,"phoneNb":"1000","since":0,"queues":[8,14,170,4,1],"cause":"available"} * AgentOnCall :: {"msgType":"AgentStateEvent","ctiMessage": {"name":"AgentOnCall","agentId":19,"phoneNb":"1000","since":0,"queues":[8,14,170,4,1], "cause":"available","acd":false,"direction":"Incoming","callType":"External","monitorState":"ACTIVE"}} * AgentLoggedOut :: {"name":"AgentLoggedOut","agentId":19,"phoneNb":"1000","since":0,"queues":[8,14,170,4,1],"cause":"available"} Agent Error ----------- * Cti.MessageType.AGENTERROR Agent Directory --------------- * Cti.MessageType.AGENTDIRECTORY Triggered by command `Cti.getAgentDirectory` :: {"directory": [ { "agent": {"context": "default", "firstName": "bj", "groupId": 1, "id": 8, "lastName": "agent", "number": "2000"}, "agentState": {"agentId": 8, "cause": "", "name": "AgentReady", "phoneNb": "1001", "queues": [1, 2], "since": 2 }}]} Agent Configuration ------------------- * Cti.MessageType.AGENTCONFIG Triggered when agent configuration changes :: {"id":23,"firstName":"Jack","lastName":"Flash","number":"2501","context":"default"} Agent List ---------- * Cti.MessageType.AGENTLIST Receives agent configuration list in a javascript Array : Command `Cti.getList("agent");` :: [ {"id":24,"firstName":"John","lastName":"Waynes","number":"2601","context":"default","groupId":1}, {"id":20,"firstName":"Maricé","lastName":"Saprïtchà","number":"2602","context":"default","groupId":1}, {"id":147,"firstName":"Etienne","lastName":"Burgad","number":"30000","context":"default","groupId":1}, {"id":148,"firstName":"Caroline","lastName":"HERONDE","number":"29000","context":"default","groupId":2}, {"id":149,"firstName":"Eude","lastName":"GARTEL","number":"75000","context":"default","groupId":3}, {"id":22,"firstName":"Alice","lastName":"Johnson","number":"2058","context":"default","groupId":5} ] Agent Listen ------------ * AGENTLISTEN: "AgentListen", Receives agent listen stop / start event, received automatically if user is an agent, no needs to subscribe. :: {"started":false,"phoneNumber":"1058","agentId":22} Agent Group List ---------------- * AGENTGROUPLIST : "AgentGroupList" Agent group list triggered by command : `Cti.getList("agentgroup")` :: [ {"id":1,"name":"default"}, {"id":2,"name":"boats"}, {"id":3,"name":"broum"}, {"id":4,"name":"bingba3nguh"}, {"id":5,"name":"salesexpert"}, {"id":6,"name":"a_very_long_group_name"} ] Agent Statistics ---------------- Received on subscribe to agent statistics with method `Cti.subscribeToAgentStats()`_, current statistics are received automatically on subscribe. * AGENTSTATISTICS : "AgentStatistics" :: {"id":22, "statistics":[ {"name":"AgentPausedTotalTime","value":0}, {"name":"AgentWrapupTotalTime","value":0}, {"name":"AgentReadyTotalTime","value":434}, {"name":"LoginDateTime","value":"2015-04-27T08:15:01.081+02:00"}, {"name":"LogoutDateTime","value":"2015-04-27T08:14:49.427+02:00"} ] } Call History ============ Cti.getUserCallHistory(size) ---------------------------- Get the call history of the logged in user, limited to the last `size` calls. Cti.getAgentCallHistory(size) ----------------------------- Get the call history of the logged in agent, limited to the last `size` calls. Cti.getQueueCallHistory(queue, size) ------------------------------------ Get a call history for a queue or a set of queues. You may pass part of a queue name (not display name). i.e. pass bl if you want to match queue name blue, black and blow Associated Handler CALLHISTORY ------------------------------ Received when calling the above methods `Cti.getAgentCallHistory(size)`_ or `Cti.getUserCallHistory(size)`_ . * CALLHISTORY : "CallHistory" :: { "start":"2014-01-01 08:00:00", "duration":"00:21:35", "srcNum":"0115878", "dstNum":"2547892", "status":"answered" } For queue calls status can be : * full - full queue * closed - closed queue * joinempty - call arrived on empty queue * leaveempty - exit when queue becomes empty * divert_ca_ratio -call redirected because the ratio waiting calls/agents was exceeded * divert_waittime - call redirected because estimated waiting time was exceeded; * answered - call answered * abandoned - call abandoned * timeout - maximum waiting time exceeded For other calls * emitted * missed * ongoing Callback Messages ================= Callback lists -------------- Received when calling `Callback.getCallbackLists()`_. * CALLBACKLISTS : "CallbackLists" :: {"uuid":"b0849ac0-4f4a-4ed0-9386-53ab2afd94b1", "name":"Liste de test", "queueId":1, "callbacks":[ {"uuid":"a967da84-bc41-4bf4-a4fc-2bcc54e11606", "listUuid":"b0849ac0-4f4a-4ed0-9386-53ab2afd94b1", "phoneNumber":"0230210082", "mobilePhoneNumber":"0789654123", "firstName":"Alice", "lastName":"O'Neill", "company":"YourSociety", "description":null, "agentId":null, "dueDate": "2016-08-01", "preferredPeriod": { "default": false, "name": "Afternoon", "periodStart": "14:00:00", "periodEnd": "17:00:00", "uuid": "d3270038-e20e-498a-af71-3cf69b5cc792" }} ]} Callback Taken -------------- Received after taking a callback with `Callback.takeCallback(uuid)`_. * CALLBACKTAKEN : "CallbackTaken" :: {"uuid":"a967da84-bc41-4bf4-a4fc-2bcc54e11606", "agentId":2} Callback Started ---------------- Received after starting a callback with `Callback.startCallback(uuid, phoneNumber)`_. * CALLBACKSTARTED : "CallbackStarted" :: {"requestUuid":"a967da84-bc41-4bf4-a4fc-2bcc54e11606", "ticketUuid":"8e82de0f-847a-4606-97bf-bef5a18ea8b0"} Callback Clotured ----------------- Received after giving to a callback a status different of ``Callback``. * CALLBACKCLOTURED : "CallbackClotured" :: {"uuid":"a967da84-bc41-4bf4-a4fc-2bcc54e11606"} Callback Released ----------------- Received after releasing a callback with `Callback.releaseCallback(uuid)`_. * CALLBACKRELEASED : "CallbackReleased" :: {"uuid":"a967da84-bc41-4bf4-a4fc-2bcc54e11606"} Callback Updated ---------------- Received when calling `Callback.updateCallbackTicket(uuid, status, description, dueDate, periodUuid)`_ with a new due date or period. * CALLBACKREQUESTUPDATED : "CallbackRequestUpdated" :: {"request":{ "uuid":"a967da84-bc41-4bf4-a4fc-2bcc54e11606", "listUuid":"b0849ac0-4f4a-4ed0-9386-53ab2afd94b1", "phoneNumber":"0230210082", "mobilePhoneNumber":"0789654123", "firstName":"Alice", "lastName":"O'Neill", "company":"YourSociety", "description":null, "agentId":null, "dueDate": "2016-08-01", "preferredPeriod": { "default": false, "name": "Afternoon", "periodStart": "14:00:00", "periodEnd": "17:00:00", "uuid": "d3270038-e20e-498a-af71-3cf69b5cc792" } }} Membership Messages =================== User default membership ----------------------- Received when calling `Membership.getUserDefaultMembership(userId)`_. * USERQUEUEDEFAULTMEMBERSHIP: "UserQueueDefaultMembership" :: { "userId":186, "membership": [ {"queueId":8,"penalty":1}, {"queueId":17,"penalty":0}, {"queueId":18,"penalty":0}, {"queueId":23,"penalty":0} ] } Agent Methods ============= Cti.loginAgent(agentPhoneNumber, agentId) ----------------------------------------- Log an agent Cti.logoutAgent(agentId) ------------------------ Un log an agent Cti.pauseAgent(agentId) ----------------------- Change agent state to pause Cti.unpauseAgent(agentId) ------------------------- Change agent state to ready Cti.listenAgent(agentId) ------------------------ Listen to an agent Methods ======= Cti.changeUserStatus() ---------------------- Update user status using a cti server configured status name Cti.dnd(state) -------------- Set or unset do not disturb, state true or false Cti.setData(variables) ---------------------- Attach data to the device current calls. When there is a call connected to a device, Data can be attached by passing key values as a json object `Cti.setData("{'var1':'val1','USR_var2':'val2'}");` The folowing json message is then sent to the server : :: {"claz":"web","command":"setData","variables":{"var1":"val1","USR_var2":"val2"}} When the call is transfered i.e. (`Cti.directTransfer(destination)`_), data is sent in the event ringing see `Phone Events`_, and in subsequent events. Data is not propagated in the reporting database. :: {"eventType":"EventRinging","DN":"1000","otherDN":"0427466347","linkedId":"1469709757.74","uniqueId":"1469709960.78","queueName":"bluesky", "userData":{ "XIVO_CONTEXT":"from-extern", "XIVO_USERID":"1", "USR_var1":"val1", "USR_var2":"val2", "XIVO_EXTENPATTERN":"_012305XXXX", "XIVO_SRCNUM":"0427466347", "XIVO_DST_FIRSTNAME":"Brucé", "XIVO_DSTNUM":"0123053012","XIVO_DST_LASTNAME":"Wail"}} Note that *USR\_* prefix is added to the key, if the key does not start with it. Only attached data beginning with *USR\_* are sent back to the client API. .. warning:: When transfering a call, these variables are attached to the new channel however to prevent propagation on all trunk channels, your trunk name must contain 'trunk' so they can be distinguished from sip devices. .. _Cti.dial: Cti.dial(destination, variables) -------------------------------- Place a call to destination with the provided variables. Variables must take the following form: :: { var1: "value 1", var2: "value 2" } USR_var1 and USR_var2 will be attached to the call and propagated to `Phone Events`_ Cti.dialFromMobile(destination, variables) ------------------------------------------ Place a call from logged user's mobile number to destination with the provided variables. Variables must take the following form: :: { var1: "value 1", var2: "value 2" } USR_var1 and USR_var2 will be attached to the call and propagated to `Phone Events`_ Cti.dialFromQueue(destination, queueId, callerId, variables) ------------------------------------------------------------ Creates outgoing call to ``destination`` from some free Agent attached to ``queueId``. Caller id on both sides is set to ``callerId``. Variables must take the following form: :: { var1: "value 1", var2: "value 2" } USR_var1 and USR_var2 will be attached to the call and propagated to `Phone Events`_ **Limitations:** Queue No Answer settings does not work - see :ref:`xivo-queues-no-answer`. Except: when there is no free Agent to queue (none attached, all Agents on pause or busy), then No answer settings work (but Fail does not). .. note:: Line should be configured with enabled "Ring instead of On-Hold Music" enabled (on "Application: tab in queue configuration - see :ref:`xivo-queues`). Otherwise the queue will answers the call and the destination rings even if there are no agents available. Cti.originate(destination) -------------------------- Originate a call Cti.hangup() ------------ Hangup a call Cti.answer() ------------ Answer a call Cti.hold() ---------- Put current call on hold Cti.directTransfer(destination) ------------------------------- Tranfert to destination Cti.attendedTransfer(destination) --------------------------------- Start a transfer to a destination Cti.completeTransfer() ---------------------- Complete previously started transfer Cti.cancelTransfer() -------------------- Cancel a transfer Cti.conference() ---------------- Start a conference using phone set capabilities Cti.monitorPause(agentId) ------------------------- Pause call recording .. note:: You can only pause the recording of a call answered by an agent (i.e. a call sent via a Queue towards an Agent). Cti.monitorUnpause(agentId) --------------------------- Unpause call recording .. note:: You can only pause the recording of a call answered by an agent (i.e. a call sent via a Queue towards an Agent). Cti.getList(objectType) ----------------------- Request a list of configuration objects, objectType can be : * queue * agent * queuemember Triggers handlers QUEUELIST, AGENTLIST, QUEUEMEMBERLIST. Subscribes to configuration modification changes, handlers QUEUECONFIG, AGENTCONFIG, QUEUEMEMBER can also be called Cti.setAgentQueue(agentId, queueId, penalty) -------------------------------------------- * agentId (Integer) : id of agent, returned in message `Agent Configuration`_ * queueId (Integer) : id of queue, returned in message `Queue Configuration`_ * penaly (Integer) : positive integer If agent is not associated to the queue, associates it, otherwise changes the penalty On success triggers a `Queue Member`_ event, does not send anything in case of failure : :: {"agentId":,"queueId":,"penalty":} Cti.removeAgentFromQueue(agentId, queueId) ------------------------------------------ * agentId (Integer) : id of agent, returned in message `Agent Configuration`_ * queueId (Integer) : id of queue, returned in message `Queue Configuration`_ On success triggers a queue member event with penalty equals to -1, does not send anything in case of failure : :: {"agentId":,"queueId":,"penalty":-1} Cti.subscribeToAgentStats() --------------------------- Subscribe to agent statistics notification. When called all current statistics are receive, and a notification is received for each updates. Both initial values and updates are transmitted by the `Agent Statistics`_ messages. Cti.subscribeToQueueStats() --------------------------- This command subscribes to the queue statistics notifications. First, all actual statistics values are sent for initialisation and then a notification is sent on each update. Both initial values and updates are transmitted by the QUEUESTATISTICS messages. Cti.naFwd(destination,state) ---------------------------- Forward on non answer Cti.uncFwd(destination,state) ----------------------------- Unconditionnal forward Cti.busyFwd(destination,state) ------------------------------ Forward on busy Callback Commands ================= Callback.getCallbackLists() --------------------------- Retrieve the lists of callbacks with teir associated callback requests, and subscribe to callback events. Callback.takeCallback(uuid) --------------------------- Take the callback with the given uuid with the logged-in agent. Callback.releaseCallback(uuid) ------------------------------ Release the callback which was previously taken Callback.startCallback(uuid, phoneNumber) ----------------------------------------- Launch the previously taken callback with the provided phone number. Callback.updateCallbackTicket(uuid, status, description, dueDate, periodUuid) ----------------------------------------------------------------------------- Update a callback ticket wih the provided description and status. Allowaed values for status are: - NoAnswer - Answered - Fax - Callback dueDate is an optional parameter specifying the new due date using ISO format ("YYYY-MM-DD"). periodUuid is an optional parameter specifying the new preferred period for the callback. Membership Commands =================== Membership.init(cti) -------------------- Initialize the Membership library using the given Cti object. Membership.getUserDefaultMembership(userId) ------------------------------------------- Request the default membership for the given user id. Warning, the userId is not the same as the agentId. Membership.setUserDefaultMembership(userId, membership) ------------------------------------------------------- Set the default membership for the given user id. Warning, the userId is not the same as the agentId. 'membership' should be an array of Queue membership like: :: [ {"queueId":8,"penalty":1}, {"queueId":17,"penalty":0}, {"queueId":18,"penalty":0}, {"queueId":23,"penalty":0} ] Membership.setUsersDefaultMembership(userIds, membership) --------------------------------------------------------- Set the default membership for the given array of user id. Warning, the userId is not the same as the agentId. 'userIds' should be an array of user id like : :: [1, 2, 3] 'membership' should be an array of Queue membership like: :: [ {"queueId":8,"penalty":1}, {"queueId":17,"penalty":0}, {"queueId":18,"penalty":0}, {"queueId":23,"penalty":0} ] Membership.applyUsersDefaultMembership(userIds) ----------------------------------------------- Apply the existing default configuration to a set of users. Warning, the userId is not the same as the agentId. 'usersIds' should be an array of userId like: :: [1, 2, 7, 9] webRTC integration ================== Methods ======= Once the cti login done, you can init the webRTC component by calling the `xc_webrtc.init` method. xc_webrtc.init(name, ssl, websocketPort, remoteAudio, ip) --------------------------------------------------------- Init the webRTC connection and register the user's line. * name - user's login to get the line details, * ssl - if set to true the wss is used, * websocketPort, ip - port and address for the webRTC websocket connection, when ip is not passed the xivo ip is used, * remoteAudio - id of the HTML5 audio element for remote audio player, if not passed 'audio_remote' is used. The element should look like: :: xc_webrtc.dial(destination) --------------------------- Start a webRTC call. xc_webrtc.answer() ------------------ Answer an incoming webRTC call. xc_webrtc.hold() ---------------- Toggle hold on a webrtc call. xc_webrtc.dtmf(key) ------------------- Send a DTMF. xc_webrtc.setHandler(eventName, handler) ---------------------------------------- Set a handler for eventName from xc_webrtc.MessageType. xc_webrtc.disableICE() ---------------------- Disable ICE server use, only LAN addresses will be used in the SDP. xc_webrtc.setIceUrls(urls) -------------------------- Set a list of STUN/TURN servers, for example: :: [{ url: 'stun:stun.l.google.com:19302'}, { url:'turn:turn.server.org’, username: ‘user’, credential:'myPassword'}] Events ====== There are for groups of events: * general, * register, * incoming, * outgoing. List of associated events is defined in the `xc_webrtc.General`, `xc_webrtc.Registration`, `xc_webrtc.Incoming`, `xc_webrtc.Outgoing`. See the xc_webrtc.js on https://gitlab.com/xivo.solutions/xucserver/blob/master/app/assets/javascripts/xc_webrtc.js. The error state events contains a description in the reason field. Call establishment event contains `caller` or `callee` detail. Use the sample page to see some examples. Security considerations ======================= Defining a user profile in the ConfigMGT impact the behavior of this api. No Profile ---------- If no profile is found, the behavior falls back on the Admin Profile behavior. Admin Profile ------------- An admin profile will be allowed to receive all events and send all commands. Supervisor Profile ------------------ A supervisor profile has the some properties impacting the events he can receive: * A list of queue which will filter the following events based on the queues in this list (send event only for queues defined in the list): * QueueList * QueueMemberList * QueueStatistics * A list of groups which will filter the following events based on the groups in this list (send event only if matching agent group is in the list): * AgentStateEvent * AgentStatistics * AgentGroupList * AgentList