Home » Technology » Putting Real Names Back in CallerID: 3 Quick Perl Solutions for the Asterisk PBX

The Most Versatile VoIP Provider: FREE PORTING

Putting Real Names Back in CallerID: 3 Quick Perl Solutions for the Asterisk PBX

If you haven't noticed, useful Caller ID (meaning a number and a name display) is pretty much a bust in the VoIP marketplace except for calls originating from Baby Bell-controlled local phone numbers. And, with some VoIP providers, getting a CallerID name with any incoming call is a rarity. Jeff Pulver has proposed a new national database where you can list yourself. In fact, you can sign up today. But, suffice it to say, it isn't soup just yet. Known in the trade as CNAM service, many telephony service providers simply throw incoming names in the bit bucket unless you are one of their subscribers. The Baby Bells are among the most notorious. Some don't even provide CNAM service from other areas of the country unless the caller is part of the local carrier's feifdom. And I guess if I charged $40 for basic local phone service with CallerID, I'd want to keep my monopoly, too. We'll have more on the pricing issue at the end of today's article.

2008 Update. For the latest in CallerID name lookup software written in PHP, visit our Best of Nerd Vittles site. For PBX in a Flash users that want a Perl version, check out the PBX in a Flash Forum.

For those of you wrestling with Caller ID on your Asterisk® PBX, we have three solutions today and more to come. Today's perl AGI utility was developed initially by Tom Vile at Baldwin Technology Solutions. Tom has graciously agreed to let us share the code with you. Thanks, Tom! It lets you intercept incoming calls to your Asterisk box and pass the CallerID number to AT&T's AnyWho.com for a reverse number lookup to decipher the CallerID name. Whether this comports with the AnyWho terms of service, we'll leave for you to resolve. Suffice it to say, the "phone company" has always maintained that the phone book information is copyrightable. And the Supreme Court of the U.S. has held just the opposite. This is not legal advice, just some historical background for you to digest before proceeding.

Once we started looking at Tom's code, we decided it might be a good time to learn Perl so you've been forewarned that nothing in the solutions which follow will qualify as elegant coding other than Tom's original handiwork, of course. But the stuff does work. What we've added to Tom's original code are two enhancements. First, you can opt to use Google for reverse number lookup if you'd like. And second, you can tie reverse number lookups into the AsteriDex web-based MySQL database application which we previously built and which you can download and use for free here. Particularly for home and small business use, the universe of incoming callers is fairly small so you may find that AsteriDex is the best solution. This is particularly true if many of your incoming calls are from cell phones since few of the American carriers associate real names with their CallerID numbers. Some do provide the city of the caller in the CallerID name. Others refer to us all as Wireless Caller(s). Gee, what a hint. Consequently, neither AnyWho nor Google have many cell phone numbers in their databases. Call it a feature. The bottom line is you can mix and match AnyWho, Google, and AsteriDex lookups as you see fit by simply setting "on" and "off" flags for each of the three services.

Footnote: As of November 13, we've added another lookup function for FoneFinder.net. This one's a little different in that it returns the city and provider type for phone numbers matching the area code and first three digits of the caller's number. It also has the lowest precedence and can be activated to at least return the city name and provider type for callers where no other information is available from the other services.

Overview. The way this works is that incoming calls will be processed through an AGI script that you configure with your lookup preferences. We recommend you use this script with Asterisk@Home because it comes bundled with all the MySQL, Apache, PHP, and Perl stuff you'll need to make everything work. The script as received does nothing since all three lookups are disabled. That lets you choose which services to activate and conveniently moves the legal monkey from our back to yours. Didn't go to law school for nothing, did we? Assuming you turn on all three lookups, the AnyWho lookup is processed first. If a match is found, the Caller ID name is added to the existing Caller ID number replacing whatever name entry already was picked up for the incoming call. If no match is found, the existing CallerID number and name are left as they were received for the incoming call. The CallerID number is then passed to the Google phonebook where the process is repeated. If there's a match, the CallerID name is replaced with the name found in the Google search. If not, nothing changes. Finally, if you're using AsteriDex as your personal phone book, the CallerID number will be looked up in your AsteriDex database. If there's a match, whatever you entered as the name for the first matching phone number entry will be picked up as the CallerID name for the call ... so these names can be as obnoxious as you choose to make them. Note that the AsteriDex lookup is a crude search. If you've entered the same phone number for three different people in the same house, then only the first one it finds will be used. You'll know which one it is when you receive the first call from this number. So, the bottom line is this: AsteriDex lookups take precedence over Google and AnyWho lookups, and Google lookups take precedence over AnyWho lookups. And, at least for the short term, if you want any meaningful information about cell phone callers and most VoIP callers, you'll need to put their names and numbers in your AsteriDex database.

