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: http://blog.schertz.name/2010/11/lync-and-exchange-im-integration/

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:
http://lyncwidget.codeplex.com/

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 () {
        Instant.nameCtl.HideOOUI();
    }
}
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" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <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");
        }
    </script>
</head>
<body>
<span onmouseover="Instant.showOOUI()" onmouseout="Instant.hideOOUI()" style="border-style:solid;">Eric Richards</span>
</body>
</html>
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!


Getting the availability of a Queue using JavaScript

When utilizing Queue Manager as a click-to-chat platform, it's important to be able to accurately know the current state of the Queue. You wouldn't want end-users trying to chat if the queue was offline, this would lead to user disappointment and dissatisfaction. You also may want a way of displaying how many experts are currently online, available, and ready to chat, to show the strength of your 'support-force'. Our Queue front-end has had support for these sort of requests for sometime, but in our most recent release, we've made these activities easier to perform. Let me walk you through a typical scenario, and I'll show you how easy it is.

Scenario: You want to check the status of the queue on a simple web page button press.

To achieve this functionality, we'll do a few things in JavaScript, but the code itself is very straightforward. To do this we'll be using the following (new!) Queue Manager API call to get the status of the queue:
Replace the fields necessary with your environment, the Queue login ID would be something like 'Demo Support' or 'support@instant-tech.com' depending on how the Queues are set up in your deployment.

