Microsoft Lync and Skype for Business have a rich set of .NET APIs which make it easy to extend the platform and integrate it with other applications. This blog helps explain how to use those APIs.

Determining whether a user has Enterprise Voice

Posted: February 16th, 2014 | Author: | Filed under: UCMA 4.0 | Tags: , , , | No Comments »

How can your UCMA application determine whether a Lync user is enabled for Enterprise Voice? The answer is a bit more complex than you might think. In short, the best way appears to be establishing a UserEndpoint for the user in question, subscribing to local owner presence, and checking the information in the userProperties presence category. The rest of this post describes how to do this.

Checking Enterprise Voice capability in local owner presence

Presence information in Lync is divided into a number of categories, of which the most obvious are the categories like state and contactCard that hold information displayed in other users’ contact lists. However, Lync also uses presence to hold some information about a user that is generally used only by that user’s own Lync client. This is held in presence categories that are visible only to the user, like alerts, rccOptions, and userProperties. Within the userProperties category is an element called telephonyMode that indicates whether the user has Enterprise Voice enabled.

It would be convenient if a UCMA application could just query the user’s presence and retrieve the information from that userProperties category in order to find out if Enterprise Voice is enabled. Unfortunately, because of the presence container (access control container) that information is associated with, it’s not visible to a UCMA endpoint doing a presence subscription or query.

However, the information IS visible to an endpoint representing that same user. If the UCMA application “signs in” as the user, it can retrieve that information just as the Lync client would.

To do this, it needs to first establish a UserEndpoint for the user, and then subscribe to local owner presence. This is a special type of presence subscription where a user subscribes to its own presence – a seemingly peculiar and pointless thing to do, like subscribing to your own Twitter feed – but actually very useful in that gives the Lync client access to a bunch of the user’s own options and configuration data regardless of where the user is signing in from.

I won’t go over how to establish a UserEndpoint here, as it’s been covered many times elsewhere, but I do want to point out that for this to work well you ideally want your UCMA application to be configured with Lync Server as a trusted application, so that it can register with Lync Server as any user without having that user’s own credentials. Otherwise establishing UserEndpoints for this purpose becomes quite a bit more difficult.

Subscribing to local owner presence requires hooking up an event handler and calling a method on the LocalOwnerPresence object associated with the UserEndpoint (the example uses the UCMA async extension methods):

_userEndpoint.LocalOwnerPresence.CategoryNotificationReceived += OnLocalOwnerPresenceNotificationReceived;
await _userEndpoint.LocalOwnerPresence.SubscribeAsync();

In the event handler, you can check for the userProperties category and extract the telephonyMode element. This will be set to “Uc” if Enterprise Voice is enabled.

void OnLocalOwnerPresenceNotificationReceived(object sender,
    LocalPresentityNotificationEventArgs e)
{
    PresenceCategoryWithMetaData userProperties =
        e.AllCategories.FirstOrDefault(c => c.Name.ToLower() == "userproperties");

    if (userProperties != null)
    {
        string categoryXml = userProperties.Category.GetCategoryDataXml();
        Console.WriteLine(categoryXml);

        System.Xml.Linq.XDocument xDoc = System.Xml.Linq.XDocument.Parse(categoryXml);
        var telephonyModeElement = xDoc.Descendants(System.Xml.Linq.XName.Get("telephonyMode",
            "http://schemas.microsoft.com/2006/09/sip/categories")).FirstOrDefault();

        if (telephonyModeElement != null)
        {
            Console.WriteLine("Telephony mode is {0}", telephonyModeElement.Value);
        }
    }
}

Once you know whether the user has Enterprise Voice enabled, you can terminate the UserEndpoint and go about your business.

Less effective alternatives

I wanted to briefly touch on some other ways you might go about getting the same information and why they don’t work as well.

First, you might try looking at the service capability information that you can get from presence notifications on a RemotePresenceView object:

void OnRemotePresenceViewNotificationReceived(object sender,
    RemotePresentitiesNotificationEventArgs e)
{
    foreach (var notification in e.Notifications)
    {
        bool isAudioEnabled =
            (notification.ServiceCapabilities.AudioEnabled == ServiceCapabilitySupport.Enabled);
    }
}

Unfortunately, although this is a great way to tell whether an endpoint can support audio calls, it may be enabled even if Enterprise Voice is not. If the endpoint supports peer-to-peer voice but doesn’t have Enterprise Voice, this flag will still be set to Enabled.

Another method is to query user information programmatically using PowerShell. This will work, but it requires consuming a separate API and possibly applying additional permissions to the service account running your application. In almost any situation, it will be easier to use the approach I’ve described above to figure out whether a Lync user has Enterprise Voice support.

If you come up with a better way of doing this, please comment or send me an email!



Leave a Reply

  • Note: Comment moderation is in use because of excessive spam. Your comment may not appear immediately.

  •