javascript logo

JavaScript VoIP developers 101

Part 6: Build a live chat application

Study the following article to get more information about doing basic tasks in the Ozeki Phone System by using your JavaScript application. This guide presents how to build a live chat application which is capable of normal chat and voice chat (Figure 1).

live chat
Figure 1 -Live chat application

1. What you need

  • A text editor (for example Notepad++)
  • Ozeki Phone System installed on your PC (Download now)

2. Get started

  • Create a Webphone outside line in Ozeki Phone System
  • Get IP address and port of your PBX (e.g. http://ozekixepbx.ip:7777/)
  • Create a html document
  • Create a css document
  • Add reference to WebphoneAPI
    (e.g. <script type="text/javascript" src="http://ozekixepbx.ip:7777/WebphoneAPI"></script>)

User manual

The Ozeki Phone System makes it possible to connect the customers and the appropriate extensions together through a fully customizable WebPhone. It can be done by using your PBX and the configurable dial plan rules. For this purpose you only need to install a Webphone outside line in the Ozeki Phone System and add the required routing rule. If the default dial plan rule has been added, no need to specify the called number before making a call. In addition, it is also possible to dial a previously installed extension or an outside line number directly by entering its telephone number. In our live chat example we will call webclients. Webclients have outside line numbers. They are connected to the webphone outside line. Everytime a webclient connects to a webphone outside line it gets a new number. How to setup a Webphone outside line

For using WebPhoneAPI a webserver is essentially needed on which your written code will be executable. Any webserver can be used, just select one and download it. In this example Wampserver and Apache was used. After installing WampServer, you need to modify the 'Listen 80' value in the httpd.conf file belonging to Apache in order to avoid port collision. Rewrite it to 'Listen 8080' (or to any other number that is not used by other applications). Do the modification then restart the service. After that open the folder where you have installed Wamp then select the 'www' folder. Here create a new folder for example 'Live Chat' and in that folder create a 'live_chat.html' file and a 'style.css' file. Put the following content into the css file:

/* CSS Document */  
body {  
    font:12px arial;  
    color: #222;  
    text-align:center;  
    padding:35px; }  
   
form, p, span {  
    margin:0;  
    padding:0; }  
   
input { font:12px arial; }  
   
a {  
    color:#0000FF;  
    text-decoration:none; }  
   
    a:hover { text-decoration:underline; }  
   
#wrapper {  
    margin:0 auto;  
    padding-bottom:25px;  
    background:#BFE6CC;  
    width:600px;  
    border:1px solid #009933; }
   
#chatbox {  
    text-align:left;  
    margin:0 auto;  
    margin-bottom:25px;  
	margin-left:25px;
    padding:10px;  
    background:#fff;  
    height:270px;  
    width:430px;  
    border:1px solid #009933;  
    overflow:auto;
	}  
   
#usermsg {  
    width:395px;  
    border:1px solid #009933;
	margin-left:25px;	}  
   
#submit { width: 60px; }
   
#menu { padding:12.5px 25px 12.5px 25px; }  
   
.welcome { float:left;}  
   
.msgln { margin:0 0 2px 0; } 

Code example 1 - style.css

The css file is necessary for the design. Put the following content into the 'live_chat.html':

<!DOCTYPE html>
<html>
<head>
	<script type="text/javascript">

	</script>
</head>
<body>
	<div id="wrapper">  
   		<div id="menu">  
        	<p class="welcome" id="welcome"></p>  
        	<div style="clear:both"></div>  
    	</div>  
      	<table>
		<tr>
		<td>
    		<div id="chatbox"></div>     
    		<form id="message" name="message" align="left">  
        		<input  type="text" id="usermsg" size="63"
        		onkeypress="return runScript(event)"></input>
				<button type="button" onclick="SendMessage()">Send</button>
    		</form>
		</td>
		<td valign="baseline">
			<div id="clients">
