Embedding the Widget

Use VideoWidget.js

In many cases, the easiest way to embed the widget is to use the 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);
    

Live Demo

To see use of this wrapper in action, a live demo is available below. You can see how VideoWidget.js is used to dynamically recreate the iframe in the #videowidget DOM element for each valid call link.

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

↱ Open the 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);
}

Server-side

An example Java integration

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

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));

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
        .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.

Creating a Call Link

This tutorial assumes a server-to-server integration with Jabber Guest. As customer authentication mechanisms will vary, this tutorial will assume Basic HTTP Authentication.

REST 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

REST Methods

HTTP Method Action
POST Create a link
DELETE Delete a link

Custom Parameter Values

If end-user provided values are needed before creating a link, a web-form could be used.

For example, if a user "Robert" prefers to go by "Bob" instead, we could give him the opportunity to set this with a text field like so:

  <p>
    <label for="myPreferredName">Display my name as:</label>
    <input type="text" id="myPreferredName" name="myPreferredName"></input>
  </p>

This value could then be passed along to your server-side via AJAX like so (we're assuming the use of jQuery here):

var postData = {
    callerName: $('#myPreferredName').val()
};

$.ajax({
  type: 'POST',
  url: '/createlink',  // <-- your server-side handler which POSTs to Jabber Guest
  data: postData,
  success: function () {
    console.log('Link created!');
  }
});

Server-side Discussion

See more about the server-side discussion here

Reference

Server-side

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

Name Type Required Description
callerName String N The name displayed to the recipient of the call, of who is calling them
destination String Y Directory number, or URI (if URI dialing has been enabled) of the recipient who the web end-user will be calling)
displayName String N The name displayed to the web end-user of whom they will be calling
isEnabled Boolean Y Whether this call link should be usable or not (still subject to validBefore and validAfter though)
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'")