Agent Only Beep
Posted: Mon Aug 25, 2014 9:32 pm
About 9 months ago I hired someone to write code that would make the bloop only audible to the agent and not the lead. I got the code back from them but it only seems to work some times. The way they did it is with an AIG that adds a line to the vicidial_manager resulting in a sound being played via chanspy to the rep. The only problem is randomly it will get the channel wrong. For example sometimes it attaches to the prospects/leads channel. In this case the prospect/lead can here the beep but not the agent.
They are supposed to test it and get back to me, but it keeps getting pushed back so I thought I would release the code here and see if anyone has any ideas. I have been pouring over this code for a few weeks now and I just can't seem to crack why it seemly randomly attaches to the wrong channel. I have ran it in AIG debug mode and it appears that everything is working perfect then I see chanspy attach to the wrong channel. Anyone have any ideas on what could be causing this? My plan is to get it fixed and submit it to the SVN for others to use once it has been thoroughly tested.
They are supposed to test it and get back to me, but it keeps getting pushed back so I thought I would release the code here and see if anyone has any ideas. I have been pouring over this code for a few weeks now and I just can't seem to crack why it seemly randomly attaches to the wrong channel. I have ran it in AIG debug mode and it appears that everything is working perfect then I see chanspy attach to the wrong channel. Anyone have any ideas on what could be causing this? My plan is to get it fixed and submit it to the SVN for others to use once it has been thoroughly tested.
- Code: Select all
#!/usr/bin/perl
#
$script = 'agi-AgentOnlyBeep.agi';
#
# This script is to use ChanSpy to beep the agent without beeping the prospect
#
# This script goes into /var/lib/asterisk/agi-bin
# Remember to "chmod +x" the file (it must be executable just like all the other files in the folder!)
#
# Place this at the end of extensions.conf (or as a "custom dialplan entry", but be aware that older versions of vicidial do not allow contexts in this field)
# [agent-only-beep]
# exten => s,1,Answer()
# exten => s,n,NoOp(${AGENT_BEEP_CHANNEL})
# exten => s,n,ChanSpy(${AGENT_BEEP_CHANNEL},wq)
#
# Modify this section of extensions.conf by adding "q" in front of "F" for "qF" and the extra agi lines and renumbering of the priorities:
# ; VICIDIAL conferences
# exten => _86000[5-9]X,1,AGI(agi-AgentOnlyBeep.agi)
# exten => _86000[5-9]X,n,Meetme(${EXTEN},qF)
# exten => _86000[5-9]X,n,Hangup()
# exten => _8600[1-2]XX,1,AGI(agi-AgentOnlyBeep.agi)
# exten => _8600[1-2]XX,n,Meetme(${EXTEN},qF)
# exten => _8600[1-2]XX,n,Hangup()
$AGILOG = '0';
$mel=1; # Mysql Error Log enabled = 1
$mysql_log_count=108;
$one_mysql_log=0;
$at='@';
$US='_';
# get date/time
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$year = ($year + 1900);
$Tyear = ($year - 2000);
$mon++;
if ($mon < 10) {$mon = "0$mon";}
if ($mday < 10) {$mday = "0$mday";}
if ($hour < 10) {$hour = "0$hour";}
if ($min < 10) {$min = "0$min";}
if ($sec < 10) {$sec = "0$sec";}
$now_date_epoch = time();
$now_date = "$year-$mon-$mday $hour:$min:$sec";
$CLInow_date = "$year-$mon-$mday\\ $hour:$min:$sec";
$start_time_epoch = $now_date_epoch;
$start_time=$now_date;
$YMD = "$year-$mon-$mday";
$CIDdate = "$mon$mday$hour$min$sec";
$tsSQLdate = "$year$mon$mday$hour$min$sec";
$filedate = "$US$year-$mon-$mday$US$hour$min$sec";
$recdate = "$year$mon$mday-$hour$min$sec";
$tinydate = "$Tyear$mon$mday$hour$min$sec";
$SQLdate = "$year-$mon-$mday $hour:$min:$sec";
$SQLdateBEGIN = $SQLdate;
$BDtarget = ($now_date_epoch - 5);
($Bsec,$Bmin,$Bhour,$Bmday,$Bmon,$Byear,$Bwday,$Byday,$Bisdst) = localtime($BDtarget);
$Byear = ($Byear + 1900);
$Bmon++;
if ($Bmon < 10) {$Bmon = "0$Bmon";}
if ($Bmday < 10) {$Bmday = "0$Bmday";}
if ($Bhour < 10) {$Bhour = "0$Bhour";}
if ($Bmin < 10) {$Bmin = "0$Bmin";}
if ($Bsec < 10) {$Bsec = "0$Bsec";}
$BDtsSQLdate = "$Byear$Bmon$Bmday$Bhour$Bmin$Bsec";
$FDtarget = ($now_date_epoch + 120);
($Fsec,$Fmin,$Fhour,$Fmday,$Fmon,$Fyear,$Fwday,$Fyday,$Fisdst) = localtime($FDtarget);
$Fyear = ($Fyear + 1900);
$Fmon++;
if ($Fmon < 10) {$Fmon = "0$Fmon";}
if ($Fmday < 10) {$Fmday = "0$Fmday";}
if ($Fhour < 10) {$Fhour = "0$Fhour";}
if ($Fmin < 10) {$Fmin = "0$Fmin";}
if ($Fsec < 10) {$Fsec = "0$Fsec";}
$FDtsSQLdate = "$Fyear$Fmon$Fmday$Fhour$Fmin$Fsec";
# default path to astguiclient configuration file:
$PATHconf = '/etc/astguiclient.conf';
open(conf, "$PATHconf") || die "can't open $PATHconf: $!\n";
@conf = <conf>;
close(conf);
$i=0;
foreach(@conf)
{
$line = $conf[$i];
$line =~ s/ |>|\n|\r|\t|\#.*|;.*//gi;
if ( ($line =~ /^PATHhome/) && ($CLIhome < 1) )
{$PATHhome = $line; $PATHhome =~ s/.*=//gi;}
if ( ($line =~ /^PATHlogs/) && ($CLIlogs < 1) )
{$PATHlogs = $line; $PATHlogs =~ s/.*=//gi;}
if ( ($line =~ /^PATHagi/) && ($CLIagi < 1) )
{$PATHagi = $line; $PATHagi =~ s/.*=//gi;}
if ( ($line =~ /^PATHweb/) && ($CLIweb < 1) )
{$PATHweb = $line; $PATHweb =~ s/.*=//gi;}
if ( ($line =~ /^PATHsounds/) && ($CLIsounds < 1) )
{$PATHsounds = $line; $PATHsounds =~ s/.*=//gi;}
if ( ($line =~ /^PATHmonitor/) && ($CLImonitor < 1) )
{$PATHmonitor = $line; $PATHmonitor =~ s/.*=//gi;}
if ( ($line =~ /^VARserver_ip/) && ($CLIserver_ip < 1) )
{$VARserver_ip = $line; $VARserver_ip =~ s/.*=//gi;}
if ( ($line =~ /^VARDB_server/) && ($CLIDB_server < 1) )
{$VARDB_server = $line; $VARDB_server =~ s/.*=//gi;}
if ( ($line =~ /^VARDB_database/) && ($CLIDB_database < 1) )
{$VARDB_database = $line; $VARDB_database =~ s/.*=//gi;}
if ( ($line =~ /^VARDB_user/) && ($CLIDB_user < 1) )
{$VARDB_user = $line; $VARDB_user =~ s/.*=//gi;}
if ( ($line =~ /^VARDB_pass/) && ($CLIDB_pass < 1) )
{$VARDB_pass = $line; $VARDB_pass =~ s/.*=//gi;}
if ( ($line =~ /^VARDB_port/) && ($CLIDB_port < 1) )
{$VARDB_port = $line; $VARDB_port =~ s/.*=//gi;}
$i++;
}
if (!$VARDB_port) {$VARDB_port='3306';}
if (!$AGILOGfile) {$AGILOGfile = "$PATHlogs/agiout.$year-$mon-$mday";}
if (!$PRSLOGfile) {$PRSLOGfile = "$PATHlogs/prsout.$year-$mon-$mday";}
if (!$PRSTESTfile) {$PRSTESTfile = "$PATHlogs/prstest.$year-$mon-$mday";}
if (!$ERRLOGfile) {$ERRLOGfile = "$PATHlogs/MySQLerror.$year-$mon-$mday";}
if (!$CEPLOGfile) {$CEPLOGfile = "$PATHlogs/Cepstral.$year-$mon-$mday";}
use DBI;
use Asterisk::AGI;
$AGI = new Asterisk::AGI;
$dbhA = DBI->connect("DBI:mysql:$VARDB_database:$VARDB_server:$VARDB_port", "$VARDB_user", "$VARDB_pass")
or die "Couldn't connect to database: " . DBI->errstr;
### Grab Server values from the database
$stmtA = "SELECT voicemail_dump_exten,ext_context,answer_transfer_agent,local_gmt,asterisk_version,max_vicidial_trunks,agi_output FROM servers where server_ip = '$VARserver_ip';";
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
$sthArows=$sthA->rows;
$dbhP=$dbhA; $mysql_count='01001'; $MEL_aff_rows=$sthArows; &mysql_error_logging;
$rec_count=0;
while ($sthArows > $rec_count)
{
@aryA = $sthA->fetchrow_array;
$DBvoicemail_dump_exten = $aryA[0];
$DBext_context = $aryA[1];
$DBanswer_transfer_agent = $aryA[2];
$DBSERVER_GMT = $aryA[3];
$asterisk_version = $aryA[4];
$DBmax_vicidial_trunks = $aryA[5];
$DBagi_output = $aryA[6];
if ($DBvoicemail_dump_exten) {$voicemail_dump_exten = $DBvoicemail_dump_exten;}
if ($DBext_context) {$ext_context = $DBext_context;}
if ($DBanswer_transfer_agent) {$answer_transfer_agent = $DBanswer_transfer_agent;}
if ($DBSERVER_GMT) {$SERVER_GMT = $DBSERVER_GMT;}
if ($asterisk_version) {$AST_ver = $asterisk_version;}
if ($DBmax_vicidial_trunks) {$max_vicidial_trunks = $DBmax_vicidial_trunks;}
if ($DBagi_output =~ /STDERR/) {$AGILOG = '1';}
if ($DBagi_output =~ /FILE/) {$AGILOG = '2';}
if ($DBagi_output =~ /BOTH/) {$AGILOG = '3';}
$rec_count++;
}
$sthA->finish();
$|=1;
while(<STDIN>)
{
chomp;
last unless length($_);
if ($AGILOG)
{
if (/^agi_(\w+)\:\s+(.*)$/)
{
$AGI{$1} = $2;
}
}
if (/^agi_extension\:\s+(.*)$/) {$extension = $1;}
}
if ($AGILOG) {$agi_string = "$unique_id|$channel|$extension|"; &agi_output;}
#################################################################################
### Get AGENT channel from conference
$stmtA = "select extension,uniqueid from vicidial_live_agents where conf_exten='$extension' and server_ip='$VARserver_ip' limit 1;";
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
$sthArows=$sthA->rows;
$dbhP=$dbhA; $mysql_count='01001'; $MEL_aff_rows=$sthArows; &mysql_error_logging;
if ($sthArows > 0)
{
@aryA = $sthA->fetchrow_array;
$agent_channel = $aryA[0];
$uniqueid = $aryA[1];
}
$sthA->finish();
print "SET VARIABLE AGENT_BEEP_CHANNEL '$agent_channel'";
### Let there be Beep!
if(length($uniqueid)>5)
{
$stmtA = "INSERT INTO `vicidial_manager` (`uniqueid`, `entry_date`, `status`, `response`, `server_ip`, `channel`, `action`, `callerid`, `cmd_line_b`, `cmd_line_c`, `cmd_line_d`, `cmd_line_e`, `cmd_line_f`, `cmd_line_g`, `cmd_line_h`, `cmd_line_i`, `cmd_line_j`, `cmd_line_k`) VALUES ('', now(), 'NEW', 'N', '$VARserver_ip', '', 'Originate', '', NULL, NULL, 'Channel: Local/s\@agent-only-beep', 'Application: Playback', 'Data: beep', NULL, '', '', '', '');";
if ($AGILOG) { $agi_string = "|$stmtA|"; &agi_output; }
$affected_rows = $dbhA->do($stmtA);
$dbhA->disconnect();
}
else
{
$stmtA = "INSERT INTO `vicidial_manager` (`uniqueid`, `entry_date`, `status`, `response`, `server_ip`, `channel`, `action`, `callerid`, `cmd_line_b`, `cmd_line_c`, `cmd_line_d`, `cmd_line_e`, `cmd_line_f`, `cmd_line_g`, `cmd_line_h`, `cmd_line_i`, `cmd_line_j`, `cmd_line_k`) VALUES ('', now(), 'NEW', 'N', '$VARserver_ip', '', 'Originate', '', NULL, NULL, 'Channel: Local/s\@agent-only-beep', 'Application: Playback', 'Data: conf-onlyperson', NULL, '', '', '', '');";
if ($AGILOG) { $agi_string = "|$stmtA|"; &agi_output; }
$affected_rows = $dbhA->do($stmtA);
$dbhA->disconnect();
}
exit;
sub agi_output
{
if ($AGILOG >=2)
{
### open the log file for writing ###
open(Lout, ">>$AGILOGfile")
|| die "Can't open $AGILOGfile: $!\n";
print Lout "$now_date|$script|$agi_string\n";
close(Lout);
}
### send to STDERR writing ###
if ( ($AGILOG == '1') || ($AGILOG == '3') )
{print STDERR "$now_date|$script|$agi_string\n";}
$agi_string='';
}
sub mysql_error_logging
{
$errno='';
$error='';
if ( ($mel > 0) || ($one_mysql_log > 0) )
{
$errno = $dbhP->err();
if ( ($errno > 0) || ($mel > 1) || ($one_mysql_log > 0) )
{
$error = $dbhP->errstr();
### open the log file for writing ###
open(Eout, ">>$ERRLOGfile")
|| die "Can't open $ERRLOGfile: $!\n";
print Eout "$now_date|$script|$mysql_count|$MEL_aff_rows|$errno|$error|$stmtA|$callerid|$CIDlead_id|\n";
close(Eout);
}
}
$one_mysql_log=0;
}