Introduction

This documentation will cover examples of how to make use of the Jabber Guest call link management REST API. Though our demos are done in Java, any modern framework with a REST client API should be able to integrate in the same way.

Note: Our examples assume we are a hosted webapp in a servlet container (e.g. Tomcat), that is external to our Jabber Guest server. Also, for demo purposes only, we use Basic HTTP Authentication for "logging in".

Our Example Scenario

For the purposes of our examples, let's assume we have a web end-user, Jonathan Smith, that has a computer problem and needs to call the IT Help Desk. By logging into his company's portal site and finding and clicking on a Jabber Guest call link to the IT Help Desk, Jonathan is able quickly and easily get the help he needs.

Basic Workflow

In all of our examples, the workflow is the same.

  1. We send an AJAX request when an end-user wants to make a call (or when he/she ends a call)
  2. A servlet accepts this request and in turn makes its own request to our Jabber Guest server via the call link REST API
  3. When our Jabber Guest server returns a response back to the servlet, the servlet then responds back to the web client with a JSON response
  4. Our Javascript then uses the JSON response to carry out further any UI actions or behavior

Client-side Discussion

Assuming we are logged in, we start with an AJAX POST to our servlet. For our purposes, let's say that our servlet is found at:

/jabberguest-demo/servlet

Assuming we have jQuery available to us, our POST then might look like this:

$.post('/jabberguest-demo/servlet',  // request path to our servlet
    {
        ...                          // our parameter data
    },
    function (data) {                // success callback
        ...
    },
    'json');                         // always expect a JSON response

As discussed below, our servlet will go and make the appropriate REST call to our Jabber Guest server, and return with an appropriate JSON response with two properties: restUrl and callUrl.

Assuming that our Jabber Guest server is set up at jabberguest.example.com, we could expect JSON response data similar to the following:

{
    "restUrl": "https://jabberguest.example.com/cjg-api/rest/links/532cda9ae4b09e16fdb78b96",
    "callUrl": "https://jabberguest.example.com/call/402741cf-e502-4206-aa25-38d8c6b114b6"
}

...and so revisiting our POST snippet above, we can use this response data as appropriate. Let's say for example we had a hidden button that we want to make appear once a call link is available. We could accomplish this with something like the following:

$.post(...

    // success callback
    function (jsonData) {
        var callUrl = jsonData.callUrl;

        // click handler to redirect to the call url
        var go = function () {
            window.location = callUrl;
        };

        // bind the click handler, and show the button
        $('button#callNow').click(go).show();
    },

    ...);

Server-side Discussion

On the server-side we have a servlet running as if it were part of a company portal. It retrieves the username of the currently signed in user, and then uses the Jabber Guest REST API to create a call link for that user to call whatever number was passed in.

The reason we don't do this directly from the client is that the Jabber Guest REST APIs require admin credentials to use, which of course we would not want to embed in the Java Script of a web application.

Our example servlet is creating a link for the signed in user for a specific destination (extension), and what we do is generate a random request path to make a unique call url, and set an expiration on the link so that it can only be used for one call:

    // Destination is set by "destination" parameter
    String destination = request.getParameter("destination");

    // Set displayName to the user's name
    String displayName = request.getUserPrincipal().getName();
    String requestPath = UUID.randomUUID().toString();

    // Set link to be valid for 10 minutes
    Date validBefore = new Date((new Date()).getTime() + (10 * 60 * 1000));
    Date validAfter = null; // Valid now
    Integer autoCallAfterSecs=null;
    String  autoCallAfterSecsStr = request.getParameter("autoCallAfterSecs");
    if(autoCallAfterSecsStr!=null&&!autoCallAfterSecsStr.trim().equals("")){
        try{
            autoCallAfterSecs =  Integer.valueOf(autoCallAfterSecsStr.trim());
        } catch (Exception e){
            System.out.println("autoCallAfterSecs parameter error, set as null");
        }
    }
   String videoPolicy = request.getParameter("videoPolicy");
   if(videoPolicy==null||videoPolicy.trim().equals("")){
      videoPolicy=null;
   }

