CNAM (CallerID with Name) on Asterisk using Reverse Phone number lookup

CallerID is cool, but CallerID with Name (CNAM), -- also known as Calling NAMe -- is where it's at. When you go with a traditional phone provider (non-VoIP) they'll often offer you CallerID with Name for an additional fee. But penny-pinching Asterisk & VoIP fans want CallerID with Name too. Unfortunately, too often the SIP trunks or traditional PSTN trunks (analog, T1/E1) connected to your Asterisk IP-PBX don't provide CallerID with Name - just regular CallerID (number only). So how do we solve this dilemma?

Well, Asterisk sits on an IP network, which of course means it can access the Internet. With access to the Internet, "in theory" a special Asterisk script can take the CallerID number, perform a reverse lookup on AnyWho, Google, and 411.com and then change the CallerID data string before it gets passed to the Asterisk extension.

Well, theory is all well and good, but has it been done? Oh yes it has!

Check out this Perl script I found on Team Forrest's website that leverages AGI (Asterisk Gateway Interface), a powerful interface that lets your programmatically control Asterisk.

Calling the CallerID with Name Perl script (calleridname.pl) is as simple as calling this single line of code:
exten => s,n(getname),AGI(calleridname.pl,${CALLERID(NUM)})

Here's the calleridname.pl script:
#!/usr/bin/perl -w
use strict;
use LWP::UserAgent;
$|=1;
sub trim($);

my %AGI; my $tests = 0; my $fail = 0; my $pass = 0; my $result = ""; my $cidnum = ""; my $cidname = "";
my $npa = ""; my $nxx = ""; my $station = ""; my $name = "";

$cidnum = $ARGV[0];

while(<STDIN>) {
    chomp;
    last unless length($_);
    if (/^agi_(\w+)\:\s+(.*)$/) {
        $AGI{$1} = $2;
    }
}

my $AnyWho = '1' ;
my $Google = '1' ;
my $www411 = '1' ;


if(substr($cidnum,0,1) eq '1'){
$cidnum=substr($cidnum,1);
}

if(substr($cidnum,0,2) eq '+1'){
$cidnum=substr($cidnum,2);
}

if ($cidnum =~ /^(\d{3})(\d{3})(\d{4})$/) {
    $npa = $1;
    $nxx = $2;
    $station = $3;
    }
elsif($cidnum =~/\<(\d{3})(\d{3})(\d{4})\>/){
    $npa = $1;
    $nxx = $2;
    $station = $3;
    }
else {
    print qq(VERBOSE "ERROR: unable to parse caller id" 2\n);
    exit(0);
}


if ($AnyWho > '0') {
    print qq(VERBOSE "STATUS: checking AnyWho for name lookup" 2\n);
    if ($name = &anywho_lookup ($npa, $nxx, $station)) {
        $cidname = $name;
        print qq(SET VARIABLE CALLERID\(name\) "$cidname"\n);
        print qq(VERBOSE "STATUS: AnyWho said name was $cidname " 2\n);
        exit(0);
        }
    else {
        print qq(VERBOSE "STATUS: unable to find name with AnyWho" 2\n);
        }
    }
else {
    print qq(VERBOSE "STATUS: AnyWho lookup disabled" 2\n);
}

if ($Google > '0') {
    print qq(VERBOSE "STATUS: checking Google for name lookup" 2\n);
    if ($name = &google_lookup ($npa, $nxx, $station)) {
        $cidname = $name;
        print qq(SET VARIABLE CALLERID\(name\) "$cidname"\n);
        print qq(VERBOSE "STATUS: Google said name was $cidname " 2\n);
        exit(0);
        }
    else {
        print qq(VERBOSE "STATUS: unable to find name with Google" 2\n);
        }
    }
else {
    print qq(VERBOSE "STATUS: Google lookup disabled" 2\n);
}

if ($www411 > '0') {
    print qq(VERBOSE "STATUS: checking www411 for name lookup" 2\n);
    if ($name = &www411_lookup ($npa, $nxx, $station)) {
        $cidname = $name;
        print qq(SET VARIABLE CALLERID\(name\) "$cidname"\n);
        print qq(VERBOSE "STATUS: www411 said name was $cidname " 2\n);
        exit(0);
        }
    else {
        print qq(VERBOSE "STATUS: unable to find name with www411" 2\n);
        }
    }
else {
    print qq(VERBOSE "STATUS: www411 lookup disabled" 2\n);
}

print qq(SET VARIABLE CALLERID\(name\) "$cidnum"\n);
print qq(VERBOSE "STATUS: Unknown name for $cidnum " 2\n);
exit(0);

sub anywho_lookup {
    my ($npa, $nxx, $station) = @_;
    my $ua = LWP::UserAgent->new( timeout => 45);
    my $URL = 'http://www.anywho.com/qry/wp_rl';
    $URL .= '?npa=' . $npa . '&telephone=' . $nxx . $station;
    $ua->agent('AsteriskAGIQuery/1');
    my $req = new HTTP::Request GET => $URL;
    my $res = $ua->request($req);
    if ($res->is_success()) {
        if ($res->content =~ /<!-- listing -->(.*)<!-- \/listing -->/s) {
            my $listing = $1;
            if ($listing =~ /<B>(.*)<\/B>/) {
                my $clidname = $1;
                return $clidname;
            }
        }
    }
    return "";
}

