Monday, March 19, 2012

CallerID AGI for Asterisk: trifecta 2012.0 includes opencnam, anywho and fonefinder


I have taken the Nerd Vittles calleridname.agi script and updated it to work with currently available free online caller ID services. My changes are in public domain, what's left of original code obviously retains original copyright and whatever license terms went with it.

I have never checked if the asteridex/npanxx part of the code has any chance of working, so tread carefully.

I have implemented lookups for OpenCnam, AnyWho (YellowPages took over them) and FoneFinder. The original code was useless for the latter two, as the pages got redesigned.

This was a quick hack, I need to redo it in Python -- properly this time. I obviously have no clue about Perl and don't care enough about this code to make it any prettier, sorry.


#!/usr/bin/perl -w 

use Asterisk::AGI;
use LWP::UserAgent;
use DBI;

$AGI = new Asterisk::AGI;

$Timeout       = 2;
$OpenCnam      = '1';
$AnyWho        = '0';
$FoneFinder    = '1';
$Asteridex     = '0';
$TermOnSuccess = 1;

my %input = $AGI->ReadParse();

my $callerid     = $input{'calleridnum'};
my $calleridfull = $input{'callerid'};

if ( $callerid eq '' ) {
   $callerid = $input{'callerid'};
}

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

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

$calleridfull =~ s/[\,\"\']+/ /g;

$AGI->verbose( "CALLERID IS: $calleridfull\n", 1 );

if ( $callerid =~ /^(\d{3})(\d{3})(\d{4})$/ ) {
   $npa     = $1;
   $nxx     = $2;
   $station = $3;
   $AGI->verbose( "Checking $npa $nxx $station...\n", 1 );
}
elsif ( $callerid =~ /\<(\d{3})(\d{3})(\d{4})\>/ ) {
   $npa     = $1;
   $nxx     = $2;
   $station = $3;
   $AGI->verbose( "Checking $npa $nxx $station...\n", 1 );
}
else {
   $AGI->verbose(
"Unable to parse phone number for NPA/NXX/station. Phone number is: $callerid\n",
      1
   );
   exit(0);
}

# handle timeouts
alarm($Timeout);
$SIG{ALRM} = sub {
   $AGI->set_callerid("\"... <$npa$nxx$station>\"");
   $AGI->verbose( "Lookup timed out\n", 1 );
   exit(0);
};

#$npa='641';
#$nxx='892';
#$station='8019';

&lookup( \&opencnam_lookup,   $npa, $nxx, $station, "OpenCnam",   $OpenCnam );
&lookup( \&anywho_lookup,     $npa, $nxx, $station, "AnyWho",     $AnyWho );
&lookup( \&fonefinder_lookup, $npa, $nxx, $station, "FoneFinder", $FoneFinder );
&lookup( \&asteridex_lookup,  $npa, $nxx, $station, "AsteriDex",  $AsteriDex );
exit(0);

sub lookup {
   my ( $fun, $npa, $nxx, $station, $description, $enabled ) = @_;
   if ( !$enabled ) {
      $AGI->verbose( "$description lookup disabled.\n", 2 );
      return "";
   }
   $AGI->verbose( "Ready for $description lookup...\n", 2 );
   if ( $name = $fun->( $npa, $nxx, $station ) ) {
      $newcallerid = "\"$name <$npa$nxx$station>\"";
      $AGI->set_callerid($newcallerid);
      $AGI->verbose( "$description match. New CallerIDName = $name\n", 1 );
      if ( $TermOnSuccess > 0 ) { exit(0); }
   }
   else {
      $AGI->verbose( "Unable to find an $description match.\n", 1 );
   }
}

sub opencnam_lookup {
   my ( $npa, $nxx, $station ) = @_;
   my $ua = LWP::UserAgent->new( timeout => 45 );
   my $URL =
       'https://api.opencnam.com/v1/phone/'
     . $npa
     . $nxx
     . $station
     . '?format=text';
   my $req = new HTTP::Request GET => $URL;
   my $res = $ua->request($req);
   if ( $res->is_success() ) {
      my $cid = $res->content;
      if ( length $cid > 0 ) {

         #print $cid . "\n";
         return $cid;
      }
   }
   return "";
}

sub fonefinder_lookup {
   my ( $npa, $nxx ) = @_;
   my $ua = LWP::UserAgent->new( timeout => 45 );
   my $URL =
       'http://www.fonefinder.net/findome.php?npa='
     . $npa . '&nxx='
     . $nxx
     . '&thoublock=&usaquerytype=Search+by+Number&cityname=';
   $ua->agent(
'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)'
   );
   my $req = new HTTP::Request GET => $URL;
   my $res = $ua->request($req);
   if ( $res->is_success() ) {
      if ( $res->content =~ /areacode=(.+)H[1-9]>/ ) {
         my $listing = $1;

         #print "$listing\n\n";
         if ( $listing =~ /<A HREF='findcity.php\?cityname=([^&]+)&.+>/ ) {
            my $city = $1;

            #print "$city\n";
            if ( $listing =~
               /npamap[^>]+>([^<]+)<.+<A HREF=[^>]+>([^<]+)<\/A><TD>([^<]+)<TD>/
              )
            {
               my $state    = $1;
               my $provider = $2;
               my $type     = $3;

               #print "$state // $provider // $type\n";
               return $city . ' ' . $state . ' ' . $provider;
            }
         }
      }
   }
   return "";
}

sub anywho_lookup {
   my ( $npa, $nxx, $station ) = @_;
   my $ua = LWP::UserAgent->new( timeout => 45 );

   # lookup a person
   my $URL =
     'http://anywhoyp.yellowpages.com/reversephonelookup?fap_terms%5Bphone%5D=';
   $URL .= $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 =~ />([^<]+)<\/a>[^<]+<span/ ) {
         my $name = $1;

         #print $name . "\n";
         return $name;

      }
   }

   # lookup a business
   $URL = 'http://anywhoyp.yellowpages.com/phone/?phone_search_terms=';
   $URL .= $npa . $nxx . $station;
   $req = new HTTP::Request GET => $URL;
   $res = $ua->request($req);
   if ( $res->is_success() ) {
      if ( $res->content =~
         /<h3 class="business-name[^<]+<a href=[^>]+>([^<]+)</ )
      {
         my $name = $1;

         #print $name . "\n";
         return $name;
      }
   }

   return "";
}

