GUI developer's guide

AsteriskNOW is the fastest way to get started building custom telephony solutions with Asterisk. Simply download the .iso file, burn it to a CD, drop it into the CD or DVD drive on the target computer and in less than 30 minutes you will have a full functional Asterisk system ready for your custom telephony application.

A GUI can be developed to interface with Asterisk 1.4. A web server is included with Asterisk 1.4, as well as the AsteriskNOW deployment, so that the user can interface with Asterisk via a web browser. This makes the configuration and fine tuning of your Asterisk implementation easier. The GUI interface already included with AsteriskNOW was created by utilizing several new technologies, as well as several enhancements of tested technologies.

Developers who are interested in creating their own interface, or in extending the existing interface, can use these technologies. The GUI Developer's Guide is an informal introduction to the components which comprise the web server and interface. The document provides a base of information to the Asterisk community so that developers can free themselves to create.

The Asterisk Web Server

The web server included with both Asterisk 1.4, as well as the AsteriskNOW deployment, is used to display the Asterisk Manager Interface (AMI). The AMI is used to manage your Asterisk installation, including configuration. The web server can be used to issue AMI commands using Asynchronous Javascript Asterisk Manager (AJAM). AJAM is a new technology available in version 1.4 (as well as trunk) which gives web browsers, or other HTTP enabled applications, the ability to directly access the AMI via HTTP.

GUI Template Page

There is a sample GUI template page!
You can jump right into commented code and start making your very own GUI page!
It comes with commented code, normal ajax calls, how to communicate with asterisk and the system itself.



You can view the page source or checkout trunk GUI



Once checked out, open up the file /var/lib/asterisk/static-http/config/cfgbasic.html

(or edit the file before installation in config/cfgbasic.html from your source directory)


Uncomment the line:

//newpanel( ["My New Gui Page", "sample.html", "My custom gui page goes here"]);



Into:

newpanel( ["My New Gui Page", "sample.html", "My custom gui page goes here"]);



After that, you can view your sample GUI page in the normal GUI interface (cfgbasic.html)



You can find out more information on Patching/Configuring/Upgrading/Installing

Web Server Setup

Configuring the Asterisk web server to process AJAM requests involves enabling the web server, enabling AMI access, and configuration of your implementation. Use the following procedure to setup the server and enable AJAM access.

Enable the Server

  1. Open the http.conf located in /etc/asterisk/
  2. Remove the comment marks from the line “enabled=yes”. This action will enable Asterisk's built-in micro web server.
  3. Remove the comment marks from the line “enablestatic=yes” is you want Asterisk to deliver simple HTML pages, CSS, javascript, etc.
  4. Adjust the “binaddr” and “bindport” settings as appropriate for your accessibility.
  5. Adjust the “prefix” setting as needed. The prefix is the beginning of any URI on the server. The default is “asterisk”. The rest of the instructions assume the default value.

Enable Manager Access

  1. Open the manager.conf file located in /etc/asterisk/
  2. Remove the comment marks from the line “enabled=yes
  3. Remove the comment marks from the line “webenabled=yes
  4. Adjust the “httptimeout” setting in order to enable a default timeout for HTTP connections
  5. Create a manager username and password.

Restart Asterisk

Once you have completed configuration of the http.conf and manager.conf files, restart Asterisk. Restarting Asterisk will restart the web server with your new configuration. Access to web-based functions will be enabled. You will be able to access these functions by entering specific URLs in a browser's location field. The URL use to access the current Asterisk GUI follows the following format:

http://<YOUR_IP>:8088/asterisk/static/config/cfgbasic.html

<Your_IP> is the same as the IP you specified in the http.conf file, and 8088 is the web server port.

Note: Enter “show http” at the Asterisk CLI to display a complete list of web server functions.

User Authentication Commands

LOGIN

The LOGIN command is used to authenticate credentials for the manager interface's "HTML" view. Once you are logged in, Asterisk stores a cookie on your browser (valid for the length of httptimeout) which is used to connect to the same session. The following URL:

http://localhost:8088/asterisk/rawman?action=login&username=foo&secret=bar

sends a login command to the web server, including the user name and password credentials. The web server will give the following response if the credentials are accurate:

Response: Success

Message: Authentication accepted
LOGOFF

The LOGOFF command is used, as you may suspect, to end your session. The following URL:

http://localhost:8088/asterisk/rawman?action=logoff&_=

sends a logoff command to the web server. The web server will return the following response:

Response: Success

Message: See ya
PING

The PING command is used to confirm that the current session is active. The following URL:

http://localhost:8088/asterisk/rawman?action=ping&_=

sends a ping command to the web server. If a session is currently active, the web server will return the following response:

Response: Pong

If your session is not active, the following response will be returned:

Response: Error

Message: Authentication Required

Channel Commands

CHANNEL

The CHANNEL command, in combination with variables such as originate, hangup, or redirect are used for calling.

Making a Call

The following URL:

http://localhost:8088/asterisk/rawman?action=originate&channel=Local/
6004&context=record_vmenu&exten=1&priority=1&Variable=var1%3dpari_test.gsm&_=

is used to connect, or originate, a channel.

Response: Success

Message: Connection Successful
Disconnecting a Call

The following URL:

http://localhost:8088/asterisk/rawman?action=hangup&channel=OSS/dsp&_=

is used to disconnect a call on a specified channel.

Response: Success

Message: Disconnect Successful
Transferring a Call

The following URL:

http://localhost:8088/asterisk/rawman?action
=redirect&channel=OSS/dsp&priority=1&exten=6001&_=

is used to transfer a call to another channel.

The response for the above command is:

Response: Success

Message: Redirect Successful

STATUS

The STATUS command is used to provide the “raw” manager status of the call channel(s). The following URL:

http://localhost:8088/asterisk/rawman?action=status

If there are no calls in Asterisk, this request will just return

Response: Success

Message: Channel status will follow

Event: StatusComplete

If there is a call (500 on OSS/dsp) as below, Asterisk will return,

Response: Success

Message: Channel status will follow

Event: Status

Privilege: Call

Channel: OSS/dsp

CallerID: <unknown>

CallerIDNum: <unknown>

CallerIDName: <unknown>

Account:

State: Up

Context: default

Extension: 500

Priority: 1

Seconds: 3

Uniqueid: 1162758033.89

Event: StatusComplete

Note: You can also get the response in xml(by calling mxml) instead of plain text(rawman) by requesting

http://localhost:8088/asterisk/mxml?action=status

