ShowTable of Contents
Introduction
I have always had an interest in development. From my university degree or my time working in the IBM Hursley labs, I've been intrigued how you can go from an idea or a concept and watch it build in front of your own eyes and the emotions you through when you work on the project. Sadness and frustration when bugs appear and things don't work, excitement and elation when your idea comes to life and people appreciate the work you've done. Most of my development was done at university so my projects had little value in terms of "real" world use, so since then I've been keen to develop tools that people can use in their day-to-day work. With that in mind, I decided to look at the development options open to me in both IBM Connections and IBM Sametime.
Why the Connections Search Bot?
For a long while I've been intrigued by Sametime Bots, the automated programs that respond to user input and reply accordingly. The power of a Sametime Bot is endless, it can bolt onto whatever system you require information from. One of the example bots I use on a regular basis within IBM is the "WhatIs" bot, which in short details all the various possibilities of a given acronym, very helpful in an organisation and industry as rife in TLAs* as mine.

Figure 1: Screenshot of an example Sametime Bot - WhatIs Bot
With the power of Bots in mind, I decided to try my hand at build one of my own, but the next question was "What will my Bot help the user access?" Another useful Bot in IBM is the "WhoIs" Bot, which returns the contact details of any person in the organisation, again very useful to look up someone's details. This got me thinking about a common problem people face....how do I find details of an expert when I do not know their name? IBM Connections helps organisations deal with this issue fantastically, using tags and social analytics to recommend the people most relevant to a given search term. So I decided to create a Connections Profiles Search Bot.
What the Bot does
The Connections Profiles Search Bot does exactly what it says on the tin....it searches Connections Profiles! The user simply opens up a chat session with the Bot and, using the prescribed format, requests a search from the Bot. The Bot connects to IBM Connections and, using the search term provided, returns the best results to the user.
The user has three options to search for Profiles, either by name, by e-mail or by profiles tags. Depending on the number of search results, the bot shows more details about the profiles are returned, so if more than one result is found, a list of results is provided, giving the profile name, job title, e-mail address and a link to their profile.

Figure 2: Screenshot of the Bot responding to a user query with multiple results
While if there is only one result found, the above information is provided as well as their photo, country and telephone number.

Figure 3: Screenshot of the Bot responding to a user query with one result
If the user types 'help' the Bot also responds with an explanation of how to use the Bot to return results, as well as handling any user input it does not recognize.

Figure 4: Screenshot of the Bot responding to a user asking for help

Figure 5: Screenshot of the Bot responding to incorrect input
How does the Bot work?
The Sametime Bot, simply put, is a Java program that uses the Sametime Software Development Kit (SDK) to connect to a Sametime Community and operate like a normal user. Since it is a Java program, once you have the framework code that enables the Bot to log into Sametime, you can build your Bot to do whatever you require. This could be connecting to a database, performing a calculation or, in the case of the Connections Profiles Search Bot, send a REST API request and process the response.

