Added instructions and scripts for creating a Gateway Recording server. See the GATEWAY_RECORDING_SERVER.txt doc for more info.

git-svn-id: svn://192.168.202.10@3678 3d104415-ff17-0410-8863-d5cf3c621b8a
This commit is contained in:
mattf
2023-02-01 13:26:56 +00:00
parent f0c47bab96
commit 28911bd5a2
15 changed files with 958 additions and 10 deletions
+3
View File
@@ -740,6 +740,9 @@ OTHER CHANGES:
NOTE: After upgrading your system, be sure to set each dialer to NOTE: After upgrading your system, be sure to set each dialer to
"Rebuild conf files" = 'Y' for this feature to work properly. "Rebuild conf files" = 'Y' for this feature to work properly.
208. Added instructions and scripts for creating a Gateway Recording server
See the GATEWAY_RECORDING_SERVER.txt doc for more info.
+14 -1
View File
@@ -13,7 +13,7 @@
# ;inbound DID catch-all: # ;inbound DID catch-all:
#exten => _X.,1,AGI(agi-DID_route.agi) #exten => _X.,1,AGI(agi-DID_route.agi)
# #
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2 # Copyright (C) 2023 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
# #
# changes: # changes:
# 81007-0324 - First Build # 81007-0324 - First Build
@@ -49,6 +49,7 @@
# 201112-0834 - Fix for AGENT routing, check for availability, issue #1211 # 201112-0834 - Fix for AGENT routing, check for availability, issue #1211
# 210315-1132 - Fix for multiple filter_clean_cid_number actions, added 'T' filter action, Issue #1247 # 210315-1132 - Fix for multiple filter_clean_cid_number actions, added 'T' filter action, Issue #1247
# 220507-0811 - Added pre_filter_recent_call function # 220507-0811 - Added pre_filter_recent_call function
# 230124-1228 - Added logging of VICIrecGatewayID channel variable, and vicidial_did_gateway_log table
# #
@@ -217,6 +218,18 @@ $callerid =~ s/\'|\"|\\\\|\\\|\\|\\;|\\\;|\;|;//gi;
$calleridname =~ s/\'|\"|\\\\|\\\|\\|\\;|\\\;|\;|;//gi; $calleridname =~ s/\'|\"|\\\\|\\\|\\|\\;|\\\;|\;|;//gi;
$extension =~ s/\'|\"|\\\\|\\\|\\|\\;|\\\;|\;|;//gi; $extension =~ s/\'|\"|\\\\|\\\|\\|\\;|\\\;|\;|;//gi;
$VICIrecGatewayID = $AGI->get_variable('VICIrecGatewayID');
$VICIrecGatewayID =~ s/[^0-9a-zA-Z]//gi;
if (length($VICIrecGatewayID) > 19)
{
if ($AGILOG) {$agi_string = "-- VICIrecGatewayID set on this call: |$VICIrecGatewayID|"; &agi_output;}
### Log the call to vicidial_did_gateway_log
$stmtA = "INSERT INTO vicidial_did_gateway_log SET uniqueid='$uniqueid',channel='$channel',server_ip='$VARserver_ip',caller_id_number='$callerid',caller_id_name='$calleridname',extension='$extension',call_date='$SQLdate',VICIrecGatewayID='$VICIrecGatewayID';";
if ($AGILOG) {$agi_string = "|$stmtA|"; &agi_output;}
$affected_rowsG = $dbhA->do($stmtA);
if ($AGILOG) {$agi_string = "-- VICIrecGatewayID LOG INSERT: |$affected_rowsG|$stmtA|"; &agi_output;}
}
### BEGIN did_system_filter filter process ### ### BEGIN did_system_filter filter process ###
if ($SSdid_system_filter > 0) if ($SSdid_system_filter > 0)
+413
View File
@@ -0,0 +1,413 @@
#!/usr/bin/perl
#
# agi-VICIrecGateway.agi version 2.14
#
# Designed to work on a stand-alone Asterisk server and record calls in stereo
#
# You need to put a line similar to this below in your extensions.conf file in
# the context for where incoming calls go from your trunks (for example, the
# trunkinbound context which is present in the default dialplan):
#
#[handler]
#exten => addheader,1,Set(PJSIP_HEADER(add,X-VICIrecGatewayID)=${VICIrecGatewayID})
#exten => addheader,n,Return()
#
#[stereo-rec-inbound]
#exten => _X.,1,Progress()
#exten => _X.,n,Noop(${CALLERID(num)})
#exten => _X.,n,AGI(agi-VICIrecGateway.agi)
#exten => _X.,n,Noop(${CARRIER_FILENAME})
#exten => _X.,n,Noop(${DIALER_FILENAME})
#exten => _X.,n,MixMonitor(,r(${CARRIER_FILENAME})t(${DIALER_FILENAME})S)
#exten => _X.,n,Dial(PJSIP/${EXTEN}@pjdial147,,Tob(handler^addheader^1))
#
#[stereo-rec-outbound]
#exten => _X.,1,Progress()
#exten => _X.,n,Noop(${CALLERID(num)})
#exten => _X.,n,AGI(agi-VICIrecGateway.agi)
#exten => _X.,n,Noop(${CARRIER_FILENAME})
#exten => _X.,n,Noop(${DIALER_FILENAME})
#exten => _X.,n,MixMonitor(,t(${CARRIER_FILENAME})r(${DIALER_FILENAME})S)
#exten => _X.,n,Dial(PJSIP/${EXTEN}@pjsgw1,,To)
#
# Copyright (C) 2023 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
#
# changes:
# 230125-2212 - First Build
#
$script = 'agi-VICIrecGateway.agi';
$US='_';
$dialer_id='';
$call_direction = 'INBOUND';
$lead_id=0;
$insert_gateway_id='';
$DBX=0; # set to 1 for extra debugging output
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$year = ($year + 1900);
$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";}
$hm = "$hour$min";
$hm = ($hm + 0);
$now_date_epoch = time();
$now_date = "$year-$mon-$mday $hour:$min:$sec";
$CLInow_date = "$year-$mon-$mday\\ $hour:$min:$sec";
$start_time=$now_date;
$CIDdate = "$mon$mday$hour$min$sec";
$tsSQLdate = "$year$mon$mday$hour$min$sec";
$SQLdate = "$year-$mon-$mday $hour:$min:$sec";
$SQLdateBEGIN = $SQLdate;
while (length($CIDdate) > 9) {$CIDdate =~ s/^.//gi;} # 0902235959 changed to 902235959
# 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 (!$DIDLOGfile) {$DIDLOGfile = "$PATHlogs/didin.$year-$mon-$mday";}
use DBI;
use Time::HiRes ('gettimeofday','usleep','sleep'); # necessary to have perl sleep command of less than one second
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 agi_output,local_gmt,asterisk_version 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;
if ($sthArows > 0)
{
$AGILOG = '0';
@aryA = $sthA->fetchrow_array;
$DBagi_output = $aryA[0];
$local_gmt = $aryA[1];
$asterisk_version = $aryA[2];
if ($DBagi_output =~ /STDERR/) {$AGILOG = '1';}
if ($DBagi_output =~ /FILE/) {$AGILOG = '2';}
if ($DBagi_output =~ /BOTH/) {$AGILOG = '3';}
}
$sthA->finish();
#############################################
##### START SYSTEM SETTINGS LOOKUP #####
$stmtA = "SELECT enable_queuemetrics_logging,queuemetrics_server_ip,queuemetrics_dbname,queuemetrics_login,queuemetrics_pass,queuemetrics_log_id,queuemetrics_eq_prepend,did_agent_log,alt_log_server_ip,alt_log_dbname,alt_log_login,alt_log_pass,tables_use_alt_log_db,did_system_filter,inbound_answer_config FROM system_settings;";
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
$sthArows=$sthA->rows;
if ($sthArows > 0)
{
@aryA = $sthA->fetchrow_array;
$enable_queuemetrics_logging = $aryA[0];
$queuemetrics_server_ip = $aryA[1];
$queuemetrics_dbname = $aryA[2];
$queuemetrics_login= $aryA[3];
$queuemetrics_pass = $aryA[4];
$queuemetrics_log_id = $aryA[5];
$queuemetrics_eq_prepend = $aryA[6];
$did_agent_log = $aryA[7];
$alt_log_server_ip = $aryA[8];
$alt_log_dbname = $aryA[9];
$alt_log_login = $aryA[10];
$alt_log_pass = $aryA[11];
$tables_use_alt_log_db = $aryA[12];
$SSdid_system_filter = $aryA[13];
$SSinbound_answer_config = $aryA[14];
}
$sthA->finish();
##### END SYSTEM SETTINGS LOOKUP #####
###########################################
$|=1;
while(<STDIN>)
{
chomp;
last unless length($_);
if ($AGILOG)
{
if (/^agi_(\w+)\:\s+(.*)$/)
{
$AGI{$1} = $2;
}
}
if (/^agi_uniqueid\:\s+(.*)$/) {$unique_id = $1; $uniqueid = $unique_id;}
if (/^agi_channel\:\s+(.*)$/) {$channel = $1;}
if (/^agi_extension\:\s+(.*)$/) {$extension = $1;}
if (/^agi_type\:\s+(.*)$/) {$type = $1;}
if (/^agi_callerid\:\s+(.*)$/) {$callerid = $1;}
if (/^agi_calleridname\:\s+(.*)$/) {$calleridname = $1;}
}
if ($calleridname =~ /^V\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d|^Y\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d|^M\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d|^DC\d\d\d\d\d\dW\d\d\d\d\d\d\d\d\d\dW/)
{
$dialer_id = $calleridname;
$call_direction = 'OUTBOUND';
if ($calleridname =~ /^V\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d|^Y\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d|^M\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d/)
{
$lead_id = substr($calleridname, 10, 10);
$lead_id = ($lead_id + 0);
}
if ($calleridname =~ /^DC\d\d\d\d\d\dW\d\d\d\d\d\d\d\d\d\dW/)
{
$lead_id = substr($calleridname, 9, 10);
$lead_id = ($lead_id + 0);
}
}
if ( ($callerid =~ /\".*\"/) && ( (!$calleridname) or ($calleridname =~ /unknown/) ) )
{
$calleridname = $callerid;
$calleridname =~ s/\<\d\d\d\d\d\d\d\d\d\d\>//gi;
$calleridname =~ s/\"|\" //gi;
}
$callerid =~ s/\D|\'//gi;
$calleridname =~ s/unknown|\'//gi;
if ( (!$callerid) or ($callerid =~ /unknown/) )
{$callerid = $calleridname;}
$callerid =~ s/\'|\"|\\\\|\\\|\\|\\;|\\\;|\;|;//gi;
$calleridname =~ s/\'|\"|\\\\|\\\|\\|\\;|\\\;|\;|;//gi;
$extension =~ s/\'|\"|\\\\|\\\|\\|\\;|\\\;|\;|;//gi;
### Log the call to gateway_recording_log
$stmtA = "INSERT INTO gateway_recording_log SET call_direction='$call_direction',call_id='$dialer_id',lead_id='$lead_id',uniqueid='$uniqueid',server_ip='$VARserver_ip',caller_id_number='$callerid',caller_id_name='$calleridname',extension='$extension',start_time=NOW();";
if ($AGILOG) {$agi_string = "|$stmtA|"; &agi_output;}
$affected_rowsG = $dbhA->do($stmtA);
if ($AGILOG) {$agi_string = "-- gateway_recording_log LOG INSERT: |$affected_rowsG|$stmtA|"; &agi_output;}
$stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;";
$sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr;
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
$sthArows=$sthA->rows;
if ($sthArows > 0)
{
@aryA = $sthA->fetchrow_array;
$insert_gateway_id = $aryA[0];
if ($AGILOG) {$agi_string = "-- gateway_id: |$insert_gateway_id|"; &agi_output;}
}
$sthA->finish();
$PADgateway_id = sprintf("%010s", $insert_gateway_id); while (length($PADgateway_id) > 10) {chop($PADgateway_id);}
$gatewayCID = "G$CIDdate$PADgateway_id";
$dialer_idSQL='';
if (length($dialer_id) < 1)
{
$dialer_id = $gatewayCID;
$dialer_idSQL = ",call_id='$gatewayCID'";
}
$AGI->set_variable('_VICIrecGatewayID',"$gatewayCID");
if ($AGILOG) {$agi_string = "-- setting gateway channel variable: |VICIrecGatewayID|$gatewayCID|"; &agi_output;}
$record_call='Y';
### if set to record this call, start recording ###
if ($record_call =~ /Y/)
{
$insert_recording_id='';
$filename = "$tsSQLdate$US$extension$US$callerid";
### code to record call goes here ###
### set variables for audio files to be used by MixMonitor application
$AGI->set_variable('CARRIER_FILENAME', "STEREO/CARRIER_$dialer_id$US$tsSQLdate.wav");
$AGI->set_variable('DIALER_FILENAME', "STEREO/DIALER_$dialer_id$US$tsSQLdate.wav");
# %ast_ver_str = parse_asterisk_version($asterisk_version);
# if (( $ast_ver_str{major} = 1 ) && ($ast_ver_str{minor} < 6))
# {
# $AGI->exec("Monitor wav|/var/spool/asterisk/monitor/MIX/$filename");
# }
# else
# {
# $AGI->exec("Monitor","wav,/var/spool/asterisk/monitor/MIX/$filename");
# }
### insert record into recording_log table ###
$stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,length_in_sec,filename,lead_id,user,location,vicidial_id) values('$channel','$VARserver_ip','$dialer_id','$SQLdate','$now_date_epoch','0','$dialer_id$US$tsSQLdate','$lead_id','GATEWAY','$dialer_id$US$tsSQLdate','G$insert_gateway_id');";
$affected_rowsR = $dbhA->do($stmtA);
if ($affected_rowsR > 0)
{
$stmtB = "select LAST_INSERT_ID() LIMIT 1;";
$sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr;
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
$sthArows=$sthA->rows;
if ($sthArows > 0)
{
@aryA = $sthA->fetchrow_array;
$insert_recording_id = $aryA[0];
}
$sthA->finish();
}
if ($AGILOG) {$did_string = "-- RECORDING LOG : |$affected_rowsR|$insert_recording_id|$stmtA|"; &did_output;}
### update gateway_recording_log
$stmtA = "UPDATE gateway_recording_log SET recording_log_id='$insert_recording_id',filename='$dialer_id$US$tsSQLdate' $dialer_idSQL where gateway_recording_id='$insert_gateway_id';";
if ($AGILOG) {$agi_string = "|$stmtA|"; &agi_output;}
$affected_rowsG = $dbhA->do($stmtA);
if ($AGILOG) {$agi_string = "-- gateway_recording_log LOG UPDATE: |$affected_rowsG|$stmtA|"; &agi_output;}
}
######### SUBROUTINES #################
sub checkresult
{
$pass=0; $fail=0;
my ($res) = @_;
my $retval;
$tests++;
chomp $res;
if ($res =~ /^200/)
{
$res =~ /result=(-?\d+)/;
if (!length($1))
{
# print STDERR "FAIL ($res)\n";
$fail++;
}
else
{
# print STDERR "PASS ($1)\n";
$pass++;
}
}
else
{
# print STDERR "FAIL (unexpected result '$res')\n";
$fail++;
}
}
sub leading_zero($)
{
$_ = $_[0];
s/^(\d)$/0$1/;
s/^(\d\d)$/0$1/;
return $_;
} # End of the leading_zero() routine.
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 did_output
{
if ($AGILOG >=2)
{
### open the log file for writing ###
open(Dout, ">>$DIDLOGfile")
|| die "Can't open $DIDLOGfile: $!\n";
print Dout "$did_string\n";
close(Dout);
}
$did_string='';
}
# subroutine to parse the asterisk version
# and return a hash with the various part
sub parse_asterisk_version
{
# grab the arguments
my $ast_ver_str = $_[0];
# get everything after the - and put it in $ast_ver_postfix
my @hyphen_parts = split( /-/ , $ast_ver_str );
my $ast_ver_postfix = $hyphen_parts[1];
# now split everything before the - up by the .
my @dot_parts = split( /\./ , $hyphen_parts[0] );
my %ast_ver_hash;
if ( $dot_parts[0] <= 1 )
{
%ast_ver_hash = (
"major" => $dot_parts[0],
"minor" => $dot_parts[1],
"build" => $dot_parts[2],
"revision" => $dot_parts[3],
"postfix" => $ast_ver_postfix
);
}
# digium dropped the 1 from asterisk 10 but we still need it
if ( $dot_parts[0] > 1 )
{
%ast_ver_hash = (
"major" => 1,
"minor" => $dot_parts[0],
"build" => $dot_parts[1],
"revision" => $dot_parts[2],
"postfix" => $ast_ver_postfix
);
}
return ( %ast_ver_hash );
}
@@ -0,0 +1,311 @@
#!/usr/bin/perl
#
# AST_CRON_audio_1_gateway_stereo.pl
#
# This is a STEP-1 program in the audio archival process
#
# runs every 3 minutes and copies and mixes the -in and -out recordings in the
# monitor/STEREO to the DONE directory for further processing. Very important for
# RAM-drive usage
#
# put an entry into the cron of of your asterisk machine to run this script
# every 3 minutes or however often you desire
#
# ### recording mixing/compressing/ftping scripts
# 0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57 * * * * /usr/share/astguiclient/AST_CRON_audio_1_gateway_stereo.pl --STEREO
# 2,5,8,11,14,17,20,23,26,29,32,35,38,41,44,47,50,53,56,59 * * * * /usr/share/astguiclient/AST_CRON_audio_3_ftp.pl --WAV
#
# make sure that the following directories exist:
# /var/spool/asterisk/monitor # default Asterisk recording directory
# /var/spool/asterisk/monitorDONE # where the merged audio files are put
#
# This program assumes that recordings are saved by Asterisk as .wav
# should be easy to change this code if you use .gsm instead
#
# Copyright (C) 2023 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
#
#
# 230131-2244 - First Build, based on AST_CRON_audio_1_move_mix.pl script
#
$MIX=0;
$STEREO=0;
$HTTPS=0;
### begin parsing run-time options ###
if (length($ARGV[0])>1)
{
$i=0;
while ($#ARGV >= $i)
{
$args = "$args $ARGV[$i]";
$i++;
}
if ($args =~ /--help/i)
{
print "allowed run time options:\n";
print " [--debug] = debug\n";
print " [--debugX] = super debug\n";
print " [-t] = test\n";
print " [--MIX] = mix audio files in MIX directory\n";
print " [--STEREO] = mix audio files in STEREO directory\n";
print " [--HTTPS] = use https instead of http in local location\n";
print "\n";
exit;
}
else
{
if ($args =~ /--debug/i)
{
$DB=1;
print "\n----- DEBUG -----\n\n";
}
if ($args =~ /--debugX/i)
{
$DBX=1;
print "\n----- SUPER DEBUG -----\n\n";
}
if ($args =~ /-t/i)
{
$T=1; $TEST=1;
print "\n-----TESTING -----\n\n";
}
if ($args =~ /--MIX/i)
{
$MIX=1;
if ($DB) {print "MIX directory audio processing only\n";}
}
if ($args =~ /--STEREO/i)
{
$STEREO=1;
if ($DB) {print "STEREO directory audio processing only\n";}
}
if ($args =~ /--HTTPS/i)
{
$HTTPS=1;
if ($DB) {print "HTTPS location option enabled\n";}
}
}
}
else
{
#print "no command line options set\n";
}
# 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 =~ /^PATHDONEmonitor/) && ($CLIDONEmonitor < 1) )
{$PATHDONEmonitor = $line; $PATHDONEmonitor =~ 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;}
if ( ($line =~ /^VARFTP_host/) && ($CLIFTP_host < 1) )
{$VARFTP_host = $line; $VARFTP_host =~ s/.*=//gi;}
if ( ($line =~ /^VARFTP_user/) && ($CLIFTP_user < 1) )
{$VARFTP_user = $line; $VARFTP_user =~ s/.*=//gi;}
if ( ($line =~ /^VARFTP_pass/) && ($CLIFTP_pass < 1) )
{$VARFTP_pass = $line; $VARFTP_pass =~ s/.*=//gi;}
if ( ($line =~ /^VARFTP_port/) && ($CLIFTP_port < 1) )
{$VARFTP_port = $line; $VARFTP_port =~ s/.*=//gi;}
if ( ($line =~ /^VARFTP_dir/) && ($CLIFTP_dir < 1) )
{$VARFTP_dir = $line; $VARFTP_dir =~ s/.*=//gi;}
if ( ($line =~ /^VARHTTP_path/) && ($CLIHTTP_path < 1) )
{$VARHTTP_path = $line; $VARHTTP_path =~ s/.*=//gi;}
$i++;
}
# Customized Variables
$server_ip = $VARserver_ip; # Asterisk server IP
if (!$VARDB_port) {$VARDB_port='3306';}
use Time::HiRes ('gettimeofday','usleep','sleep'); # necessary to have perl sleep command of less than one second
use DBI;
$dbhA = DBI->connect("DBI:mysql:$VARDB_database:$VARDB_server:$VARDB_port", "$VARDB_user", "$VARDB_pass")
or die "Couldn't connect to database: " . DBI->errstr;
### find soxmix or sox to do the mixing
$soxmixbin = '';
if ( -e ('/usr/bin/soxmix')) {$soxmixbin = '/usr/bin/soxmix';}
else
{
if ( -e ('/usr/local/bin/soxmix')) {$soxmixbin = '/usr/local/bin/soxmix';}
else
{
if ($DB) {print "Can't find soxmix binary! Trying sox...\n";}
if ( -e ('/usr/bin/sox')) {$soxmixbin = '/usr/bin/sox -m';}
else
{
if ( -e ('/usr/local/bin/sox')) {$soxmixbin = '/usr/local/bin/sox -m';}
else
{
print "Can't find sox binary! Exiting...\n";
exit;
}
}
}
}
### find soxi to gather the length info if needed
$soxibin = '';
if ( -e ('/usr/bin/soxi')) {$soxibin = '/usr/bin/soxi';}
else
{
if ( -e ('/usr/local/bin/soxi')) {$soxibin = '/usr/local/bin/soxi';}
else
{
if ( -e ('/usr/sbin/soxi')) {$soxibin = '/usr/sbin/soxi';}
else
{
if ($DB) {print "Can't find soxi binary! No length calculations will be available...\n";}
}
}
}
### directory where in/out recordings are saved to by Asterisk
$dir1 = "$PATHmonitor";
$dir2 = "$PATHDONEmonitor";
$STEREOarch='';
if ($MIX > 0)
{$dir1 = "$PATHmonitor/MIX";}
if ($STEREO > 0)
{
$dir1 = "$PATHmonitor/STEREO";
$dir2 = "$PATHDONEmonitor";
# $STEREOarch='/STEREO';
}
opendir(FILE, "$dir1/");
@FILES = readdir(FILE);
### Loop through files first to gather filesizes
$i=0;
$calls=0;
foreach(@FILES)
{
$FILEsize1[$i] = 0;
if ( (length($FILES[$i]) > 4) && (!-d "$dir1/$FILES[$i]") )
{
$FILEsize1[$i] = (-s "$dir1/$FILES[$i]");
if ($DBX) {print "$FILES[$i] $FILEsize1[$i]\n";}
if ($FILES[$i] !~ /^DIALER_/i) {$calls++;}
}
$i++;
}
if ($DB) {print "Total recording files found: $i (calls: $calls)\n";}
sleep(5);
### Loop through files a second time to gather filesizes again 5 seconds later
$i=0;
foreach(@FILES)
{
$FILEsize2[$i] = 0;
if ( (length($FILES[$i]) > 4) && (!-d "$dir1/$FILES[$i]") )
{
$FILEsize2[$i] = (-s "$dir1/$FILES[$i]");
if ($DBX) {print "$FILES[$i] $FILEsize2[$i]\n\n";}
if ( ($FILES[$i] !~ /^CARRIER_|lost\+found/i) && ($FILEsize1[$i] eq $FILEsize2[$i]) && (length($FILES[$i]) > 4))
{
$INfile = $FILES[$i];
$OUTfile = $FILES[$i];
$OUTfile =~ s/DIALER_/CARRIER_/gi;
$ALLfile = $FILES[$i];
$ALLfile =~ s/DIALER_//gi;
$SQLFILE = $FILES[$i];
$SQLFILE =~ s/DIALER_|\.wav//gi;
$length_in_sec=0;
$stmtA = "select recording_id,length_in_sec from recording_log where filename='$SQLFILE' order by recording_id desc LIMIT 1;";
if($DBX){print STDERR "\n|$stmtA|\n";}
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
$sthArows=$sthA->rows;
if ($sthArows > 0)
{
@aryA = $sthA->fetchrow_array;
$recording_id = $aryA[0];
$length_in_sec = $aryA[1];
}
$sthA->finish();
if ($DB) {print "|$recording_id|$length_in_sec|$INfile|$OUTfile| |$ALLfile|\n";}
`$soxmixbin -M "$dir1/$INfile" "$dir1/$OUTfile" "$dir2/$ALLfile"`;
$lengthSQL='';
if ( ( ($length_in_sec < 1) || ($length_in_sec =~ /^NULL$/i) || (length($length_in_sec)<1) ) && (length($soxibin) > 3) )
{
@soxi_output = `$soxibin -D $dir2/$ALLfile`;
$soxi_sec = $soxi_output[0];
$soxi_sec =~ s/\..*|\n|\r| //gi;
$soxi_min = ($soxi_sec / 60);
$soxi_min = sprintf("%.2f", $soxi_min);
$lengthSQL = ",length_in_sec='$soxi_sec',length_in_min='$soxi_min'";
}
$HTTP='http';
if ($HTTPS > 0) {$HTTP='https';}
$stmtA = "UPDATE recording_log set location='$HTTP://$server_ip/RECORDINGS$STEREOarch/$ALLfile' $lengthSQL where recording_id='$recording_id';";
if($DBX){print STDERR "\n|$stmtA|\n";}
$affected_rows = $dbhA->do($stmtA); # or die "Couldn't execute query:|$stmtA|\n";
if (!$T)
{
`mv -f "$dir1/$INfile" "$dir2/ORIG/$INfile"`;
`mv -f "$dir1/$OUTfile" "$dir2/ORIG/$OUTfile"`;
}
### sleep for twenty hundredths of a second to not flood the server with disk activity
usleep(1*200*1000);
}
}
$i++;
}
if ($DB) {print "DONE... EXITING\n\n";}
$dbhA->disconnect();
exit;
@@ -28,7 +28,7 @@
# #
# This program assumes that recordings are saved by Asterisk as .wav # This program assumes that recordings are saved by Asterisk as .wav
# #
# Copyright (C) 2017 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2 # Copyright (C) 2023 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
# #
# #
# 80302-1958 - First Build # 80302-1958 - First Build
@@ -38,6 +38,7 @@
# 110524-1059 - Added run-check concurrency check option # 110524-1059 - Added run-check concurrency check option
# 160523-0652 - Added --HTTPS option to use https instead of http in local location # 160523-0652 - Added --HTTPS option to use https instead of http in local location
# 170212-0732 - Added --file-sorting option to put files into dated directories (THIS WILL NOT ALLOW FTP ARCHIVING) # 170212-0732 - Added --file-sorting option to put files into dated directories (THIS WILL NOT ALLOW FTP ARCHIVING)
# 230201-0007 - Allowed for handling of stereo gateway recordings
# #
$GSM=0; $MP3=0; $OGG=0; $GSW=0; $GSM=0; $MP3=0; $OGG=0; $GSW=0;
@@ -303,6 +304,7 @@ foreach(@FILES)
$ALLfile = $FILES[$i]; $ALLfile = $FILES[$i];
$SQLFILE = $FILES[$i]; $SQLFILE = $FILES[$i];
$SQLFILE =~ s/-all\.wav|-all\.gsm//gi; $SQLFILE =~ s/-all\.wav|-all\.gsm//gi;
$SQLFILE =~ s/\.wav|\.gsm//gi;
$stmtA = "select recording_id, LEFT(start_time,10) AS file_date from recording_log where filename='$SQLFILE' order by recording_id desc LIMIT 1;"; $stmtA = "select recording_id, LEFT(start_time,10) AS file_date from recording_log where filename='$SQLFILE' order by recording_id desc LIMIT 1;";
if($DBX){print STDERR "\n|$stmtA|\n";} if($DBX){print STDERR "\n|$stmtA|\n";}
@@ -339,6 +341,7 @@ foreach(@FILES)
{ {
$GSMfile = $FILES[$i]; $GSMfile = $FILES[$i];
$GSMfile =~ s/-all\.wav/-all.gsm/gi; $GSMfile =~ s/-all\.wav/-all.gsm/gi;
$GSMfile =~ s/\.wav/.gsm/gi;
if ($DB) {print "|$recording_id|$ALLfile|$dir2/$location$GSMfile| |$SQLfile|\n";} if ($DB) {print "|$recording_id|$ALLfile|$dir2/$location$GSMfile| |$SQLfile|\n";}
@@ -353,6 +356,7 @@ foreach(@FILES)
{ {
$OGGfile = $FILES[$i]; $OGGfile = $FILES[$i];
$OGGfile =~ s/-all\.wav/-all.ogg/gi; $OGGfile =~ s/-all\.wav/-all.ogg/gi;
$OGGfile =~ s/\.wav|\.gsm/.ogg/gi;
if ($DB) {print "|$recording_id|$ALLfile|$dir2/$location$OGGfile| |$SQLfile|\n";} if ($DB) {print "|$recording_id|$ALLfile|$dir2/$location$OGGfile| |$SQLfile|\n";}
@@ -367,6 +371,7 @@ foreach(@FILES)
{ {
$MP3file = $FILES[$i]; $MP3file = $FILES[$i];
$MP3file =~ s/-all\.wav/-all.mp3/gi; $MP3file =~ s/-all\.wav/-all.mp3/gi;
$MP3file =~ s/\.wav|\.gsm/.mp3/gi;
if ($DB) {print "|$recording_id|$ALLfile|$dir2/$location$MP3file| |$SQLfile|\n";} if ($DB) {print "|$recording_id|$ALLfile|$dir2/$location$MP3file| |$SQLfile|\n";}
@@ -21,11 +21,12 @@
# FLAGS FOR ENCRYPTION OPTIONS # FLAGS FOR ENCRYPTION OPTIONS
# --GPG = GnuPG encryption(assumes recipient public keys are loaded on server) # --GPG = GnuPG encryption(assumes recipient public keys are loaded on server)
# #
# Copyright (C) 2016 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2 # Copyright (C) 2023 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
# #
# #
# 150911-1814 - First Build based upon 110524-1059 AST_CRON_audio_2_compress.pl # 150911-1814 - First Build based upon 110524-1059 AST_CRON_audio_2_compress.pl
# 160523-0651 - Added --HTTPS option to use https instead of http in local location # 160523-0651 - Added --HTTPS option to use https instead of http in local location
# 230201-0003 - Allowed for handling of stereo gateway recordings
# #
$WAV=0; $GSM=0; $MP3=0; $OGG=0; $GSW=0; $WAV=0; $GSM=0; $MP3=0; $OGG=0; $GSW=0;
@@ -320,6 +321,7 @@ foreach(@FILES)
$ALLfile = $FILES[$i]; $ALLfile = $FILES[$i];
$SQLFILE = $FILES[$i]; $SQLFILE = $FILES[$i];
$SQLFILE =~ s/-all\.wav|-all\.gsm|-all\.mp3|-all\.gsw|-all\.ogg//gi; $SQLFILE =~ s/-all\.wav|-all\.gsm|-all\.mp3|-all\.gsw|-all\.ogg//gi;
$SQLFILE =~ s/\.wav|\.gsm|\.ogg|\.mp3//gi;
$stmtA = "select recording_id from recording_log where filename='$SQLFILE' order by recording_id desc LIMIT 1;"; $stmtA = "select recording_id from recording_log where filename='$SQLFILE' order by recording_id desc LIMIT 1;";
if($DBX){print STDERR "\n|$stmtA|\n";} if($DBX){print STDERR "\n|$stmtA|\n";}
@@ -344,6 +346,11 @@ foreach(@FILES)
$GPGfile =~ s/-all\.mp3/-all.mp3.gpg/gi; $GPGfile =~ s/-all\.mp3/-all.mp3.gpg/gi;
$GPGfile =~ s/-all\.gsw/-all.gsw.gpg/gi; $GPGfile =~ s/-all\.gsw/-all.gsw.gpg/gi;
$GPGfile =~ s/-all\.ogg/-all.ogg.gpg/gi; $GPGfile =~ s/-all\.ogg/-all.ogg.gpg/gi;
$GPGfile =~ s/\.wav/.wav.gpg/gi;
$GPGfile =~ s/\.gsm/.gsm.gpg/gi;
$GPGfile =~ s/\.mp3/.mp3.gpg/gi;
$GPGfile =~ s/\.gsw/.gsw.gpg/gi;
$GPGfile =~ s/\.ogg/.ogg.gpg/gi;
if ($DB) {print "$i|$recording_id|$ALLfile|$GPGfile| |$SQLfile|\n";} if ($DB) {print "$i|$recording_id|$ALLfile|$GPGfile| |$SQLfile|\n";}
+3 -1
View File
@@ -39,7 +39,7 @@
# #
# This program assumes that recordings are saved by Asterisk as .wav # This program assumes that recordings are saved by Asterisk as .wav
# #
# Copyright (C) 2018 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2 # Copyright (C) 2023 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
# #
# #
# 80302-1958 - First Build # 80302-1958 - First Build
@@ -59,6 +59,7 @@
# 160406-2055 - Added YMDdatedir option # 160406-2055 - Added YMDdatedir option
# 180511-2018 - Added --YearYMDdatedir option # 180511-2018 - Added --YearYMDdatedir option
# 180616-2248 - Added --localdatedir option # 180616-2248 - Added --localdatedir option
# 230131-2321 - Allowed for handling of stereo gateway recordings
# #
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
@@ -432,6 +433,7 @@ foreach(@FILES)
$SQLFILE = $FILES[$i]; $SQLFILE = $FILES[$i];
$SQLFILE =~ s/\.gpg//gi; $SQLFILE =~ s/\.gpg//gi;
$SQLFILE =~ s/-all\.wav|-all\.gsm|-all\.ogg|-all\.mp3//gi; $SQLFILE =~ s/-all\.wav|-all\.gsm|-all\.ogg|-all\.mp3//gi;
$SQLFILE =~ s/\.wav|\.gsm|\.ogg|\.mp3//gi;
$stmtA = "select recording_id,start_time from recording_log where filename='$SQLFILE' order by recording_id desc LIMIT 1;"; $stmtA = "select recording_id,start_time from recording_log where filename='$SQLFILE' order by recording_id desc LIMIT 1;";
if($DBX){print STDERR "\n|$stmtA|\n";} if($DBX){print STDERR "\n|$stmtA|\n";}
@@ -52,13 +52,14 @@
# #
# This program assumes that recordings are saved by Asterisk as .wav # This program assumes that recordings are saved by Asterisk as .wav
# #
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2 # Copyright (C) 2023 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
# #
# #
# 180518-0732 - First Build based upon AST_CRON_audio_3_ftp.pl script # 180518-0732 - First Build based upon AST_CRON_audio_3_ftp.pl script
# 180616-2248 - Added --localdatedir option # 180616-2248 - Added --localdatedir option
# 200205-1716 - Added comments for TLS Session Resumption settings # 200205-1716 - Added comments for TLS Session Resumption settings
# 221002-1602 - Added comments for optional additional FTPSSL variable: "OverridePASV" # 221002-1602 - Added comments for optional additional FTPSSL variable: "OverridePASV"
# 230201-0004 - Allowed for handling of stereo gateway recordings
# #
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
@@ -451,6 +452,7 @@ foreach(@FILES)
$SQLFILE = $FILES[$i]; $SQLFILE = $FILES[$i];
$SQLFILE =~ s/\.gpg//gi; $SQLFILE =~ s/\.gpg//gi;
$SQLFILE =~ s/-all\.wav|-all\.gsm|-all\.ogg|-all\.mp3//gi; $SQLFILE =~ s/-all\.wav|-all\.gsm|-all\.ogg|-all\.mp3//gi;
$SQLFILE =~ s/\.wav|\.gsm|\.ogg|\.mp3//gi;
$stmtA = "select recording_id,start_time from recording_log where filename='$SQLFILE' order by recording_id desc LIMIT 1;"; $stmtA = "select recording_id,start_time from recording_log where filename='$SQLFILE' order by recording_id desc LIMIT 1;";
if($DBX){print STDERR "\n|$stmtA|\n";} if($DBX){print STDERR "\n|$stmtA|\n";}
+3 -1
View File
@@ -53,12 +53,13 @@
# --ftp-host="10.10.10.15" --ftp-port=21 --ftp-user="username" --ftp-pass="password" --ftp-dir="RECORDINGS" \ # --ftp-host="10.10.10.15" --ftp-port=21 --ftp-user="username" --ftp-pass="password" --ftp-dir="RECORDINGS" \
# --url-path="http://10.10.10.15/RECORDINGS" --transfer-limit=50 --list-limit=200 --campaign_id="TESTCAMP1-TESTCAMP2" # --url-path="http://10.10.10.15/RECORDINGS" --transfer-limit=50 --list-limit=200 --campaign_id="TESTCAMP1-TESTCAMP2"
# #
# Copyright (C) 2015 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2 # Copyright (C) 2023 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
# #
# CHANGELOG: # CHANGELOG:
# 90930-1405 - mikec - first build # 90930-1405 - mikec - first build
# 110524-1054 - Added run-check concurrency check option # 110524-1054 - Added run-check concurrency check option
# 150912-0837 - Added GPG encrypted audio file compatibility # 150912-0837 - Added GPG encrypted audio file compatibility
# 230201-0002 - Allowed for handling of stereo gateway recordings
# #
use 5.008; use 5.008;
@@ -504,6 +505,7 @@ foreach(@files) {
my $SQLFILE = $files[$file_loop_count]; my $SQLFILE = $files[$file_loop_count];
$SQLFILE =~ s/\.gpg//gi; $SQLFILE =~ s/\.gpg//gi;
$SQLFILE =~ s/-all\.wav|-all\.gsm|-all\.ogg|-all\.mp3//gi; $SQLFILE =~ s/-all\.wav|-all\.gsm|-all\.ogg|-all\.mp3//gi;
$SQLFILE =~ s/\.wav|\.gsm|\.ogg|\.mp3//gi;
my $rec_log_db_stmt = "select recording_id, start_time, vicidial_id, lead_id from recording_log where filename=$SQLFILE order by recording_id desc LIMIT 1;"; my $rec_log_db_stmt = "select recording_id, start_time, vicidial_id, lead_id from recording_log where filename=$SQLFILE order by recording_id desc LIMIT 1;";
$rec_log_sth->execute($SQLFILE) or die "executing: $rec_log_db_stmt ", $dbhA->errstr; $rec_log_sth->execute($SQLFILE) or die "executing: $rec_log_db_stmt ", $dbhA->errstr;
+3 -1
View File
@@ -26,7 +26,7 @@
# #
# This program assumes that recordings are saved by Asterisk as .wav # This program assumes that recordings are saved by Asterisk as .wav
# #
# Copyright (C) 2015 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2 # Copyright (C) 2023 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
# #
# CHANGES: # CHANGES:
# 91123-0005 - First Build # 91123-0005 - First Build
@@ -34,6 +34,7 @@
# 111128-1617 - Added Ftp persistence option # 111128-1617 - Added Ftp persistence option
# 111130-1801 - Added Ftp validate option # 111130-1801 - Added Ftp validate option
# 130116-1536 - Added ftp port CLI flag # 130116-1536 - Added ftp port CLI flag
# 230201-0006 - Allowed for handling of stereo gateway recordings
# #
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
@@ -332,6 +333,7 @@ foreach(@FILES)
$SQLFILE = $FILES[$i]; $SQLFILE = $FILES[$i];
$SQLFILE =~ s/\.gpg//gi; $SQLFILE =~ s/\.gpg//gi;
$SQLFILE =~ s/-all\.wav|-all\.gsm|-all\.ogg|-all\.mp3//gi; $SQLFILE =~ s/-all\.wav|-all\.gsm|-all\.ogg|-all\.mp3//gi;
$SQLFILE =~ s/\.wav|\.gsm|\.ogg|\.mp3//gi;
$stmtA = "select recording_id,start_time from recording_log where filename='$SQLFILE' order by recording_id desc LIMIT 1;"; $stmtA = "select recording_id,start_time from recording_log where filename='$SQLFILE' order by recording_id desc LIMIT 1;";
if($DBX){print STDERR "\n|$stmtA|\n";} if($DBX){print STDERR "\n|$stmtA|\n";}
@@ -39,7 +39,7 @@
# #
# This program assumes that recordings are saved by Asterisk as .wav # This program assumes that recordings are saved by Asterisk as .wav
# #
# Copyright (C) 2022 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2 # Copyright (C) 2023 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
# #
# CHANGES: # CHANGES:
# 130730-1849 - First Build based upon AST_CRON_audio_4_ftp2.pl script # 130730-1849 - First Build based upon AST_CRON_audio_4_ftp2.pl script
@@ -47,6 +47,7 @@
# 180516-2011 - Added --noping option # 180516-2011 - Added --noping option
# 200205-1717 - Added comments for TLS Session Resumption settings # 200205-1717 - Added comments for TLS Session Resumption settings
# 221002-1601 - Added comments for optional additional FTPSSL variable: "OverridePASV" # 221002-1601 - Added comments for optional additional FTPSSL variable: "OverridePASV"
# 230201-0005 - Allowed for handling of stereo gateway recordings
# #
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
@@ -364,6 +365,7 @@ foreach(@FILES)
$SQLFILE = $FILES[$i]; $SQLFILE = $FILES[$i];
$SQLFILE =~ s/\.gpg//gi; $SQLFILE =~ s/\.gpg//gi;
$SQLFILE =~ s/-all\.wav|-all\.gsm|-all\.ogg|-all\.mp3//gi; $SQLFILE =~ s/-all\.wav|-all\.gsm|-all\.ogg|-all\.mp3//gi;
$SQLFILE =~ s/\.wav|\.gsm|\.ogg|\.mp3//gi;
$stmtA = "select recording_id,start_time from recording_log where filename='$SQLFILE' order by recording_id desc LIMIT 1;"; $stmtA = "select recording_id,start_time from recording_log where filename='$SQLFILE' order by recording_id desc LIMIT 1;";
if($DBX){print STDERR "\n|$stmtA|\n";} if($DBX){print STDERR "\n|$stmtA|\n";}
+2 -1
View File
@@ -1,4 +1,4 @@
CALLER ID NAME CODES DOC Started: 2013-07-15 Updated: 2022-12-02 CALLER ID NAME CODES DOC Started: 2013-07-15 Updated: 2023-02-01
This document is meant for reference only, and it does not contain all CID name codes possible, but more will be added over time. This document is meant for reference only, and it does not contain all CID name codes possible, but more will be added over time.
@@ -36,3 +36,4 @@ BW - Real-time screen blind whisper (BW149425456200006666)
E - Inbound Email, tracking only (E0001797980001237995) E - Inbound Email, tracking only (E0001797980001237995)
ACagcW - Noone in session call agent phone (ACagcW15167259066666) ACagcW - Noone in session call agent phone (ACagcW15167259066666)
AM - Agent mute of recording (AM273955W0001922575W) AM - Agent mute of recording (AM273955W0001922575W)
G - Recording Gateway inbound call (G2010021380000000023)
@@ -0,0 +1,111 @@
VICI RECORDING GATEWAY SERVER Started: 2023-01-14 Updated: 2023-02-01
This project was designed to allow for a dedicated recording gateway server to generate stereo audio recordings of the entirety of all inbound and outbound phone calls, with the customer on one channel and the agent/dialer on the other, within the same WAV audio file.
The recording files can be archived on the normal archive server, although keep in mind that if the uncompressed WAV audio format is used, that these new recordings will take up ten times as much space as MP3 audio files. Also, these recordings will be for entire phone calls, including any queue time on inbound calls and ring time on all outbound calls(even unanswered calls), so the space required(even if compressed) could be substantially more than standard VICIdial recordings would take.
For outbound calls, the gateway recordings can be tied to the original Lead ID and the call_id of the call, providing that the CallerIDname is not modified before it reaches the recording gateway server.
For inbound calls, the gateway recordings can be tied to the original DID Log entry and UniqueID of the call on the VICIdial system. Depending on how complex the inbound call routing is, the gateway recording may also be able to be tied to a Lead ID.
New scripts added:
- agi-VICIrecGateway.agi Logs calls and recordings on the gateway
- AST_CRON_audio_1_gateway_stereo.pl Merges L/R into Stereo, updates recording_log
Existing scripts modified:
- agi-DID_route.agi Check for Gateway inbound call, log if found
- AST_CRON_audio_...pl scripts Allow for gateway recordings to be processed
Scripts to add to the crontab on the Gateway Recording server, staggered every 3 minutes during production times:
/usr/share/astguiclient/AST_CRON_audio_1_gateway_stereo.pl --STEREO --debugX
(if required:)
/usr/share/astguiclient/AST_CRON_audio_3_ftp.pl --WAV --debugX --run-check --ftp-persistent --ftp-validate
Example extensions.conf changes:
INBOUND EXISTING VICIDIAL SERVERS:
(add the first line, change the priority of second line to 'n')
[trunkinbound]
exten => _X.,1,Set(VICIrecGatewayID=${SIP_HEADER(X-VICIrecGatewayID)})
exten => _x.,n,Noop(${SIP_HEADER(X-VICIrecGatewayID)})
exten => _X.,n,AGI(agi-DID_route.agi)
exten => _X.,n,Hangup()
NEW VICI RECORDING GATEWAY SERVER:
(Assumes use of PJSIP on the Gateway Recording server, adjust for your inbound dialer and outbound carrier)
[handler]
exten => addheader,1,Set(PJSIP_HEADER(add,X-VICIrecGatewayID)=${VICIrecGatewayID})
exten => addheader,n,Return()
[stereo-rec-inbound]
exten => _X.,1,Progress()
exten => _X.,n,Noop(${CALLERID(num)})
exten => _X.,n,AGI(agi-VICIrecGateway.agi)
exten => _X.,n,Noop(${CARRIER_FILENAME})
exten => _X.,n,Noop(${DIALER_FILENAME})
exten => _X.,n,MixMonitor(,r(${CARRIER_FILENAME})t(${DIALER_FILENAME})S)
exten => _X.,n,Dial(PJSIP/${EXTEN}@pjdial147,,Tob(handler^addheader^1))
[stereo-rec-outbound]
exten => _X.,1,Progress()
exten => _X.,n,Noop(${CALLERID(num)})
exten => _X.,n,AGI(agi-VICIrecGateway.agi)
exten => _X.,n,Noop(${CARRIER_FILENAME})
exten => _X.,n,Noop(${DIALER_FILENAME})
exten => _X.,n,MixMonitor(,t(${CARRIER_FILENAME})r(${DIALER_FILENAME})S)
exten => _X.,n,Dial(PJSIP/${EXTEN}@pjsgw1,,To)
-------------------------------------------------------------------------------------------------
New Database Tables (FOR REFERENCE ONLY!):
CREATE TABLE gateway_recording_log (
gateway_recording_id INT(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL,
recording_log_id INT(10) UNSIGNED default '0',
call_direction ENUM('INBOUND','OUTBOUND','NA') default 'NA',
call_id VARCHAR(40) default '',
lead_id INT(9) UNSIGNED,
uniqueid VARCHAR(20) NOT NULL,
server_ip VARCHAR(15),
caller_id_number VARCHAR(18),
caller_id_name VARCHAR(20),
extension VARCHAR(100),
start_time DATETIME,
end_time DATETIME,
length_in_sec MEDIUMINT(8) UNSIGNED default '0',
filename VARCHAR(100),
location VARCHAR(255),
index(start_time),
index(call_id),
index(lead_id)
) ENGINE=MyISAM;
CREATE TABLE vicidial_did_gateway_log (
uniqueid VARCHAR(20) NOT NULL,
channel VARCHAR(100) NOT NULL,
server_ip VARCHAR(15) NOT NULL,
caller_id_number VARCHAR(18),
caller_id_name VARCHAR(20),
extension VARCHAR(100),
call_date DATETIME,
VICIrecGatewayID VARCHAR(30) default '',
index (uniqueid),
index (VICIrecGatewayID),
index (extension),
index (call_date)
) ENGINE=MyISAM;
@@ -4840,6 +4840,42 @@ country CHAR(3),
index (postal_code) index (postal_code)
) ENGINE=MyISAM; ) ENGINE=MyISAM;
CREATE TABLE gateway_recording_log (
gateway_recording_id INT(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL,
recording_log_id INT(10) UNSIGNED default '0',
call_direction ENUM('INBOUND','OUTBOUND','NA') default 'NA',
call_id VARCHAR(40) default '',
lead_id INT(9) UNSIGNED,
uniqueid VARCHAR(20) NOT NULL,
server_ip VARCHAR(15),
caller_id_number VARCHAR(18),
caller_id_name VARCHAR(20),
extension VARCHAR(100),
start_time DATETIME,
end_time DATETIME,
length_in_sec MEDIUMINT(8) UNSIGNED default '0',
filename VARCHAR(100),
location VARCHAR(255),
index(start_time),
index(call_id),
index(lead_id)
) ENGINE=MyISAM;
CREATE TABLE vicidial_did_gateway_log (
uniqueid VARCHAR(20) NOT NULL,
channel VARCHAR(100) NOT NULL,
server_ip VARCHAR(15) NOT NULL,
caller_id_number VARCHAR(18),
caller_id_name VARCHAR(20),
extension VARCHAR(100),
call_date DATETIME,
VICIrecGatewayID VARCHAR(30) default '',
index (uniqueid),
index (VICIrecGatewayID),
index (extension),
index (call_date)
) ENGINE=MyISAM;
ALTER TABLE vicidial_email_list MODIFY message text character set utf8; ALTER TABLE vicidial_email_list MODIFY message text character set utf8;
@@ -5196,4 +5232,4 @@ INSERT INTO `wallboard_reports` VALUES ('AGENTS_AND_QUEUES','Agents and Queues',
UPDATE system_settings set vdc_agent_api_active='1'; UPDATE system_settings set vdc_agent_api_active='1';
UPDATE system_settings SET db_schema_version='1675',db_schema_update_date=NOW(),reload_timestamp=NOW(); UPDATE system_settings SET db_schema_version='1676',db_schema_update_date=NOW(),reload_timestamp=NOW();
+38
View File
@@ -2101,3 +2101,41 @@ ALTER TABLE vicidial_campaigns ADD agent_hangup_ig_override ENUM('Y','N') defaul
UPDATE vicidial_campaigns SET agent_hangup_value='' where agent_hangup_value IS NULL; UPDATE vicidial_campaigns SET agent_hangup_value='' where agent_hangup_value IS NULL;
UPDATE system_settings SET db_schema_version='1675',db_schema_update_date=NOW() where db_schema_version < 1675; UPDATE system_settings SET db_schema_version='1675',db_schema_update_date=NOW() where db_schema_version < 1675;
CREATE TABLE gateway_recording_log (
gateway_recording_id INT(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL,
recording_log_id INT(10) UNSIGNED default '0',
call_direction ENUM('INBOUND','OUTBOUND','NA') default 'NA',
call_id VARCHAR(40) default '',
lead_id INT(9) UNSIGNED,
uniqueid VARCHAR(20) NOT NULL,
server_ip VARCHAR(15),
caller_id_number VARCHAR(18),
caller_id_name VARCHAR(20),
extension VARCHAR(100),
start_time DATETIME,
end_time DATETIME,
length_in_sec MEDIUMINT(8) UNSIGNED default '0',
filename VARCHAR(100),
location VARCHAR(255),
index(start_time),
index(call_id),
index(lead_id)
) ENGINE=MyISAM;
CREATE TABLE vicidial_did_gateway_log (
uniqueid VARCHAR(20) NOT NULL,
channel VARCHAR(100) NOT NULL,
server_ip VARCHAR(15) NOT NULL,
caller_id_number VARCHAR(18),
caller_id_name VARCHAR(20),
extension VARCHAR(100),
call_date DATETIME,
VICIrecGatewayID VARCHAR(30) default '',
index (uniqueid),
index (VICIrecGatewayID),
index (extension),
index (call_date)
) ENGINE=MyISAM;
UPDATE system_settings SET db_schema_version='1676',db_schema_update_date=NOW() where db_schema_version < 1676;