We'll make a simple JavaScript call to call this, and return the Queue status. The function below shows how the code would look to perform this task. It's a mixture of JavaScript and jQuery, so you'd need to make sure the page you are testing with is using jQuery for this example to work.
var Instant = {
    getQueueStatus: function (queueID) {
        var url = "http://192.168.1.214:8080/ITFramework/webclient?getSTStatus=" + queueID;
        
        $.ajax({
            url: url,
            type: "GET",
            complete: function(result){
                status = $.trim(result.responseText);
                if (status === "na") {
                    console.log("Queue is offline, or doesn't exist."); // Log the message out to the Chrome/Firefox/Firebug console
                }
                else if (status === "STATUS_ACTIVE") {
                    console.log("Queue is online."); // Log the message out to the Chrome/Firefox/Firebug console
                }
                else if (status === "STATUS_AWAY") {
                    console.log("Queue is unavailable. All experts are unavailable/offline."); // Log the message out to the Chrome/Firefox/Firebug console
                }
                else {
                    console.log("Queue may be available, check it's status in Sametime."); // Log the message out to the Chrome/Firefox/Firebug console
            }              
        });
    }
}
In the code above, we've created a function getQueueStatus inside our Instant object that takes the Queue ID as a parameter. We build a 'url' variable with the FQDN to our Queue Server, and the Queue ID that we passed in. Once we have that, we do a simple AJAX GET request to the url variable we built. Once we get the response, our code with run through the 'complete:' section of our code and it will assess what the server has returned. We use jQuery's $.trim() function to strip any '\n' line breaks that may be returned with the data. The API call could return up to 12 responses, but we are only really concerned with 3.
  • If we get 'na' as a response, the Queue is offline in Sametime, or it isn't a valid queue. This means our server can't see it. For this we are writing out to the Chrome/Firebug console Queue is offline, or doesn't exist. 
  •  If we get 'STATUS_ACTIVE', our server can see the queue, it's online. For this we'll write out Queue is online.
  • The other response we'd want to check for this the 'STATUS_AWAY' response, this means that the queue is online, but that all experts are currently busy. 
 Inside these if statements, you could write your own code to execute when these status' are returned. You could have this function load with the page, and if the server returns 'na' you could disable the chat button and give a message the the chat feature is currently disabled.

The other API call which we have surfaced is a way for you to get the number of available experts in the requested Queue. The code itself is almost identical to the code above, except we are requesting a different API endpoint URL:
The JavaScript below lays out this API call simply.
getAvailableExpertCount: function (queueID) {
    var url = "http://192.168.1.214:8080/ITFramework/webclient?getQueueExpertsReady=" + queueID; // Change this to the FQDN of your IQM server

    $.ajax({
        url: url,
        type: "GET",
        complete: function(result){
                count = $.trim(result.responseText);
                console.log("Experts available: " + count);
        }
    });
}
Just like the first block of code, we set a URL using our FQDN and Queue ID, and perform a simple AJAX GET to the URL that we built. We trim the response, and console out the number of experts that we have in the Queue available. This response could be set into a variable itself, which maybe you would want to include in a counter somewhere on the page to show visitors how many agents are there to help. Because this is all JavaScript, it is very flexible to wire these API calls into your website to perform some basic to advanced tasks.

Tuesday, May 8, 2012

Using JMX to Investigate Queue Manager and Java on Linux

Recently, we have been involved in a rather large Queue Manager deployment running on a Linux environment.  During this process, we have been reviewing various tools and techniques to help analyze and detect issues in a remote production environment.  As part of this process, we discovered the value of JMX, VisualVM, and the tools associated with debugging Java applications.  Most of these practices are useful on both Linux and Windows deployments. 

As a bit of background, our Queue Manager for Sametime application is built using Java and a collection of Java libraries.  Queue Manager leverages the Sametime Java API for access to the core Sametime services, it uses the Domino libraries for accessing Lotus Notes/Domino services, and Queue Manager uses Spring as the main application framework.  So, at a high level, Queue Manager is a Java Spring application running under Tomcat. 

Typically, we deploy Queue Manager on a Windows OS.  However, during a recent deployment, we configured Queue Manager to run on a Linux server.  As part of this deployment, we wanted to remotely monitor the thread activity of the application, the CPU usage of the application, and identify any issues related to either thread usage or memory management.

While there are some very useful tools (typically command line) to help with this type of analysis, we particularly like JMX and VisualVM.  After enabling JMX on the server hosting Queue Manager, our application developers then connect to the JMX monitoring system using VisualVM.  This allows our developers to monitor the performance, health, thread usage, and memory usage in real-time - using a very nice graphical display.  The added advantage is that we can use VisualVM to both remotely monitor a variety of internal servers, as well as use VisualVM to review thread dumps and heap dumps (memory allocation dumps) from a remote production environment. 

Here is a screen shot of VisualVM monitoring an internal Linux instance of Queue Manager:


VisualVM is also very useful during extended periods of load testing and stress testing.  Our internal developers created a variety of load testing tools in order to simulate the various Queue Manager  users and systems.  Our load testing suite includes the ability to scale the number of inbound Sametime IM seekers (people looking for help), the number of experts in a queue, the number of web service requests to the system, as well as experts entering and leaving various queues.  During these load tests, VisualVM provides a real time display of the threads, memory, and CPU usage for the system.

In addition to high level monitoring, VisualVM enables the ability to sample (collect) data over a specific period of time.  So, during certain load testing cycles, we can enable VisualVM to sample the activity of the system and then we can review the data to inspect threads, CPU usage across threads, and memory allocation.

View CPU usage by thread:


One of the most useful tools in VisualVM is the ability to dump threads.  To create a thread dump, right click on the JMX instance and select Dump Threads...

Snapshots and System Sampling:

While the ability to capture a thread dump is useful, we have found the ability to save and export a snapshot of the system, using the sampling module, to be incredibly valuable. The 'sampler' area of VisualVM provides the ability to 'snapshot' the current system state and then export this information.
Navigate to the Sampler tab and enable sampling:

Click the Snapshot button

Export the snapshot


Save the snapshot as a file (so it can be shared)


The exported snapshot may then be transferred to another machine and opened using VisualVM.  The ability to save profile snapshots, transfer these snapshots, and then inspect the snapshots using VisualVM has proved extremely valuable.

We have found JMX and VisualVM to be invaluable tools during both our internal load testing and remote performance tuning and analysis efforts.  JMX is a standard component of the Java environment, and the addition of VisualVM provides a compelling, and powerful, collection of debugging and analysis tools.

Here are some helpful links that we have collected during this process:

VisualVM and JMX
Pretty good Spring presentation on JMX and other useful topics:

Getting started with VisualVM:

20 Linux System Monitoring Tools Every SysAdmin Should Know:
Tomcat Related Links:

Reviewing Tomcat Configuration and Tuning:

Presentation by Mark Thomas on Tomcat Tuning:

Mulesoft article on Tomcat performance tuning:

Misc:
Checking for looping code:

Friday, May 4, 2012

IMtegrity 5 Product Launch - Continued Commitment to IBM Sametime

At a time when many of our competitors are exiting the IM compliance and e-discovery market, Instant Technologies is continuing to invest, innovate, and extend our product offerings for IBM Sametime.  Yesterday, we announced the immediate availability of IMtegrity 5.  IMtegrity 5 continues to build on the outstanding platform that we have developed for compliance, archiving, and e-discovery for IBM Sametime. 

IMtegrity 5 is a major product release for Instant and represents our commitment to our customers and the IBM Sametime user community.  In addition to adding native support for Sametime 8.5, IMtegrity 5 includes two significant features that have been requested across a large community of our install base.  First, IMtegrity 5 adds the ability to create ethical IM firewalls within an organization.  By providing a real-time monitoring service for IBM Sametime, IMtegrity now has the ability to detect, and optionally prevent, Sametime IM conversations between individuals and groups.   The ability to support ethical walls has been requested for many years and we are excited that we can now deliver this level of functionality to our customers.

In addition to ethical firewalls, IMtegrity 5 adds support for configurable IM disclaimers.  These disclaimer notifications are designed to notify chat participants whenever new IM conversations are initiated.  Disclaimer text may be customized for the local language and may be triggered based on a set of rules or actions.  Many of our large customers have been requesting individual IM based disclaimers and we anticipate that this additional feature will help IMtegrity continue to gain momentum into new markets.

IMtegrity has always been based on simplicity of design, the ability to scale within large deployment, and the development of a stable platform for compliance and e-discovery.  This latest release of IMtegrity continues this tradition of design and simplicity and includes a seamless installation process for Sametime 8.5 servers, a highly scalable archiving engine, and new features that will enable the IMtegrity platform to meet the demands of new and existing customers.

Our customer base for IMtegrity continues to grow as does our investment in the core IBM Sametime platform.

Peyton McManus
May 4, 2012

Thursday, May 3, 2012

Good Presentation on Installing Sametime 8.5.1

This is a pretty concise presentation (converted to a pdf) detailing the steps to install Sametime 8.5.1.  The presentation is from Lotusphere 2011 and was presented by Frank Altenburg and Volker Juergensen.



Tuesday, May 1, 2012

Apache Tomcat 6 Shutdown Failure Resolution on SUSE Enterprise 11

Recently, in a development environment, and customer site production environment we noticed some issues shutting down Apache Tomcat for our Queue Manager product running on SUSE Enterprise Linux 11. Running './catalina.sh stop' appeared to work fine, but upon further inspection, it failed to stop it's running Java process, and it left its PID file behind (/var/run/tomcat6.pid). Running the '/etc/init.d/tomcat6 stop' command showed us that, in fact, there was an error in the shut down process.


Review of the catalina.out log file revealed a permissions error writing one of the logs. The log entry itself wasn't terribly helpful, but the implications of a permissions issue were intriguing. It's important to mention that we installed Tomcat 6 using SUSE's YaST tool, we hadn't built it from source, so permissions problems shouldn't be an issue. After inspecting Tomcat's directories, I decided to explicitly give group execution privileges to the folders. The folders were already set to attributes 755, so that didn't appear to be an issue. I used the commands below for the Tomcat directories.


Before starting Tomcat again, I removed the PID file (/var/run/tomcat6.pid), killed the left behind Java process (using kill), and cleared out our logs. Once Tomcat was started, and everything was running smoothly, we sent the shutdown.


This time it shut down fine. Upon further inspection the spawned Java process that had lingered before was gone, as was the PID file. Further inspection of the logs showed no further errors with Tomcat's shut down either.

Tuesday, April 17, 2012

Enabling Calendar Sharing in Office 365

We recently worked with a customer who moved their mailboxes to the cloud, and now run their organization on Office 365. Mailbox migration was smooth, but enabling calendar sharing (vital requirement) proved to be a larger task. After reading tons of Microsoft Technet articles and posts, we were able to get calendar sharing/permissions all sorted out (disabled by default in Office 365). Read the full blog article to follow the steps, a word of warning though, we'll be using Powershell today.

To start, you'll need to install and configure the Microsoft Online Services Module for Windows PowerShell . You can follow the instructions here to do so, it's easy enough.

Next we'll want to open the Microsoft Online Services Module for Windows Powershell program. It will launch like any other Powershell program. Once loaded, we need to give Powershell the credentials we'll be logging in to Office 365 as. These need to be for a user with Administrator privileges in your Office 365 domain. To do so, run the following command:

  • $credentials = Get-Credential
    • This will spawn a window asking for credentials, enter your Office 365 administrative credentials.   


Once Powershell has your credentials, we need to log into the Office 365 servers using the credentials we just set, and start our remote session. Use the command below to do so.

  • $session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell -Credential $credentials -Authentication Basic -AllowRedirection
    • This might take a few seconds to complete.

Next, we need to lower our shell security. This enables us to run the cmdlet after this which executes a script from Microsoft’s servers. Use this command to do so:
  • Set-ExecutionPolicy -ExecutionPolicy unrestricted
Now we need to import the Powershell commands, from the Microsoft servers, to our local session. Use the command below to do so.
  • $ImportResults = Import-PSSession $session

Once that finishes, we should restore our default shell security. Use the command below to restore our default Execution Policy.
  • Set-ExecutionPolicy -ExecutionPolicy  restricted
All that's left now is to turn on the calendar sharing. It's a longer command, but it will set a default policy for enabling calendar sharing across the domain.
  • Set-SharingPolicy ‘Default Sharing Policy’ –Domains ‘*: CalendarSharingFreeBusySimple’
You can now exit Powershell using the 'Exit' command. Sharing has now been enabled across your organizational domain! Users can now publish their calendars, and share them with other users. Feel free to comment below if you run into any issues.


Wednesday, March 21, 2012

Enabling the Sametime Connect Web API in Lotus Notes Installations

In prior posts we've discussed some advanced functioning that can be performed using some JavaScript/jQuery and the Sametime Connect Web API/SDK. This all works just fine unless you are using Sametime from within a Lotus Notes client, in which case none of these examples will work. By default, the Sametime Connect Web features (port/servlets) are disabled by the client and need to be turned on. Thankfully, it's a straightforward process to enable it, an you can follow the steps below to do so.

  1. Open the following file '<Notes install directory>\framework\rcp\plugin_customization.ini'.
  2. Modify the entries to mirror our versions below:
    1. com.ibm.collaboration.realtime.webapi/startWebContainer=true
    2. com.ibm.collaboration.realtime.brokerbridge/startBroker=true
  3. Save the file.
  4. Restart the Lotus Notes client.
That's all it takes. Once the steps above have been completed the port that we call during our API calls is open, and the Web API is online.

Thursday, February 9, 2012

Improving the Sametime Connect Web API (a bit) with a Dash of jQuery

Previously, we discussed using some of the features built in to the Sametime SDK/Connect Web API to check the presence of a user, or in our case a queue, before initiating a conversation through an internal portal page. At a high level, our 'click to chat' web application needs to detect whether a Sametime Connect client is available, or whether we should initiate a conversation using our web client.  We checked the user's presence before starting a conversation because we found, in some cases, that the Sametime web API wouldn't be able to tell if a user was online or not, and an attempt to launch a Sametime conversation to that user (or queue) would invariably fail, so we needed to launch our web client in these cases.

The previous blog post resolved a lot of our problems with presence detection, but it also uncovered some additional issues related to successfully detecting whether to launch our web client or the native Sametime client. More specifically, our custom Instant.detectPresenceOfUser(' [user] ') JavaScript function would work fine (and would return true indicating that Sametime could see the user online) and it should therefore be able to launch a Sametime conversation with that user. However, this is where the trouble begins; even though our code would detect a native Sametime client, the Sametime window would never appear and our web client would launch by default. In most test scenarios we would get the web client about 4 out of 5 times (even when the person had a local Sametime client installed). Clearly there was an issue in the API code for invoking the Sametime window.

Below you will see the code as it exists in the Sametime Connect Web API, the function is called sametime_invoke, it takes in a series of parameters which we will lay out below.

 var sametime_invoke = function(action, userId, params)  
 {  
      var d = new Date();  
      var url = sametime_servletUrl + action+'?userId='+userId;  
      if(params != null)  
           url += "&" + fixupParams(params);  
      url += "&time=" + d.getTime();  
      var imgObj =new Image();  
      imgObj.src = url;  
 }  

First, the function requires an action, in our case, chat. Next a userId, following the same example as our previous post, System p. And last it takes in some optional parameters which we aren't using. So normally, our JS to invoke the Sametime client would look like this:

 sametime_invoke('chat', 'System p');  

This would launch a chat conversation with the 'System p' user. Through our testing though, this sametime_invoke function proved to be deficient, working properly only a handful of times. Looking at the sametime_invoke function, it appeared as though the last two lines of the function are where the magic request happens to spring the window. Stepping through the function logically, we can follow it like this:

  var sametime_invoke = function(action, userId, params)   
  {   
    // Creates a new JavaScript Date object, this is used later to create a timestamp   
    var d = new Date();  
      
    // Forms the URL which it will post to, using the parameters we passed in (action, userId, params)   
    var url = sametime_servletUrl + action+'?userId='+userId;  
      
    // Looks to see if we have passed in parameters  
    if(params != null)  
       url += "&" + fixupParams(params); // Appends them to the URL  
      
    // Adds a timestamp to the end of the URL using the Date object (d) we created above.   
    url += "&time=" + d.getTime();  
      
    // Creates an image object on the page  
    var imgObj =new Image();   
      
    // 'Loads' the image using the URL we built. This makes a request to the URL, and should open the window.   
    imgObj.src = url;  
  }  

The issue with inconsistent launching appears to come from the last two lines. The creating of the Image object, and staging the image request to the URL provided doesn't appear to be the best approach to this. It also lacks the ability to detect any failures, its essentially a blind post. That being said, all of the code leading up to those two lines, is very useful, and tells us quite a bit about what the Sametime client's servlet requires in order for us to make a POST (or in our case, for this article, a GET) to launch that window.

By visiting the URL that it builds (http://localhost:59449/stwebapi/chat?userId=Demo%20Sales&time=1328650958738, for our purposes), we get a launched Sametime client chat to our 'Demo Sales' queue, and we also get, in the browser, a response from the servlet, formed as parsed JSON (JSONP). This is very useful. This response (returnCode:200), lets us know that the servlet understood our request, was able to find the user, and launch the Sametime window. Unfortunately, this doesn't help us detect presence, so if the user is offline, it'll still launch the window, it will just error once it does saying the user is offline. So we will still need to do those presence checks up front using our Instant.detectPresenceOfUser function.

So, enough talk about it, lets re-write that sametime_invoke function using jQuery, AJAX, and a callback function.

 Instant.launchSametimeConversation = function (stid) {  
   var time = new Date();  
   var getUrl = 'http://localhost:59449/stwebapi/chat?userId=' + stid + '&time=' + time.getTime() + '&jsonp=Instant.handleResponse';  
   
   // Use jQuery to request the Sametime servlet URL. If a request makes it to the URL successfully, the servlet will return a code 200 and open the Sametime client chat with the user.  
   // We use the Instant.handleResponse() function as a callback to process the JSONP data object that the servlet hands back.  
   $.ajax({  
     type: 'GET',  
     url: getUrl,  
     dataType: 'jsonp',  
     jsonpCallback: 'Instant.handleResponse'  
   });  
 };  
   
 // A rudimentary callback function to handle JSONP data objects retrieved by the Instant.launchSametimeConversation() function.  
 Instant.handleResponse = function (data) {  
   if (data.returnCode === 200) {  
     alert('Success!');  
   } else {  
     alert('Failed!');  
   }  
 };  

In the functions above, you an see that we follow the same approach initially as the bundled sametime_invoke function, but stray heavily once we are staged up.

First, since we are always using chat, and never using the custom parameters, we strip the function parameters down to just stid (the username) of the user we are chatting with. We bundle the rest of this into our getUrl variable, along with the timestamp. We did add something new though, you'll notice the '&jsonp=Instant.handleResponse' parameter at the end of the URL. This specifies our callback function to the servlet. Normally, jQuery handles this fairly well, but the Sametime servlet we are posting against seems fairly specific with how this needs to be formed, so we include it in the URL. We also include it into the jQuery $.ajax method.

Our callback function is very simple for this example. It could be made much more complex though, simply by providing extra checks for different return codes, and added functionality based off of those checks.

After rebuilding this function, and adding the callback function, we are able to have much more control over how we launch the Sametime client window, and are able to check for failures finally. This function also consistently launches the Sametime client chat window when expected and hasn't failed to do so yet. The only two requirements are to have a Sametime client logged in, and to have the jQuery library linked in to the page that will house the above functions.

I'll post screenshots of the success below, as well as a GitHub gist of the code. Reach out to me at zclancy@instant-tech.com with any questions/comments.



Wednesday, January 25, 2012

Integrating Instant Alert Manager for OCS and Lync with Email

Instant Alert Manager for OCS and Lync provides a server based alerting engine and notification system for Microsoft Lync and Microsoft OCS.  Our application is capable of dispatching a series of instant messages (IMs) to users - typically this is used to notify people who are running either Microsoft Lync or Microsoft OCS of some event (i.e. a system outage, the status of a help request, etc.). 

We have developed Alert Manager with an extensible API - with the idea that other systems might want to dispatch messages using our framework.  Recently, a prospective customer requested the ability to integrate an email notification system with our IM dispatching system.  At a high level, our application will monitor a mail box and will immediately dispatch the messages to a set of online users running OCS or Lync - as the messages are received by the mail system.  The idea is provide a single inbound notification bridge, via an email account, and then immediately alert the correct set of people using IM.

So, several days after the initial request, we have developed a new listening service that integrates our alerting system with a POP3 mail account.  This new listening service will monitor a mail account and immediately dispatch inbound mail messages to an appropriate group of users who are online in either Microsoft OCS or Microsoft Lync 2010.

Here is a screen shot of the mail account - with a message pending:

This is a sample message - where the message is currently encoded as XML.

After the email is received, our new email listening service parses the message and dispatches the request to Alert Manager - where it is placed in queue for immediate delivery.

As soon as the message is placed into the dispatching queue, it is staged for delivery - awareness for the recipient(s) is verified, and then the message is delivered using either Microsoft Lync 2010 or Microsoft OCS.

Setting up a TrustedApplication for Lync 2010





  1. Open Lync Management Shell
  2. Create TrustedApplicationPool
    1. Run Get-CsSite.  Note SiteId
    2. Run Get-CsService –Registrar.  Note Identity:Registrar:
    3. Run New-CsTrustedApplicationPool –Identity [LyncServer] –Registrar [Registrar] –Site [SiteId]
    4. Run Enable-CsTopology
  3. Run New-CsTrustedApplication – Save these settings, as you will need them to configure BLM
    1. ApplicationId: Supply a descriptive name here
    2. TrustedApplicationPoolFqdn: The fully-qualified domain name of the trusted application pool created in the previous step.  Can be found by running Get-CsTrustedApplicationPool
    3. Port: Select a port to access the trusted application.  Should be >1024.  Be sure that the port is open on your firewall.
    4. Run Enable-CsTopology to commit the changes
    5. Run “Get-CsTrustedApplication > [some file name].txt”  This will save the information you will need to configure BuddyList Migrator to a text file, as it is very difficult to copy from the Management Shell.
  4.    Setup TrustedApplicationEndpoint
    1.   Run New-CsTrustedApplicationEnpdoint –ApplicationID urn:application:yourAppname –TrustedApplicationPoolFqdn appPoolFQDN –SipAddress sip:name@domain –DisplayName “Name”
  5. Setup Certificates for the machine on which you will install BuddyList Migrator.  If installing to the Lync Server, this can be ignored
    1. Run mmc
    2. Add the Certificates snap-in.  Select “Local Computer”
    3. Go to Personal->Certifcates
    4. Action->All Tasks->Request New Certificate
    5. Continue through the Wizard.  Select “Computer” for the type of certificate.