Figure 6: Screenshot of the architecture and protocols
When the Bot program is started, its first operation is the load some details, namely the Sametime Community server details and the Connections server details, from a Properties file. I could have hard coded these details into the Bot, however it is good practice to keep these kind of details within a properties file. This makes the Bot (and any kind of program for that matter!) easier to configure and share for other environments. Once these details are loaded, the Bot uses the Sametime details to log into the Sametime Community server and sets itself to "Available". Then, it waits for someone to start a chat with it.
Next, an intrepid user comes along and decides "I need to search for someone in IBM Connections" and decides to use the Bot (as they should!). They open a chat window and the Bot responds straight away with a welcome message. All this communication uses the Sametime Virtual Places protocol, which is the very same protocol used when two human Sametime users chat with each other. The user sends their search to the Bot (let's use the example "email=leon.beckett@uk.ibm.com") and the Bot does a number of operations before responding to the user.
- First of all, it strips away all the rich text so it is left with "email" and "leon.beckett@uk.ibm.com". This Bot is configured to understand and send rich text, important for sending links, bold text and images.
- Using the search term, it builds the necessary REST URL required to perform the correct search in Connections. In our example, the URL created looks like this:
https://<connections-server>/profiles/atom/search.do?email=leon.beckett@uk.ibm.com
- Once built, the Bot sends the REST request to IBM Connections as well as sending the its own previously loaded Connections credentials to ensure the request is authenticated.
- IBM Connections processes this request and returns an ATOM XML feed to the Bot, which parses it and collates all the necessary information from the feed.
- After collating this information, the Bot formats the information, including links, tables and other rich text, into a chat response that it returns to the user.

Figure 7: Result of the above Bot process
As mentioned, this is all achieved through Java programming as well as a little consideration of how the returned XML feeds are formatted and how users operate (for instance using all upper-case characters or entering the wrong information).
A few code snippets
To show how the Bot works, here are a few code snippets from the program.
Setting up the Bot - Presence Awareness
if(botStatus == 1){
status = STUserStatus.ST_USER_STATUS_ACTIVE;
}else if(botStatus == 2){
status = STUserStatus.ST_USER_STATUS_AWAY;
}else if(botStatus == 3){
status = STUserStatus.ST_USER_STATUS_IN_MEETING;
}
commService.setLoginStatus(true, new STUserStatus(status, 0, getBotStatusMessage()));
The above controls how the Bot's presence awareness is set. The actual status is read from the Properties file, and is set when the Bot launches
Setting up the Bot - Send and receive rich text
byte[] data = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dataStream = new DataOutputStream(baos);
try {
dataStream.writeUTF("data");
dataStream.writeUTF("richtext");
dataStream.write(new byte[] { (byte) 0xEE });
data = baos.toByteArray();
} catch (IOException errorexception) {
throw new AssertionError("sendDataMessage failed");
}
event.getIm().sendData(true, 27191, 0, data);
The above code is the Bot signalling to the Sametime client the person is using that it can send and receive rich text. This is important, not for the client to send, but for the Bot to send as the Bot will send hyperlinks and images back to the user.
Setting up the Bot - Welcome message and activate listener
event.getIm().sendText(true, "Hello and welcome to the IBM Connections Profiles Search Bot. Type \"help\" to read the Help Section for the bot.<br/>");
event.getIm().addImListener(new MessageListener());
Here, the Bot sends it's welcome message to the user and add an "ImListener". This instance of ImListener (in my case "MessageListener") is what determines how the Bot reacts to input from the user.
The Bot in action - Setting up the REST URL
if(param.getParam() == ConnectionsHelper.SEARCH_TAGS){
searchTerm += ConnectionsHelper.SEARCH_PAGE_SIZE + "=" + num + HttpHelper.AMPERSAND + param.getParam() + "=";
String [] tags = param.getSearchTerm();
for(int x = 0; x < tags.length; x++){
searchTerm += tags[x];
if (x != (tags.length-1)){
searchTerm += ",";
}
else{
break;
}
}
}else if(param.getParam() == ConnectionsHelper.SEARCH_NAME){
searchTerm += ConnectionsHelper.SEARCH_PAGE_SIZE + "=" + num + HttpHelper.AMPERSAND + param.getParam() + "=" + HttpHelper.encodeString(param.getSearchTerm()[0]);
}else if(param.getParam() == ConnectionsHelper.SEARCH_EMAIL){
searchTerm += ConnectionsHelper.SEARCH_PAGE_SIZE + "=" + num + HttpHelper.AMPERSAND + param.getParam() + "=" + HttpHelper.encodeString(param.getSearchTerm()[0]);
}
return ConnectionsHelper.HTTPS_PROTOCOL + ConnectionsHelper.CONNECTIONS_SERVER + app + path + "?" + searchTerm;
Here is my code to build the REST URL. First of all, it checks to see the type of search being undertaken (tags, email or name) and then builds the necessary URL. For a tags search, this is a little more complex since we do not know how many tags the user includes in their search.
The Bot in action - Connecting to the IBM Connections Server
URL profiles_url = new URL(url);
String loginPassword = CONNECTIONS_USER_NAME + ":" + CONNECTIONS_PASSWORD;
byte[] encodedAuth = Base64.encodeBase64(loginPassword.getBytes());
HttpsURLConnection conn = (HttpsURLConnection) profiles_url.openConnection();
conn.setRequestProperty(HttpHeaders.AUTHORIZATION, "Basic " + new String(encodedAuth));
Using the Properties loads from file, the Bot uses Basic Authorization to connect to the constructed REST URL. Not shown in my code, is the user agent set up for my Bot, that is required for the Connections server to understand what is requesting information. The above returns a "HttpsURLConnection", which I retrieve the ATOM feed from.
The Bot in action - Building the response
private static ArrayList<Profile> retrieveProfilesFromDocument(){
names = new ArrayList<Profile>();
NodeList list = xmlDocument.getDocumentElement().getElementsByTagName(XML_PROFILE_ENTRY);
//For each Profile
for(int i = 0; i < list.getLength(); i++){
Node node = list.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE){
Element entry = (Element) node;
Element contributor = (Element) entry.getElementsByTagName(XML_PROFILE_CONTRIBUTOR).item(0);
...
//add the profile to the list
names.add(new Profile(name, telephone, eMail, profileId, jobTitle, country, photoUrl));
By looking at the structure of a returned XML feed, I built the Bot to navigate the XML Document programmatically. With all the "Element" lines of code in place, the Bot works through the XML document, retrieving all the information it needs for the Profile, adding it to Array List when finished.
The Bot in action - Sending the result
if(results.size() == 0){
im.sendText(true,"No profiles found");
}else if(results.size() == 1){
Profile result = results.get(0);
String photoURL = result.getPhotoUrl();
HttpsURLConnection https_photo_conn = ConnectionsHelper.connect(photoURL);
...
im.sendText(true,"<span>"
+"One result found"
+"<br/></br/>"
+"<table border='0' width='100%' cellspacing='0'>"
+"<tr><td width='30%' align='center' rowspan='6'><img src=\"\" width=\"115px\" height=\"115px\"/></td><td width='15%'><b>Name:</b></td><td width='54%'>"+result.getName()+"</td></tr>"
+"<tr><td><b>Job Title:</b></td><td>"+result.getJobTitle()+"</td></tr>"
+"<tr><td><b>Country:</b></td><td>"+result.getCountry()+"</td></tr>"
+"<tr><td colspan='2'><a href=\""+ConnectionsHelper.HTTPS_PROTOCOL+ConnectionsHelper.getConnectionsServer()+"/profiles/html/profileView.do?userid="+result.getProfileId()+"\">IBM Connections Profile</a></td></tr>"
+"<tr><td><b>E-mail:</b></td><td><a href=\"mailto:"+result.getEmail()+"\">"+result.getEmail()+"</a></td></tr>"
+"<tr><td><b>Phone:</b></td><td>"+result.getTelephoneNumber()+"</td></tr>"
+"</table>"
+"</span>");
What next for the Connections Profiles Search Bot?
The Bot was mainly created as an experiment for me to exercise my Java development brain, and see what I could easily achieve using the Sametime SDK and the Connections REST API. I do plan to add more Connections Search features into the Bot (e.g. the ability to search for Files or Blogs), as well as see what else can be achieved with the Sametime SDK, e.g. detecting the device the person is using. Also, I will review the code and see where I can make the code more efficient, so that the Bot responds much faster to user input. However, this will be as and when time permits.
I fully appreciate your comments and feedback on my Bot and I hope I have inspired you to create your very own Sametime Bot. If you are interested in developing your own Sametime Bots, then I recommend looking at the Sametime SDK which contains a number of guides to help understand what is possible, as well as take a look at the DeveloperWorks articles "Building your own Sametime Bot" Part 1 and Part 2.
Leon Beckett, Technical Sales Specialist
IBM Social Business, United Kingdom and Ireland
E-mail: leon.beckett@uk.ibm.com
Twitter: @leonbeckett
Find me on IBM Greenhouse Connections: https://ibm.biz/GH_LeonBeckett
Find me on IBM Connections Cloud: https://ibm.biz/ConnCloud_LeonBeckett
Find me on w3 Connections (IBM only): https://ibm.biz/w3_LeonBeckett
*TLA stands for "Three Letter Acronym" in case you were wondering!