<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>TEAM FORREST Blog &#187; AGI</title>
	<atom:link href="http://www.teamforrest.com/blog/tag/agi/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.teamforrest.com/blog</link>
	<description>Asterisk, VoIP, and IT Consulting</description>
	<lastBuildDate>Thu, 27 May 2010 19:07:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Parking Availability, Team Forrest, and Asterisk</title>
		<link>http://www.teamforrest.com/blog/98/parking-availability-team-forrest-and-asterisk/</link>
		<comments>http://www.teamforrest.com/blog/98/parking-availability-team-forrest-and-asterisk/#comments</comments>
		<pubDate>Sun, 11 Jan 2009 16:45:29 +0000</pubDate>
		<dc:creator>Team Forrest</dc:creator>
				<category><![CDATA[VoIP]]></category>
		<category><![CDATA[AGI]]></category>
		<category><![CDATA[ann arbor]]></category>
		<category><![CDATA[asterisk]]></category>
		<category><![CDATA[government]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[news]]></category>
		<category><![CDATA[parking]]></category>
		<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://www.teamforrest.com/?p=98</guid>
		<description><![CDATA[Recently, Fred Posner of Team Forrest, assisted Edward Vielmetti with a simple idea — help make information accessible. In this case, the information was the availability of Parking Spots in Ann Arbor, Michigan. The Ann Arbor Downtown Development Authority (A2DDA) publishes data regarding parking spot availability on the web, however, when you’re driving to the [...]]]></description>
			<content:encoded><![CDATA[<p><img class="size-full wp-image-100 alignright" title="ann-arbor-parking-project" src="http://www.teamforrest.com/blog/wp-content/uploads/2009/01/ann-arbor-parking-project.jpg" alt="Ann Arbor Parking" /></p>
<p>Recently, Fred Posner of Team Forrest, assisted <a href="http://vielmetti.typepad.com/">Edward Vielmetti</a> with a simple idea — help make information accessible. In this case, the information was the availability of Parking Spots in Ann Arbor, Michigan.</p>
<p>The <a href="http://www.a2dda.org/">Ann Arbor Downtown Development Authority</a> (A2DDA) publishes data regarding parking spot availability on the web, however, when you’re driving to the garage navigating to a web site is the least of your worries. So, an idea was born to make parking information readily accessible — and with that, Team Forrest’s Fred Posner built a quick prototype to demonstrate how <a href="http://www.asterisk.org">Asterisk</a> (by <a href="http://www.digium.com">Digium</a>) can help rethink how data can be accessed.</p>
<p>In the prototype, a caller can select which garage to query. The system will then speak to the caller the remaining number of spaces and offer 3 options — select another garage, exit (and hear the local weather), or choose to be notified if there are fewer than 10 spaces remaining. If the caller selects the notification option, the system will automatically check once a minute (for 30 minutes) and initiate a call out to the user. The call will remind the user which garage they selected and inform them of the current number of available spaces.</p>
<p>The prototype for this project can be accessed from the Team Forrest main line, at <strong>+1 (212) 937-7844</strong>. Then, choose <strong>6</strong> for check local Ann Arbor Parking availability.</p>
<h3>About Team Forrest</h3>
<p>Team Forrest offers complete Internet Consulting services, specializing in VoIP and Asterisk solutions. Team Forrest has one simple goal: Help the client. Whether you need emergency assistance or if you are planning a deployment, Team Forrest is here to help. With over 15 years experience, our team can quickly assess your needs and help deploy the most appropriate solution.</p>
<h3>About Asterisk</h3>
<p><a href="http://www.asterisk.org">Asterisk</a> (by <a href="http://www.digium.com">Digium</a>) is the world’s leading open source telephony engine and tool kit. Asterisk empowers communication with it’s flexibility. Asterisk is released as open source under the <a href="http://www.gnu.org">GNU</a> General Public License (GPL), and it is available for download free of charge. Asterisk is the most popular open source software available, with the Asterisk Community being the top influencer in VoIP.</p>
<h4>Related Information:</h4>
<ul>
<li>Fred&#8217;s post on VoIP Tech Chat, &#8220;<a href="http://www.voiptechchat.com/voip/218/use-asterisk-cepstral-and-perl-to-get-parking-and-weather-updates/">Using Asterisk, Cepstral, and Perl to get Parking and Weather</a>.&#8221;</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.teamforrest.com/blog/98/parking-availability-team-forrest-and-asterisk/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using AGI to get Caller ID Name CNAM</title>
		<link>http://www.teamforrest.com/blog/89/using-agi-to-get-caller-id-name-cnam/</link>
		<comments>http://www.teamforrest.com/blog/89/using-agi-to-get-caller-id-name-cnam/#comments</comments>
		<pubDate>Mon, 05 Jan 2009 19:13:53 +0000</pubDate>
		<dc:creator>Team Forrest</dc:creator>
				<category><![CDATA[VoIP]]></category>
		<category><![CDATA[AGI]]></category>
		<category><![CDATA[asterisk]]></category>
		<category><![CDATA[CNAM]]></category>
		<category><![CDATA[communication]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[SIP]]></category>

		<guid isPermaLink="false">http://www.teamforrest.com/?p=89</guid>
		<description><![CDATA[Everyone has them — and here&#8217;s Team Forrest&#8217;s version of a Caller ID to Name (CNAM, CIDNAME, etc.) lookup using AnyWho, Google, and 411.com. The first file is the calleridname.pl: UPDATE April 4, 2009 — Frank (user comment) let us know that AnyWho had changed their website. As a result the code has been updated. [...]]]></description>
			<content:encoded><![CDATA[<p>Everyone has them — and here&#8217;s Team Forrest&#8217;s version of a Caller ID to Name (CNAM, CIDNAME, etc.) lookup using AnyWho, Google, and 411.com. The first file is the <a title="Download CallerIDName.zip" href="http://www.teamforrest.com/tf-downloads/calleridname.zip">calleridname.pl</a>: <span id="more-89"></span></p>
<p class="alert"><strong>UPDATE April 4, 2009 —</strong> Frank (user comment) let us know that AnyWho had changed their website. As a result the code has been updated. Thanks Frank!</p>
<p class="alert"><strong>UPDATE November 18, 2009 —</strong> Robert (user comment) let us know of another change. As a result the code has been updated. Thanks Robert!</p>
<pre>#!/usr/bin/perl -w
use strict;
use LWP::UserAgent;
$|=1;

my ($cidnum,$cidname,$npa,$nxx,$station,$name);

#----------------------------------------------------------------
# get asterisk initial info
#----------------------------------------------------------------

while(&lt;STDIN&gt;) {
	chomp;
	last unless length($_);
}

#----------------------------------------------------------------
# check if we have a caller id
#----------------------------------------------------------------

if ($ARGV[0]) {
		$cidnum = $ARGV[0];
	} else {
		print qq(VERBOSE &quot;ERROR: no callerid provided&quot; 2\n);
		exit(0);
}

#----------------------------------------------------------------
# check caller id and split into npa, nxx, and station
#----------------------------------------------------------------

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 =~/\&lt;(\d{3})(\d{3})(\d{4})\&gt;/) {
		$npa = $1;
		$nxx = $2;
		$station = $3;
	} else {
		print qq(VERBOSE &quot;ERROR: unable to parse caller id&quot; 2\n);
		exit(0);
}

print qq(VERBOSE &quot;STATUS: CID is $npa-$nxx-$station&quot; 2\n);

#----------------------------------------------------------------
# check npa, nxx, and station for cid name
# 1 = check. 0 = skip.
#----------------------------------------------------------------

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

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

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

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

#----------------------------------------------------------------
# return results and exit
#----------------------------------------------------------------

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

#----------------------------------------------------------------
# parse anywho
# http://whitepages.anywho.com/results.php?qnpa=$npa&amp;qnpanxx=$npa$nxx&amp;qnxx=$nxx&amp;qp=$nxx$station&amp;qstation=$station
# Find More Information for First Last&lt;/a&gt;
#----------------------------------------------------------------

sub anywho_lookup {
	my ($npa, $nxx, $station) = @_;
	my $ua = LWP::UserAgent-&gt;new( timeout =&gt; 45);
	my $URL = 'http://whitepages.anywho.com/results.php';
	$URL .= qq(?qnpa=$npa&amp;qnpanxx=$npa$nxx&amp;qnxx=$nxx&amp;qp=$nxx$station&amp;qstation=$station);
	$ua-&gt;agent('AsteriskAGIQuery/1');
	my $req = new HTTP::Request GET =&gt; $URL;
	my $res = $ua-&gt;request($req);
	if ($res-&gt;is_success()) {
		if ($res-&gt;content =~ /Find More Information for (.*)&lt;\/a&gt;/) {
			my $clidname = $1;
			return $clidname;
		}
	}
	return &quot;&quot;;
}

#----------------------------------------------------------------
# parse google
# http://www.google.com/search?rls=en&amp;q=phonebook:$npa$nxx$station
# &lt;td&gt;First Name&lt;td&gt;(&lt;b&gt;$npa
#----------------------------------------------------------------

sub google_lookup {
	my ($npa, $nxx, $station) = @_;
	my $ua = LWP::UserAgent-&gt;new( timeout =&gt; 45);
	my $URL = qq(http://www.google.com/search?rls=en&amp;q=phonebook:$npa$nxx$station&amp;ie=UTF-8&amp;oe=UTF-8);
	$ua-&gt;agent('AsteriskAGIQuery/1');
	my $req = new HTTP::Request GET =&gt; $URL;
	my $res = $ua-&gt;request($req);
	if ($res-&gt;is_success()) {
		if ($res-&gt;content =~ /&lt;td&gt;(.+)&lt;td&gt;\(&lt;b&gt;$npa/) {
			my $clidname = $1;
			return $clidname;
		}
	}
	return &quot;&quot;;
}

#----------------------------------------------------------------
# parse 411
# http://www.411.com/search/Reverse_Phone?phone=$npa$nxx$station
# View map, driving directions, and more&quot;&gt;Name&lt;/a&gt;
#----------------------------------------------------------------

sub www411_lookup {
	my ($npa, $nxx, $station) = @_;
	my $ua = LWP::UserAgent-&gt;new( timeout =&gt; 45);
	my $URL = qq(http://www.411.com/search/Reverse_Phone?phone=$npa$nxx$station);
	$ua-&gt;agent('AsteriskAGIQuery/1');
	my $req = new HTTP::Request GET =&gt; $URL;
	my $res = $ua-&gt;request($req);
	if ($res-&gt;is_success()) {
		if ($res-&gt;content =~ /View map, driving directions, and more\&quot;&gt;(.*)&lt;\/a&gt;/) {
			my $clidname = $1;
			if ($clidname eq &quot;Listing Detail&quot;) {
				if ($res-&gt;content =~ /Type: &lt;strong&gt;(.*)&lt;\/strong&gt;/) {
					$clidname = $1;
					if ($res-&gt;content =~ /Location: &lt;strong&gt;(.*)&lt;\/strong&gt;/) {
						$clidname = $clidname . &quot; $1&quot;;
					}
				}
			}
			return $clidname;
		}
	}
	return &quot;&quot;;
}
</pre>
<p>This perl script will work well as an AGI script — checking AnyWho, Google, and then 411 for a caller&#8217;s name or location. If all else fails, the callerid name is set as the callerid number.</p>
<p>The perl script was designed to only use the Internet with minimal installation; so it will work without a database, Perl Asterisk module, or locally hosted NPA / NXX (phone number to region) file.</p>
<p>Team Forrest recommends using a subroutine context to get the callerid when needed; calling the script with either a <strong>GoSub</strong> or <strong>GosubIf</strong> command, such as:</p>
<pre>exten =&gt; s,n,Gosub(cidname-lookup,s,1)
exten =&gt; s,n,dial(${PHONE},30,t)
...

...
[cidname-lookup]
exten =&gt; s,1,NoOp(looking up callerid name)
exten =&gt; s,n,GotoIf($["foo${CALLERID(NAME)}" = "foo" ]?getname)
exten =&gt; s,n,GotoIf($["${CALLERID(NAME)}" = "${CALLERID(NUM)}" ]?getname)
exten =&gt; s,n,NoOp(caller id name exists as ${CALLERID(NAME)})
exten =&gt; s,n,Return
exten =&gt; s,n(getname),AGI(calleridname.pl,${CALLERID(NUM)})
exten =&gt; s,n,NoOp(Caller ID Name is now ${CALLERID(NAME)})
exten =&gt; s,n,Return</pre>
<p>Enjoy the file (<a title="Download the script" href="http://www.teamforrest.com/tf-downloads/calleridname.zip">download here</a>) and remember, Team Forrest is here to assist you will all of your Asterisk, VoIP, or technical needs.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.teamforrest.com/blog/89/using-agi-to-get-caller-id-name-cnam/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
	</channel>
</rss>
