Map My Lync Contacts

A couple of months ago I wrote a blog post title “Microsoft Lync 2010 and Bing Maps Integration”. This blog post gave a walk through on how to create a simple application that allowed you to view a Lync contact on Bing Maps. Since the goal of that post was to keep things simple I made it so that we assigned the coordinates of where the contact would show up on the map. That method of displaying contacts on a map is pretty common and has a lot of us cases. For example, this method works well if you wanted to show sales regions on a map and then overlay the sales manager for each region, thus making it easy to not only determine who the sales manager is for a region, but to also contact them as well. Recently I had a comment on my original blog post asking if it would be possible to display a user on the map based on the location property in Lync. This blog post will expand upon the original blog post and show how to map all the contacts in your Lync based off the location property. To make things simple we will reuse all of the code from the original article.

Installing the Lync SDK

Download the Microsoft Lync 2010 SDK and run the executable. Note that you will need to have the Lync client installed already on your computer and will also need a Lync account. Don’t have a Lync account? Why not create an Office 365 trial account and make use of Lync there. For those integrating Bing Maps with Office 365 or SharePoint here is a good development resource: http://bingmapsdemos.sharepoint.com

Creating the project

In Visual Studios you will now find under the Silverlight section of the new Project panel a Lync Silverlight Application project. Set the name of your project to LyncMapMyContacts. When the application first loads you will see there is a presence indicator on Page.xaml. One of the first things you will want to do is test this out as outlined in the “Microsoft Lync 2010 and Bing Maps Integration” blog post. Once this is done you will also want to add a folder called Views and create a user control called Infobox. This Infobox control will be identical the one created in the last blog post.

Adding Bing Map’s

In this application we will want to display a map and render the location of all the contacts in our Lync account. To make things clean we will use two MapLayer’s, one to store the pushpins for the contacts, and the other for an Infobox. We will reuse the infobox user control from the previous blog post. To get started we will first need to add the Bing Maps libraries to our project as documented here. Once that is done we can create the markup for the Page.xaml file. The markup for the functionalities we want will look like this:

<UserControl x:Class=”LyncMapMyContacts.Page”

    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation&#8221;

    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml&#8221;

    xmlns:d=”http://schemas.microsoft.com/expression/blend/2008&#8243;

    xmlns:mc=”http://schemas.openxmlformats.org/markup-compatibility/2006&#8243;

    xmlns:controls=”clr-namespace:Microsoft.Lync.Controls;assembly=Microsoft.Lync.Controls”

    xmlns:m=”clr-namespace:Microsoft.Maps.MapControl;assembly=Microsoft.Maps.MapControl”

    xmlns:views=”clr-namespace:LyncMapMyContacts.Views”>

   

    <Grid>

        <m:Map Name=”MyMap” CredentialsProvider=”YOUR_BING_MAPS_KEY”>

            <m:Map.Children>

                <m:MapLayer Name=”UserLayer”/>

                <m:MapLayer>

                    <views:Infobox x:Name=”Infobox” Visibility=”Collapsed”

                                   m:MapLayer.PositionOffset=”0,-25″

                                   m:MapLayer.PositionOrigin=”BottomLeft”/>

                </m:MapLayer>

            </m:Map.Children>

        </m:Map>

    </Grid>

</UserControl>

 

Adding Your Contacts to the Map

In order to map our contacts we will first need to get the contacts using the LyncClient class. Once we do that we will need to loop through each contact and check to see if the location property has a value and if it does we will then need to geocode it. Once geocoded we can then create a pushpin and add it to the map.

Since we will need to geocode the location we will need to access the Bing Maps REST services from .NET code. To do this we will need to add in a library to parse the responses from the service. Rather than writing these from scratch we’ll make use of some code I put together in a previous blog post titled Bing Maps REST Service .NET Libraries. To include this library into the project we will right click on the project and select Add -> New Item.  Add a class file called BingMapsRESTServices.cs. Remove any content that’s in this file and copy and paste in the complete code from the bottom of the previous blog post. We will also need to add a reference to System.Runtime.Serialization and to System.ServiceModel.Web. At this point your project should look something like this:

clip_image002[4]

Since we will be using the Bing Maps REST services while also using one of the Bing Maps controls we can create a session key which is a special type of Bing Maps key. A session key allows us to access the REST service while marking all the calls as non-billable in the reports. This is a very important this application could potential make a call to the geocoding service for every contact in your Lync account. To make things easy we will create a global variable in the Page.xaml.cs file for the session key and set it when the page initializes. We will then use this session key every time we make a request to geocode a contacts location. Putting this all together we will end up code that looks like this:

using System;

using System.IO;

using System.Net;

using System.Runtime.Serialization.Json;

using System.Windows;

using System.Windows.Controls;

using BingMapsRESTService.Common.JSON;

using Microsoft.Lync.Model;

using Microsoft.Maps.MapControl;

 

namespace LyncMapMyContacts

{

    public partial class Page : UserControl

    {

        private string _sessionKey;

 

        public Page()

        {

            InitializeComponent();

 

            MyMap.CredentialsProvider.GetCredentials((x) =>

            {

                _sessionKey = x.ApplicationId;

                MapMyContacts();

            });

        }

 

        private void MapMyContacts()

        {

            try

            {

                LyncClient lyncClient = LyncClient.GetClient();

 

                foreach (var g in lyncClient.ContactManager.Groups)

                {

                    foreach (var c in g)

                    {

                        string location = c.GetContactInformation(ContactInformationType.LocationName).ToString();

                        string query = string.Format(http://dev.virtualearth.net/REST/v1/Locations?q={0}&key={1}”, location, _sessionKey);

 

                        //We can only map those that have a location

                        if (!string.IsNullOrWhiteSpace(location))

                        {

                            WebClient wc = new WebClient();

                            wc.OpenReadCompleted += (s, a) =>

                            {

                                using (Stream stream = a.Result)

                                {

                                    DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Response));

                                    Response response = ser.ReadObject(stream) as Response;

                                   

                                    if(response != null &&

                                    response.ResourceSets != null &&

                                    response.ResourceSets.Length > 0 &&

                                    response.ResourceSets[0] != null &&

                                    response.ResourceSets[0].Resources != null &&

                                    response.ResourceSets[0].Resources.Length > 0){

 

                                        BingMapsRESTService.Common.JSON.Location loc = response.ResourceSets[0].Resources[0] as BingMapsRESTService.Common.JSON.Location;

 

                                        Contact contact = a.UserState as Contact;

 

                                        Pushpin pin = new Pushpin()

                                        {

                                            Tag = contact.Uri,

                                            Location = new Microsoft.Maps.MapControl.Location(loc.Point.Coordinates[0], loc.Point.Coordinates[1])

                                        };

 

                                        pin.MouseLeftButtonDown += PushpinClicked;

 

                                        UserLayer.Children.Add(pin);

                                    }

                                }

                            };

                            wc.OpenReadAsync(new Uri(query), c);

                        }

                    }

                }

            }

            catch (NotStartedByUserException)

            {

                MessageBox.Show(“Lync is not running”);

            }

        }

 

        private void PushpinClicked(object sender, System.Windows.Input.MouseButtonEventArgs e)

        {

            Infobox.DataContext = (sender as Pushpin).Tag;

            MapLayer.SetPosition(Infobox, (sender as Pushpin).Location);

            Infobox.Visibility = System.Windows.Visibility.Visible;

        }

    }

}

 

Now if you run this application you should find that all your contacts, which have set the location setting in Lync will be displayed on the map.

It should be noted that the instructions in Lync recommend putting “Work” or “Home” in this field and based on my tests, many people leave this field blank, other will put in the name of the office they are in. Needless to say these types of locations will not geocode well, however you can create a simple look up using a Dictionary class for common locations that your contacts use and assign a manual location that way.

 

About these ads

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s