This will give you the same status view, but represented as Ajax data, which is theoretically compatible with RICO (http://www.openrico.org).

User Administration Commands

The following commands are used in the administration of user accounts on the web server.

Adding a User

Users can be added to the web server by sending a long request which updates the users.conf file. The request may look quite confusing at first. When you examine the request closely you will realize that the request consists of { Action, Category, Variable, Value, (&Match optional) }, which tells Asterisk what action to perform in which category, which variable to use, and what value to use. The optional value-match can be used if you need to delete or edit a user.

http://localhost:8088/asterisk/rawman?action=updateconfig&reload=yes
&srcfilename=users.conf&dstfilename=users.conf&Action-000000=newcat&Cat
-000000=6001&Var-000000=&Value-000000=...

Deleting a User

A user can be deleted from the web server by using a command similar to the following string:

http://localhost:8088/asterisk/rawman?action=updateconfig&reload
=yes&srcfilename=users.conf
&dstfilename=users.conf&Action-000000=delcat&Cat-000000=6003&Var-000000=
&Value-000000=&_=

Editing a User Category (extension)

You can edit a user category by using a command similar to the following string:

http://localhost:8088/asterisk/rawman?action=updateconfig&reload=yes

&srcfilename=users.conf&dstfilename=users.conf&Action-000000=renamecat&Cat
-000000=6001&Var-000000=&Value-000000=6003&Action-000001=update&Cat-
000001=6003&Var-000001=mailbox&Value-000001=6003&_=

Editing a User (field)

You can edit a user record by sending a command similar to the following string:

http://localhost:8088/asterisk/rawman?action=updateconfig&reload=
yes&srcfilename=users.conf
&dstfilename=users.conf&Action-000000=update&Cat-000000=6003&Var-000000=email
&Value-000000=billclinton%40gmail.com&_=

Miscellaneous

Reading a Configuration File

The GETCONFIG command can be used to return the contents of a configuration file. In the example below, the contents of the users.conf file is displayed. The following string:

http://localhost:8088/asterisk/rawman?action=getconfig&filename=users.conf

returns the following response:

Response: Success

Category-000000: general

Line-000000-000000: fullname=New User

Line-000000-000001: userbase=6000

Line-000000-000002: hasvoicemail=yes

Line-000000-000003: hassip=yes

Line-000000-000004: hasiax=yes

Line-000000-000005: hasmanager=no

Line-000000-000006: callwaiting=yes

Line-000000-000007: threewaycalling=yes

Line-000000-000008: callwaitingcallerid=yes

Line-000000-000009: transfer=yes

Line-000000-000010: canpark=yes

Line-000000-000011: cancallforward=yes

Line-000000-000012: callreturn=yes

Line-000000-000013: callgroup=1

Line-000000-000014: pickupgroup=1

Line-000000-000015: host=dynamic

Category-000001: 6007

Line-000001-000000: fullname=Bob Jones

Line-000001-000001: secret=1234

Line-000001-000002: email=bob@jones.com

Line-000001-000003: cid_number=6001

Line-000001-000004: zapchan=

Line-000001-000005: context=numberplan-custom-1

Line-000001-000006: hasvoicemail=yes

Line-000001-000007: hasdirectory=no

Line-000001-000008: hassip=yes

Line-000001-000009: hasiax=yes

Line-000001-000010: hasmanager=no

Line-000001-000011: callwaiting=yes

Line-000001-000012: threewaycalling=yes

Line-000001-000013: mailbox=6007

Line-000001-000014: hasagent=yes

Line-000001-000015: group=
Error Response

A user must be logged into the web server before any other commands can be issued. Any of the commands described above will return an error response if the user is not authenticated. The following string:

http://10.18.4.11:8088/asterisk/rawman?action=ping&_=

will return this response:

Response: Error

Message: Authentication Required

Ajax

Ajax stands for “Asynchronous Javascript and XML”. While the acronym includes the words “asynchronous” and “XML”, this does not mean that you can only make asynchronous requests, nor are you required to use XML. Some authors describe Ajax as simply a combination of HTML, Javscript, DHTML and DOM. The next generation browsers, such as Mozilla/Firefox, utilize an XMLHTTPRequest - a JavaScript object. XMLHTTP is available in Internet Explorer 5 or later. A user can utilize this object to make independent XML HTTP requests from Javascript in the background and can store the response into a javascript variable.

Before going any further with Ajax or Javascript, lets take a look at how the traditional web application works. Traditional web applications take the help of HTML's <FORM> element to define a form in which all the parameters a user needs to send to the server are defined. In addition the action="login.php" informs the browser where to send all these variables. The method="" (POST/GET) tells the browser how to send these variables to the server.

Example of a Traditional Web Application

HTML elements are usually identified by name="" attribute. And the form is usually submitted by using the submit button (type="submit")

    <FORM action=”login.php” method=”POST”>

    <input type="text" name=”username”>

    <input type="password" name="password">

    <input type="submit">

    </FORM>

An Ajax application on the other hand, uses Javascript to send these variables to the server. If you have made the request asynchronously, your Javascript code doesn't wait for the server to respond. This also means that you can let the users do what they were doing if you can. Some times you have to restrict the users from doing what they were doing - like deleting an entry. The browser, by default, shows no visual indication that a request is being made in the background. In other words it is your responsibility to inform the user about the progress of request.

Example of an Ajax Application

    <input type="text" id=”username”>

    <input type="password" id="password">

    <input type="button" onclick="submitform()">

    <script language="javascript" type="text/javascript">

    function submitform(){

    // gather all form variables in javascript

    // make a XMLHttpRequest to the desired URL

    // get the response into a javascript variable

    // if necessary parse the ouput

    // update the necessary elements of the page - using DOM

    }

    </script>

Accessing HTML Elements Using DOM

In the above example you can read the value of the username field and the password field using the getElementById method().

    <script language="javascript" type="text/javascript">

    function submitform(){

    var uname = document.getElementById("username").value;

    var pwd = document.getElementById("password").value;

    // make a XMLHttpRequest to the desired URL

    // get the response into a javascript variable

    // if necessary parse the ouput

    // update the necessary elements of the page - using DOM

    }

    </script>

Making the XMLHttpRequest

    <script language="javascript" type="text/javascript">

    function submitform(){

    var uname = document.getElementById("username").value;

    var pwd = document.getElementById("password").value;

    // xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); // IE 7

    // xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); // IE 5

    xmlHttp = new XMLHttpRequest(); // Mozilla or firefox

    var url = "/rawman?action=login&username=" + escape(uname) + "&secret=" + escape(pwd);

    xmlHttp.open("GET", url, true);

    xmlHttp.onreadystatechange = dosomething;

    // dosomething() would be another Javascript function

    xmlHttp.send(null);

    }

    </script>

Dealing With the Response

The above example only deals with making the XMLHttp request, and it tells the browser to call the dosomething() function when there is a response from the server.

    <script language="javascript" type="text/javascript">

    function dosomething() {

    if (xmlHttp.readyState == 4) {

    var login_response = xmlHttp.responseText;

    }

    }

    </script>

The javascript variable 'login_response' now contains the response of the login page.

Prototype

Prototype is a JavaScript framework (http://prototype.conio.net)released under an MIT-style license. Prototype can make your job extremely easy while developing an Ajax application. For instance in the above example, the document.getElementById() function can be replaced by the $() function. For example you can replace document.getElementById("username") with $('username') and the value of the HTML/DOM element can be accessed using the $F() function.

Example: var uname = $F('username');

Prototoype also makes it easy to make xmlhttp requests in an elegant manner. For example using Prototype's Ajax object, the above submitform() function can be reqritten as

    <script language="javascript" type="text/javascript">

    function submitform(){

    var url = '/rawman';

    var pars = 'username=' + escape($F('username')) + '&secret=' + escape($F('password'));

    var myAjax = new Ajax.Request( url,

    { method: 'get',

    parameters: pars,

    onComplete: dosomething

    });

    }

    </script>

Prototype has lot of built-in functions, some of which have been extensively used in the Asterisk framework.

For More Information

Please refer to the following website for more information Prototype.

http://www.sergiopereira.com/articles/prototype.js.html

Note: The Asterisk GUI currently only supports Prototype 1.4.

Using astman.js

The following example shows you how to use the included astman.js framework to develop a basic HTML interface. The example below reads the users.conf and parses the list of users into a select box. The fields - name, fullname, and email are automatically tied to the events of select box and the buttons new, delete, save, and cancel.

<script src="scripts/prototype.js"></script>

<script src="scripts/astman.js"></script>

<script>

var widgets = new Array;

var callbacks = new Object;

var eventeater = new Object;

var fieldnames = new Array('name','fullname','email','new','delete','save','cancel');

eventeater.eventcb = function(msgs) {

if (loggedon == 1)

astmanEngine.pollEvents();

}

callbacks.format = function(t){

if ((t.name == 'general'))

return null;

if (t.name.substring(0,6) == 'trunk_')

return null;

if (t.fieldbyname['fullname'] && t.fieldbyname['fullname'].length) {

return t.name + " -- " + t.fieldbyname['fullname'];

} else

return t.name;

}

callbacks.loaded = function(){

// This code will be executed after the users.conf is parsed into $('devices')

}

callbacks.newcategory = function(){

// This code will be executed when the user clicks on the New Button

var tmp = null;

var x;

if ($('devices').stored_config.catbyname['general'])

tmp = objcopy($('devices').stored_config.catbyname['general']);

if (tmp) {

x = tmp.fieldbyname['userbase'];

if (x) {

tmp.name = first_free_exten($('devices'), x);

}

}

// the returned object is used to set the default values for a new user entry

return tmp;

}

callbacks.identifier = "extension";

astmanEngine.setURL('../../rawman');

astmanEngine.setEventCallback(eventeater.eventcb);

function localinit(){

for (var x=0; x < fieldnames.length; x++ ) {

widgets[fieldnames[x]] = $(fieldnames[x]);

}

astmanEngine.config2list("users.conf", $('devices'), widgets, callbacks);

}

</script>

<body onload="localinit()">

Users: <select id="devices" size=2></select><br /><br />

Extension : <input id='name'><br />

Name : <input id='fullname'><br />

E-mail : <input id='email'><br />

<div id='status'></div>

<input type='button' id='new' value='New'>

<input type='button' id='delete' value='Delete'>

<input type='button' id='save' value='Save'>

<input type='button' id='cancel' value='Cancel'>

</body>

GUI Interaction with the OS

The GUI uses the Asterisk System() application command to interact with the OS. During the setup of the GUI an [asterisk_guitools] context is added to the extensions.conf and can be called as a Local channel.

Example:

in extensions.conf


    [asterisk_guitools]

    exten = executecommand,1,System(${command})

    exten = executecommand,n,Hangup()

    exten = record_vmenu,1,Answer

    exten = record_vmenu,n,Playback(vm-intro)

    exten = record_vmenu,n,Record(${var1})

    exten = record_vmenu,n,Playback(vm-saved)

    exten = record_vmenu,n,Playback(vm-goodbye)

    exten = record_vmenu,n,Hangup

    exten = play_file,1,Answer

    exten = play_file,n,Playback(${var1})

    exten = play_file,n,Hangup

So to execute something like

/bin/grep /var/log/asterisk/messages -e 'Jan 10 ' > /var/lib/asterisk/static-http/config/bkps/today_log.html

on the server side the Gui actually makes the following request:

http://localhost:8088/asterisk/rawman?action=originate&channel=Local
%2Fexecutecommand%40asterisk_guitools&Variable=command%3d%2Fbin%2Fgrep%20

%2Fvar%2Flog%2Fasterisk%2Fmessages%20-e%20'Jan%2010%20'%20%3E%20%2Fvar%2Flib
%2Fasterisk%2Fstatic-http%2Fconfig%2Fbkps%2Ftoday_log.html&application=noop
&timeout=60000&_=

Please refer to http://www.albionresearch.com/misc/urlencode.php for assistance with decoding the above URL.

GUI Files

The GUI home page is cfgbasic.html. All other pages are loaded into the iframe contained within the cfgbasic.html page. The cfgbasic.html page loads home.html by default. There is an advanced configuration page (cfgadvacned,html) which is intended for advanced users. The advanced configuration currently contains only a few options to manage sip.conf and iax.conf. Future implementations of cfgadvanced.html will contain more advanced configuration options.

If you want to add a new panel to the GUI – say “your_file.html”,

just add the following to the cfgbasic.html

    new PanelDef("your_file", "Your File", "accordion-icon.gif",
"Description for your file goes here")

The “.html” part of the file name is ignored.

Some Tips

  1. Use of Firebug (http://www.getfirebug.com) is strongly recommended for debugging javascript apps like asterisk-gui.
  2. Make sure you make the next XMLHTTP request only after the success or failure of a previous request.