To get started, download the calleridname.agi script from here. Then copy it to the /var/lib/asterisk/agi-bin folder on your Asterisk server. Log in to your Asterisk server as root and change the ownership of the file: chown asterisk:asterisk /var/lib/asterisk/agi-bin/calleridname.agi. And change the permissions: chmod 775 /var/lib/asterisk/agi-bin/calleridname.agi. To activate the services you want to use, edit the calleridname.agi script: nano -w /var/lib/asterisk/agi-bin/calleridname.agi. CAUTION: Before you open the file with nano, be sure your editing window is at least 180 characters wide unless you use the -w switch, or some of the commands in the file will be truncated. Then nothing works! Nano doesn't do word wrap in a Perl-friendly way if left to its own devices. Once you open the file, beginning on line 10, you'll see the following entries:

$Fonetastic = '0' ;
$AnyWho = '0' ;
$Google = '0' ;
$Asteridex = '0' ;

For each service you want to activate, change the '0' to '1' and then save the file: Ctrl-X, Y, then press Enter key. Now we're ready to reconfigure your incoming call dialplan.

If you've been following along with our other tutorials, you should already have the Stealth AutoAttendant in place to handle your incoming calls. If not, start there ... or you're on your own. After making the security modifications, here's how our autoattendant code looks in the extensions_custom.conf config file:

exten => s,1,Zapateller(answer|nocallerid)
exten => s,2,Wait(1)
exten => s,3,SetMusicOnHold(default)
exten => s,4,GotoIf($["${CALLERIDNUM}" = ""]?who-r-u,s,1)
exten => s,5,GotoIf($["foo${CALLERIDNUM}" = "foo"]?who-r-u,s,1)
exten => s,6,GotoIf($["${CALLERIDNAME:0:9}" = "Anonymous"]?who-r-u,s,1)
exten => s,7,GotoIf($["${CALLERIDNAME:0:7}" = "Unknown"]?who-r-u,s,1)
exten => s,8,GotoIf($["${CALLERIDNUM:0:7}" = "Private"]?who-r-u,s,1)
exten => s,9,GotoIf($["${CALLERIDNAME:0:7}" = "Private"]?who-r-u,s,1)
exten => s,10,GotoIf($["${CALLERIDNUM:0:10}" = "Restricted"]?who-r-u,s,1)
exten => s,11,GotoIf($["${CALLERIDNUM:0:4}" = "PSTN"]?who-r-u,s,1)
exten => s,12,DigitTimeout,3
exten => s,13,ResponseTimeout,3
exten => s,14,Background(custom/welcome)

We're going to introduce another new trick in the incoming dial plan. What we want to do is answer the call, do some processing, and then pass the call to where it's supposed to go. The trick is that we don't want the caller to know we've already answered the call while we're doing the processing. So what we're going to do is play a fake ringing tone to the caller so the caller doesn't get bored. Just insert a new third line in the dialplan that looks like this: exten => s,3,Playtones(ring) and then renumber the remaining lines. Next we want to add our new CallerIDName lookup immediately before the custom/welcome message plays: exten => s,17,AGI(calleridname.agi) and then renumber the lines. When you're all finished, your code should look like this:

exten => s,1,Zapateller(answer|nocallerid)
exten => s,2,Wait(1)
exten => s,3,Playtones(ring)
exten => s,4,SetMusicOnHold(default)
exten => s,5,GotoIf($["${CALLERIDNUM}" = ""]?who-r-u,s,1)
exten => s,6,GotoIf($["foo${CALLERIDNUM}" = "foo"]?who-r-u,s,1)
exten => s,7,GotoIf($["${CALLERIDNAME:0:9}" = "Anonymous"]?who-r-u,s,1)
exten => s,8,GotoIf($["${CALLERIDNAME:0:7}" = "Unknown"]?who-r-u,s,1)
exten => s,9,GotoIf($["${CALLERIDNUM:0:7}" = "Private"]?who-r-u,s,1)
exten => s,10,GotoIf($["${CALLERIDNAME:0:7}" = "Private"]?who-r-u,s,1)
exten => s,11,GotoIf($["${CALLERIDNUM:0:10}" = "Restricted"]?who-r-u,s,1)
exten => s,12,GotoIf($["${CALLERIDNUM:0:4}" = "PSTN"]?who-r-u,s,1)
exten => s,13,DigitTimeout,3
exten => s,14,ResponseTimeout,3
exten => s,15,AGI(calleridname.agi)
exten => s,16,Background(custom/welcome)