Presumably the call is going to be made right away, so we provide a 10 minute window for the link to be active.

The link should also be deleted so we don't clutter up the system with expired links, but the expiration gives us a safeguard there just in case (and so we can show how to use expiration in our example.)

Calling the REST API

The next thing the servlet does is call the REST API on Jabber Guest to create the link we defined above. To do this we can use BASIC authentication and some admin credentials (the servlet reads those in from web.xml -- definitely not recommended for production!)

The link API is very REST-ful, so we need to POST a JSON object to the links url to create a new link. JSON is fairly simple and you can easily build up a string of JSON by hand, but for this demo we're using a lightweight JSON library to keep things simple (https://github.com/ralfstx/minimal-json):

JsonObject linkObject = new JsonObject()
    .add( "isEnabled", true )
    .add( "destination", destination )
    .add( "displayName", displayName )
    .add( "callerName", callerName )
    .add( "requestPath", requestPath );
if (validAfter != null)
    linkObject.add( "validAfter", dateToJSON(validAfter));
if (validBefore != null)
    linkObject.add( "validBefore", dateToJSON(validBefore));
if(autoCallAfterSecs!=null) 
    linkObject.add("autoCallAfterSecs", autoCallAfterSecs);
if(videoPolicy!=null)
    linkObject.add("videoPolicy", videoPolicy);

The only real trick there is that we need to get the dates in a nice format - this particular JSON library doesn't do that automatically. So in case you run into this too, here's a snippet for doing that converstion:

private static String dateToJSON(Date d) {
    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
    df.setTimeZone(TimeZone.getTimeZone("UTC"));
    return(df.format(d));
}

Anway, we now have an object that we can get as a JSON string by simple calling toString().

Step 2 - POST JSON to server

The next step is to POST our JSON to the server. Again to keep things simple we're using a library to help us out here, which helps to illustrate the ideas without having to write a bunch of boilerplate helper code. This time we went with the excelent http-request library that can be found here: https://github.com/kevinsawicki/http-request

Before showing the code snippet to create a link, here are a few things to keep in mind:

  1. Set the Content-Type header to "application/json" so the server knows we are sending it JSON
  2. Success is determined by a 201 code (HTTP code for CREATED)
  3. The URL of the created link is returned in the Location header
  4. Java doesn't like self-signed certificates by default, which is what Jabber Guest servers come with

That might sound like a lot, but fortunately in code it's really fairly straight forward:

HttpRequest r = HttpRequest
        .post(this.linksUrl)
        .contentType("application/json")
        .accept("application/json")
        .basic(this.accountName,this.accountPassword)
        .trustAllCerts()    // For self signed certs
        .trustAllHosts()    // For self signed certs
        .send(linkObject.toString());

// Look for HTTP code 201 ("CREATED")
if (r.code() == 201)
    // Link created, get link URL from Location header
    return r.header("Location");

Note that for production you probably do not want to use "trustAllCerts()" because that will create a "man in the middle" attack vulnerability.

Also note that HTTP code 200 OK does not mean that the link was created, so be careful about that in your own application.

Examples

In the following live demo examples, we use a mock website and Basic HTTP Authentication to simulate logging in to a company portal. When prompted, simply login using the sample credentials:

  login:    jsmith
  password: 12345

The only required parameter for our servlet is a destination (ie. directory number to call). Let's say in our case, the IT Help Desk's extension is: 5555.

Assuming we have jQuery available to us, our POST might look like this:

var helpDeskNumber = '5555';
var paramData = {
    destination: helpDeskNumber
};

$.post('/jabberguest-demo/servlet',  // request path to our servlet
    paramData,                       // parameter data
    function (jsonData) {},          // success callback
    'json');                         // set to explictly expect JSON data back

Now that we have the logic for actually creating a call link, let's put this to use. We could of course use this whenever the page loads, but that is unnecessarily wasteful. Instead, let's allocate the call link only when Jonathan actually clicks on the link.

