#!/usr/bin/perl # # Simple AGI Application to show some of the features of AGI # # Written by: James Golovich # Munched by: Richard Lyman # # needs - asterisk-perl-0.08, Bundle::CPAN, Bundle::DBI, DBD::mysql # # ;exten => talk,1,Queue(CS_agents|tn|||2) # ;exten => talk,1,Queue(CS_agents|tn|http://your.domain.com/cgi-bin/lookup.cgi?clid=${CALLERID}||60) # # I actually had invested around 3-4 hours doing this for a client that # walked away. so if you are feeling generous, please goto this page # and donate. (thank you) http://dynx.net/donate.html # # I figure someone might as well get some use out of it. (if nothing more than awaken some ideas) # use Asterisk::AGI; use DBI; my $dbh = DBI->connect("dbi:mysql:dialer:localhost:3306",'dialer','1234',{AutoCommit => 1, PrintError => 0, RaiseError => 0}); $AGI = new Asterisk::AGI; my %input = $AGI->ReadParse(); # this parses the AGI vars so we have access to data such as #----------------------------------------------------------- # AGI Tx >> agi_request: agiIVR.agi # AGI Tx >> agi_channel: IAX2/someuser-x # AGI Tx >> agi_language: en # AGI Tx >> agi_type: IAX2 # AGI Tx >> agi_uniqueid: 1179825920.169 # AGI Tx >> agi_callerid: XXXXXXXXXX # AGI Tx >> agi_calleridname: Your Name # AGI Tx >> agi_callingpres: 1 # AGI Tx >> agi_callingani2: 0 # AGI Tx >> agi_callington: 0 # AGI Tx >> agi_callingtns: 0 # AGI Tx >> agi_dnid: XXXXXXXXXX # AGI Tx >> agi_rdnis: unknown # AGI Tx >> agi_context: gnud_inbound # AGI Tx >> agi_extension: XXXXXXXXXX # AGI Tx >> agi_priority: 5 # AGI Tx >> agi_enhanced: 0.0 # AGI Tx >> agi_accountcode: youraccount #---------------------------------------------------------- # which can be used like # if ( $input{callerid} ne "unknown" ) { # $newvar = $input{callerid}; # various vars my $tests = 0; my $pass = 0; my $fail = 0; my $verbal_debug = 1; my $logfile = "/tmp/agiIVR.log"; #setup callback $AGI->setcallback(\&mycallback); print STDERR "AGI Environment Dump:\n"; foreach $i (sort keys %input) { print STDERR " -- $i = $input{$i}\n"; } #testing crap #score($AGI->exec('Dial', 'IAX/asterisk@demo')); #$res = $AGI->exec("DIAL $dialstr"); score($AGI->answer()); my $CurDate = $AGI->get_variable("DATETIME"); score($AGI->verbose("$CurDate: agiIVR (v3.2) munch'D by Richard", 3)); # replace with the initial welcome message score($AGI->stream_file('you-have-reached-a-test-number')); $somerec = "1"; #only here in case you want to set some default stuff #score($AGI->set_variable('CAMPAIGN', 'INBOUND')); #score($AGI->set_variable('LEADID', "" . $somerec . "")); #score($AGI->set_variable('CALLERID', "~INBOUND-" . $somerec . "-true~<" . $input{callerid} . ">")); #score($AGI->set_variable('TOTALHITS', "" . $total_hits . "")); &write_log(stamp(), $input{callerid}, $input{calleridname}, $logfile); # start survey &question_1(); # bye bye exit 0; #################################################################### sub score { my ($returncode) = @_; $tests++; if ($returncode >=0) { print STDERR "PASS ($returncode)\n"; $pass++; } else { print STDERR "FAIL ($returncode)\n"; $fail++; } } #################################################################### sub mycallback { my ($returncode) = @_; $AGI->verbose("MYCALLBACK: User Hungup ($returncode)", 3); print STDERR "MYCALLBACK: User Hungup ($returncode)\n"; exit($returncode); } #################################################################### sub write_log { my ($l_when, $l_clid, $l_clidname, $l_logfile) = @_; open (LOGUSER, ">>$l_logfile"); print LOGUSER "$l_when|$l_clid|$l_clidname\n"; close (LOGUSER); } #################################################################### sub stamp { ($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = (localtime(time))[0,1,2,3,4,5,6,7,8]; $mydatetimestamp = sprintf("%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d%9.9d", $year+1900, $month, $mday, $hour, $min, $sec, rand(999999999)); return $mydatetimestamp } ################################################################### sub what_dbs { local($thecallerid) = @_; my $ret = 0; my $sth = $dbh->prepare("SHOW TABLES"); $sth->execute; my $total_hits=0; while(@table = $sth->fetchrow_array) { if ($table[0] ne 'cdr' && $table[0] ne 'CDR' && $table[0] ne 'dnc' && $table[0] ne 'DNC') { $total_hits += search_table($table[0],$thecallerid); } } if ($total_hits lt 1) { $sth = $dbh->prepare("INSERT INTO INBOUND (id,phone) values (NULL,'" . $thecallerid . "')"); $sth->execute; $sth = $dbh->prepare("SELECT LAST_INSERT_ID()"); $sth->execute; while(@record = $sth->fetchrow_array) { score($AGI->set_variable('CAMPAIGN', 'INBOUND')); score($AGI->set_variable('LEADID', "'" . $record[0] . "'")); score($AGI->set_variable('CALLERID', "'~INBOUND-" . $record[0] . "-true~<'" .$thecallerid . ">")); score($AGI->set_variable('TOTALHITS', "'" . $total_hists . "'")); #other method # print "SET VARIABLE CAMPAIGN INBOUND\n"; # print "SET VARIABLE LEADID " . $record[0] . "\n"; # print "SET CALLERID ~INBOUND-" . $record[0] . "-true~<" . $thecallerid . ">\n"; # print "SET VARIABLE TOTALHITS " . $total_hits . "\n"; } } $sth->finish; return $ret; } #################################################################### sub search_table { local($thetable,$clid) = @_; my $mystring = "SELECT * FROM " . $thetable . " WHERE phone LIKE '%" . $clid . "%'"; my $sth = $dbh->prepare("$mystring"); $sth->execute; my $hit_count=0; while(@record = $sth->fetchrow_array) { $hit_count++; score($AGI->set_variable('CAMPAIGN', "'" . $thetable . "'")); score($AGI->set_variable('LEADID', "'" . $record[0] . "'")); score($AGI->set_variable('CALLERID', "'~" . $thetable . "-" . $record[0] . "-true~<'" .$thecallerid . ">")); score($AGI->set_variable('TOTALHITS', "'" . $total_hists . "'")); #other method # print "SET VARIABLE CAMPAIGN " . $thetable . "\n"; # print "SET VARIABLE LEADID " . $record[0] . "\n"; # print "SET CALLERID ~" . $thetable . "-" . $record[0] . "-true~<" . $clid . ">\n"; # print "SET VARIABLE HITCOUNT " . $hit_count . "\n"; } $sth->finish; return $hit_count; } #################################################################### sub question_1 { # replace with the sound file for # press 1, if the provider arrived already # press 2, if they have not, this will connect you to an agent score($AGI->exec("READ dialed|gnudialer-intro|1||3|5")); my $getdigit = $AGI->get_variable("dialed"); $AGI->verbose("getDigit received: $getdigit", 3); if ($getdigit == 1) { if ($verbal_debug) { score($AGI->say_number('1')); } $AGI->verbose("Provider Arrived: YES", 3); &question_2(); } elsif ($getdigit == 2) { if ($verbal_debug) { score($AGI->say_number('2')); } $AGI->verbose("Provider Arrived: NO (should send to Agent Queue Now!)", 3); score($AGI->stream_file('please-wait-connect-oncall-eng')); my $notanswered = 1; while($notanswered) { # add code to find another agent $AGI->verbose("Looking for closer...", 3); score($AGI->send_text("Incoming SALE! (someone should answer this call)")); # testing crap #exten => 2400,1,Set(VXML_URL=intercom=true) #exten => 2400,2,SIPAddHeader(Call-Info: sip:domain.de\;answer-after=0) #exten => 2400,3,Page(SIP/snom1&SIP/snom2) #score($AGI->exec("SIPADDHEADER", "Alert-Info\: someinfo")); #SIPAddHeader(X-Header-1: test1) score($AGI->exec("Dial", "IAX2/pchammer|20|t|http://www.dynx.net/")); my $getds = $AGI->get_variable("DIALSTATUS"); $AGI->verbose("getds received: $getds", 3); if ($getds eq 'ANSWER') { $notanswered = 0; } #CHANUNAVAIL | CONGESTION | NOANSWER | BUSY | ANSWER | CANCEL | DONTCALL | TORTURE if ($getds ne 'ANSWER') { score($AGI->exec("WaitExten", "5")); } } my $loopcount = 0; my $notanswered = 1; while($notanswered) { score($AGI->stream_file('please-wait-connect-oncall-eng')); score($AGI->exec("Queue CS_agents|tn|||20")); my $getqs = $AGI->get_variable("QUEUESTATUS"); $AGI->verbose("getqs received: $getqs", 3); if ($getqs ne 'TIMEOUT') { $notanswered = 0; } #TIMEOUT | FULL | JOINEMPTY | LEAVEEMPTY | JOINUNAVAIL | LEAVEUNAVAIL $loopcount++; # 15 loops at 20 secs is 5 minutes, plus playback of message time if ($loopcount eq 15) { score($AGI->stream_file('all-reps-busy')); $notanswered = 0; } } score($AGI->stream_file('goodbye')); score($AGI->hangup()); } else { # invalid input try again score($AGI->stream_file('invalid')); &question_1(); } } ####################################################################### sub question_2 { # replace with sound file for # press 1, if the provider arrived before the scheduled time # press 2, if the provider arrived on time # press 3, if the provider show up late score($AGI->exec("READ dialed|gnudialer-intro|1||3|5")); my $getdigit = $AGI->get_variable("dialed"); $AGI->verbose("getDigit received: $getdigit", 3); if ($getdigit == 1) { if ($verbal_debug) { score($AGI->say_number('1')); } $AGI->verbose("Provider Arrived: EARLY", 3); &question_3(); } elsif ($getdigit == 2) { if ($verbal_debug) { score($AGI->say_number('2')); } $AGI->verbose("Provider Arrived: ONTIME", 3); &question_3(); } elsif ($getdigit == 3) { if ($verbal_debug) { score($AGI->say_number('3')); } $AGI->verbose("Provider Arrived: LATE", 3); &question_3(); } else { # invalid input try again score($AGI->stream_file('invalid')); &question_2(); } } ###################################################################### sub question_3 { # replace with sound file for # press 1, if you have time for a short 3 question survey # press 2, if you do not score($AGI->exec("READ dialed|gnudialer-intro|1||3|5")); my $getdigit = $AGI->get_variable("dialed"); $AGI->verbose("getDigit received: $getdigit", 3); if ($getdigit == 1) { if ($verbal_debug) { score($AGI->say_number('1')); } $AGI->verbose("Time for Survey: YES", 3); &question_4(); } elsif ($getdigit == 2) { if ($verbal_debug) { score($AGI->say_number('2')); } $AGI->verbose("Time for Survey: NO", 3); score($AGI->stream_file('thank-you-cooperation')); score($AGI->stream_file('goodbye')); score($AGI->hangup()); # need to write info to database } else { # invalid input try again score($AGI->stream_file('invalid')); &question_3(); } } #################################################################### sub question_4 { # replace with sound file for # we would like to know about the quality of the service performed # from 1 to 5, where 1 was a poor experience to 5 being excellent score($AGI->exec("READ dialed|gnudialer-intro|1||3|5")); my $getdigit = $AGI->get_variable("dialed"); $AGI->verbose("getDigit received: $getdigit", 3); if ($getdigit == 1 || $getdigit == 2 || $getdigit == 3 || $getdigit == 4 || $getdigit == 5) { if ($verbal_debug) { score($AGI->say_number($getdigit)); } # write info to database &question_5(); } else { # invalid input try again score($AGI->stream_file('invalid')); &question_4(); } } ################################################################### sub question_5 { # replace with sound file for # we would like to know how courtious the provider was # from 1 to 5, where 1 was a poor experience to 5 being excellent score($AGI->exec("READ dialed|gnudialer-intro|1||3|5")); my $getdigit = $AGI->get_variable("dialed"); $AGI->verbose("getDigit received: $getdigit", 3); if ($getdigit == 1 || $getdigit == 2 || $getdigit == 3 || $getdigit == 4 || $getdigit == 5) { if ($verbal_debug) { score($AGI->say_number($getdigit)); } # write info to database &question_6(); } else { # invalid input try again score($AGI->stream_file('invalid')); &question_5(); } } ################################################################### sub question_6 { # replace with sound file for # and finally we would like to know if you would like to be entered in # our free drawing, we are giving away... # from 1 to 5, where 1 was a poor experience to 5 being excellent score($AGI->exec("READ dialed|gnudialer-intro|1||3|5")); my $getdigit = $AGI->get_variable("dialed"); $AGI->verbose("getDigit received: $getdigit", 3); if ($getdigit == 1 || $getdigit == 2 || $getdigit == 3 || $getdigit == 4 || $getdigit == 5) { if ($verbal_debug) { score($AGI->say_number($getdigit)); } # write info to database score($AGI->stream_file('thank-you-cooperation')); score($AGI->stream_file('goodbye')); score($AGI->hangup()); } else { # invalid input try again score($AGI->stream_file('invalid')); &question_6(); } } ##################################################################