Remember that, if you cut-and-paste the code above, you'll need to manually fix the typographic quotation marks to make them regular quote marks that Asterisk can understand or disaster awaits. Once you save your changes and reload Asterisk, you should be good to go. Start up the Asterisk Command Line Interface (CLI) and make a test call to yourself. You should see something like this in the CLI display:

calleridname.agi: CALLERID IS: 3035551616 <3035551616>
calleridname.agi: Checking 303 555 1616...
calleridname.agi: Fonetastic.US lookup disabled.
calleridname.agi: AnyWho lookup disabled.
calleridname.agi: Ready for Google lookup...
calleridname.agi: Google match. New CallerIDName = R. Smith
calleridname.agi: Ready for AsteriDex lookup...
calleridname.agi: AsteriDex match. New CallerIDName = Robbie the Nerd

Money-Saver Tip of the Week. We regularly hammer BellSouth and the other RBOCs for their pricing policies on home phone service so it's great to finally have something nice to say about our hometown company. Actually, BellSouth might not think this is too nice, but we sure do. A post on DSL Reports this week had this helpful tip for those with BellSouth DSL service that would prefer not to keep paying $40 a month for a BellSouth phone line you never use. You can suspend your phone service for up to six months and reduce your monthly line costs by 50% or more while still retaining your $24.95 DSL service through BellSouth. You can even get a recorded message referring callers to your new [VoIP] number at no charge. For details, visit this BellSouth link. To put things in proper perspective, this means you can suspend your BellSouth line, order two new TelaSIP VoIP lines with unlimited U.S. long distance on both lines for $14.95 a month, notify your BellSouth callers of your new number, and still put $5 in the bank each month compared to what you're paying BellSouth today for just one line with pay-through-the-nose long distance access. Now that's a sweet deal! For those that are curious, a garden-variety residential line from BellSouth in Atlanta with nothing other than CallerID and dial tone runs $39.75 per month with tip and taxes, and I've got this month's statement to prove it. Does it take a collision with a freight train for the RBOCs to wake up before all their residential customers have jumped ship just like their pay phone customers did? Probably so.

Sony Anyone? Just Say No! If you missed the latest attack on your home computer this week, don't worry. It wasn't a malicious virus creator this time. It's S-O-N-Y. Before you spend another dime with Sony, read this C|NET article. Here's a brief snippet:

"You buy a CD. You put the CD into your PC in order to enjoy your music. Sony grabs this opportunity to sneak into your house like a virus and set up camp, and it leaves the backdoor open so that Sony or any other enterprising intruder can follow and have the run of the place. If you try to kick Sony out, it trashes the place. And what does this software do once it's on your PC ..."