sub asteridex_lookup {
   my ( $npa, $nxx, $station ) = @_;
   my $dbh = DBI->connect( "dbi:mysql:asteridex", "root", "passw0rd" )
     or die("Connect failed");
   my $sth = $dbh->prepare("select * from user1 where out = '$npa$nxx$station'")
     or die("Prepare failed.");
   $sth->execute;
   if ( $sth->rows == 0 ) {
      return "";
   }
   else {
      my $resptr   = $sth->fetchrow_hashref();
      my $clidname = $resptr->{"name"};
      return $clidname;
   }

   $dbh->disconnect;
   return "";
}

sub npanxx_lookup {
   my ( $npa, $nxx ) = @_;
   my $dbh = DBI->connect( "dbi:mysql:phone", "root", "passw0rd" )
     or die("Connect failed");
   my $lookup = $npa . "-" . $nxx;

   #print $lookup ;
   my $sth = $dbh->prepare("select * from npanxx where npanxx = '$lookup'")
     or die("Prepare failed.");
   $sth->execute;

   #print $sth->rows ;
   if ( $sth->rows == 0 ) {
      return "";
   }
   else {
      my $resptr     = $sth->fetchrow_hashref();
      my $ratecenter = $resptr->{"ratecenter"};
      my $state      = $resptr->{"state"};
      my $company    = $resptr->{"company"};
      $company = substr( $company, 0, -1 );
      $company = substr( $company, 1, 9 );
      my $clidname =
        substr( $ratecenter, 0, 3 ) . "-" . $state . "-" . $company;
      return $clidname;
   }

   $dbh->disconnect;
   return "";
}

No comments:

Post a Comment