At work we have a Vertical Televantage phone system. The client software that every one has to use is, to put it simply, a space thief. So much desktop space is wasted by unnecessary window chrome and empty list space. It is not really the applications fault, as it is basically a design flaw of most window user interface designs. (As a side note, I’ve come to the conclusion that all applications should be designed such that the tool bars, status bars and scroll bars should be, by default, hidden until the user indicates they want to make use of said interface by moving their mouse cursor to the region it would appear).
The problem, in this particular case, with being a space thief is that our sales employees (whom are already on 22″ wide screen monitors) have multiple windows open for their messenger, email, phone client, intranet, order entry and customer information windows. It would be rather beneficial to free up any screen real estate possible. The important information of the phone software is basically customers in their call queue, customer notes on the selected caller, and basic call control (hold, send to customer service queue etc). If some how we could condense that information and those functionality features and reduce the screen space the program took up it would reduce a lot of window clutter.
One of the technologies I’ve been exploring lately is Adobe’s new AIR product. Which is a cross platform desktop application software. I thought to myself that it would be really easy to design a nice desktop app user interface with air and if there were only some way to control the phone system through that app I’d be set!
Well luckily, the phone software when we upgraded (read paid lots of money) for the most recent version came with an API. The luck ends there however, as the API is COM based. Which basically means it has be compiled into a win32 program using .NET or VB or some other standard compiled language. I was about to abandon the idea of pursuing this endeavor when I remembered that PHP(windows version) has a COM extension built in. Since I happen to be PHP developer I found this be rather fortuitous.
Then I had to think about just how I was going to translate user interaction with the desktop application to some PHP script running the phone server API. The obvious solution was to use XHR requests to a PHP server where the script ran. A couple problems unfolded from this tact however. The first problem, is that it takes PHP several seconds to actually load and initialize the COM API object for the phone server. So as a traditional REST based end point, it would be excruciatingly slow response time. The second problem, is that the desktop application clients would be stuck with PULL based updates. In other words, they would have to pull information updates from the server. Combined with problem one, this is a double whammy on time constraint as the client application would need near real time information updates to actively monitor thier phone queues.
Here I thought I had reached the dead end. Fortunately, after further reading through the Adobe AIR documentation I found that it supported Socket connections. With a socket connection, I could maintain a continuous read/write connection with a PHP script running as a server. This solution lands me the benefit of having a single initialization time for the COM API object, as well as providing both PULL and PUSH information updates. (PUSH meaning the server initiates a status update with the client).
But now I had to write a PHP server. And I couldn’t write a typical daemon program do to the lack of Fork on windows based machines. Another potential dead end. Technically, I could have wrote a php script that runs an infinite loop in which each iteration stops to check if it needs to handle any activity–but it would be really time consuming to come up some process control mechanisms to control the server while it was running. But I remembered working with a PHP extension for GTK called PHP-GTK which brings window applications to PHP. I decided to write a little GUI based TCP socket server. With GTK I can easily create little control and monitoring windows for the server.
Gradually, I was coming closer to the desired end goal, but as I did so, it seemed like I was involving more and more technology. But hey, that’s is the fun part of it after all. So now I know how to solve the client and server issues respectively, but I’ve actually got to come up how they are going to communicate. To be the most compatible with the Adobe AIR client and frankly because it seemed like the easiest solution, I decided on a JSON based protocol. I’d simply pass the binary string data of JSON objects which contained keys for the API method being called and parameters to be passed to the method as well as keys for response status, and method return properties.
Briefly, the process of the client server communication is as follows:
Client connects to server
Client sends JSON request to authenticate
{request: 'authenticate', username: user, password: pass}
Server uses the credentials to attempt to login to the phone server using the SDK COM API. If it fails a response is sent and the connection is terminated. However if the response succeeds it generates a unique id called a token and associates it with the IP:Port the client is connected from. For later requests, the token will be provided by the client and the server will simply verify the token belongs to the IP:Port of the client.
Server sends client response:
{status: '200', request: 'authenticate', token: 'ab223cd702ec2'}
When the user interacts with the client interface to say hold a call it will send a request to the server:
{request: 'hold', data: {call: 'current'}, token: 'ab223cd702ec2'}
When the server detects a state change for the user, such as a caller hanging up it will initiate a PUSH message to the client:
{request: 'update_caller_list', data: {caller: 2, status: 'disconnect' }}
When the client receives this update it knows to update its active caller list and remove the specified caller.
Currently, I’ve got the base work completed for this project. A working PHP server with a little window that shows socket/client status and logs messages sent and received. The client and server are successfully connecting and authenticating. At this point, all that is left to do is design the UI for the client software and come up with the protocol API that will cover updating/changing agent status as well and provide call control.
Looking back, I find it quite amusing how many different technologies came in to play to bring the project into reality. Togehter they included: JavaScript, PHP, Flash, GTK, COM, Sockets and a little programmer dedication.