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.
- Authenticate to a Lync or Skype for Business service
- Retrieve a collection of all contacts
- Collate properties of each contact (in the example below, name,email,title,company,telephone)
- 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","[email protected]","Senior Consultant","n/a","Melbourne, Australia"
"Bob Boss","[email protected]","CEO","n/a","Sydney, Australia"
"Ella Martin","[email protected]","Communications & PR","n/a","Melbourne, Australia"
"Jane Morton","[email protected]","n/a","n/a","n/a"
"Michael Wong","[email protected]","n/a","n/a","n/a"
"Tim Craig","[email protected]","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