Long ago, in a world much different from today, one could check 411.com, anywho, and even google for Caller ID names. Those days are gone my friends. It’s slowly becoming a pay to play world…

I just played with a solution from OpenCNAM that was pretty freaking simple. There’s a negativeit ain’t free. The cost is nominal… $0.004/lookup. That means that $10 will get you 2500 lookups.

Before you get all crazy on me — yes, there is a free “hobbyist” version. I think it’s worthless, since all the cellphones I tried returned the cidnam value of “currently unavailable for Hobbyist Tier users.”

I digress.

I chose Perl to integrate opencnam into my Asterisk dialplan. Why? Because I like Perl. Yes, I’ve heard of Python, and Lua, and Ruby, and when it comes down to it… I like Perl.

Here’s how I chose to integrate the lookup:

Asterisk Dialplan

exten => _X.,1,Verbose(3,Look an incoming call. Yay.)
exten => _X.,n,AGI(get-opencnam.pl,${CALLERID(num):-10})
exten => _X.,n,Verbose(3,result: ${OPENCNAM})

get-opencnam.pl

#!/usr/bin/perl -w
use strict;
$|=1;
my ($phone, $url, $apikey, $authkey, $result);

while(<STDIN>) {
    chomp;
    last unless length($_);
}

if ($ARGV[0]) {
    $phone = &URLEncode($ARGV[0]);
} else {
    &setvar("OPENCNAM", "No Phone");
    &setvar("CALLERID(name)", "Unknown");
    &printverbose("OPENCNAM: No CALLFROM received.",2);
    exit(0);
}

#Get the cid
$apikey = "APIKEY";
$authkey = "AUTHKEY";
$url = "api.opencnam.com/v2/phone/";

$result = qx(curl -m 2 -s https://$apikey:$authkey@$url+1$phone?format=text);

#or free version would be...

#$result = qx(curl -m 2 -s https://api.opencnam.com/v2/phone/+1$phone);

if ($result) {
    &setvar("OPENCNAM", "$result");
    &setvar("CALLERID(name)", "$result");
    &printverbose("OPENCNAM: $result.",2);
} else {
    &setvar("OPENCNAM", "FAIL");
    &setvar("CALLERID(name)", "Unknown");
    &printverbose("OPENCNAM: Timeout or error",2);
}

sub URLEncode {
   my $theURL = $_[0];
   $theURL =~ s/([W])/"%" . uc(sprintf("%2.2x",ord($1)))/eg;
   return $theURL;
}

sub setvar {
    my ($var, $val) = @_;
    print STDOUT "SET VARIABLE $var "$val" n";
    while(<STDIN>) {
        m/200 result=1/ && last;
    }
    return;
}

sub printverbose {
    my ($var, $val) = @_;
    print STDOUT "VERBOSE "$var" $valn";
    while(<STDIN>) {
        m/200 result=1/ && last;
    }
    return;
}

The beauty is you can choose when to run this… considerations (for you to save money) would be:

  • If cnam already exists, skip the check.
  • Run a local check first… for example, using a local phonebook or db lookup
  • Only running calls from the PSTN
  • etc.

Happy coding.