sub google_lookup {
  my ($npa, $nxx, $station) = @_;
  my $ua = LWP::UserAgent->new( timeout => 45);
  my $URL = 'http://www.google.com/search?rls=en&q=phonebook:' .  $npa . $nxx . $station . '&ie=UTF-8&oe=UTF-8';
  $ua->agent('AsteriskAGIQuery/1');
  my $req = new HTTP::Request GET => $URL;
  my $res = $ua->request($req);
  if ($res->is_success()) {
    if ($res->content =~ /<font size=-2><br><\/font><font size=-1>(.+)<font color=green>/) {
      my $temp = $1;
      my $clidname = "";
      if ( $temp =~ /(.+)<font color=green>/o ) {
        $clidname = substr($1, 0, -3);
      } else {
        $clidname = substr($temp, 0, -3);
      }
      if ($clidname =~ /<a href(.+)\//) {
        $clidname = $1 ;
        if ($clidname =~ />(.+)</) {
          $clidname = $1 ;
        }
      }
      return $clidname;
    }
  }
  return "";
}

sub www411_lookup {
  my ($npa, $nxx, $station) = @_;
  my $ua = LWP::UserAgent->new( timeout => 45);
  my $URL = 'http://www.411.com/search/Reverse_Phone?phone=' .  $npa . $nxx . $station;
  $ua->agent('AsteriskAGIQuery/1');
  my $req = new HTTP::Request GET => $URL;
  my $res = $ua->request($req);
  if ($res->is_success()) {
    if ($res->content =~ /Location: <strong>(.*)<\/strong>/s) {
      my $temp = $1;
      my $clidname = "";
      $temp =~ s/&amp\;/&/g;
      $temp =~ s/%20/ /g;
                        $clidname = $temp;
            return $clidname;
     }
  }
  return "";
}


For more details, head on over here.
| 4 Comments | 0 TrackBacks

Listed below are links to sites that reference CNAM (CallerID with Name) on Asterisk using Reverse Phone number lookup:

CNAM (CallerID with Name) on Asterisk using Reverse Phone number lookup TrackBack URL : http://blog.tmcnet.com/mt/mt-tb.cgi/38690

4 Comments

Great code and it looks so familiar. Attribution is a wonderful thing. If you use someone else's term paper, at least give them credit. And this isn't directed toward you, Tom!

In fact, this code includes numerous chunks of code that several Nerd Vittles' contributors wrote several years ago coupled with more recent PERL code from Titanous. For some more current and more flexible CallerID solutions, here are some links:

http://bestof.nerdvittles.com/applications/callerid/

http://pbxinaflash.com/forum/showthread.php?t=65

http://pbxinaflash.com/forum/showthread.php?t=2919

What's ironic is that I thought this code might have existed elsewhere. Performing reverse number lookup is such an obvious thing to do on Asterisk. So I googled "asterisk callerid" and your site came up on Page 1.

callerid+Asterisk Google Search

Your 'Asterisk CallerID on Steroids: Here’s How' article came up. I checked it out, but it had nothing to do with reverse number lookup. Tried a few other searches but came up empty. Though I didn't try googling pieces of the source code. Maybe would have had a 'hit' that way.

I definitely want to give proper attribution and credit, so thanks Ward for providing some insight to who created this code, as well as links to more info.

.., I cant understand your codes, though i agree that the usage of CNAM is really helpful..

I appreciate the links regarding the flexible caller ID solutions.

Leave a comment

Recent Activity

Today

  • Tom Keating queued The Blind Side

Sunday

Sunday

  • Tom Keating tweeted, "Moving a Data Center: Moving a data center can be fun. Yes, if you enjoy being up from 6am (Friday) to 2am (Satur... http://bit.ly/cX6L0j"
  • Tom Keating posted Moving a Data Center

Friday

  • Tom Keating tweeted, "Tearing down TMC's entire network infrastructure. My sweet beautiful network! [sniff] [sniff]"

Thursday

  • Tom Keating tweeted, "why the heck am I still awake when I have an all-nighter tomorrow moving the entire #TMCNet data center? (www.tmcnet.com) fun fun!"
  • Tom Keating tweeted, "No, Gremlins Didn't Eat TMCNet's Web Servers: Starting tomorrow around 7am, TMC will be shutting down its entire d... http://bit.ly/bS3OOn"

More...

Recent Comments

  • Peter Radizeski: I'm not certain that is accurate. The staff for VON read more
  • טכנאי מחשבים: Fast, organized, thorough, non-intrusive, and free! THANKS AVG. read more
  • SomeGuy: I've had sipgate setup for less than 24 hours on read more
  • Uverse instaler: Being a uverse installer in the StL area, I can read more
  • Roger: Dan did you find out what the music is?? I read more
  • VoIP Spear: I don't think this site is active anymore. You can read more
  • Mamrez: Hi guys , I'm looking for cracked MOBILELOG for iphone read more
  • Symplicity: Works amazing thanks :) read more
  • wirefly customer: I got my phone from wirefly and it turned out read more
  • Maher: Dear Sir, I am looking for a slim credit card read more

Subscribe to Blog

Recent Entry Images

  • apple-ipad.jpg
  • google-nexus-one.jpg
  • freetalk-connect.jpg
  • freetalk-connect.jpg
  • calliflower-skype.jpg
  • itexpo-logo.jpg

Entry Archives

Around TMCnet Blogs

  • Communications and Technology Blog - Tehrani.com:
    Apple Antitrust Issues
  • On Rad's Radar?:
    Endstream Plans
  • VoIP & Gadgets Blog:
    Moving a Data Center
  • Communications and Technology Blog - Tehrani.com:
    IfByPhone Interview ITEXPO East 2010 Miami
  • First Coffee:
    Frost & Sullivan Webcast, LCEC and ENERGYprism, IDC for
  • On Rad's Radar?:
    Freeside's new CEO
  • The Readerboard:
    Tune In, Call in (And Donate), 'Hope for Haiti
  • VoIP & Gadgets Blog:
    No, Gremlins Didn't Eat TMCNet's Web Servers
  • Latest Whitepapers

    TMCnet Videos