Overview

This API is in Alpha. Unless you work for babblevoice there will be zero support (well buy us a beer, tickle us under the chin and we may start talking - we are easily bought!). This part of the API offers live information. It is designed to work in browsers inside Javascript applications amongst other applications. There is a 2 stages to get access to the information Register your interest in information Make a call to the presence server to wait for the information

Stage 1

To register your interest a call is made to http://www.babblevoice.com/api/presence with the follow parameters

  • d=
  • q=

The request must be oauth signed.

For example: http://www.babblevoice.com/api/presence?d=1000@bling.babblevoice.com,1001@bling.babblevoice.com&q=myqueue@bling.babblevoice.com This will create a session for you and return a JSON response with either an error or details of the session. The response could either be:

{ "server" : "pres.babblevoice.com", "session" : "session5194baa0a9655", "token" : "Yi5Zh95nNtgHrlH08088jT998gEXXsia", "agent_uuid": "432472f9-d143-11f3-9554-23004a55334e" }

or

{ "error": "some error message" }

The different values in the JSON array are:

  • server: the server you should now connect to in stage 2.
  • session: the session identifier - which will need to be passed to the server.
  • token: a secret token you must now use to sign the request when connecting to the web socket in stage 2.
  • agent_uuid: a unique identifier for this agent, it is generally used to identifier this installed instance, it is currently for future use.

Stage 2

In the previous section we ended up with a response which can now be used to connect to a presence server using a websocket. Example: We received the response above so we create a new call to: ws://pres.babblevoice.com?session_id=session5194baa0a9655&seq=0&auth=234567ijhgfrtyuijhgftyuij

Every call we make to the server for this session we must increment the seq value, so the next call will be 1, when this value reaches 99999 it should be wrapped back around to 0 (modulos). If you do not do this the call will be rejected. The auth hash is calculated as follows:

hash = sha1( token + params ) token comes from our stage 1 call. The params are the get params without the auth appended, so in this case: ?session_id=session5194baa0a9655&seq=0

So in this example hash = sha1 (“Yi5Zh95nNtgHrlH08088jT998gEXXsia?session_id=session5194baa0a9655&seq=0”) Putting it all together in some html5 Javascript

function createWebSocket(server, session_id, token)
{
    if ('WebSocket' in window)
    {
         var url = "ws://" + server;
         var querystring = "?session_id=" + session_id;
         querystring = signQueryString(querystring, token);

         websocketconnection = new WebSocket(url + querystring);

         websocketconnection.onmessage = function(e)
         {
              var server_message = e.data;
              eval ( " resp = " + server_message );
              // now do something with our message...
              // this will be called every time something happens of interest with the phone or queue
         }

         // we should probably do something with websocketconnection.onopen and other event handlers onclose, onerror
    }
}

function signQueryString(query, token)
{
    console.log("signing query " + query + " with token " + token);
    var fullquery = query + "&seq=" + sequence;
    var hash = CryptoJS.SHA1( token + fullquery);
    var fullquery = fullquery + "&auth=" + hash;

    sequence = ( sequence + 1 ) % 99999;

    console.log("signed query " + fullquery);
    return fullquery;
}

You may not get an immediate message (well you might but don’t expect one). A message is only generated when information is available of interest (.i.e. a telephone event). Stage 2 Response

When information is available and is return you will end up with a JSON response.

{
  "type": "device",
  "device": "1001@bling.babblevoice.com",
  "state": "registered",
  "callcount": 1,
  "now":123456789,
  "calls": [
    {"uuid": "873265837658367", "direction": "inbound", "callid": "7887687-8775-6576576-767575", "callidname": "Some Name", "callstart": 123456776, "calledid": "01442299280", "calledidname": ""}
  ],
  hangup: { "uuid": "",
            "cause": "normal_clearing",
            "when": 123456789 }
}

This JSON tells us there is a change to the state of 1001@bling.babblevoice.com.

  • type: For an update to a device is the string device.
  • device: The full URL of the device.
  • state: Is the device registered or not (registered, unregistered)
  • callcount: How many calls are active at the moment
  • now: UNIX epoch time as the server sees it now
  • calls: an array with details for each call
  • uuid: unique id of the call
  • direction: inbound or outbound (with respect to the device (phone))
  • callid: caller id for inbound, called id for outbound
  • callidname: as callid but for name
  • callstart: UNIX epoch time when the call started
  • calledid: inbound calls only, contains the originally dialled number by the caller
  • calledidname: currently unused, maybe in the future
  • hangup: if the event is sent becuase of a hangup event then this will be included which includes a reference to the uuid of the call, the hangup reason and the unix timestamp of when teh hangup happened.
{
  "type": "queue",
  "queue": "test@bling.babblevoice.com" ,
  "waiting_count": 1 ,
  "talking_count": 0 ,
  "agent_count": 1 ,
  "now": 1369303228 ,
  "calls": [
    {"uuid": "e993ee38-c390-11e2-875b-cf8dc6d8088e", "callid": "01123456789", "callidname": "01123456789", "callstart": 1369303228}
  ]
}
  • type: For an update to a queue is the string queue.
  • queue: The full URL of the queue.
  • waiting_count: How many calls are waiting in the queue
  • talking_count: How many calls have gone through the queue to be answered
  • agent_count: How many agents are servicing this queue
  • now: UNIX epoch time as the server sees it now
  • calls: an array with details for each call
  • uuid: unique id of the call
  • callid: caller id
  • callidname: as callid but for name
  • callstart: UNIX epoch time when the call started
  • callstate: new, connected, hangup

Watch out for error responses which are perfectly normal and should be silently handled:

{ "error": "noop" } { "error": "timeout" }

noop: no operation, the server gave a noop response because it needed to handle a second (pipelined) request. You should immediately make another call to the wait method.

  • timeout: a timeout condition has occurred. This is designed to ensure the connection is still alive (i.e. in normal conditions if a phone or queue has remained idle then we will not see any documents returned from the http server, so we can set a timeout to test if the connection is still alive. We would recommend that timeouts of > 2 minutes are used - the more frequent the less responsive your application will be, but the longer the timeout the longer your client will be able to detect a stale connection).

Cross Domain Ajax request

On the presence server, which you only have access to if a session is created on the main API, we present HTTP header Access-Control-Allow-Origin: * HTTP header. This allows clients to connect to the presence inside a browser with no issues.

More information about

Also, check out the babblevoice University on Youtube or ask a question in our Google Group.