<b>Online clients</b><br><br>
<button type="button" id="client0" onclick="CallClient(0)"></button><br>
<button type="button" id="client1" onclick="CallClient(1)"></button><br>
<button type="button" id="client2" onclick="CallClient(2)"></button><br>
<button type="button" id="client3" onclick="CallClient(3)"></button><br>
<button type="button" id="client4" onclick="CallClient(4)"></button><br>
<button type="button" id="client5" onclick="CallClient(5)"></button><br>
<button type="button" id="client6" onclick="CallClient(6)"></button><br>
<button type="button" id="client7" onclick="CallClient(7)"></button><br>
<button type="button" id="client8" onclick="CallClient(8)"></button><br>
<button type="button" id="client9" onclick="CallClient(9)"></button><br>
<button type="button" id="client10" onclick="CallClient(10)"></button>
			</div>
		</td>
		</table>    		
	</div>	
</body>
</html>

Code example 2 - Basic html structure

The JavaScript code which you will write needs to be placed between <script> </script> tags. The reason for adding so many buttons to the html is that every client will be symbolised by a button. You will be able to send a chat request to the client if you click on the button symbolizing him. The targeted client can either accept or refuse your chat request.

Implementation

Before developing JavaScript, reference the WebphoneAPI JavaScript file into your source. Place the following row directly after the opening <head> tag:

<script type="text/javascript"
src="http://ozekixepbx.ip:PBX_ServerPort/WebphoneAPI"></script>

Code example 3 - <script> nodes after the <head> tag

In this script the 'ozekixepbx.ip' and the 'PBX_ServerPort' needs to be the same as the server address and port number of the Ozeki Phone System configured previously. The default port number is 7777.

Reference the jquery too. This contains methods you can use on HTML objects. You can put it directly after the head tag (Code example 4).

<script type="text/javascript"
src="http://code.jquery.com/jquery-latest.min.js"></script>

Code example 4 - <script> nodes after the <head> tag

3. Create JavaScript code running the live chat

This code shows you an example of how to make a live chat, however you can program a chat that fits you better. With this chat client application a client is able to chat with one more clients at a time. To see an example where all of the clients are chatting with each other I advise you to check out the conference chat example application here.

  1. Define variables
  2. Connect to the webphone outside line
  3. Refresh clientlist
  4. Create a call
  5. Accept a call
  6. Hangup a call
  7. Receive/Send messages

Define variables

Let us start the JavaScript code by defining the variables (Code Example 5). The MyCall will be an object in the call class, this is the call which is created betweem two clients.

The UserName variable is the chat name used by the user if not filled the default value will be 'user'. We ask for the username when the webclient opens. The UserName can not be longer then 16 characters.

The chat variable contains a string which is seen in the chatbox, we will chain more strings to this variable as the chat goes on. The message variable will contain the message the webclient would like to send.

The clients array contains details of the other clients. The clients are represented by client objects which contain three attributes: displayName (this is the chat username of a client), status (this can be OFFLINE or ONLINE), phoneNumber. We fill out the clients array by building 20 client objects with a for cycle.

The alreadyAdded is a boolean variable, the i is an int and the answer is a boolean, they will be used later on.

var MyCall = null;
var UserName=prompt("Please enter your chat username: (maximum 16 characters)");
var chat = "Click on someone to start a private chat with him. You can only chat with one person at a time.
"; var message; var clients = new Array(); var alreadyAdded = false; var i; var answer; while(UserName.length>16){ alert("The maximum allowed character length is 16."); UserName=prompt("Please enter your chat username: (maximum 16 characters)"); } if (UserName == null || UserName == "") UserName = "user"; function client(displayName,status,phoneNumber){ this.displayName=displayName; this.status=status; this.phoneNumber=phoneNumber; } for(i=0;i<20;i++){ //we build 20 client objects clients[i] = new client("Anonymus","OFFLINE","inactive"); }

Code example 5 - Variables

Connect to the webphone outside line

After declaring the variables we wait till the user writes in his/her username then we wait a short amount of time, for example 0.2 seconds till the page is loaded, finally we call the begin() function. This function hides all the client buttons on the right side of the screen, welcomes the user, registers to the onConnectionStateChanged event and the onClientStateChanged event and finally it tries to connect to the webphone outside line.

