Caller ID with Asterisk and Ajax
I've been using an Asterisk server to handle all of our telephone service for about a year now. During this time, I've discovered many really neat things that can be done with Asterisk, VoIP and various other technologies. One of the more gimmicky things I've done is sent the caller-ID information from incoming calls to a Web page on my browser, in real time. To do this, I had to use Asterisk, Perl, CGI, HTML, CSS, SQL, XML and Asynchronous JavaScript, or Ajax. There are a lot of different pieces to bring together, but sometimes that's what makes a project interesting.
Here's how it works in a nutshell. When someone calls us at the house, the Asterisk server waits for the caller-ID information to be sent. The server then puts this information, and a few other pieces of information, into a file in a subdirectory under /tmp. This is all done in the Asterisk dial plan. Then, I have a Web page open in my browser that runs a JavaScript program every second. This JavaScript program uses an XMLHttpRequest object to query the server for new caller-ID information. The CGI script on the server returns an XML file containing the caller information. The JavaScript program parses the returned XML and displays the content. I've created a Cascading Style Sheet (CSS) that makes the caller information look like a sticky note placed on the Web page. When the incoming call is complete, the Asterisk server creates a Call Detail Record, or CDR, which resides in an SQL database.
Each time the JavaScript contacts the server, the CGI script looks for the CDR. If it exists, the program knows that the call is over and deletes the caller information file in /tmp. This has the effect of causing the sticky notes to disappear when the call is complete.
As an added bonus, the program supports up to four concurrent calls and can be used to indicate outbound calls as well. It's kind of nice to be able to see who's on the phone, regardless of whether the person is the caller or callee, without having to interrupt the person on the phone to ask. When my boys get older, this may become an even more important feature.
For this system to work, you must configure your Asterisk server to put CDRs in an SQL database. By default, Asterisk puts CDRs in a comma-delimited file. The problem is that the flat file CDRs don't contain the call's unique ID, which this system uses to detect when a call has completed. The CDRs that get put into the SQL database contain this field. This shouldn't be a steep requirement though. As I recall, configuring Asterisk to store CDRs in a Postgres database was fairly straightforward and well documented in the cdr_pgsql.conf file. You also could use a MySQL or ODBC database, if you like.
The first, and easiest, part of this project is to modify the Asterisk dial plan to create the flat file when an incoming or outgoing call is made. Once you determine where to make the change, it's a simple one-line addition, as shown here (all one line):
exten => s, n, system(echo "IN#${CALLERID(name)}
↪#${CALLERID(number)}#${UNIQUEID}" >
↪/tmp/panels/cid/${UNIQUEID})
This line creates a file in /tmp/panels/cid that contains four fields, delimited by the # character. Of course, you need to create /tmp/panels/cid and give it appropriate permissions so that the Asterisk server can create files in it and the CGI script can read and delete those files. The first field is either IN or OUT and indicates that the call is INcoming, or OUTgoing. The next two fields call the CALLERID() function to retrieve the caller's name and phone number. The last field is the call's unique identifier. You need to place this line in your dial plan, such that the server has already received the caller-ID information but before the call is handed off to the dial command. If you want to receive information about outgoing calls, you could add a line like this to your dial plan:
exten => s, n, system(echo "OUT##${EXTEN}#${UNIQUEID}"
↪> /tmp/panels/cid/${UNIQUEID})
In the case of the outgoing call, we don't have any caller-ID information to display, so the second field is left blank. We do know the number that was dialed, which is retrieved via the ${EXTEN} variable in the third field.
In both the incoming and outgoing cases, you need to make sure to update the extension field and the priority fields (s and n in this example).
For the purpose of demonstration, I've stripped the Web page down to its most basic requirements, as shown in Listing 1.
Listing 1. Example Web Page
<html>
<head>
<title>CID Test</title>
<script language=javascript src=http://hostname/cid.js>
</script>
<style type="text/css">
@import "cid.css";
</style>
</head>
<body>
<div id="phone1"></div>
<div id="phone2"></div>
<div id="phone3"></div>
<div id="phone4"></div>
<script>
start_cid();
</script>
Your Content Would Go Here.
</body>
</html>
This seemingly simple HTML code does a lot of things. First, it loads the cid.js JavaScript code. Then, it imports a stylesheet called cid.css. This stylesheet will give you a lot of flexibility to customize the appearance of the sticky notes. Then, the HTML code creates four div sections, called phone1 through phone4. These sections will be made visible later on and will be filled in with caller information. Finally, the HTML code starts the periodic polling by calling the start_cid() function. We'll discuss that function later.
Even though my CSS skills aren't world-class, I've included a sample cid.css file to get you started (Listing 2).
Mike Diehl is a freelance Computer Nerd specializing in Linux administration, programing, and VoIP. Mike lives in Albuquerque, NM. with his wife and 3 sons. He can be reached at mdiehl@diehlnet.com
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Designing Electronics with Linux | May 22, 2013 |
| Dynamic DNS—an Object Lesson in Problem Solving | May 21, 2013 |
| Using Salt Stack and Vagrant for Drupal Development | May 20, 2013 |
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
- New Products
- Linux Systems Administrator
- Senior Perl Developer
- Technical Support Rep
- UX Designer
- Web & UI Developer (JavaScript & j Query)
- Designing Electronics with Linux
- Dynamic DNS—an Object Lesson in Problem Solving
- Using Salt Stack and Vagrant for Drupal Development
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Nice article, thanks for the
4 hours 13 min ago - I once had a better way I
9 hours 59 min ago - Not only you I too assumed
10 hours 16 min ago - another very interesting
12 hours 9 min ago - Reply to comment | Linux Journal
14 hours 3 min ago - Reply to comment | Linux Journal
20 hours 57 min ago - Reply to comment | Linux Journal
21 hours 13 min ago - Favorite (and easily brute-forced) pw's
23 hours 4 min ago - Have you tried Boxen? It's a
1 day 4 hours ago - seo services in india
1 day 9 hours ago
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi

It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
Featured Jobs
| Linux Systems Administrator | Houston and Austin, Texas | Host Gator |
| Senior Perl Developer | Austin, Texas | Host Gator |
| Technical Support Rep | Houston and Austin, Texas | Host Gator |
| UX Designer | Austin, Texas | Host Gator |
| Web & UI Developer (JavaScript & j Query) | Austin, Texas | Host Gator |
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?




Comments
Regarding script in linux
Hi,
I need a script which will count the number of lines in a file or directory without counting the commented lines with different patterns.Can anyone help me out in this.
This is great, however, it
This is great, however, it requires that your browser window be open at all times and on top of all other windows for you to see the caller info.
I have created a windows service that will listen on a defined port. When the call comes in, * posts some details to the listener service and this pops open my default browser to a predefined page and the page then loads the caller information from a call database. This way the only thing running on the windows pc is a small service and not javascript refreshing every second.
The above solution was for my windows machines...but for a linux solution wouldn't it be just as easy to run a system command to open the browser along with the url to a page like myserver.com/phonebook.php?id=123456 And then have the php page pull the caller information when the page loads from the unique id 1 time instead of constantly?
sarge! if you can share your windows listener
agree. I need the same functionality as you developed for windows environment.
I will appreciate if you will share this windows listener.
Great combination of scripts
Just wanted to than you Mike for these great examples. I just finished adding your scripts into our intranet web page and enjoyed learning on the way. This is my first time trying out anything on AJAX and I'm already impressed.
Thank you
Thank you for the kind words. Sorry I'm just getting back to you; I don't usually check this forum. Take care and have fun,
Mike Diehl.
Caller ID with Asterisk and Ajax
Thanks for sharing your in depth knowledge with us.