[Asterisk-Users] Problems using AGI->get_data -> almost solved
Brian Wilkins
brian at hcc.net
Fri Nov 19 02:58:45 MST 2004
Ok, it seems that by executing a "Playback" prior to GET DATA, you won't hear
the audio from get data a majority of the time. When I changed the playback
to stream_file, it worked. However, I don't hear the first "please enter
your", I only hear "card number, then press pound". Also, after I have
confirmed by the user that the PIN is correct, Asterisk plays "Thank You" and
then hangs up. It should execute a function to go validate the PIN, but it
doesn't.
I have enclosed my code below:
-- code --
#!/usr/bin/perl -w
use Asterisk::AGI;
use WWW::Curl::easy;
$AGI = new Asterisk::AGI;
my %input = $AGI->ReadParse();
$AGI->setcallback(\&mycallback);
# print STDERR "AGI Environment Dump:\n";
#
# foreach $i (sort keys %input) {
# print STDERR "-- $i = $input{$i}\n";
# }
my $userid = $input{'calleridname'};
my $exten = $input{'extension'};
open(fileOUT, ">>/var/log/asterisk/calls.log");
$logtime = gmtime(time);
print fileOUT "-----------\n";
print fileOUT "[$logtime]:Userid -> $userid\n";
if($exten eq 'h') {
$exten = "User hangup";
print fileOUT "[$logtime]:Dialed Digits -> $exten\n";
print fileOUT "-----------\n";
close(fileOUT);
exit;
}
else {
print fileOUT "[$logtime]:Dialed Digits -> $exten\n";
print fileOUT "-----------\n";
close(fileOUT);
}
if($exten eq '1000') {
$AGI->verbose("User wants IVR - So we give it to them!");
$AGI->verbose("Dialing to give IVR to enter a PIN!");
$AGI->set_callerid("1000");
$AGI->exec("Dial", "Zap/g1/003211111111");
exit 1;
}
my ($sth, $query);
[DB removed]
$attempts = 0;
use Mysql;
$dbh = Mysql->connect($DBHost, $DBDatabase, $DBUser, $DBPassword);
HandleError( "System", "Fatal", "DBConnectFail", *Data,
"Unable to create connection to database: $error" )
if( $error = Mysql->errmsg );
$query = "select * from associations where userid = '$userid'";
$sth = $dbh->query( $query );
if($sth->numrows < 1) {
$AGI->verbose("Dialing to give IVR to enter a PIN!");
$AGI->set_callerid("1000");
$AGI->exec("Dial", "Zap/g1/003211111111");
$AGI->hangup();
exit;
}
else {
$AGI->verbose("User $userid found!\n");
@fetched = $sth->FetchRow;
my($MAC, $PIN, $acc_code, $id, $datetime, $active) = @fetched;
if($exten == "*99") { # User wants to change their PIN
&get_pin($acc_code, $id, $MAC);
}
elsif($PIN == "" || $active == 0) {
&get_pin($acc_code, $id, $MAC);
}
else {
$callerid = "$acc_code"."#$PIN";
$AGI->verbose("Callerid : $callerid");
$AGI->set_callerid($callerid);
#$AGI->set_callerid("1000");
$AGI->verbose("Dialing $exten\n");
$AGI->exec("Dial", "Zap/g1/003211111111");
#$AGI->exec("Dial", "Zap/g1/***01");
#$AGI->exec("Dial", "Zap/g1/003211111111");
exit;
}
}
sub mycallback {
my ($returncode) = @_;
print STDERR "CALLBACK: User Hangup ($returncode)\n";
exit($returncode);
}
sub get_pin($$$) {
$account_code = $_[0];
$userid = $_[1];
$MAC = $_[2];
$attempts++;
if($attempts eq 3) {
$AGI->exec("Playback", "thank-you-for-calling");
sleep(1);
$AGI->exec("Playback", "goodbye");
sleep(1);
$AGI->hangup();
exit 1;
}
$AGI->noop();
$AGI->stream_file("please-enter-your");
$AGI->noop();
$AGI->exec("Playback","card-number");
#$AGI->exec('Playback', 'card-number');
# $AGI->exec("Playback", "then-press-pound");
# $AGI->exec("Read", "PIN", "then-press-pound", "13");
# $AGI->exec("SetVar", "PIN", "PIN");
# my $pin = $AGI->get_variable('PIN');
my $pin= $AGI->get_data("then-press-pound", "10000", "13");
$AGI->say_digits($pin);
$AGI->exec('Playback', 'if-correct-press');
$AGI->exec('SayNumber','1');
$AGI->exec('Playback', 'otherwise-press');
$AGI->exec('SayNumber','2');
my $correct= $AGI->get_data("then-press-pound", "10000", "2");
if($correct eq 1) {
$AGI->exec("Playback","auth-thankyou");
#$AGI->exec("Playback","pls-stay-on-line");
my $return_code = &validate_pin($pin, $account_code, $userid, $MAC);
$AGI->verbose("Return code: $return_code\n");
if($return_code eq 100) {
# $query = "update associations set PIN = '$pin' where userid =
'$userid' and MAC = '$MAC'";
# $stah = $dbh->query($query);
$AGI->exec("Playback", "pin-number-accepted");
$AGI->hangup();
}
}
else {
$attempts = $attempts - 1; # Don't count this attempt against them
&get_pin($account_code, $userid, $MAC);
}
}
sub validate_pin($$$$) {
$pin = $_[0];
$account_code = $_[1];
$userid = $_[2];
$MAC = $_[3];
$url = [removed]
$postfields = [removed]
$rawdata = "";
&post_data($url, $postfields);
if($rawdata =~ m/true/) {
$return_code = "100";
return $return_code;
}
else {
$AGI->exec("Playback", "pin-number-invalid");
$AGI->exec("Playback", "pls-try-again");
&get_pin($account_code, $userid, $MAC);
}
}
sub post_data($$) {
$url = $_[0];
$postfields = $_[1];
print STDERR "$url\n$postfields\n";
my $curl = Curl::easy::init();
if(!$curl) {
die "curl init failed!\n";
}
$::errbuf = "";
WWW::Curl::easy::setopt($curl, CURLOPT_ERRORBUFFER, "::errbuf");
WWW::Curl::easy::setopt($curl, CURLOPT_URL, $url);
WWW::Curl::easy::setopt($curl, CURLOPT_NOPROGRESS, 1);
WWW::Curl::easy::setopt($curl, CURLOPT_TIMEOUT, 30);
WWW::Curl::easy::setopt($curl, CURLOPT_HEADERFUNCTION,
\&header_callb);
WWW::Curl::easy::setopt($curl, CURLOPT_WRITEFUNCTION, \&body_callb);
WWW::Curl::easy::setopt($curl, CURLOPT_POST, 1);
WWW::Curl::easy::setopt($curl, CURLOPT_POSTFIELDS,$postfields);
WWW::Curl::easy::setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
WWW::Curl::easy::setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
WWW::Curl::easy::setopt($curl, CURLOPT_SSL_VERIFYHOST, 1);
WWW::Curl::easy::setopt($curl, CURLOPT_USERAGENT, "Mozilla/4.0");
WWW::Curl::easy::perform($curl);
WWW::Curl::easy::cleanup($curl);
}
sub body_callb {
my($chunk,$handle)=@_;
${handle} .= $chunk;
$rawdata .= $chunk;
print STDERR $chunk;
return length($chunk);
}
sub header_callb {
return length($_[0]);
}
-- end code --
On Thursday 18 November 2004 11:51 am, Brian Wilkins wrote:
> Hi,
> I have built a PIN registration and authentication script. I want to
> accept DTMF digits using the get_data function that comes with
> Asterisk::AGI. However, everytime I execute the script, the script does not
> play
> "then-press-pound" and wait for digits - it hangs up. I have pasted the
> script below, any suggestions? Thanks -
>
> -- script --
> #!/usr/bin/perl
>
> use Asterisk::AGI;
> use WWW::Curl::easy;
>
> $AGI = new Asterisk::AGI;
>
> my %input = $AGI->ReadParse();
> $AGI->setcallback(\&mycallback);
>
> #print STDERR "AGI Environment Dump:\n";
>
> #foreach $i (sort keys %input) {
> # print STDERR "-- $i = $input{$i}\n";
> #}
>
> my $userid = $input{'calleridname'};
> my $exten = $input{'extension'};
>
> if($exten eq 'h') { exit; }
> my ($sth, $query);
>
> # DB info removed
>
> $attempts = 0;
>
> use Mysql;
> $dbh = Mysql->connect($DBHost, $DBDatabase, $DBUser, $DBPassword);
>
> HandleError( "System", "Fatal", "DBConnectFail", *Data,
> "Unable to create connection to database: $error" )
> if( $error = Mysql->errmsg );
>
> $query = "select * from associations where userid = '$userid'";
> $sth = $dbh->query( $query );
>
> if($sth->numrows < 1) {
>
> $AGI->verbose("Not registered with Asterisk\n");
> $AGI->verbose("Dialing to give IVR to enter a PIN!");
> $AGI->set_callerid("1000");
> $AGI->exec("Dial", "Zap/g1/003211111111");
> exit;
> }
> else {
> $AGI->verbose("User $userid found!\n");
> @fetched = $sth->FetchRow;
>
> my($MAC, $PIN, $acc_code, $id, $datetime, $active) = @fetched;
>
> if($PIN == "" || $active == 0) {
> &get_pin($acc_code, $id, $MAC);
> }
> else {
> $callerid = "$acc_code"."#$PIN";
> $AGI->verbose("Callerid : $callerid");
> $AGI->set_callerid($callerid);
> #$AGI->set_callerid("1000");
> $AGI->verbose("Dialing $exten\n");
>
> $AGI->exec("Dial", "Zap/g1/$exten");
> #$AGI->exec("Dial", "Zap/g1/***01");
> #$AGI->exec("Dial", "Zap/g1/003211111111");
> exit;
> }
> }
>
> sub mycallback {
> my ($returncode) = @_;
> print STDERR "CALLBACK: User Hangup ($returncode)\n";
> exit($returncode);
> }
>
> sub get_pin(\$\$\$) {
> $account_code = $_[0];
> $userid = $_[1];
> $MAC = $_[2];
>
> $attempts++;
> if($attempts eq 3) {
> $AGI->exec("Playback", "thank-you-for-calling");
> sleep(1);
> $AGI->exec("Playback", "goodbye");
> sleep(2);
> exit 1;
> }
>
> $AGI->exec("Playback", "please-enter-your");
> $AGI->exec("Playback", "card-number");
> my $pin = $AGI->get_data('then-press-pound');
> print STDERR "PIN : $pin\n";
>
> my $return_code = &validate_pin($pin, $account_code, $userid, $MAC);
>
> print STDERR "Return Code: $return_code\n";
>
> if($return_code == 100) {
> # $query = "update associations set PIN = '$pin' where userid =
> '$userid' and MAC = '$MAC'";
> # $stah = $dbh->query($query);
> $AGI->exec("Playback", "pin-number-accepted");
> }
> }
>
> sub validate_pin(\$\$\$\$) {
> $pin = $_[0];
> $account_code = $_[1];
> $userid = $_[2];
> $MAC = $_[3];
>
> print STDERR "Validate_PIN:\n";
> print STDERR "-> $pin\n";
> print STDERR "-> $account_code\n";
> print STDERR "-> $userid\n";
> print STDERR "-> $MAC\n";
>
> $url = "[removed]";
> $postfields = "[removed]";
> $rawdata = "";
>
> &post_data($url, $postfields); # Validate PIN with soft-switch
>
> if($rawdata =~ m/true/) {
> $return_code = "100";
> return $return_code;
> }
> else {
> $AGI->exec("Playback", "pin-number-invalid");
> sleep(2);
> &get_pin($account_code, $userid, $MAC);
> }
> }
>
> sub post_data($$) {
> $url = $_[0];
> $postfields = $_[1];
> print STDERR "$url\n$postfields\n";
>
> my $curl = Curl::easy::init();
>
> if(!$curl) {
> die "curl init failed!\n";
> }
>
> $::errbuf = "";
> WWW::Curl::easy::setopt($curl, CURLOPT_ERRORBUFFER, "::errbuf");
> WWW::Curl::easy::setopt($curl, CURLOPT_URL, $url);
> WWW::Curl::easy::setopt($curl, CURLOPT_NOPROGRESS, 1);
> WWW::Curl::easy::setopt($curl, CURLOPT_TIMEOUT, 30);
> WWW::Curl::easy::setopt($curl, CURLOPT_HEADERFUNCTION,
> \&header_callb);
> WWW::Curl::easy::setopt($curl, CURLOPT_WRITEFUNCTION,
> \&body_callb); WWW::Curl::easy::setopt($curl, CURLOPT_POST, 1);
> WWW::Curl::easy::setopt($curl, CURLOPT_POSTFIELDS,$postfields);
> WWW::Curl::easy::setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
> WWW::Curl::easy::setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
> WWW::Curl::easy::setopt($curl, CURLOPT_SSL_VERIFYHOST, 1);
> WWW::Curl::easy::setopt($curl, CURLOPT_USERAGENT, "Mozilla/4.0");
> WWW::Curl::easy::perform($curl);
> WWW::Curl::easy::cleanup($curl);
> }
>
> sub body_callb {
> my($chunk,$handle)=@_;
> ${handle} .= $chunk;
> $rawdata .= $chunk;
> print STDERR $chunk;
> return length($chunk);
> }
>
> sub header_callb {
> return length($_[0]);
> }
>
> -- end script --
--
Brian Wilkins
Software Engineer
brian at hcc.net
Heritage Communications Corporation
Melbourne, FL USA 32935
321.308.4000 x33
http://www.hcc.net
More information about the asterisk-users
mailing list