The onConnectionStateChanged event occurs when the state of the connection changes. It can have 4 states: "ACCESS_GRANTED", "ACCESS_DENIED", "CONNECTION_FAILED", "CONNECTION_CLOSED". When it connects it also registers to onIncomingCall event, this event occurs when the webclient receives a call. You can connect to the webphone outside line by using the connect method . As a parameter of this method you need to provide the IP address of the Ozeki Phone System you use and the name of the webphone outside line (Code Example 6).

setTimeout('begin()', 200);

function begin() {
	$('#client0').hide();
	$('#client1').hide();
	$('#client2').hide();
	$('#client3').hide();
	$('#client4').hide();
	$('#client5').hide();
	$('#client6').hide();
	$('#client7').hide();
	$('#client8').hide();
	$('#client9').hide();
	$('#client10').hide();
	document.getElementById("welcome").innerHTML=("Welcome " + UserName + " to the chatroom!");
	OzWebClient.onConnectionStateChanged(connectionStateChanged);
	OzWebClient.onClientStateChanged(clientstatechanged);
	OzWebClient.connect("192.168.115.131", "Webphone1", UserName);
}
		
function connectionStateChanged(state) {
	console.log(state);
	OzWebClient.onIncomingCall(incoming);
}

Code example 6 - Connecting to the webphone outside line

Refresh clientlist

The following function refreshes the clientlist. This function is only called when an onClientStateChanged event occurs. It gets a clientinfo object as a parameter which looks the same way as an object in the clients array, so it has a phoneNumber, displayName and status attribute.

Every client gets a different phone number, so they can be differed by their phoneNumber attribute. The first thing we need to check is that if the client is already added to the clients array, if no and the client status in "ONLINE" then it will be added to the clients array, if yes and the client status is "OFFLINE" it will be deleted from the clients array. The application can show a maximum of 11 clients in the form of buttons on the right side of the screen and writes in the chatbox if a clients goes ONLINE or OFFLINE (Code Example 7).

function clientstatechanged(clientinfo){
	alreadyAdded = false;
			
	for (i=0;i<clients.length;i++){
		if(clients[i].phoneNumber == clientinfo.phoneNumber){
			alreadyAdded = true;
		}
	}
			
	if(clientinfo.status == "ONLINE") {
		if(alreadyAdded == false){
			for(i=0;i<(clients.length+1);i++){
				if(clients[i].phoneNumber == "inactive"){
					clients[i] = clientinfo;
					chat = chat+'<font color="green">'+clients[i].displayName+" is ONLINE</font><br>";
					if(i<11){
						$('#client'+i).show();
						document.getElementById("client"+i).innerHTML = clients[i].displayName;
					}
					break;
				}
			}
		}
	}
	
	if(clientinfo.status == "OFFLINE") {
		if(alreadyAdded == true){
			for(i=0;i<clients.length;i++){
				if(clients[i].phoneNumber == clientinfo.phoneNumber){
					if(i<11) $('#client'+i).hide();
					chat = chat+'<font color="red">'+clients[i].displayName+" is OFFLINE</font><br>";
					clients[i].phoneNumber = "inactive";
					break;
				}
			}
		}
	}
	document.getElementById("chatbox").innerHTML = chat;
	document.getElementById("chatbox").scrollTop = document.getElementById("chatbox").scrollHeight;
}

Code example 7 - Refreshes the clientslist

Create a call

When a button representing a client is pressed a call is created in the direction of the client and the previous call is terminated. A call can be created with the OzWebClient.createCall constructor, it gets the phone number of the target client as a parameter. With the start method the call is started. Then we register to the onCallStateChanged event which occurs when the state of the call changes. Finally we refresh the chatbox (Code Example 8).

function CallClient(clientnumber){
	if(MyCall != null) {
		MyCall.hangUp();
		MyCall = null;
	}
	MyCall = OzWebClient.createCall(clients[clientnumber].phoneNumber);
	MyCall.start();
	MyCall.onCallStateChanged(callStateChanged);
	console.log("calling " + MyCall.getOtherParty() + "...");
	chat = chat + '<font color="blue">You have sent a chat request to ' + clients[clientnumber].displayName + ". Your previous chat session is terminated.</font><br>";
	document.getElementById("chatbox").innerHTML = chat;
	document.getElementById("chatbox").scrollTop = document.getElementById("chatbox").scrollHeight;
}