To do that, we can wrap all of this logic in a click handler for the a element in question. Furthermore, we can redirect immediately once we have the call link URL, making our link behavior almost indistinguishable from any other normal link.

var helpDeskNumber = '5555';
var paramData = {
    destination: helpDeskNumber
};

var createLinkAndGo = function () {
    $.post('/jabberguest-demo/servlet',
        paramData,

        // success callback
        function (jsonData) {
            // redirect once we have our call link url
            var callUrl = jsonData.callUrl;
            window.location = callUrl;
        },

        'json');
};

// bind our click handler to the element in question
$('#callHelpDesk').on('click', createLinkAndGo);

↱ Open the live demo.

The call link management REST API allows for various properties to be set when creating a call link. It is at your discretion as to which parameters should be allowed to be passed in by the client-side.

That being said, for demo purposes here are some examples of parameters that can be set on the client-side in order to customize the names use in the Jabber Guest call.

var helpDeskNumber = '5555';
var paramData = {
    destination: helpDeskNumber,

    // call recipient-side will see that 'Jon S.' is calling
    callerName: 'Jon S.',

    // Jonathan will see that he is about to call 'IT Help Desk'
    displayName: 'IT Help Desk',

    // 'Jon S.' will not automatically call 'IT Help Desk'
    autoCallAfterSecs: -1,

    // both 'Jon S.' and 'IT Help Desk' can start/stop sending video during call
    videoPolicy: 'sendrecv'
};

Please refer to the Call Link JSON Attributes for a list of these parameters available to set before making the REST call to the Jabber Guest server.

↱ Open the live demo.

Embedding the Widget

Use VideoWidget.js

In many cases, the easiest way to embed the widget is to use our provided wrapper VideoWidget.js, which takes care of dynamically creating and attaching an iframe element to a DOM node that you specify. There are performance benefits from this approach, since it defers the loading and initialization logic until you absolutely need it.

To make use of it, copy it into your web project, and in the source of your containing web page:

  1. Add a DOM container with id="videowidget" (or customize your own in VideoWidget.js)

     <!-- The <iframe> will be inserted in this tag -->
     <div id="videowidget"></div>
    
  2. Set a global videowidgetParams object (or customize your own in VideoWidget.js)

     window.videowidgetParams = {
    
         // a valid call link
         callUrl: callUrl,
    
         // Event will be 'CALLSTARTED' or 'CALLENDED'
         onEvent: function (e) { ... }
     };
    
  3. Attach VideoWidget as a script element as needed via Javascript.

     var script, parentElem;
    
     // create a script element for VideoWidget.js
     script = document.createElement('script');
     script.type = 'text/javascript';
     script.async = true;
     script.src = "js/VideoWidget.js";
    
     // attach to DOM to trigger
     parentElem = (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]);
     parentElem.appendChild(script);
    

Important: as this demo uses a host with a self-signed SSL certificate, please click through https://jabberguestsandbox.cisco.com and accept the security warning in your browser first before opening the demo.

↱ Open the live demo.

...Or roll your own

The VideoWidget.js is a fully-functional sample that can be dropped into an existing codebase with minimal changes required. However, for those that prefer to roll their own solution, here are the basic details of how to do that.

Use an iframe

To embed the widget, use an iframe element whose src is a valid call link, but with the additional parameter of widget=true in the querystring.

For example, a valid call link this:

  https://www.example.com/call/webmaster

...would become this:

  https://www.example.com/call/webmaster?widget=true

And so, the HTML of a page embedding the widget might look like this:

  <div id="widget-container">
      <iframe id="my-widget" src="https://www.example.com/call/webmaster?widget=true" />
  </div>

Again, it is advisable to mention that as this widget is meant to be used for dynamic calling, it is likely that you will only want to attach the iframe element to the DOM only as needed via Javascript.

Querystring parameters

Name Value Required
widget true Y
uselang ex. en, fr, zh, en-US, ... N (defaults to browser language setting)

