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.

Monday, January 2, 2012

Checking the presence of a user (or queue) in Sametime using JavaScript

Recently, while tracking down a potential bug in one of our Queue Manager deployments, it was decided that we needed a way to check the presence of a logged in user through the Sametime Connect Web API. For instance, while on a website an end user clicks on a ‘Live Chat’ link, they are logged into a Sametime client on their computer, so we use JavaScript to talk to that Sametime client to get a bit more information. We check with the Sametime client to see if our ‘Live Chat’ support queue (user) is online, if the Sametime client can see that user online, we will start the conversation through their installed Sametime client, if it can’t, we will launch our branded web client so the conversation can still happen.

After reading through the Sametime SDK/Connect Web API documentation fairly extensively, I determined that there was no real official or right way of doing the above on the client side with JavaScript, so we’d have to improvise a bit, piecing different parts of the API together to get it to do what we wanted. Let’s look at some code.

The first thing we needed to do was wire up some Sametime livenames. According to the documentation, livenames are a UI representation of a contact; they display the online status using a status icon, and bold coloring of the contact’s display name. To do this, we include the getStatus.js JavaScript file; this file exists inside the user’s local Sametime client, and includes a lot of utility functions to deal with livenames/presence.

<script type="text/javascript" src="http://localhost:59449/stwebapi/getStatus.js"></script>

The Sametime client listens on http://localhost:59449, so if the user currently has Sametime running, these files will exist for us to include in our HTML/JS pages.

The next step is to add some HTML links for the users which we’ll be checking presence on. For our use case, we didn’t want these links to appear on the page, we just wanted our JavaScript and the getStatus.js file provided to utilize them as needed, so I added a style=”display: none;” tag to the link to hide it. These links need to have the class=”awareness”, as that is how the getStatus.js file will pick them up when the page loads.

<a class="awareness" userId="System%20p" style="display: none;">Resolving contact, please wait....</a><br />
<a class="awareness" userId="zac" style="display: none;">Resolving contact, please wait....</a><br />
<a class="awareness" userId="test user" style="display: none;">Resolving contact, please wait....</a><br />

The userId=” {username} ” denotes the user which we are tracking presence of. In the example, we have System p (one of our test support queues), zac (my internal username), and test user (a non-existent user which will show up as offline).

After saving the file, we can access the HTML page we created. It will appear blank, but if we have Sametime running, we should be able to see some things under the covers in the browser. Using Firebug, we can see that the getStatus.js file has built up an array, called sametime_livenames, where it has stored a bunch of values about the users which we added to the page.


Now that we have these populated objects, let’s see how we can manipulate them to get a presence. In this example, we have three users; two (System p, zac) of them online, 1 (test user) that is offline. Now that we have sametime_livenames built up, we need to find the user’s presence. This took some serious digging on my part to find the differences, and good ways of doing this. I eventually settled on the fact that if the user is online, a “_properties” variable will be defined, if the user is offline, this variable doesn’t exist. Below is the Firebug output that lead me to this while testing.

sametime_livenames[0]._properties represents the first user we are tracking, System p, which is logged in.
sametime_livenames[2]._properties represents the last user we are tracking, test user, which is not logged in, and returns undefined.

So now we know what we are looking for to detect presence, but we need this to happen automatically when a user clicks a link, and have some custom logic to determine which chat client to launch, so let’s build our function to do this.

We will be using object literal notation since we don’t want our JavaScript to interfere with any other libraries the site we post to may be using.
// Detect presence of watched Sametime users
Instant.detectPresenceOfUser = function (stid) {
    user = stid.toLowerCase(); // Convert stid variable to lower case for switch statement

    switch (user) {
        // Check if STID is System p
        case 'system p':
            livename = sametime_livenames[0];

            // Check if user is logged in
            if (typeof livename._properties === "undefined") {
                return false;
            } else {
                return true;
            }
            break;
        // Check if STID is zac
        case 'zac':
            livename = sametime_livenames[1];

            // Check if user is logged in
            if (typeof livename._properties === "undefined") {
                return false;
            } else {
                return true;
            }
            break;
        // Check if STID is test user
        case 'test user':
            livename = sametime_livenames[2];

            // Check if user is logged in
            if (typeof livename._properties === "undefined") {
                return false;
            } else {
                return true;
            }
            break;
    }
};