Code example 8 - Creating a call

Accept a call

When an other client requests a call from your client a pop up window will appear. By clicking 'OK' you can accept it. If you accept the incoming call your previous call will be hung up. The call variable is an object from the call class it will get value when an onIncomingCall event occurs. We run the accept method on the call to accept the call. The we register to the onCallStateChanged event. Finally we send a message to the other party and write a message on the chatbox (Code Example 9).

function incoming(call) {
	answer=confirm("You received a chat request. Click 'OK' to answer it. If you click 'OK' your previous chat session will be terminated.");
	if(answer == true){
		if(MyCall != null) {
			MyCall.hangUp();
			MyCall = null;
		}
		MyCall = call;
		MyCall.accept();
		MyCall.onCallStateChanged(callStateChanged);
		MyCall.sendMessage('<font color="blue">'+UserName+" accepted your chat request.</font>");
		chat = chat + '<font color="blue"> You accepted the chat request. Your previous chat session is terminated.</font><br>';
		document.getElementById("chatbox").innerHTML = chat;
		document.getElementById("chatbox").scrollTop = document.getElementById("chatbox").scrollHeight;
	}
} 

Code example 9 - Accept a call

Hang up a call

When an onCallStateChanged event occurs we can check the current state of the call. The webclient hangs the call up if the state is not "RINGING", "IN_CALL" or "HOLD". If the state changes to "IN_CALL" it registers to the onMessageReceived event (Code Example 10).

function callStateChanged(state) {
	console.log(state);
    if (state != "RINGING" && state != "IN_CALL" && state != "HOLD") {
        setTimeout(hangUpCall, 1000);
        }
	if (state == "IN_CALL") {
		MyCall.onMessageReceived(messagereceived);
	}		
}

function hangUpCall() {
    if (MyCall) {
        MyCall.hangUp();
		console.log("The call is hung up.");
        MyCall = null;
    }
}

Code example 10 - Hangup a call

Receive/Send messages

The chatbox shows the previous and recent chattings. We need to refresh the inner HTML of the chatbox everytime a message is sent or a message is received. You can send a message by pressing enter while the cursor is in the inputbox or by pressing the 'Send' button. Both of these actions will call the SendMessage function. This function is used to refresh the chatbox and send the message. The username is included in the message so the other parties of the conference will be able to see who sent the message.

The messagereceived function is called when the onMessageReceived event occurs. This function gets the message as an input parameter. It refreshes the chatbox to view the recent incoming message (Code example 11).

function messagereceived(message){
	chat = chat + message + "<br>";
	document.getElementById("chatbox").innerHTML = chat;
	document.getElementById("chatbox").scrollTop = document.getElementById("chatbox").scrollHeight; //scrolls to bottom
}
		
//this is called when the "Send" button is pressed
function SendMessage(){
	message = document.getElementById("usermsg").value;
	document.getElementById("usermsg").value = "";
	chat = chat + "You said: " + message + "<br>";
	document.getElementById("chatbox").innerHTML = chat;
	document.getElementById("chatbox").scrollTop = document.getElementById("chatbox").scrollHeight; //scrolls to bottom
	if(MyCall != null) {
		MyCall.sendMessage(UserName + " said: " + message);
	}
}
		
//if enter is pressed sends message when the cursor is in the inputbox:
function runScript(e) {
	if (e.keyCode == 13) {
		SendMessage();
		return false;
	}
}

Code example 11 - View received message, send message, check if enter is pressed

4. Create a more advanced project

Ozeki Phone System offers much more options for JavaScript developers. You can interact with existing calls, control and configure the PBX, you can introduce new communication techniques and media formats.
For a complete list of JavaScript commands, check out: JavaScript API reference book

If you have any questions or need assistance, please contact us at  info@ozekiphone.com

More information