Pages Menu
TwitterRssFacebook

Posted by on May 14, 2015 in Learn Skype Web SDK

Learn Skype Web SDK Day 11 : Searching for Users & Groups

Learn Skype Web SDK Day 11 : Searching for Users & Groups

This is one post in a series of more than 30, devoted to helping you get up to speed quickly with the new Skype Web SDK. Each lesson comes with source code (in GitHub) and a working demo page so you can see what it does. Check out the full list of posts on the Skype Web SDK page.


View Demo

The Skype for Web API provides a means for you to query a user’s contact list for specific contacts or groups, rather than requiring you to download the entire list and then parse it on the front-end. This means that your application can select individual contacts much easier. For instance, if you’re writing an application in which you want to display the presence information of a specific contact (either hard-coded, stored in a database, or entered by the user at run-time) you can pick out just that single contact and subscribe to their presence.

Searching for contacts and groups is very similar. Both searches require you to specify a maximum number of return records, and a simple text search term, which can be the full or part name of a contact or group. And they both return their results in an async promise function, getMore().

Both searches are instantiated via the personsAndGroupsManager object. To create a contact query, create the search object with:


var contactSearch = application.personsAndGroupsManager.createPersonSearchQuery();

for groups it’s:


var groupSearch = application.personsAndGroupsManager.createGroupSearchQuery();

Both of these functions will only work once you’ve completed the login process.

To set up the return limit and search text, for both objects it’s the same (using contact search in these examples, but swap the contactSearch object for groupSearch for a group search):


contactSearch.limit(10); //only return 10 results
contactSearch.text('bob') //the search term

To actually execute the search, call getMore and then access the results in the return method:


contactSearch.getMore(function (searchResults) {
searchResults.forEach(function (item) {
var contact = item.result; //for contacts
var group = item.result; //for groups;
});
});

The code sample shows this in action:

<div class="form-horizontal">
<div class="form-group">
<label for="username" class="col-sm-2 control-label">Username</label>
<div class="col-sm-10">
<input type="email" class="form-control" id="username" placeholder="Email">
</div>
</div>
<div class="form-group">
<label for="password" class="col-sm-2 control-label">Password</label>
<div class="col-sm-10">
<input type="password" class="form-control" id="password" placeholder="Password">
</div>
</div>
</div>

<div class="form-horizontal">
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button class="btn btn-default" id="btnLogIn">Log in</button>
</div>
</div>

<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button class="btn btn-default" id="btnLogOut">Log out</button>
</div>
</div>
</div>

<div>
<span id="loginStatus"></span><hr/>

<div class="form-horizontal">
<div class="form-group">
<label for="searchTerm" class="col-sm-2 control-label">Search for</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="searchTerm" placeholder="Search Term">
</div>
</div>

<div class="form-group">
<label for="optionsRadios" class="col-sm-2 control-label">Search Type</label>
<div class="radio-inline">
<label>
<input type="radio" name="optionsRadios" id="optionsContact" value="contact" checked>
Contacts
</label>
</div>
<div class="radio-inline">
<label>
<input type="radio" name="optionsRadios" id="optionsGroup" value="group">
Groups
</label>
</div>
</div>

<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button class="btn btn-default" id="btnSearch" disabled="disabled">Search</button>
</div>
</div>
</div>

Search Results:
<ul id="lstSearchResults"></ul>

<script type="text/javascript">

var client;
$(function () {
'use strict';

Skype.initialize({
apiKey: 'SWX-BUILD-SDK',
}, function (api) {
client = new api.application();

// whenever client.state changes, display its value
client.signInManager.state.changed(function (state) {
$('#loginStatus').text("Login State: " + state);
});

}, function (err) {
alert('Error loading Skype Web SDK: ' + err);
});

$('#btnLogIn').click(function () {

// start signing in
client.signInManager.signIn({
username: $('#username').val(),
password: $('#password').val()
}).then(function () {
//log in worked!
alert('Logged in!');
$('#btnSearch').prop('disabled', false);
GetContactList();
GetGroupList();

}, function (error) {
//Something went wrong.
alert(error);
});
});

$('#btnLogOut').click(function () {
// start signing out
client.signInManager.signOut()
.then(function () {
//log out worked!
alert('Logged out!');
$('#btnSearch').prop('disabled', true);
}, function (error) {
//Something went wrong.
alert(error);
});
});

$('#btnSearch').click(function () {
PerformSearch($('#searchTerm').val());
//JustGroupSearch($('#searchTerm').val());
});

function isContactSearch()
{
return $('#optionsContact').is(':checked');
}

function JustGroupSearch(searchTerm)
{
var searchQuery = client.personsAndGroupsManager.createGroupSearchQuery();
$('#lstSearchResults').empty(); //clear the previous resulsts

searchQuery.limit(10); //number of results to return
searchQuery.text($('#searchTerm').val()); //search term

searchQuery.getMore().then(function (results) {
results.forEach(function (result) {
var group = result.result;
group.name.get().then(function (groupName) {
$("#lstSearchResults").append('<li>' + groupName + '</li>');
});

});
});

}

function PerformSearch(searchTerm)
{
var searchQuery;
if (isContactSearch())
{
//do a contact search
searchQuery = client.personsAndGroupsManager.createPersonSearchQuery();
}
else
{
//do a group search
searchQuery = client.personsAndGroupsManager.createGroupSearchQuery();
}

$('#lstSearchResults').empty(); //clear the previous resulsts

searchQuery.limit(10); //number of results to return
searchQuery.text($('#searchTerm').val()); //search term

searchQuery.getMore().then(function (results) {
results.forEach(function (result) {

if (isContactSearch())
{
var contact = result.result;

contact.displayName.get().then(function (theName) {
$("#lstSearchResults").append('<li>' + contact.id() + " - " + theName + '</li>');
});

}
else
{
var group = result.result;
group.name.get().then(function (groupName) {
$("#lstSearchResults").append('<li>' + groupName + '</li>');
});
}
});
});

}

});

</script>

Demo Online

You can try this code out against your own Skype for Business environment by going to the demo page. From here you can also download the code from GitHub if you want to host it locally, or take it and use it in your next project.

Disclaimer: This is sample code, intended to inform and educate. It is not production-ready and is lacking key components such as error handling. You use it entirely at your own risk. You should fully understand the effects, limitations and risks of the code before executing, and understand the implications of any set-up steps. By using these code examples you are using the Skype Web SDK, so you should read the Skype Software License Terms to which you are agreeing.

Good to Know

Written by Tom Morgan

Tom is a Microsoft Teams Platform developer and Microsoft MVP who has been blogging for over a decade. Find out more.
Buy the book: Building and Developing Apps & Bots for Microsoft Teams. Now available to purchase online with free updates.

1 Comment

  1. Hi,

    I was just fiddling around with your examples, and found it strange that when searching for groups the address of the request was still /people/search? etc..

    Do you now if this is a bug in the SDK? I can’t seem to access distribution groups through the SDK, I understand that this should be possible through UCWA, and thought that this may be the problem.

Post a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.