The Instant.detectPresenceOfUser function is where we will return a true/false based on whether or not the user that we pass into the function is online or offline. The user gets passed in (ex. Instant.detectPresenceOfUser(“System p”);), the function converts it all to lower-case, and then passes it through the switch which determines what user we are looking for the presence of. Next, it checks that _properties variable, if it exists, the user is online, and the function returns true, otherwise, it returns false as it can’t see the user.

This gets bundled into our Instant.startChat function, so that we can have some logic about how we want to start the conversation. Now, if the website can’t see the user when a chat is initialized, it will launch the web client. In our case, the user may not be offline, just the site can’t see them, and the web client will bridge that gap.

Our full file of JavaScript utilities can be seen below. This includes checking whether the user is running Sametime, the presence detection function, and the function that can start a chat conversation from the web using Sametime.



Thursday, December 8, 2011

Instant Profile Manager


Have you ever wished that it was easier to switch between accounts in Microsoft Communicator?

Having to do this every time you switch accounts is less than ideal...
Here at Instant Technologies, we've been doing a lot of work of late around Microsoft Lync 2010.  One minor, but irritating issue that we have faced is that there isn't really a good way to switch between accounts on the vanilla Lync Communicator client.  For the typical Lync user, that's probably not a big concern, but in our development environment, it becomes irksome rather quickly, particularly since it is not possible to run multiple instances of the client at the same time.  Some sort of tool to automate logins, and preserve more than a single set of credentials would be very helpful for in-house testing and development purposes.

We decided to spend a couple days ginning something up that we could use internally, and add another Microsoft API to our toolbox in the process.  It's proven fairly useful for testing and development here, and so we have decided to release it to the community.

Instant Profile Manager in action
Features:

  • Stores log in credentials for an arbitrary number of Lync accounts.
  • Passwords can be stored, or, if you prefer, you can be prompted each log in.
  • Option to manually set the fully-qualified domain name of the server pool, so that you can easily switch between users on different pools.
  • Log in to a Lync account with just a couple clicks.
Here is a video demonstration of Instant Profile Manager in action. link

Setting up a profile in Instant Profile Manager
Requirements:

  • Microsoft .Net Framework 3.5
  • Microsoft Lync 2010 Communicator Client

Download Link: Instant Profile Manager (ZIP)

If you're interested in how we did it, read on...

