Exporting Lync or Skype for Business Contacts with the Skype Web SDK


Tuesday, 27 October 2015

Share with: 
 

Introduction

The Lync and Skype for Business desktop clients, for both Windows and Mac OS, don't have a simple 'Export Contacts' option, that you would expect in a modern day UC client. In fact, they don't have any export capabilities at all.

Historically, one way to export contacts was to use PowerShell, but that required access to the Lync or Skype for Business servers themselves, which isn't always possible or practical.

With the release of the Skype Web SDK (which is compatible with Lync 2013), exporting contacts suddenly becomes as simple as using JavaScript.

Prerequisites

The code below can only be run on a web server and Lync or Skype for Business environment that has been configured to support UCWA, and thus the Skype Web SDK.

See my Skype Web SDK Prerequisites article for more information on how to configure the SDK.

The Process

Exporting contacts from Lync or Skype for Business using the Skype Web SDK is remarkably easy, and follows the steps below.

  1. Authenticate to a Lync or Skype for Business service
  2. Retrieve a collection of all contacts
  3. Collate properties of each contact (in the example below, name,email,title,company,telephone)
  4. Display the results

In the code example, we output a few properties of each field in a comma delimited format, with text values encapsulated in quotes (").

There's also a handy button to copy the output to the clipboard of the local computer, using the popular clipboard.js framework.

The resulting output will look something like this:


"Anne Smith","Anne@productivecorporation.com","Senior Consultant","n/a","Melbourne, Australia"
"Bob Boss","Bob@productivecorporation.com","CEO","n/a","Sydney, Australia"
"Ella Martin","Ella@productivecorporation.com","Communications & PR","n/a","Melbourne, Australia"
"Jane Morton","Jane@productivecorporation.com","n/a","n/a","n/a"
"Michael Wong","Michael@productivecorporation.com","n/a","n/a","n/a"
"Tim Craig","Tim@productivecorporation.com","Consultant","n/a","Brisbane, Australia"
        

Authentication

To save duplicating content, check out my article on how to send an instant message to learn how to instantiate the SDK in JavaScript and authenticate against a Lync or Skype for Business service.

Retrieving the list of contacts

The client.personsAndGroupsManager.all.persons.get() function returns a collection of 'persons', which are literally your Lync or Skype for Business contacts. In the code below, I loop through each item in this collection returning a person object, from which I can then derive one or more properties, such as displayName shown here.

At the bottom of this article is a brief listing of properties available, and a link to where you can see the full list on MSDN.


    client.personsAndGroupsManager.all.persons.get().then(function (persons) {
        persons.forEach(function (person) {
            person.displayName.get().then(function (name) {
                console.log(name);
            });
        });
    });

Download

You can download the code to this project from GitHub, or check out the code below.

Download Follow @matthewproctor

The Full Code

<!doctype html>
<html>
<head>
    <title>Exporting Lync or Skype for Business Contacts with the Skype Web SDK</title>
    <!-- SkypeWeb library requires IE compatible mode turned off -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <!-- the jQuery library written by John Resig (MIT license) -->
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.10.1.min.js"></script>

    <!-- SkypeWebSDK Bootstrap Libray -->
    <script src="https://swx.cdn.skype.com/shared/v/1.1.23.0/SkypeBootstrap.min.js"></script>

    <!-- Load Bootstrap -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>

    <!-- Javascript used in this example -->
    <script src="index.js"></script>

    <!-- clipboard.js library to copy text to the clipboard (all browsers except Safari) -->
    <!-- See: https://zenorocha.github.io/clipboard.js/ -->
    <script src="https://cdn.jsdelivr.net/clipboard.js/1.5.1/clipboard.min.js"></script>

    <!-- Styles for this demonstration -->
    <link href="index.css" rel="stylesheet">
</head>
<body>

    <div class="container">
        <h3>Exporting Lync or Skype for Business Contacts with the Skype Web SDK</h3>
        <div class="row">
            <div class="col-md-6">
                <div id="loginbox" class="loginbox">
                    <div>Login</div>
                    <div id="address" contenteditable="true" class="input form-control"></div>
                    <div>Password</div>
                    <input type="password" id="password" name="password" class="input form-control" />
                    <div id="signin" class="button">Sign In</div>
                </div>
            </div>
        </div>
        <div class="row">
            <div class="col-md-12">
                <div id="contacts">
                    <div id="signout" class="button">Sign Out</div>
                    <div id="retrieve_all" class="button">Export Contacts</div>
                </div>
            </div>
        </div>
    </div>

    <div class="container">
        <br />
        <div class="row" id="logs">
            <div class="col-md-12 small">
                <div id="logging_box" contenteditable="false" class="code"></div>
            </div>
        </div>
        <div class="row">
            <div class="col-md-12 small">
                <b>Contact List Export</b><br />
                <div id="export_box" contenteditable="false" class="code"></div>
                <br />
                <button class="btn" id="btn" title="Copied!"  data-clipboard-target="#export_box">
                    <img src="assets/clippy.svg" alt="Copy to clipboard">
                </button></div>
        </div>
    </div>

</body>
</html>

// Array in which to store contacts
var contacts = new Array();

// Output activity log to the JavaScript console with a time/date stamp for debugging
function log(texttolog) {
    var d = new Date();
    var time = padLeft(d.getHours(), 2) + ":" + padLeft(d.getMinutes(), 2) + ":" + padLeft(d.getSeconds(), 2) + ":" + padLeft(d.getMilliseconds(), 3);
    console.log(time + ": " + texttolog);
    $('#logging_box').html("<b>Status: </b>" + time + ": " + texttolog + "<br>");
}
function padLeft(nr, n, str) {
    return Array(n - String(nr).length + 1).join(str || '0') + nr;
}

// Creates a comma delimited string for each contact found
function addToContacts(name, emailAddress, title, company, workPhone) {
    // Not every contact will have a title or company, 
    // so lets check for undefined values and display them more politely
    if (typeof (title) == "undefined") { title = 'n/a'; }
    if (typeof (company) == "undefined") { company = 'n/a'; }
    if (typeof (workPhone) == "undefined") { workPhone = 'n/a'; }
    // Comma delimited
    contacts.push('"' + name + '","' + emailAddress + '","' + title + '","' + company + '","' + workPhone + '"<br>');
    // Lets sort the contact alphabetically.
    contacts.sort();
    $('#export_box').html('name,email,title,company,telephone<br>' + contacts.join(""));
    log("");
    $('#logs').hide();
}


$(function () {
    'use strict';

    // new instance of clipboard.js
    var clipboard = new Clipboard('.btn');
    clipboard.on('success', function (e) {
        // clear selection after copying to clipboard
        e.clearSelection();
    });
    // Let's hide the Copy to Clipboard button until the export is finished.
    $('#btn').hide();

    log("App Loaded");

    var Application
    var client;
    Skype.initialize({
        apiKey: 'SWX-BUILD-SDK',
    }, function (api) {
        Application = api.application;
        client = new Application();
        
    }, function (err) {
        log('some error occurred: ' + err);
    });

    // Authenticates against a Lync or Skype for Business service
    function sign_in() {
        $('#signin').hide();
        log('Signing in...');
        // and invoke its asynchronous "signIn" method
        client.signInManager.signIn({
            username: $('#address').text(),
            password: $('#password').text()
        }).then(function () {
            log('Logged In Succesfully');
            $('#loginbox').hide();
        }).then(null, function (error) {
            // if either of the operations above fails, tell the user about the problem
            log(error || 'Oops, Something went wrong.');
            $('#signin').show()
        });
    }
    // when the user clicks the "Sign In" button
    $('#signin').click(function () {
        sign_in();
    });

    // Retrieves all contacts ('persons') asynchronously.
    // Note they do not return in any particular order, so they should be sorted
    function retrieve_all() {
        log('Retrieving all contacts...');
        client.personsAndGroupsManager.all.persons.get().then(function (persons) {
            // `persons` is an array, so we can use Array::forEach here
            persons.forEach(function (person) {
                person.displayName.get().then(function (name) {
                    var personEmail = "";
                    person.emails.get().then(function (emails) {
                        // a JSON string is returned containing one or more email addresses
                        var json_text = JSON.stringify(emails, null, 2).toString();
                        json_text = json_text.replace("[", "");
                        json_text = json_text.replace("]", "");
                        var obj = $.parseJSON(json_text);
                        var personEmail = obj['emailAddress'];
                        // Pass values to the addToContacts function that creates the CSV export
                        addToContacts(name, personEmail, person.title(), person.company(), person.office());
                    });
                });
            });
            // Once finished, we can show the copy button
            $('#btn').show();
        });
    }
    $('#retrieve_all').click(function () {
        retrieve_all();
    });

    // when the user clicks on the "Sign Out" button
    $('#signout').click(function () {
        // start signing out
        log("Signing Out");
        client.signInManager.signOut().then(
                //onSuccess callback
                function () {
                    // and report the success
                    log('Signed out');
                    $('#loginbox').show();
                    $('#signin').show();
                },
            //onFailure callback
            function (error) {
                // or a failure
                log(error || 'Cannot Sign Out');
            });
    });

});
.input {
    border: 1pt solid gray;
    padding: 2pt;
    overflow: hidden;
    white-space: nowrap;
}

.button {
    border: 1pt solid gray;
    cursor: pointer;
    padding: 2pt 5pt;
    display: inline-block;
}

.button:hover {
    background: lightgray;
}

.signinframe > .button {
    margin-top: 8pt;
}

.userdetails {
    border: 1pt solid lightgray;
    padding:5px;
}

.logoutbox, .loginbox {
    padding: 5px 0 10px 0;
}
 

Additional Fields Available

The Skype Web SDK exposes a wide range range of additional properties about contacts, which can be found on MSDN

Some of these include (but there are more!):

Property

Description

id - String

a unique id of this person - either a Skype id or a Lync SIP URI.

displayName - String

Display name.

firstName - String

First name of person.

lastName - String

Last name of person.

title - String

Person title.

workPhone - String

Work phone number (as tel uri).

office - String

department - String

company - String

sourceNetwork - String

Can be "SameEnterprise" or "Federated".

type - String

Person type (i.e. "User").

avatarUrl - String

Person avatar URL.

status - String

Person availability.

activity - String

Extracted from the `activity` property.

relationship - String

Privacy relationship (e.g. "Colleagues").

Further reading

Tags

Skype, Skype Web SDK, Lync, UCWA
There's no easy way to export a list of contacts from the Lync or Skype for Business desktop client, but this can be achieved using the Skype Web SDK.
 
 

Popular Articles

What is Kutamo?
Kilimanjaro 2015
Exploring Lync and IoT
Exchange 2013 in 60 minutes
Monitoring Lync with MRTG
Lync UCWA Tutorial - Introduction
Tutorial Parts 1 | 2 | 3 | 4 | 5

Recent Articles

Australian Postal Codes
Skype Web SDK
Using the Skype Web SDK from any language or framework
Building a Skype for Business Auto Responder using the Skype Web SDK
Exporting Lync or Skype for Business Contacts with the Skype Web SDK

Favourite Links

Kutamo
Telco Together Foundation
Cloud on Kilimanjaro

Tags / Keywords

Skype, Skype Web SDK, Lync, UCWA