Javascript Events

There are only two events emitted by the iframe once it has been initialized:

Event Name Description
CALLSTARTED Fired when the 'Call' button is clicked.
CALLENDED Fired when an established call has ended, or a server error has occurred.

These events can be handled by listening to the message event in the containing page. For example:

// simple handler
var myHandler = function (e) {
    console.log('e.event: ', e.event);
    console.log('e.data: ', e.data);
}

// listen for the 'message' event
if (window.attachEvent) {
    window.attachEvent('onmessage', myHandler);
} else {
    window.addEventListener('message', myHandler, false);
}

Cleaning up

To tear down the widget, simply remove it from the DOM:

var elem = document.getElementById('my-widget');
if (elem) {
    elem.parentNode.removeChild(elem);
}

For our demo purposes, deleting a call link once it is no longer needed can be done simply via an AJAX call of type DELETE.

$.ajax({
    type: 'DELETE',
    url: '/jabberguest-demo/servlet',
    success: function () {
        console.log('Call link deleted.');
    }
});

Note: in our demo app, for security reasons, we do not allow the web client to specify the restUrl to be deleted. Instead we track this value in a session attribute, that the servlet itself uses when making the REST call.

Imagine if Jonathan called the IT Help Desk with a question, and then decided to call the HR Help Line with another question (or vice versa). This might be an appropriate time to delete the call link just created, right before generating another.

One simple way to ensure the order of this is to use an AJAX request in synchronous mode.

// delete the previous call link
$.ajax({
    type: 'DELETE',
    url: '/jabberguest-demo/servlet',

    // use synchronous mode to ensure link is deleted first
    async: false,

    success: function () {
        console.log('Call link deleted.');
    }
})

// and then create the new link
$.post('/jabberguest-demo/servlet',
    paramData,
    function (jsonData) { ... },
    'json');

However you will likely want to leave everything as asynchronous as possible and simply chain them together using a Promise-compatible library. jQuery for example supports this Promise-style interface:

// delete the previous call link
$.ajax({
    type: 'DELETE',
    url: '/jabberguest-demo/servlet',
    success: function () {
        console.log('Call link deleted.');
    }
})
// and then create a new one
.then(function () {
    $.post('/jabberguest-demo/servlet',
        paramData,
        function (jsonData) { ... },
        'json');
});

Note: for demo simplicity and readibility purposes, we demonstrate the method using synchronous AJAX.

↱ Open the live demo.

REST Reference

URI

The REST URI for Jabber Guest is:

  /cjg-api/rest/links

For example if a Jabber Guest service is set up at a hostname jabberguest.example.com, we would be making our requests to:

  https://jabberguest.example.com/cjg-api/rest/links

HTTP Methods

HTTP Method Action
POST Create a link
DELETE Delete a link

When using the Call Link REST API, these are the relevant JSON attributes to consider.

Name Type Required Description
destination String Y Directory number, or URI (if URI dialing has been enabled) of the recipient who the web end-user will be calling)
isEnabled Boolean Y Whether this call link should be usable or not (still subject to validBefore and validAfter though)
callerName String N The name displayed to the recipient of the call, of who is calling them
displayName String N The name displayed to the web end-user of whom they will be calling
requestPath String N The tail-end of a call link URL (ex. http://www.example.com/call/<requestPath>)
validAfter String N Datetime of the earliest moment in which the call link is valid (format: "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
validBefore String N Datetime of when the call link should expire (format: "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
autoCallAfterSecs Integer N Timer in seconds to automatically start a guest call. The value range is [-1, 60] as integer. Default value is -1 which means not to start a call automatically. Value 0 means start a immediate call automatically.
videoPolicy String N Guest video policy which can be set as four options:
  • "sendrecv": send and receive, can start/stop sending during call (default);
  • "inactive": cannot send or receive throughout call;
  • "recvonly": receive only, cannot start sending during call;
  • "recvonlyinitially": receive only initially, can start/stop sending during call.