Technical: 
As it turns out, it is relatively simple to automate logins to the Lync Client, using the Microsoft Lync 2010 SDK (SDKDocs).  The heavy lifting is mostly handled by the LyncClient class, which exposes functions to sign in and out, and (although we haven't explored it yet) it would appear contact management and messaging are available as well.

We save the profile list as XML, to the current user's My Documents folder.  It'a a dead-simple implementation, using the .Net XmlSerializer to handle transforming our list of Profile objects into XML for us.

Since the Communicator client sets a registry key (HK_CurrentUser/Software/IM Providers/Communicator/UpAndRunning), it is a simple matter to check, and then launch the client if it is not running.  One caveat, for users with 64-bit systems, or who have installed Lync to a non-default location: You will need to edit ProfileManager.exe.config and set "PathToClient" to point at the location your communicator client is installed to.

We made an effort to also support OCS 2007 R2, as we also have a number of products that we regularly test targeting that platform, but by all indications, the Microsoft Office Communicator 2007 SDK doesn't work, or at least not with the 3.5.6907 version we are using.  Specifically, the IMessenger.Signin method doesn't seem to do any more than pop the client window up, regardless of the values passed as parameters.  Perhaps this once worked, as there are a number of examples citing it (see Programming for Unified Communications, Chapter 3), but it is now marked deprecated, suggesting that IMessenger.AutoSignin() be used instead, which is wholly unsatisfactory for our purposes.  While there appear to be some hacks one can do to make a Lync Client connect to an OCS 2007 R2 server, we didn't have much luck, and so had to abandon the idea of supporting 2007.

Thursday, October 6, 2011

Queue Manager - New Charting Options

In response to several customer requests, we are extending the measurements and reporting area of Queue Manager to support some additional charting options.  One new option will be the ability to chart information based on a selectable date range. 

For example, all queue traffic between the dates of October 1, 2011 and October 6, 2011.


Will produce the following chart - which may also be exported to Excel:




In addition to these new charts, the next update for the charting system will provide:
  1. Dual axis charting (so you can chart 2 data sets - for example queue traffic v. % connected)
  2. Ability to display all questions submitted before entering a queue (it would be cool to display trending topics)
  3. Date selectable charts
  4. New views to show connected/unconnected requests as well as resolved/unresolved requests
  5. Charts to display cumulative chat time for experts as well as queues

Friday, September 9, 2011

Thank You SaskEnergy for a Great IMtegrity Case Study

We'd like to send a special 'Thank You' to SaskEnergy for their help with our recent IMtegrity case study - focused on Sametime chat logging as well as Sametime charting and reporting. 

As a company, we know that IMtegrity is an excellent application and is a great fit for customers looking to log and archive Sametime chat conversations.  However, it's even more important when a customer uses their own words to express their experience with the product and their requirements. 

So, thank you SaskEnergy for an excellent case study on Instant IMtegrity and your selection of IMtegrity as your Sametime chat archiving application.  SaskEnergy is also an early adopter of Instant's Charting and Reporting suite for Sametime.

It was a pleasure working the entire team at SaskEnergy and we appreciate their support and encouragement.

Thursday, September 8, 2011

Queue Manager Charting Updates

Based on some recent customer deployments, we have added some features to our charting plaform and provided several new charts, and one new chart type, to our charting module for Queue Manager.  In summary, we have added the ability to:
  1. Capture and log usage metrics for both queues and experts
  2. New charts to view usage metrics for queues and experts
  3. A New chart type to layer 2 datasets in one chart
  4. Several new charts to display comparisons of various metrics within one chart

Since many of our customers deploy Queue Manager within a help desk environment, one customer requested mertics to determine  how long help desk experts spend in actual chat conversations with customers.  We have therefore added several new charts that will provide metrics on chat duration, and usage, for both experts and queues.

Here is a sample chart that demonstrates the chat duration for a collection of experts.  These new drill down enabled charts should provide a more detailed set of metrics on how long experts spend in actual chat conversations.



In addition to metrics on usage, we are providing the ability to compare 2 metrics within on a single chart.  For instance, display the total number of conversations for a queue as well as the percentage of inbound requests that were successfully answered (Total Requests v. % Answered).  We have added a new base chart type that will allow us to layer 2 data sets within one chart.

Here is an example of a chart that displays 2 sets of metrics


Queue Manager continues to gain great traction within environments that need a click to chat solution leveraging Lotus Sametime.  With these new metrics, and chart extensions, we continue to expand our help desk platform for Lotus Sametime environments.

Friday, September 2, 2011

Social Communities and Collisions of Culture



Like the phrase Web 2.0, the term Social is a loaded term with some room for interpretation.   In a world where everyone is tethered with an IP address at all times, it becomes relatively easy to communicate with anyone, anywhere, at any time.

In the old days, like the early 1990s (well, pre 1990), email was pretty standard, but it was typically transmitted over modems that connected to various service providers and then blasted out, and took in, the mail packages for that period.  In this semi-connected world, email made sense – and so did a plain old telephone call.  This is probably what we refer to as the early Internet era.

In the next transition, most companies became constantly tethered to a service provider and simultaneously deployed internal networks throughout their organization.  Here, the organization had a pretty stable collection of IP addresses, employees had internally assigned IP addresses, and folks could easily connect within, and across, organizations.  This may broadly defined the Internet boom and bubble of the late 90s – extending through web 2.0.

In this new phase, everyone is tethered with an IP address at all times.  Typically, most people have more than one IP address – one for work, one for a work phone, one for a personal phone, and one for their home.  My 8th grader has a phone that essentially provides him with an IP address at all times.  At most times during the day, most folks probably have at least two, or possibly three totally different IP addresses that they can use to communicate.  This tethering, and multi-tethering of IP addresses providing an inherently personal experience is what I consider social.

So, Social may be thought of a ubiquitous access to either one, or two, IP connections.  This connection, or collection of connections, provides access to both a personal community and a professional community – active and available at all times.  Applications are then pushed to various end-points (mobile, desktop, tablet, etc) to bridge these various social and personal communities.  Currently, this explosion seems have focused on connecting (or reconnecting) fundamentally personal relationships and personal communities (i.e. friends from high school, colleagues from previous companies, classmates).

It is interesting to imagine what happens when we experience a collision of these various communities and networks – read differently, a collision of cultures.  What takes place when the personal community collides with the corporate community – both operating in real-time?  Does one fracture or absorb the other?  What happens when the communities within a corporation are extended, or possible relocated, and placed into a personal or social space?  How are new channels created in the corporate community to absorb, mine, and manage the personal networks that are developing in the social landscape?  In this ‘post social’ space, these networks of networks collide, transform, are managed, created, and potentially shift from corporate, to social, and back again.

Wednesday, August 31, 2011

Lotus Notes as a Platform

Recently, we have been exploring different software platforms as possible alternatives for our future development efforts.  As with all platform choices, it's not an easy decision.   However, as I have been thinking about this, I've had some soul searching around using Lotus Notes as a platform - which for all practical purposes, we have been using for many years.

These possible platform choices kinda look like this:
Spring + SQL variant
Spring with Groovy and Grails + SQL variant
Ruby and Rails
Node.js (maybe with CouchDB)
Microsoft .net + SQL Server and IIS

While I can debate the merits of all of these platforms, the one 'platform' that we are cautiously re-evaluating for future development is Lotus Notes.  That is a bit strange, since Lotus Notes is inherently a platform - and a pretty awesome platform at that.  Notes includes some great stuff - most of which is just starting to show up in other environments/platforms.

Let me count the things that I like about Notes (as a platform):

  1. Fully functional and robust multi level security model - server, database, document, field level
  2. A 'no sql' database without the pain of relational data models
  3. A replicating database - that is  really fast - even over slow connections
  4. Internal directory management and hooks to all popular directories
  5. Rich development environment including support for Java, xml, JS, Lotuscript, etc..
  6. Nice deployment model (using templates and replication)
  7. Server based management tools and very rich admin tools
  8. HTTP stack - although the servlet container and other tools are dated
  9. Ability to easily update development, testing, production environments by simply updating database templates and replicating databases
  10. Stability and scalability

Here are many of the standard issues/platform consider impediments that we experience with Notes - most of which will familiar to folks in the Notes field.

  1. We will only be able to sell into existing Lotus Notes shops
  2. No good cloud based runtime model/hosting scenario - or good runtime model that works in 'non Notes' shops
  3. Licensing is confusing and expensive
  4. Young employees/prospective employees don't understand the platform or have any skills
  5. I don't think IBM considers Lotus Notes as a viable platform and they (IBM) would like to see folks move to their industrial strength platform - Wepsphere

So, as we consider future platforms, and hear young developers espouse the virtues or Ruby/Rails, Spring, 'no sql' databases that just deal with name/value pairs, etc, I'm always brought back to the idea that many of these platforms are repurposes functionality that has been available in the Notes community for many years.

So, we will take the relatively safe approach and stick with Java, Spring, Groovy, JQuery, maybe some Grails, and then mount a standard SQL db under the covers.  We will run under Apach/Tomcat and use standard libraries such as Log4J, Velocity, etc..

Peyton




Tuesday, July 26, 2011

Configuring Linux for the Notes API

Recently, while installing/running some test Java applications, we came across the following error:
Exception in thread "AWT-EventQueue-0" java.lang.UnsatisfiedLinkError: lsxbe (Not found in java.library.path)
This was on a box running SUSE Linux Enterprise Server 11 SP1, with Lotus Notes installed as well as the Java 1.6 Runtime Environment.

Running 'echo $PATH' showed that while the Java Runtime Environment was in our system/environment path, none of the Notes directories were. To do this we needed to add to the default path that SUSE provides each user. This is controlled in a few places, but, the safest place to make adjustments is inside the .bash_profile file (located in the users home folder, create this file if it doesn't already exist).

Here's how it looked after we created and added to it:
PATH=$PATH:/opt/ibm/lotus/notes
PATH=$PATH:/opt/ibm/lotus/notes/jvm/lib/ext
export PATH
After restarting our shell and running 'echo $PATH' we can see the new additions to our users path. Running the application gave us the same error as above, so we hadn't fixed it yet. After investigating more into Lotus Notes, we found some more things that needed to be added to our path.

Here's .bash_profile with our new changes:
PATH=$PATH:/opt/ibm/lotus/notes
PATH=$PATH:/opt/ibm/lotus/notes/jvm/lib/ext
PATH=$PATH:$NOTES_HOME
export PATH
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/ibm/lotus/notes
export LD_LIBRARY_PATH

After restarting our shell, the test application ran fine, and the exception above was gone. This was all done as the root user, to push this file to other users profiles, use this command from your home folder:
cp ~/.bash_profile /home/{username of the user}
Just replace after /home/ with the user name of the user to push the changes to.