Friday, May 25, 2012

Web Client for Microsoft Lync 2010

This week, we have spent some time exploring options to provide a web client for Microsoft Lync 2010.  As we started to explore this area, we anticipated that we would simply use a Lync web client SDK from Microsoft.  However, with Lync 2010, there is no default web client or web client SDK.

So, we have explored a few options during this assessment
  1. Leverage the Lync web client that can be configured to run as part of an Exchange 2010 OWA deployment
  2. Deploy an internal web client proxy service that uses the UCMA api and a custom web client
  3. Integrate with the name.dll component that is installed as part of a Lync 2010 client installation

Initially, we thought that we might be able to extend, and possibly use, the Lync web client that is provisioned as part of a Microsoft Office 365 configuration.  Apparently, this web client can also be configured as an extension to an Exchange 2010 installation with the addition of the OWA and OCS 2007 R2 web client installation.  After some low level investigation with Fiddler we decided that a more structured, and open, approach would be better option.

Here is the Office 365 Lync client:

Here is a link to a good article on integrating Lync and Exchange:

While the integration provided with the Exchange 2010 OWA looked promising, it was a bit too heavy for what we wanted.  So, we continued our investigation and located a few promising projects on Codeplex. 

Specifically, this Codeplex project is very interesting:

This project provided a nice base platform for developing a customized web client for Lync 2010.  After a bit of work, and some modifications on our side, we had a nice looking web client for Lync 2010. 

In terms of our modifications, we externalized some of the configuration - to allow for manually configuring the Lync server details.  We also migrated the Lync end point from using application end point to an end point that acts as a simulated SIP user.  We typically experience a high level of success (mostly with presence based API calls) when we use a end user end point - as opposed to the application end point.

Here is the presence example on a page:
Starting a chat:

With the Lync client on the other side of the conversation:

Our next steps will focus on some additional wiring to pass the end user's credentials to the the client (using Windows pass thru authentication) as well as some other configuration options.

Detecting presence of a local Lync client

Another interesting facet of a web-based Lync client, is that we are able to detect whether a Lync client is already running on a user's desktop, and if it is, rather than surfacing a web-based Lync client, we could bring up the users native Lync client running locally on their desktop. There are a few requirements for this functionality:
  1. Internet Explorer must be used when navigating the site. It's the only way to interface with the necessary DLLs to call the local Lync client.
  2. Office 2007 or 2010 must be installed. This places down the proper Lync presence/integration DLLs for us to use through the web.
  3. Lync client must be installed (running too if you expect to get the Lync client and not the web client).
We'll be using JavaScript to perform these tasks, and to get a basic example, it's really minimal code. First, let's make a simple JavaScript library that we can use to access some functions from the name.dll that we'll be manipulating for Lync.
var Instant = {
    sipUri: "eric_lync@instant.local", // Change this to the user's SIP URI you want to chat with
    nameCtl: new ActiveXObject('Name.NameCtrl.1'),

    onStatusChange: function (name, status, id) {
        alert(name + ", " + status + ", " + id);

    showOOUI: function () {
        Instant.nameCtl.ShowOOUI(Instant.sipUri, 0, 15, 15);

    hideOOUI: function () {
Our code here builds an object called nameCtl out of the name.dll NameCtrl control that is enabled with Lync and Office 2007+. This object opens up some other properties and functions that we can use to show information about the user, and track status. Our 'onStatusChange' function tracks a user's presence, it polls for the users current settings, and alerts it. The 'showOOUI' function will show an interactive display when called (more on that in a bit) and the hideOOUI function removes it. Let's build a page now that we can use to test our library.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">

<html xmlns="">
    <title>Lync Presence Test</title>
    <!-- le JS -->
    <script type="text/javascript" src="assets/js/instant-presence-0.0.1.js"></script>
    <script type="text/javascript">
        if (Instant.nameCtl.PresenceEnabled) {
            Instant.nameCtl.OnStatusChange = Instant.onStatusChange;
            Instant.nameCtl.GetStatus(Instant.sipUri, "1");
<span onmouseover="Instant.showOOUI()" onmouseout="Instant.hideOOUI()" style="border-style:solid;">Eric Richards</span>
Our page above includes our JavaScript library (instant-presence-0.0.1.js, in this case), and includes a span with some onmouseover and onmouseout functions that will get called from our library. When the page loads, we reference Instant.nameCtl.PresenceEnabled, which checks to see if the Lync client is currently running, if it is, we start checking status with Instant.onStatusChange. Now if we were to hover over the span, we would see a full Lync menu like the screenshot below.

From this menu, we can chat, call, video call, meet, etc. We have the full capacity of the local Lync client, all with just a few lines of HTML/JavaScript!