Other Asterisk Tutorials. There are numerous additional articles in this Asterisk HOW-TO series to keep you busy. You can read all of them by clicking here and scrolling down the page. We recommend reading at least the first four or five articles from the bottom up so that the learning curve is less painful. Then you can skip around to your heart's content.


  1. Excellent article! One question, line 129 of the callerid.agi file contains reference to "root" and "passw0rd". Is this a weak password for the Astridex database? Should it be changed?

    my $dbh = DBI->connect("dbi:mysql:asteridex","root","passw0rd") or die("Connect failed");

    Keep up the good work!

    [WM: It’s a mighty weak password, but it can only be used by those with direct physical access to the localhost machine. Assuming your Asterisk machine is secure in your own home or office, it’ll be just fine.]

  2. Ok, I am not using the auto attndant. I have started with Asterisk@home and still learning. What would the extension file look like if it was just incoming without the auto attendant? As I stated, I am still learning so seeing just the inserted lines following the default install will be helpful to me in learning.

  3. CyClore you need to add this to the top of your extensions_custom.conf.

    exten => s,1,Playtones(ring)
    exten => s,2,AGI(calleridname.agi)

    That should work for you. If not let me know.

  4. Thanks for the great utility. I just switched providers to Teliax, and I think they pass a 1 at the front of the number, so my caller id is not working. It is trying to lookup +1XXXXXXXXXX and is coming up with :Unable to parse phone number for NPA/NXX/station. Is there something I can modify in the calleridname.agi file to remove the 1?

    [WM: You may have an older version of the .agi file. Before the line that begins with $calleridfull, add the following:]

    if(substr($callerid,0,2) eq '+1'){

  5. The FoneFinder.net site has implemented a referrer block to keep this utility from working. Here’s a quick fix for those of you that want to still use it:

    Edit calleridname.agi with nano
    Search (Ctrl-W) for AsteriskAGIQuery/1
    Replace AsteriskAGIQuery/1 with the following:
    Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)
    Save your changes: Ctrl-X, y, then enter.

    [WM: Actually, it started as a referrer block and then escalated to other tricks. Rather than hassle this guy who obviously doesn’t want the visits, we’ve built our own system at fonetastic.us. It is and always will be free, and we’ll follow up with a web page similar to FoneFinder when time permits. But the lookup function works now! Just download the calleridname.agi file using the link in the article above, and you’ll get the new version. Follow the existing instructions to set it up. Sorry for the problems.]

  6. I don’t get the output as noted above in the CLI. I get:
    — Launched AGI Script /var/lib/asterisk/agi-bin/calleridname.agi
    — AGI Script calleridname.agi completed, returning 0
    I made the changes in the calleridname.agi as follows:
    $Fonetastic = ‘0’ ;
    $AnyWho = ‘1’ ;
    $Google = ‘1’ ;
    $Asteridex = ‘0’ ;

    [WM: Try "set verbose 10″ in CLI and see if you get any additional feedback.]

  7. I’m using this for all incoming calls, whether from sip/iax or from pstn. Problem is, whenever my internet connection goes out, any incoming calls from pstn aren’t ringing through. I checked the cli, and calleridname.agi is just sitting there waiting for a response, which it’ll never get. Is there a way to force a timeout of say 5 seconds or so, so if the site’s down or the user’s internet connection is offline, we can still get calls?

    BTW, for the person above, I had the same problem until I installed the required perl modules. You need at least Asterisk::AGI, LWP::UserAgent, and DBI.

  8. Thanks, for all the great articles Ward! You have made the learning curve for asterisk much easier. I have found a new way to implement your callerID Name fix, this allows you to fix the callerID Name before anything answers the line.

    Instead of using the auto-attandant, I put the following line in the built-in user-callerid macro in extensions.conf.

    Just edit the macro my going to AMP->Maintenance->Config Edit->extensions.conf->macro-user-callerid

    Insert this line between the existing priorities s,4 and s,5

    exten => s,5,AGI(calleridname.agi)

    Then renumber the priorities so that you have s,1 through s,6. Don’t forget to reload Asterisk.

    This works beautifully!

    [WM: See also Comment #11, below, if you’re using AAH 2.7 with FreePBX 2.0.1! Great work, Kaleb. I edited your post a bit because of WordPress quirks that drop some characters.]

  9. Due to the way I’ve implemented my landline, Telasip, and ipkall, I have my incoming calls all going to the same place. What I’d like to do is call calleridname.agi iff there is no CallerID name info (if the phone company supplies the name I’d rather keep that). I don’t quite understand the syntax to do that though.

    [WM: Take a look at our Stealth AutoAttendant for some hints.]

  10. I recently updated my Asterisk@home 2.7 box to FreePBX 2.0.1 (freepbx is the new name for AMP) after the upgrade, the calleridname fix I posted in #8 above stopped working. Turns out the code changed a bit, to get it working in FreePBX 2.0.1, do the following:

    Just edit the macro my going to AMP->Maintenance->Config Edit->extensions.conf->macro-user-callerid

    Insert this line between the existing priorities s,5 and s,6

    exten => s,5,AGI(calleridname.agi)

    Then renumber the priorities so that you have s,1 through s,7. Don?ข‚วจ‚ัขt forget to reload Asterisk.

  11. Why not connect the callerid script with the database of SugarCRM?
    Has anyone implemented a function for this?

    [WM: Good idea. I’ll have a look… soon.]

  12. Interesting call today from "google maps"! Any idea where that came from?

    [WM: Heh, heh! Yeah, I’ve started getting a few of those, too. We call it a ‘feature.’ My wife keeps asking: "Who’s keeps calling us from Google?" Rest easy, it’s not the Map Police. Google has apparently changed the web site display code a bit, and I haven’t had time to wrestle with what’s new and causing it. Doesn’t happen all the time. I’ll track it down one day soon.]

  13. re: callerid lookup in sugarcrm
    I’m about to create this functionality:
    1. callerid lookup in sugarcrm
    2. when the call is picked up the following will take place:
    a) a Call record will be created on the customer
    b) subject for the call "automatic call logging"
    c) when the call is ended the duration of the call will be calculeted
    d) the user that talked to the caller will be assigned the call "Assigned to" field in sugarcrm

    Anyone thinking the same as me ?

  14. How would I go about creating my own cid system instead of looking at google or fonetastic.us or something? Is there a simple way to create my own lookup for all NPA NXX so that if the internet was down I could still query the database locally? I know there is asteridex but I can not get it to match NPA-NXX only. There may be a simple way to do this that I am missing. I was thinking more like the fonetastic.us system you created in the post #5 above. If anyone knows where I can import a complete list of NPA-NXX with city, state that would be helpful as well. Any recommendations or suggestions would be greatly appreciated.

    [WM: It’s already on my TO-DO list. So hang in there until we get past our move, and we’ll cover it with an NPA-NXX database as well.]

  15. Don’t know what u can do with it but this site has a complete list of NPA-NXX

    and does anyone know if there’s a way to lookup canadian phone numbers, google and att only have a US database. i’m looking for a canadian database as well. thanks

    [WM: Can’t help much on Canadian phone numbers. As for NPA-NXX, we already have converted the data to MySQL in preparation for our upcoming article. Anyone that wants to get a head start and roll your own is welcome to use the database. You can download it from here: npanxx.zip. Just share your work here and save us all a little time.

  16. Changed the calleridname.agi – to work with SugarCrm.
    (its customized to work for europeans – so no NPA-NPX-STATION …)
    It uses contacts and accounts db – and pulls out – Firstname,Lastname from contacts and name (companyname) from accounts.

    Enter: $Sugarcrm=’1′; under $Asteridex

    ## i also remarked the lines below:
    #if(substr($callerid,0,1) eq ‘1’){

    #if(substr($callerid,0,2) eq ‘+1’){

    #$calleridfull =~ s/[,"‘]+/ /g;

    ###### now the real stuff ###

    create the following section:

    sub sugarcrm_lookup {
    my $callerid = shift @_;
    my $dbh = DBI->connect("dbi:mysql:sugarcrm","root","passw0rd") or die("Connect failed");
    #my $sql = "select * from contacts where phone_work = ‘$callerid'";
    #return $sql;
    # [contacts.id -> accounts_contacts.contact_id] mit [accounts_contacts.account_id->accounts.id] get [accounts.name]
    #my $sth = $dbh->prepare("select * from contacts where phone_work = ‘$callerid’ OR phone_home = ‘$callerid’ OR phone_mobile = ‘$callerid’ OR phone_other = ‘$callerid'") or die("Prepare failed.");
    my $sth = $dbh->prepare(" SELECT c.first_name,c.last_name, if(a.name IS NULL,"unknown",a.name) AS "company"
    FROM contacts c
    LEFT JOIN accounts_contacts ac ON ac.contact_id=c.id
    LEFT JOIN accounts a ON a.id=ac.account_id
    WHERE c.phone_work like ‘$callerid’ OR c.phone_home like ‘$callerid’
    OR c.phone_mobile like ‘$callerid’ OR c.phone_other like ‘$callerid'")
    or return "FAILED";
    if($sth->rows == 0)
    return "null";
    my $resptr = $sth->fetchrow_hashref();
    my $clidname = $resptr->{"first_name"}." ".$resptr->{"last_name"}." @".$resptr->{"company"};
    # $clidname = trim ($clidname);
    return $clidname;

    return "disconnect";


    have fun!

    [WM: Fantastic! Can’t wait to try it. Thanks for sharing it with all of us!]

  17. As you may have noticed, this routine no longer operates if you upgrade to FreePBX. I got it working with FreePBX version 2.1.0 by changing the macro-user-callerid context as follows (note that until and unless FreePBX officially supports this, you may need to tweak this macro every time you upgrade FreePBX):

    exten => s,1,GotoIf($["${CHANNEL:0:5}" = "Local"]?report)
    exten => s,n,GotoIf($["${REALCALLERIDNUM:1:2}" != ""]?start)
    exten => s,n,Set(REALCALLERIDNUM=${CALLERID(number)})
    exten => s,n(start),NoOp(REALCALLERIDNUM is ${REALCALLERIDNUM})
    exten => s,n,Set(AMPUSER=${DB(DEVICE/${REALCALLERIDNUM}/user)})
    exten => s,n,Set(AMPUSERCIDNAME=${DB(AMPUSER/${AMPUSER}/cidname)})
    exten => s,n,GotoIf($["x${AMPUSERCIDNAME:1:2}" = "x"]?chknamelen)
    exten => s,n,Set(CALLERID(all)=${AMPUSERCIDNAME} < ${AMPUSER}>)
    exten => s,n(chknamelen),GotoIf($[${LEN(${CALLERID(name)}) > 0 ]?report)
    exten => s,n,AGI(calleridname.agi)
    exten => s,n(report),NoOp(Using CallerID ${CALLERID(all)})

    Note that one line is changed in the existing macro (the label at the end of the line is changed:

    ,n,GotoIf($["x${AMPUSERCIDNAME:1:2}" = "x"]?chknamelen)

    And two lines are added:

    exten => s,n(chknamelen),GotoIf($[${LEN(${CALLERID(name)}) > 0 ]?report)
    exten => s,n,AGI(calleridname.agi)

    I also changed the dialplan.agi itself. Because I do live in North America and do not use SugarCRM, I did not incorporate TBB’s changes. But I did make several other changes, among which are:

    1) It now searches from the type of lookup you probably most want (name) and only if it is unsuccessful there does it proceed to try and find a city. More to the point, once it finds valid data it stops looking. The existing routine eats up a lot of time by checking every enabled service, and discarding earlier results if it finds a "better" result. This is clearly inefficient; why not check the services you would most like to get a result from first and only move to the next check when a previous one has failed?

    2) I implemented a subroutine to check what I consider the best service out there, Whitepages.com. It’s a bit slow (mainly because a request sends back a huge page of data, most of which is unnecessary for our purposes) but their database seems to contain both businesses and residences, and both U.S. and Canadian numbers (in fact I read somewhere that they are the most popular directory service in Canada).

    3) I also added a reverse lookup search at Canada411.com – this one only returns Canadian numbers. So I added a check for Canadian area codes that sets a flag if the NPA is Canadian, and only checks Canada411 if it’s a Canadian NPA. And it will only check AnyWho and Google if the NPA is NOT Canadian, because they don’t appear to support Canadian reverse lookups.

    4) I really hated the place lookup display from Fonetastic – all I really wanted was City and State (or Province), thank you very much. Well, I found that Telcodata.us gives something pretty close to this, which is ratecenter and state. Ratecenter is usually the city (abbreviated to ten characters maximum) but you will see things like DETROITZN1 which simply means Detroit Zone 1. It’s still far more readable that what the Fonetastic routine spits out. And Telcodata lets you retrieve the data in an XML file, which is very easy to process IF you have the Perl XML::Simple module installed. Unfortunately, that isn’t included in a standard Asterisk@Home distribution. The easiest way to install it that I’ve found is to do this from the command line:

    cd /tmp
    wget http://search.cpan.org/CPAN/authors/id/G/GR/GRANTM/XML-Simple-2.14.tar.gz
    tar xzvf XML-Simple-2.14.tar.gz
    cd XML-Simple-2.14
    perl Makefile.PL
    make install

    After doing the above you can delete the XML::Simple module stuff from the /tmp directory (it’s only needed during the install).

    NOTE THAT IF YOU DON’T INSTALL THE XML::SIMPLE MODULE THE MODIFIED AGI SCRIPT WON’T RUN – Perl will barf because it can’t find the module, even if you don’t use the Telcodata.us service.

    5) I changed the default timeout for each service to 5 seconds. Remember your callers are waiting (and hearing nothing) while the lookups are being performed. Even 5 seconds is too long in my opinion, but 45 seconds (the original default) was outrageously too long.

    6) Finally, I removed the orphaned subroutine that did the Fonefinder lookups. It no longer works, and it’s no longer called from anywhere, so why keep it around?

    Now a couple of caveats:

    1) I am releasing my additions to the original code under the same terms as the original code (whatever they may have been), so anyone that used the original code may use this. However, notwithstanding the above, I must also say that I’m providing these modifications to the original routine for educational and experimental purposes only, and in particular, without saying or implying that it is permissible to use the services accessed by this routine. If you plan to use this in any sort of commercial environment, you may need to actually get a license and/or pay some money to whichever services you use. Whitepages.com, for example, has a commercial product that they sell to companies that do many lookups. While I doubt anyone running Asterisk AT HOME will get in trouble for doing an occasional lookup, the situation may be much different if you implement this routine in a business or corporate setting. I am not a lawyer, so I cannot tell you what your obligations may or may not be.

    (Specific note regarding Whitepages.com – I think that if you buy the commercial product, you can get the results in XML format, which would be far more reliable and could potentially decrease the lookup time by a couple of seconds per lookup, which might make a big difference if you were running something like a call center. Right now the modified routine won’t use the XML files because I have no idea what format Whitepages.com uses, but if you do, it would be fairly easy to add a subroutine to parse whatever their XML format is. Again, if you are running any kind of call center environment, you definitely should contact Whitepages.com to see how you can use their service in the most efficient and legal manner.)

    2) This code works FOR ME as of the day I posted it, under very limited testing. It may not work if the services change how they display their results. It may not work if you encounter an unusual listing. I do NOT offer any guarantees of any sort as to how it will work for you, or that it will work for you at all. I will also add that I’ve been messing with Perl for all of a month or two and I am a slow learner, so you may see better ways to do things in the code – I don’t know about the original author and his code, but I assure you that I will NOT be offended by any suggestions for improvement to the parts I wrote (or modified). Note that I may fix bugs in this routine or add additional services if I find them, but don’t use this routine in any situation where it could cost you money if it doesn’t work, without doing your own testing. THERE IS NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, ON THIS ROUTINE.

    By downloading and/or using the modified calleridname.agi routine, you agree that you have read and will observe the above-mentioned caveats. It will be available for download for a limited time at this location. Ward, feel free to move it to your site and change the link (assuming the original author has no objections).

    One thing I do NOT do here, but that probably should be done in any commercial operation, is to cache the results of a lookup for a period of time (say one week) so you don’t make repeated requests to get the same data. I’m afraid I don’t know Perl well enough to do that, but if anyone does, please feel free to add it in. And one final note, this routine is intended for use primarily in the U.S. and Canada, but in searching for alternative reverse-lookup sites I did stumble across this page, which may be of interest to anyone in Germany (or that wants to get German caller ID information).

  18. I just upgraded to Trixbox 1.0 / with all updates and modules updates, has anybody been able to get calleridname.agi to function again…


  19. Hi Guys,
    I just submitted a module for FreePBX that let you lookup caller names against different sources (astDB, mysql, http, enum).

    Please, take a look at it, I think it will be a good starting point to eventually add the sources you were talking about and did implement in your AGI

    You can find the module here:

    Hope it helps

    Have fun ๐Ÿ˜‰

  20. webrainstorm – this is very exciting , i am going to take a good look at it, i am going to try and get names from sugercrm OS .
    well done and thanks for sharing your hard work.

  21. i have installed it and configuerd it , i aslo installed the phonebook module , pretty cool. i had a similar phonebook on my old aah2.4 system . woulb be nice to have the phone book be able to import csv. also i like the other work that people have done with reverse lookups , it would be great to bring it all together as one project , and mabay have the reverse lookups create entryies in you phonebook , sort of like a cache? but not really . the other really cool thing would be to get the sugercrm stuff working in this module.

    Intergrated freepbx modules are definatly the way forward !!

  22. Hello ddwyer, tnx for your feedback.

    Adding a way to bulk load the phonebook will be the next step of development ๐Ÿ˜‰

    SugarCRM integration also is in my next developing steps ๐Ÿ˜‰

    Also integrating with other sources, as the ones described in this page, it’s a good idea but we need first to analyze issues related to internationalization, copyright, performances (caching is a good idea ๐Ÿ˜‰ ) and website variability.

    I’ll probably open up a discussion Wiki page on freepbx.org tomorrow to get proposal and ideas about the next developing step.

    Regards ๐Ÿ˜‰

  23. Here’s a fix for the "Google Map’s" calleridname problem.

    In calleridname.agi, replace the current google_lookup function.

    [WM: Here’s a link to chandave’s reworked calleridname.agi script with our extra special thanks. We knew chandave could do it!]

    See ya…


  24. Hi, I am looking for a way to call a long distance number once a week and play a message then ask the person to respond to the message.
    anyone that can help.

  25. Have a question about comment #17 where the user changed the calleridname.agi – to work with SugarCrm.

    I have SugarCRM running on a PC separate from the Asterisk PC. What do I need to do to get the calleridname.agi to connect to the SugarCRM on the other PC?

  26. I am using a modified calleridname.agi script given by Jack in comment 18. This script includes Canadian numbers lookup. It works well, but when executed, it produces warning or error:
    asterisk1*CLI> Use of uninitialized value in concatenation (.) or string at /usr/lib/perl5/site_perl/5.8.5/Asterisk/AGI.pm line 587, line 30.
    How it can be fixed?

  27. I was able to work this example code into a script, but there are still a few numbers not popping up. I found one that works at addresses.com. Anyone want to take a stab at writing something for that service?


  28. Ward, I don’t know if you got my last comment about $AGI->verbose(). When I hit the "Say it!" button, I just get a blank screen in return.


    $AGI->verbose() requires 2 parameters: a message and a verbose logging level. Previous versions of Perl appear to overlook the fact that you didn’t include a verbose logging level when using $AGI->verbose() in your calleridname.agi. But, more recent Perl versions appear to pop up a warning about use of an uninitialized variable (in this case, the missing $level parameter). My suggestion would be to change all the $AGI->verbose("some message") to $AGI->verbose("some message",1).

    This would alleviate the warning messages plaguing Alex in comment 31 and some people on Voxilla.

    See ya…


    [WM: Thanks, as usual, Davy. I’ve updated the script using your instructions, and I’ll post a comment below just to be sure everyone gets it.]

  29. CallerIDname script update. There’s been a change in the way Perl handles uninitialized variables so we’ve updated the calleridname.agi script. Log in to your server as root and issue the following commands to get the update:

    cd /var/lib/asterisk/agi-bin
    mv calleridname.agi calleridname.agi.old
    wget http://nerdvittles.com/wp-content/calleridname.agi
    chmod +x calleridname.agi
    chown asterisk:asterisk calleridname.agi

    Special thanks to Davy Chan for the fix.

  30. I got the SugarCRM integration working based on the code in comment #17. It took me quite some time since I don’t know perl or Linux. I also don’t have the Auto-attendant setup so I had to figure out how to make it work without the instructions of this article. The code and instructions are here.


    It works great. I had to format all of my Outlook contact phone numbers into this exact format (111) 111-1111 This was a minor inconvenience considering all that I went through to get it to work.

    I had some issues with the MySQL password "root","passw0rd" I’m not sure what is up with that. But once I rebooted my VM it worked. I did not change the password. It works as is.

    Also I am multi-ringing my cell phone (TMobile) and the caller ID name is not transfered (only the number). Any clues on how to get that working?

    [WM: Telephone providers insert their own CallerID names. The incoming CallerID name info gets thrown in the bit bucket. Thanks for the tips on SugarCRM. I’ll have a look.]

  31. hi
    i want to use a mysql data base(i create it)that include information about the users and in some case i want to connect that database from asterisk 1.4 and use that information.i don’t know how i should do it that work.please help me.send the solution to my email.

    [WM: Hmmm. Send your check by mail. When it clears… anything is possible, depending upon the amount of the check.]

  32. Hi! Great idea for the asterisk lookup script. However, I just tested it and it appears that these lookups (except google) have stopped allowing this type of queries. For example, AnyWho says that this is an outdated page and gives no results. FoneFinder doesn’t even bring up a name or allow you to enter the full phone number.
    I think Google lookups are still working, if the user hasn’t blocked his number.

    Am I doing something wrong? or have you heard of new lookup sites which can be used?


    [WM: Ryan, This article is over three years old or roughly three lifetimes in VoIP years. Try this link instead.]

Comments are closed.