Mark
Wallace
Software
Architect
Dublin
Software Laboratory
IBM
Ireland
November
2009
Summary:
This article explains how a
user's telephone number is retrieved when making a telephone call
with IBM® Lotus®
Sametime® Unified Telephony
and how you can modify the default behavior to meet your specific
requirements. It provides a step-by-step guide on how to build
extensions for the Sametime client and Sametime Unified Telephone
core server.
Introduction
IBM
Lotus Sametime Unified Telephony software is a middle-ware product
that provides unified communications features in heterogeneous
telephony environments. The product features include:
the
ability to start a phone call with one or more contacts or external
numbers
telephony
presence to show whether a contact is currently on a phone call
preferences
that allow the user to configure how their incoming calls are routed
using multiple criteria.
The
product also includes a Representational State Transfer (REST)
interface to allow a third party to integrate click-to-call semantics
with an existing application.
Retrieving
a phone number
When
using the click-to-call feature to start a call with a user from your
contact list, the telephone number that is dialed will be the same as
the one in the user's business card (retrieved using the Sametime
User Information servlet application).
By
default the phone number comes from the enterprise directory that the
Sametime server is configured to use, but this can be customized for
a particular Sametime deployment. Refer to the “Business
Card” section in the IBM Lotus Sametime information center for
more information about the User Information application and how it
can be configured and customized.
In
some organizations the phone number that's entered in the enterprise
directory cannot be dialed. For example, suppose your organization
supports a self-service model in which all users are allowed to edit
certain parts of their user record in the enterprise directory,
including their phone numbers. In that case, users might enter their
number in a format that cannot be dialed, for example:
1-222-333-4444
4
ext: 44444
Another
scenario in which this can happen is when the phone numbers are
configured by the administrator to display multiple entries, for
example:
/
This
can occur if the User Information servlet application has been
customized either by changing the configuration or using a custom
black-box. Again, refer to the Business
Card topic in the Sametime information center for more
information on customizing the contents of the business card.
Figure
1 shows an example of a business card with a phone number format that
cannot be dialed.
Figure
1. Business card with phone number that can't be dialed

To
address these and similar problems, two extension points have been
defined that allow the phone numbers retrieved from the enterprise
directory to be modified before they are dialed.
One
extension point is used to modify the behavior of the Sametime
Connect client. The second extension point is used to modify the
behavior of the Sametime Unified Telephony Core server, which is
needed only when using the REST API to make calls. Here we describe
how to contribute to both these Telephone Number Service extension
points.
Modifying
the default behavior provides a mechanism to control what number is
dialed when a Sametime Unified Telephony user calls a contact.
Companies that have multiple phone numbers associated with their LDAP
user entries can use this extension point to implement a policy for
determining which number gets used, or this mechanism can be used to
provide the formatting of telephone numbers before they are dialed.
To
get the most from this article, you should be familiar with Lotus
Sametime, Eclipse Plug-in development, and the JavaTM
programming language.
Extending
the Sametime Client
The
Sametime Unified Telephony plug-ins define a new extension point for
a telephone number service that can be used to control what phone
number is dialed when a person is called.
The
default implementation of the telephone number service takes the
phone number associated with the Person, that is, the one returned by
the user information application and displayed in their business
card.
A
custom telephone number service can implement any solution to return
a phone number, but typically it will manipulate the existing number
by converting it to a valid callable number.
To
contribute a custom telephone number service to the client you must
do the following:
Refer
to the information center section, “Automatically upgrading
Sametime Connect 8.0 clients,” for a description of how to deploy a
new plug-in to the Sametime client.
Creating
the plug-in project
First
you must set up a development environment for building Eclipse
plug-ins for Lotus Sametime. For the steps to set up this
environment, refer to the IBM Redbooks®
publication, “Extending
Sametime 7.5 Building Plug-ins for Sametime,”
that comes with the Sametime SDK.
Use
the following steps to create a new plug-in that contributes to the
telephone number service extension point:
com.ibm.collaboration.realtime.people
com.ibm.collaboration.realtime.telephony.sti
com.ibm.collaboration.realtime.telephony.sti.TelephoneNumberService
Figure
2. Sample telephony number service extension

