Caller ID with Asterisk and Ajax

Combine Asterisk and Ajax to display incoming and outgoing call information.

This CSS file could have been made more concise by putting all of the common formatting in a common class; I'll leave that as an exercise for the reader. This stylesheet creates four evenly spaced sticky notes at the bottom of the screen. The sticky notes are yellow with a neat 3-D drop-shadow effect (Figure 1).

Figure 1. The incoming call information is displayed in a Web page in sticky note format.

Now, it's time to take a look at the CGI script (Listing 3).

This Perl script scans the /tmp/panels/cid directory for files, skipping the . and .. entries. Each file it finds is opened and read. The final result is an XML file like the one shown in Listing 4.

Of course, the XML file could contain up to four <panel> blocks corresponding to phone1 through phone4. The <content> block contains the text that is put into each sticky note. I've found that because this is an XML file, it's difficult to embed HTML in the <content> block, so I don't do much formating of this text. It's fairly easy to see how incoming and outgoing calls are handled separately.

As the XML is generated for each phone call and sent to the client, the call to expire_call() is made. This function simply searches the CDR database to see if the phone call has been completed. Asterisk adds CDR records only when a call is concluded, so if the record is in the database, the call is finished and the file in /tmp/panels/cid can be removed.

The JavaScript component is both the workhorse of the system and the most difficult part to understand (Listing 5).

As mentioned previously, the whole system is started by the initial call to start_cid(). All this function does is arrange for the update_cid() function to be called every second. The update_cid() function makes a call to get_from_server() to get an XMLHttpRequest object in a browser-independent fashion. This request object is returned for later use.

Next, the update_cid function calls clear_panels(), which simply arranges for each sticky note to be empty and invisible, initially. The sticky notes will become visible as we put content into them.

The rest of the program is a bit more difficult to follow. Using the request object mentioned earlier, and the getElementsByTagName() function, we get an XML object with the <panels> block intact. Another application of the getElementsByTagName() applied to this XML object gives us an array of individual <panel> blocks.

Then, we start a loop over each <panel> block in the array with the understanding that each time through the loop will correspond to a phone call in progress; we'll create a new sticky note for each call. Each <panel> block contains a <name> and a <content> block, the values of which we extract into appropriate variables. Then, by using the getElementById() document method, we find the <div> element in the HTML document with the same ID as the name of the panel. Now we have all of the information we need about the sticky note: the name, the content and the location in the Web page. So, we set the <div> block to be visible, then assign some content to it via the innerHTML attribute. Finally, we go back to the top of the loop and continue again.

This “poll the server and display the results” process runs every second without any intervention from the user and without having to reload the Web page. This gives the user the perception that the sticky notes simply pop up when the phone rings and disappear when the phone is hung up.

As you can see, JavaScript is a very powerful language. Unfortunately, browser support and development tools for JavaScript are poor to nonexistent. During the development of this program, I had to contend with browser crashes, inadvertently cached information and cryptic runtime error messages. Once I got it working, I had to make sure it worked on each of the browsers I use regularly, Konqueror and Firefox. I suspect that it will run on “that other browser”, but I've not tested it. Because I do most of my software development with vi, I'm not really big on Integrated Development Environments (IDEs), but if you know of one that works well for JavaScript, I'd love to hear from you.

Now that the program is working, it's time to think about ways to improve and extend it. The first obvious change I'd like to make to this program is to have it display a hyperlink that would allow me to bring up additional information about the caller. It could get this information from my contact list or even from an additional database. Maybe it could display a picture of the caller, though it might take a lot of time to photograph all my friends, family and acquaintances. It might also be nice to have a button display for incoming calls that would allow me to reject an incoming call and have it go straight to voice mail. I could also extend this same method to have a Web page display other information besides caller ID. It wouldn't be hard to extend this system to let me know when I have unread voice mail waiting, or when my friends become available for chat via IM.

So there you have it—a fun little toy that brings together many different tools and technologies. Recalling that Qwest used to charge us $6 US a month for caller ID, I wonder what they would charge to make it Web-accessible?

Mike Diehl works for SAIC at Sandia National Laboratories in Albuquerque, New Mexico, where he writes network management software. Mike lives with his wife and two small boys and can be reached via e-mail at


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


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Regarding script in linux

Sagar's picture

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

sarge's picture

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 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

Abdul Basit's picture

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

eayala's picture

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

Mike Diehl.'s picture

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

Tattoo Design's picture

Thanks for sharing your in depth knowledge with us.