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@hcc.net Heritage Communications Corporation Melbourne, FL USA 32935 321.308.4000 x33 http://www.hcc.net
Brian Wilkins
2004-Nov-19 02:58 UTC
[Asterisk-Users] Problems using AGI->get_data -> almost solved
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@hcc.net Heritage Communications Corporation Melbourne, FL USA 32935 321.308.4000 x33 http://www.hcc.net