NOTE:
The community host can include wild cards for matching, so that you
can match all Sametime servers in a particular domain.
Creating
the telephone number service
Create
a new class (with the same name you specified above) in the plug-in
project you've just created that implements the custom telephone
number service. You have two options when creating this new class; it
can either
com.ibm.collaboration.realtime.telephony.sti.number.DefaultTelephoneNumberService
com.ibm.collaboration.realtime.telephony.sti.number.ITelephoneNumberService
Use
the first option if you need to manipulate the numbers that are being
retrieved from the enterprise directory (see figure 3). This is the
option we use for the remainder of this article.
Alternatively,
use the second option if you want to completely override how numbers
are retrieved when dialing with Sametime Unified Telephony only.
Figure
3. Sample telephony number service class
Next,
you must override the getTelephoneNumber(Person)
method and call the default implementation to get the number from the
directory service (see listing 1).
Listing
1. Code to override the getTelephoneNumber method
@Override
public
String getTelephoneNumber(Person person) {
The default implementation uses the directory information
associated with the person to provide their telephone number
String
number = super.getTelephoneNumber(person);
add code here to provide custom formatting of the number
return
number;
}
You
can now add logic to manipulate the telephone number as retrieved
from the enterprise directory before it is dialed using Sametime
Unified Telephony.
Understanding
the sample plug-in
Included
with this article is a sample plug-in that provides a customized
phone number service. This service handles phone numbers formatted
like this:
1-222-333-4444
4
ext: 44444
There
are two problems with how this number is formatted:
The
phone number service implementation extends the default
implementation that reads each person's number by using the Sametime
UserInfoService. It then
tests for both the known problems in how the number may be formatted
and automatically corrects the phone number that will be used (see
listing 2).
Listing
2. Implementation from the sample plug-in
public
String getTelephoneNumber(Person person) {
The default implementation uses the directory information
associated with the person to provide their telephone number
String
number = super.getTelephoneNumber(person);
remove the 'ext:' part
int
index = number.indexOf("ext:");
$NON-NLS-1$
if
(number != null
&& (index != -1)) {
number
= number.substring(0, index).trim();
}
add a leading '+' if needed
if
(number != null
&& !number.startsWith("+"))
{ $NON-NLS-1$
number
= "+"
+ number;$NON-NLS-1$
}
return
number;
}
First,
the default implementation is called to retrieve the person's phone
number. This information will have been loaded and cached for each
person in their contact list. If the person being called is not in
the users contact list, then this method will block waiting for the
information to be retrieved from the enterprise directory.
Next,
two tests are performed:
The
first checks whether the phone number contains an extension; if it
does, this part is removed.
The
second test checks whether the phone number has a leading +; if
not, it will be added.
Finally,
the number is returned and passed to the Sametime Unified Telephony
core server to be dialed.
Extending
the Sametime Unified Telephony core server
If
you are using the Sametime Unified Telephony REST API or if you are
using the Sametime 8.5 Web client to make phone calls, it may
necessary to extend the telephone number service on the Sametime
Unified Telephony core server also.
The
REST API lets you place a call to a specific person by specifying
their user ID, for example, an email address or any uniquely
resolvable user identifier. In this case the server-side telephone
number service is used to resolve the person's phone number, again
using the user information service.
To
contribute a custom telephone number service to the core server, you
must do the following:
Creating
the Java project
The
remainder of this article describes how to use the Eclipse Integrated
Development Environment (IDE). Specifically, to create a new Java
project that contributes to the telephone number service extension
point, follow these steps:
Copy
the following file from the core server to your development machine:
/enterprise/ibm/dist/sutbcomadapter-1.0.0.jar
Unzip
the file into a folder called sutbcomadapter-1.0.0
Create
a new Java project, accepting all the default options when creating
the project.
Once
the project is created, you must add the following two JAR files
(these are available from where you unzipped the communications
adapter) as libraries:
sut-comm-8.0.jar
sut-comm-service-8.0.jar
Creating
the telephone number service
Create
a new class in the Java project you've just created that implements
the custom telephone number service. You have two options when
creating this new class; it can either:
com.ibm.collaboration.realtime.telephony.sti.service.TelephoneNumberServiceImpl
com.ibm.collaboration.realtime.telephony.sti.TelephoneNumberService
Use
the first option if want to manipulate the numbers that are being
retrieved from the enterprise directory. This is the option we will
use for the remainder of this article. Use the second option if you
want to completely override how numbers are retrieved when dialling
with Sametime Unified Telephony only.
Next,
you must override the getTelephoneNumber(Person)method
and call the default implementation to get the number from the
directory service (see listing 3).
Listing
3. Code to override getTelephoneNumber and call default
implementation
@Override
public
void
getTelephoneNumber(String userId,
final
TelephoneNumberListener listener) {
super.getTelephoneNumber(userId,
new
TelephoneNumberListener() {
public
void
telephoneNumberQueried(String userId, String number) {
The default implementation uses the directory information
associated with the person to provide their telephone number
add code here to provide custom formatting of the number
listener.telephoneNumberQueried(userId,
number);
}
public
void
telephoneNumberQueryFailed(String userId) {
listener.telephoneNumberQueryFailed(userId);
}
}
You
can now add logic to manipulate the telephone number as retrieved
from the enterprise directory before it is dialed, using Sametime
Unified Telephony.
Deploying
the custom communications service
First
we must package the custom phone number service as part of the
communications service and copy it up to the core server. Then we
change the configuration on the server so as to ensure this service
gets used and, finally, restart the core server framework.
Here
are the steps for these operations:
Export
your custom phone number service as a JAR file (this is one of the
options available in Eclipse).
Copy
the exported JAR file to the lib folder of the unzipped
sutbcomadapter-1.0.0.jar
file.
Edit
the manifest file (META-INF/MANIFEST.MF),
adding the new JAR file to the Bundle-Classpath (remember to include
the lib folder).
Create
a new sutbcomadapter-1.0.0.jar
that contains the new telephone number service JAR file.
Back
up the existing sutbcomadapter-1.0.jar
file on the core server and then copy over the new files.
Edit
the /enterprise/ibm/sutbcomadapter.properties
file, adding the following line:
STITelephoneNumberService=
Restart
the framework (using /etc/init.d/framework
restart).
Conclusion
You
should now understand how to implement a custom phone number service
for the Sametime Unified Telephony client and server. One example
discussed here illustrates the case in which the enterprise directory
contains phone numbers that cannot be dialed. Another example is the
case in which the enterprise directory returns multiple numbers for
some or all people, and custom phone number services can be employed
to select the correct phone number to use.
Resources
IBM
Lotus Sametime Unified Telephony 8 information center: http://publib.boulder.ibm.com/infocenter/sametime/v8r0/index.jsp?topic=/com.ibm.help.sametime.telephony.doc/welcome_sut.html
Lotus
Sametime product page: http://www.ibm.com/developerworks/lotus/products/instantmessaging/?S_TACT=105AGX13&S_CMP=LP
Lotus
Sametime United Telephony product page: http://www-01.ibm.com/software/lotus/products/sametime/unifiedtelephony/
Download
the IBM Lotus Sametime SDK for your Lotus Sametime version: http://www.ibm.com/developerworks/lotus/downloads/toolkits.html
Download
the Eclipse IDE: http://www.eclipse.org/
About
the author
Mark
Wallace is a software architect working out of IBM's Dublin Software
Lab in Ireland. He joined IBM Lotus in 1993 and has worked on a wide
range of projects including Sametime Translation Services, Sametime
Everyplace, the IBM data access tool and Lotus Component Designer.
His current role is technical lead for a Dublin team who are
contributing to the Sametime Unified Telephony project. You can reach
Mark at mark_wallace@ie.ibm.com.