Added basic one-way Cross-Cluster-Communication feature

Added ccc_lead_info API function
If phone entry fullname and cidnumber are empty, don't populate a callerid conf line in ADMIN_keepalive_ALL.pl script

git-svn-id: svn://192.168.202.10@2776 3d104415-ff17-0410-8863-d5cf3c621b8a
This commit is contained in:
mattf
2017-06-09 20:13:55 +00:00
parent 1e5dc3ec83
commit cee52889a0
8 changed files with 827 additions and 25 deletions
+4
View File
@@ -165,6 +165,10 @@ OTHER CHANGES:
36. Added Add-to-hopper options to update_lead function in the Non-Agent API
37. Added basic one-way Cross-Cluster-Communication feature. Allowing for lead
information to pass from one VICIdial system to another with a call.
See the CROSS_CLUSTER_COMMUNICATION.txt document for more information.
+504
View File
@@ -0,0 +1,504 @@
#!/usr/bin/perl
#
# cm_sc_ccc_lookup_insert.agi version 2.14
#
# Designed to work with Call Menus to send a URL defined in a Settings Container
# for a call with a call_id associated with it for calls coming from an external
# VICIdial system on a private IAX trunk so that the lead information can be
# copied to this destination cluster.
#
# If container is not found, call will go to the 'C' option in the call menu
# If call_id is not defined, call will go to the 'D' option in the call menu
# If lead is not found on external system, call will go to the 'B' option in the call menu
# If lead is found on external system, call will go to the 'A' option in the call menu
#
# Flag Options: (separated by triple-pipe: "---")
# 1- container_id for settings container with URL to send
# 2- local list_id to insert lead into(if not populated, will use external list_id)
#
# example of what to set in the Call Menu:
# Set the prompt to "wait-moment|cm_sc_ccc_lookup_insert.agi,ccc_test---8199"
#
# The URL that you define in the Settings Container will need to be sent to you
# by the administrator of the external system. It should look something like this:
# http://server/vicidial/non_agent_api.php?user=6666&pass=1234&source=test&function=ccc_lead_info&call_id=--A--call_id--B--
#
# Copyright (C) 2017 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
#
# changes:
# 170609-1326 - First build
#
$script = 'cm_sc_ccc_lookup_insert.agi';
($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";}
$secX = time();
$now_date_epoch = time();
$now_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;
$state='';
$CIDlead_id='';
$US='_';
$AGILOG=1;
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";}
### find wget binary
$exit_no_wget=0;
$wgetbin = '';
if ( -e ('/bin/wget')) {$wgetbin = '/bin/wget';}
else
{
if ( -e ('/usr/bin/wget')) {$wgetbin = '/usr/bin/wget';}
else
{
if ( -e ('/usr/local/bin/wget')) {$wgetbin = '/usr/local/bin/wget';}
else
{
if ($AGILOG) {$agi_string = "Can't find wget binary! Exiting..."; &agi_output;}
$exit_no_wget=1;
}
}
}
use DBI;
use Asterisk::AGI;
$AGI = new Asterisk::AGI;
$|=1;
while(<STDIN>)
{
chomp;
last unless length($_);
if ($AGILOG)
{
if (/^agi_(\w+)\:\s+(.*)$/)
{
$AGI{$1} = $2;
}
}
if (/^agi_context\:\s+(.*)$/) {$context = $1;}
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;}
}
foreach $i (sort keys %AGI)
{
if ($AGILOG) {$agi_string = " -- $i = $AGI{$i}"; &agi_output;}
}
$callerid =~ s/\'|\\\\|\\\|\\|\\;|\\\;|\;|;//gi;
$calleridname =~ s/\'|\\\\|\\\|\\|\\;|\\\;|\;|;//gi;
$extension =~ s/\'|\"|\\\\|\\\|\\|\\;|\\\;|\;|;//gi;
$blind_xfer=0;
$three_way=0;
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|^J\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d/)
{
$blind_xfer=1;
}
elsif ($calleridname =~ /^DC\d\d\d\d\d\dW\d\d\d\d\d\d\d\d\d\dW/)
{
$three_way=1;
}
else
{
if ($AGILOG) {$agi_string = "call_id not set($calleridname), exiting the cm_sc_ccc_lookup_insert.agi app, transferring call to D @ $context"; &agi_output;}
print "SET CONTEXT $context\n";
$result = <STDIN>;
checkresult($result);
print "SET EXTENSION D\n";
$result = <STDIN>;
checkresult($result);
print "SET PRIORITY 1\n";
$result = <STDIN>;
checkresult($result);
exit;
}
if ($exit_no_wget > 0)
{
if ($AGILOG) {$agi_string = "wget not found, exiting the cm_sc_ccc_lookup_insert.agi app, transferring call to D @ $context"; &agi_output;}
print "SET CONTEXT $context\n";
$result = <STDIN>;
checkresult($result);
print "SET EXTENSION D\n";
$result = <STDIN>;
checkresult($result);
print "SET PRIORITY 1\n";
$result = <STDIN>;
checkresult($result);
exit;
}
if ($AGILOG) {$agi_string = "AGI Variables: |$unique_id|$channel|$extension|$blind_xfer|$three_way|$callerid|"; &agi_output;}
$AGI->stream_file('sip-silence');
$AGI->stream_file('sip-silence');
$AGI->stream_file('sip-silence');
$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 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;
$rec_count=0;
while ($sthArows > $rec_count)
{
$AGILOG = '0';
@aryA = $sthA->fetchrow_array;
$DBagi_output = $aryA[0];
if ($DBagi_output =~ /STDERR/) {$AGILOG = '1';}
if ($DBagi_output =~ /FILE/) {$AGILOG = '2';}
if ($DBagi_output =~ /BOTH/) {$AGILOG = '3';}
$rec_count++;
}
$sthA->finish();
### begin parsing run-time options ###
if (length($ARGV[0])>1)
{
if ($AGILOG) {$agi_string = "Perl Environment Dump:"; &agi_output;}
$i=0;
while ($#ARGV >= $i)
{
$args = "$args $ARGV[$i]";
if ($AGILOG) {$agi_string = "$i|$ARGV[$i]"; &agi_output;}
$i++;
}
### list of command-line array arguments:
@ARGV_vars = split(/---/, $ARGV[0]);
$container_id = $ARGV_vars[0];
$local_list_id = $ARGV_vars[1];
}
$no_container=0;
if (length($container_id) < 1)
{$no_container=1;}
else
{
$stmtA= "SELECT container_entry from vicidial_settings_containers where container_id='$container_id';";
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
$sthArows=$sthA->rows;
if ($AGILOG) {$agi_string = "$sthArows|$stmtA|"; &agi_output;}
if ($sthArows > 0)
{
@aryA = $sthA->fetchrow_array;
$sc_call_url = $aryA[0];
}
else
{$no_container=2;}
$sthA->finish();
}
if ($no_container > 0)
{
if ($AGILOG) {$agi_string = "container_id not set($container_id|$no_container), exiting the cm_sc_ccc_lookup_insert.agi app, transferring call to C @ $context"; &agi_output;}
print "SET CONTEXT $context\n";
$result = <STDIN>;
checkresult($result);
print "SET EXTENSION C\n";
$result = <STDIN>;
checkresult($result);
print "SET PRIORITY 1\n";
$result = <STDIN>;
checkresult($result);
exit;
}
$sc_call_url =~ s/--A--call_id--B--/$calleridname/gi;
$sc_call_url =~ s/ /+/gi;
$sc_call_url =~ s/&/\\&/gi;
$external_found=0;
### insert a new url log entry
$SQL_log = "$sc_call_url";
$SQL_log =~ s/;|\||\\//gi;
$stmtA = "INSERT INTO vicidial_url_log SET uniqueid='$uniqueid',url_date='$now_date',url_type='ccc_look',url='$SQL_log',url_response='';";
$affected_rows = $dbhA->do($stmtA);
$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;
$url_id = $aryA[0];
}
$sthA->finish();
$url = $sc_call_url;
$url =~ s/'/\\'/gi;
$url =~ s/"/\\"/gi;
$secW = time();
`$wgetbin --no-check-certificate --output-document=/tmp/ASUBtmpD$US$url_id$US$secX --output-file=/tmp/ASUBtmpF$US$url_id$US$secX $url `;
$secY = time();
$response_sec = ($secY - $secW);
open(Wdoc, "/tmp/ASUBtmpD$US$url_id$US$secX") || die "can't open /tmp/ASUBtmpD$US$url_id$US$secX: $!\n";
@Wdoc = <Wdoc>;
close(Wdoc);
$i=0;
$Wdocline_cat='';
foreach(@Wdoc)
{
$Wdocline = $Wdoc[$i];
$Wdocline =~ s/\n|\r//gi;
$Wdocline =~ s/\t|\`|\"//gi;
$Wdocline_cat .= "$Wdocline";
$i++;
}
if (length($Wdocline_cat) < 1)
{
$external_found=0;
$Wdocline_cat='<RESPONSE EMPTY>';
}
if ( (length($Wdocline_cat) > 29) && ($Wdocline_cat !~ /ERROR: ccc_lead_info /) )
{
@lead_data = split(/\|/, $Wdocline_cat);
$LEADstatus = $lead_data[0];
$LEADuser = $lead_data[1];
$LEADvendor_lead_code = $lead_data[2];
$LEADsource_id = $lead_data[3];
$LEADlist_id = $lead_data[4];
$LEADgmt_offset_now = $lead_data[5];
$LEADphone_code = $lead_data[6];
$LEADphone_number = $lead_data[7];
$LEADtitle = $lead_data[8];
$LEADfirst_name = $lead_data[9];
$LEADmiddle_initial = $lead_data[10];
$LEADlast_name = $lead_data[11];
$LEADaddress1 = $lead_data[12];
$LEADaddress2 = $lead_data[13];
$LEADaddress3 = $lead_data[14];
$LEADcity = $lead_data[15];
$LEADstate = $lead_data[16];
$LEADprovince = $lead_data[17];
$LEADpostal_code = $lead_data[18];
$LEADcountry_code = $lead_data[19];
$LEADgender = $lead_data[20];
$LEADdate_of_birth = $lead_data[21];
$LEADalt_phone = $lead_data[22];
$LEADemail = $lead_data[23];
$LEADsecurity_phrase = $lead_data[24];
$LEADcomments = $lead_data[25];
$LEADcalled_count = $lead_data[26];
$LEADlast_local_call_time = $lead_data[27];
$LEADrank = $lead_data[28];
$LEADowner = $lead_data[29];
if (length($LEADlist_id) < 2)
{$external_found=0;}
else
{
# insert lead into local system
if (length($local_list_id) > 1)
{$LEADlist_id = $local_list_id;}
$stmtA = "INSERT INTO vicidial_list SET status=\"$LEADstatus\",user=\"$LEADuser\",vendor_lead_code=\"$LEADvendor_lead_code\",source_id=\"$LEADsource_id\",list_id=\"$LEADlist_id\",gmt_offset_now=\"$LEADgmt_offset_now\",phone_code=\"$LEADphone_code\",phone_number=\"$LEADphone_number\",title=\"$LEADtitle\",first_name=\"$LEADfirst_name\",middle_initial=\"$LEADmiddle_initial\",last_name=\"$LEADlast_name\",address1=\"$LEADaddress1\",address2=\"$LEADaddress2\",address3=\"$LEADaddress3\",city=\"$LEADcity\",state=\"$LEADstate\",province=\"$LEADprovince\",postal_code=\"$LEADpostal_code\",country_code=\"$LEADcountry_code\",gender=\"$LEADgender\",date_of_birth=\"$LEADdate_of_birth\",alt_phone=\"$LEADalt_phone\",email=\"$LEADemail\",security_phrase=\"$LEADsecurity_phrase\",comments=\"$LEADcomments\",called_count=\"$LEADcalled_count\",last_local_call_time=\"$LEADlast_local_call_time\",rank=\"$LEADrank\",owner=\"$LEADowner\";";
$affected_rows = $dbhA->do($stmtA);
$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;
$new_lead_id = $aryA[0];
}
$sthA->finish();
$PADlead_id = sprintf("%010s", $new_lead_id); while (length($PADlead_id) > 10) {chop($PADlead_id);}
# YmmddhhmmssLLLLLLLLL
$YqueryCID = "Y$CIDdate$PADlead_id";
$callerid = $YqueryCID;
$VCcallerid = $YqueryCID;
### set the callerid
$Ynewcallerid = "\"$YqueryCID <$LEADphone_number>\"";
$AGI->set_callerid($Ynewcallerid);
if ($AGILOG) {$agi_string = "callerID changed: $Ynewcallerid"; &agi_output;}
$external_found=1;
}
}
open(Wfile, "/tmp/ASUBtmpF$US$url_id$US$secX") || die "can't open /tmp/ASUBtmpF$US$url_id$US$secX: $!\n";
@Wfile = <Wfile>;
close(Wfile);
$i=0;
$Wfileline_cat='';
foreach(@Wfile)
{
$Wfileline = $Wfile[$i];
$Wfileline =~ s/\n|\r/!/gi;
$Wfileline =~ s/\"|\`/'/gi;
$Wfileline =~ s/ |\t|\`//gi;
$Wfileline_cat .= "$Wfileline";
$i++;
}
if (length($Wfileline_cat)<1)
{$Wfileline_cat='<HEADER EMPTY>';}
### update url log entry
$stmtA = "UPDATE vicidial_url_log SET url_response=\"$Wdocline_cat|$Wfileline_cat\",response_sec='$response_sec' where url_log_id='$url_id';";
$affected_rows = $dbhA->do($stmtA);
if ($AGILOG) {$agi_string = "$affected_rows|$stmtA"; &agi_output;}
if ($external_found < 1)
{
if ($AGILOG) {$agi_string = "call_id not found on external system, exiting the cm_sc_ccc_lookup_insert.agi app, transferring call to B @ $context"; &agi_output;}
print "SET CONTEXT $context\n";
$result = <STDIN>;
checkresult($result);
print "SET EXTENSION B\n";
$result = <STDIN>;
checkresult($result);
print "SET PRIORITY 1\n";
$result = <STDIN>;
checkresult($result);
}
else
{
if ($AGILOG) {$agi_string = "call_id found, new lead ID($new_lead_id), exiting the cm_sc_ccc_lookup_insert.agi app, transferring call to A @ $context"; &agi_output;}
print "SET CONTEXT $context\n";
$result = <STDIN>;
checkresult($result);
print "SET EXTENSION A\n";
$result = <STDIN>;
checkresult($result);
print "SET PRIORITY 1\n";
$result = <STDIN>;
checkresult($result);
}
exit;
##### SUBROUTINES #####
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 checkresult
{
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++;
}
}
+18 -5
View File
@@ -118,9 +118,10 @@
# 170320-1338 - Added conf_qualify phones option for IAX
# 170327-0847 - Added drop list triggering code
# 170513-1728 - Added alternative uptime counter in seconds
# 170609-1601 - If phone entry fullname and cidnumber are empty, don't populate a callerid conf line
#
$build = '170513-1728';
$build = '170609-1601';
$DB=0; # Debug flag
$teodDB=0; # flag to log Timeclock End of Day processes to log file
@@ -2358,7 +2359,10 @@ if ( ($active_asterisk_server =~ /Y/) && ($generate_vicidial_conf =~ /Y/) && ($r
$Piax .= "username=$extension[$i]\n";
$Piax .= "secret=$conf_secret[$i]\n";
$Piax .= "accountcode=$extension[$i]\n";
$Piax .= "callerid=\"$fullname[$i]\" <$outbound_cid[$i]>\n";
if ( (length($fullname[$i])>0) || (length($outbound_cid[$i])>0) )
{
$Piax .= "callerid=\"$fullname[$i]\" <$outbound_cid[$i]>\n";
}
$Piax .= "mailbox=$voicemail[$i]\n";
if ($conf_qualify[$i] =~ /Y/)
{$Piax .= "qualify=yes\n";}
@@ -2383,7 +2387,10 @@ if ( ($active_asterisk_server =~ /Y/) && ($generate_vicidial_conf =~ /Y/) && ($r
$Piax .= "username=$extension[$i]\n";
$Piax .= "secret=$conf_secret[$i]\n";
$Piax .= "accountcode=$extension[$i]\n";
$Piax .= "callerid=\"$fullname[$i]\" <$outbound_cid[$i]>\n";
if ( (length($fullname[$i])>0) || (length($outbound_cid[$i])>0) )
{
$Piax .= "callerid=\"$fullname[$i]\" <$outbound_cid[$i]>\n";
}
$Piax .= "mailbox=$voicemail[$i]\n";
$Piax .= "requirecalltoken=no\n";
$Piax .= "context=$phone_context[$i]\n";
@@ -2515,7 +2522,10 @@ if ( ($active_asterisk_server =~ /Y/) && ($generate_vicidial_conf =~ /Y/) && ($r
$Psip .= "username=$extension[$i]\n";
$Psip .= "secret=$conf_secret[$i]\n";
$Psip .= "accountcode=$extension[$i]\n";
$Psip .= "callerid=\"$fullname[$i]\" <$outbound_cid[$i]>\n";
if ( (length($fullname[$i])>0) || (length($outbound_cid[$i])>0) )
{
$Psip .= "callerid=\"$fullname[$i]\" <$outbound_cid[$i]>\n";
}
$Psip .= "mailbox=$voicemail[$i]\n";
if ($codecs_with_template[$i] > 0)
{$Psip .= "$Pcodec";}
@@ -2538,7 +2548,10 @@ if ( ($active_asterisk_server =~ /Y/) && ($generate_vicidial_conf =~ /Y/) && ($r
$Psip .= "username=$extension[$i]\n";
$Psip .= "secret=$conf_secret[$i]\n";
$Psip .= "accountcode=$extension[$i]\n";
$Psip .= "callerid=\"$fullname[$i]\" <$outbound_cid[$i]>\n";
if ( (length($fullname[$i])>0) || (length($outbound_cid[$i])>0) )
{
$Psip .= "callerid=\"$fullname[$i]\" <$outbound_cid[$i]>\n";
}
$Psip .= "mailbox=$voicemail[$i]\n";
$Psip .= "context=$phone_context[$i]\n";
$Psip .= "$Pcodec";
+54 -12
View File
@@ -1,7 +1,59 @@
CROSS-CLUSTER COMMUNICATION Started: 2011-05-27 Updated: 2017-01-01
CROSS-CLUSTER COMMUNICATION Started: 2011-05-27 Updated: 2017-06-09
!!!!! THIS FEATURE DOES NOT EXIST, THIS IS FOR PLANNING PURPOSES ONLY !!!!!
--------------------------------
SIMPLER IMPLEMENTED OPTION: implemented in SVN/trunk revision 2776
--------------------------------
Below is a description of a simple cross-cluster option, which is to send lead data in one direction from one cluster to another as a phone call is sent over.
- A call to be sent from one cluster to another should leave its callerIDname as the Caller Code, the 20-character code that includes the lead_id
- This call will go through an IAX trunk between the two systems into an internal DID on the destination cluster
Set up an IAX "carrier" on the originating cluster and an IAX "phone" on the destination cluster to link the two together.
(Note: the phone entry on the destination cluster must have the Outbound CallerID and Fullname fields blank)
The destination phone entry needs to use "trunkinbound" as it's phone and exten context
- At the DID, the call will get sent to a Call Menu where the call will go through an AGI script
Set the prompt to "wait-moment|cm_sc_ccc_lookup_insert.agi,ccc_test---8199"
# Flag Options: (separated by triple-pipe: "---")
# 1- container_id for settings container with URL to send
# 2- local list_id to insert lead into(if not populated, will use external system's list_id for the lead)
- The AGI script will use parameters defined in a Settings Container for the URL of the originating system's Non-Agent API and credentials
The originating server will need to set up a user of level 8 with view reports and Agent API abilities, and the ccc_lead_info API function enabled
You will need to add a Settings Container to hold the URL for the originating system to look up the lead data, something like this:
http://server/vicidial/non_agent_api.php?user=6666&pass=1234&source=test&function=ccc_lead_info&call_id=--A--call_id--B--
- That AGI script will look up the lead on the originating system using the Non-Agent API and credentials set in a Settings Container
- The originating system will validate that the caller_code was a valid recent call before sending any data(within last 10 hours)
- If there is a match, then the AGI script will gather the default lead information, insert the information into the new system and change the callerIDname with the destination system's lead_id included
- The call will then go to option "A" and should probably be routed to an In-Group with the handle method set to "CLOSER" so it can go to an agent
NOTES:
# If lead is not found on external system, call will go to the 'B' option in the call menu
# If container is not found, call will go to the 'C' option in the call menu
# If call_id is not defined, call will go to the 'D' option in the call menu
BELOW THIS LINE ARE THE OLD PLANNING NOTES FOR A MUCH MORE COMPLEX CROSS-CLUSTER SETUP DESIGN
---------------------------------------------------------------------------------------------------------------------------------------------
!!!!! THIS FEATURE DOES NOT EXIST AS DESCRIBED BELOW, THIS IS FOR PLANNING PURPOSES ONLY !!!!!
This is a planning document for how different vicidial clusters can communicate
@@ -103,13 +155,3 @@ cluster_server_status:
--------------------------------
SIMPLER ALTERNATIVE OPTION:
--------------------------------
Below is a description of a more simple option, which is to send lead data from one cluster to another as the lead is sent over.
- A call to be sent from one cluster to another should leave its callerIDname as the Caller Code, the 20-character code that includes the lead_id
- This call will go into an internal DID on the other cluster through an IAX trunk between the two
- At the DID, the call will get sent to a Call Menu where the call will go through an AGI script
- That AGI script will look up the lead_id on the originating system using the Non-Agent API and credentials set in a Settings Container
- If there is a match, then the AGI script will gather the default lead information, insert the information into the new system and change the callerIDname with the new system's lead_id included
- The call will then go to an In-Group with that lead_id set so it can then go on to an agent
+33 -1
View File
@@ -1,4 +1,4 @@
NON-AGENT API DOCUMENT Started: 2008-07-24 Updated: 2017-06-01
NON-AGENT API DOCUMENT Started: 2008-07-24 Updated: 2017-06-09
This document describes the functions of an API(Application Programming
Interface) for all functions NOT directly relating to the VICIDIAL Agent screen.
@@ -42,6 +42,7 @@ check_phone_number - allows you to check if a phone number is valid and dialable
logged_in_agents - list of agents that are logged in to the system
update_campaign - updates campaign settings in the system
phone_number_log - exports list of calls placed to one of more phone numbers
ccc_lead_info - outputs lead data for cross-cluster-communication call
New scripts:
@@ -126,6 +127,7 @@ Changes:
170508-1048 - Added blind_monitor logging
170527-2254 - Fix for rare inbound logging issue #1017
170601-0747 - Added add_to_hopper options to update_lead function
170609-1107 - Added ccc_lead_info function
API Functions use the 'function' variable
@@ -575,6 +577,36 @@ A SUCCESS response will not show "SUCCESS", but instead will just print the valu
--------------------------------------------------------------------------------
ccc_lead_info - outputs lead data for cross-cluster-communication call
NOTE: api user for this function must have user_level set to 7 or higher and "view reports" enabled
REQUIRED FIELDS-
source - description of what originated the API call (maximum 20 characters)
call_id - 16-40 characters
SETTINGS FIELDS-
stage - the format of the exported data: csv, tab, newline, pipe(default)
header - include a header(YES) or not(NO). This is optional, default is not to include a header
Example URL strings for API calls:
http://server/vicidial/non_agent_api.php?source=test&user=6666&pass=1234&function=ccc_lead_info&call_id=M4050908070000012345&stage=csv&header=YES
Example responses:
ERROR: ccc_lead_info USER DOES NOT HAVE PERMISSION TO GET LEAD INFO - 6666|0
ERROR: ccc_lead_info INVALID SEARCH PARAMETERS - 6666||
ERROR: ccc_lead_info CALL NOT FOUND - 6666||
ERROR: ccc_lead_info LEAD NOT FOUND - 6666||
A SUCCESS response will not show "SUCCESS", but instead will just print the results in the following format:
status|user|vendor_lead_code|source_id|list_id|gmt_offset_now|phone_code|phone_number|title|first_name|middle_initial|last_name|address1|address2|address3|city|state|province|postal_code|country_code|gender|date_of_birth|alt_phone|email|security_phrase|comments|called_count|last_local_call_time|rank|owner
TD|6666|554443||501|-4.00|1|9998887112|Mr|Billy'Oj|U|O'Reillyo|ad1|ad2|ad3|city next|FL|U|33777||U|0000-00-00|bobo'brien|test@test.com||2017-06-01 18:38:41|79|2017-06-09 14:53:27|0|4646
--------------------------------------------------------------------------------
update_log_entry - updates the status of a vicidial_log or vicidial_closer_log entry
+4 -3
View File
@@ -126,7 +126,7 @@ $UGreports = 'ALL REPORTS, NONE, Real-Time Main Report, Real-Time Campaign Summa
$Vtables = 'NONE,log_noanswer,did_agent_log,contact_information';
$APIfunctions = 'ALL_FUNCTIONS add_group_alias add_lead add_list add_phone add_phone_alias add_user agent_ingroup_info agent_stats_export agent_status audio_playback blind_monitor call_agent callid_info change_ingroups check_phone_number did_log_export external_add_lead external_dial external_hangup external_pause external_status in_group_status logout moh_list park_call pause_code preview_dial_action ra_call_control recording recording_lookup send_dtmf server_refresh set_timer_action sounds_list st_get_agent_active_lead st_login_log transfer_conference update_fields update_lead update_list update_log_entry update_phone update_phone_alias update_user user_group_status vm_list webphone_url webserver logged_in_agents update_campaigns lead_field_info phone_number_log switch_lead';
$APIfunctions = 'ALL_FUNCTIONS add_group_alias add_lead add_list add_phone add_phone_alias add_user agent_ingroup_info agent_stats_export agent_status audio_playback blind_monitor call_agent callid_info change_ingroups check_phone_number did_log_export external_add_lead external_dial external_hangup external_pause external_status in_group_status logout moh_list park_call pause_code preview_dial_action ra_call_control recording recording_lookup send_dtmf server_refresh set_timer_action sounds_list st_get_agent_active_lead st_login_log transfer_conference update_fields update_lead update_list update_log_entry update_phone update_phone_alias update_user user_group_status vm_list webphone_url webserver logged_in_agents update_campaigns lead_field_info phone_number_log switch_lead ccc_lead_info';
######################################################################################################
######################################################################################################
@@ -4134,12 +4134,13 @@ else
# 170516-0632 - Added Real-Time Monitoring Log Report
# 170527-0041 - Added filtering of browser details before logging
# 170529-2320 - Added agent events push settings
# 170609-1529 - Added ccc_lead_info API function
#
# make sure you have added a user to the vicidial_users MySQL table with at least user_level 9 to access this page the first time
$admin_version = '2.14-617a';
$build = '170529-2320';
$admin_version = '2.14-618a';
$build = '170609-1529';
$STARTtime = date("U");
$SQLdate = date("Y-m-d H:i:s");
+2 -2
View File
@@ -730,9 +730,9 @@ if ($SSqc_features_active > 0)
<B><?php echo _QXZ("Agent API Access"); ?> -</B><?php echo _QXZ("This option allows the account to be used with the agent and non-agent API commands."); ?>
<BR>
<A NAME="users-vdc_agent_api_access">
<A NAME="users-api_list_restrict">
<BR>
<B><?php echo _QXZ("Agent API Access"); ?> -</B><?php echo _QXZ("This option allows the account to be used with the agent and non-agent API commands."); ?>
<B><?php echo _QXZ("API List Restrict"); ?> -</B><?php echo _QXZ("If enabled, the API commands that involve leads and lists will be restricted to the lists within the allowed campaigns for the user group of this user. Default is 0 for disabled."); ?>
<BR>
<A NAME="users-api_only_user">
+208 -2
View File
@@ -120,10 +120,11 @@
# 170508-1048 - Added blind_monitor logging
# 170527-2254 - Fix for rare inbound logging issue #1017
# 170601-0747 - Added add_to_hopper options to update_lead function
# 170609-1107 - Added ccc_lead_info function
#
$version = '2.14-96';
$build = '170601-0747';
$version = '2.14-97';
$build = '170609-1107';
$api_url_log = 0;
$startMS = microtime();
@@ -6364,6 +6365,211 @@ if ($function == 'callid_info')
################################################################################
### ccc_lead_info - outputs lead data for cross-cluster-communication call
################################################################################
if ($function == 'ccc_lead_info')
{
if(strlen($source)<2)
{
$result = 'ERROR';
$result_reason = "Invalid Source";
echo "$result: $result_reason - $source\n";
api_log($link,$api_logging,$api_script,$user,$agent_user,$function,$value,$result,$result_reason,$source,$data);
echo "ERROR: Invalid Source: |$source|\n";
exit;
}
else
{
if ( (!preg_match("/ $function /",$api_allowed_functions)) and (!preg_match("/ALL_FUNCTIONS/",$api_allowed_functions)) )
{
$result = 'ERROR';
$result_reason = "auth USER DOES NOT HAVE PERMISSION TO USE THIS FUNCTION";
echo "$result: $result_reason: |$user|$function|\n";
$data = "$allowed_user";
api_log($link,$api_logging,$api_script,$user,$agent_user,$function,$value,$result,$result_reason,$source,$data);
exit;
}
$stmt="SELECT count(*) from vicidial_users where user='$user' and vdc_agent_api_access='1' and view_reports='1' and user_level > 6 and active='Y';";
$rslt=mysql_to_mysqli($stmt, $link);
$row=mysqli_fetch_row($rslt);
$allowed_user=$row[0];
if ($allowed_user < 1)
{
$result = 'ERROR';
$result_reason = "ccc_lead_info USER DOES NOT HAVE PERMISSION TO GET LEAD INFO";
echo "$result: $result_reason: |$user|$allowed_user|\n";
$data = "$allowed_user";
api_log($link,$api_logging,$api_script,$user,$agent_user,$function,$value,$result,$result_reason,$source,$data);
exit;
}
else
{
$call_search_SQL='';
$search_ready=0;
$call_id = preg_replace("/\n|\r|\t| /",'',$call_id);
if ( (strlen($call_id)>17) and (strlen($call_id)<40) and (preg_match("/^Y|^J|^V|^M|^DC|^S|^LP|^VH|^XL/",$call_id)) )
{
$tenhoursago = date("Y-m-d H:i:s", mktime(date("H")-10,date("i"),date("s"),date("m"),date("d"),date("Y")));
$call_search_SQL .= "where caller_code='$call_id' and call_date > \"$tenhoursago\"";
$search_ready++;
}
if ($search_ready < 1)
{
$result = 'ERROR';
$result_reason = "ccc_lead_info INVALID SEARCH PARAMETERS";
$data = "$user|$call_id";
echo "$result: $result_reason: $data\n";
api_log($link,$api_logging,$api_script,$user,$agent_user,$function,$value,$result,$result_reason,$source,$data);
exit;
}
else
{
$stmt="SELECT admin_viewable_groups,allowed_campaigns from vicidial_user_groups where user_group='$LOGuser_group';";
if ($DB) {$MAIN.="|$stmt|\n";}
$rslt=mysql_to_mysqli($stmt, $link);
$row=mysqli_fetch_row($rslt);
$LOGadmin_viewable_groups = $row[0];
$LOGallowed_campaigns = $row[1];
$LOGallowed_campaignsSQL='';
if ( (!preg_match("/ALL-CAMPAIGNS/i",$LOGallowed_campaigns)) )
{
$LOGallowed_campaignsSQL = preg_replace('/\s-/i','',$LOGallowed_campaigns);
$LOGallowed_campaignsSQL = preg_replace('/\s/i',"','",$LOGallowed_campaignsSQL);
$LOGallowed_campaignsSQL = "and campaign_id IN('$LOGallowed_campaignsSQL')";
}
$k=0;
$output='';
$DLset=0;
if ($stage == 'csv')
{$DL = ','; $DLset++;}
if ($stage == 'tab')
{$DL = "\t"; $DLset++;}
if ($stage == 'newline')
{$DL = "\n"; $DLset++;}
if ($stage == 'pipe')
{$DL = '|'; $DLset++;}
if ($DLset < 1)
{$DL='|'; $stage='pipe';}
if (strlen($time_format) < 1)
{$time_format = 'HF';}
if ($header == 'YES')
{
$output .= 'status' . $DL . 'user' . $DL . 'vendor_lead_code' . $DL . 'source_id' . $DL . 'list_id' . $DL . 'gmt_offset_now' . $DL . 'phone_code' . $DL . 'phone_number' . $DL . 'title' . $DL . 'first_name' . $DL . 'middle_initial' . $DL . 'last_name' . $DL . 'address1' . $DL . 'address2' . $DL . 'address3' . $DL . 'city' . $DL . 'state' . $DL . 'province' . $DL . 'postal_code' . $DL . 'country_code' . $DL . 'gender' . $DL . 'date_of_birth' . $DL . 'alt_phone' . $DL . 'email' . $DL . 'security_phrase' . $DL . 'comments' . $DL . 'called_count' . $DL . 'last_local_call_time' . $DL . 'rank' . $DL . 'owner' . "\n";
}
$stmt="SELECT uniqueid,call_date,lead_id from vicidial_log_extended $call_search_SQL;";
if (preg_match("/^DC/",$call_id))
{$stmt="SELECT uniqueid,call_date,lead_id from vicidial_dial_log $call_search_SQL;";}
$rslt=mysql_to_mysqli($stmt, $link);
if ($DB) {echo "$stmt\n";}
$vle_to_list = mysqli_num_rows($rslt);
if ($vle_to_list > 0)
{
$row=mysqli_fetch_row($rslt);
$uniqueid = $row[0];
$call_date = $row[1];
$lead_id = $row[2];
$stmt="SELECT status,user,vendor_lead_code,source_id,list_id,gmt_offset_now,phone_code,phone_number,title,first_name,middle_initial,last_name,address1,address2,address3,city,state,province,postal_code,country_code,gender,date_of_birth,alt_phone,email,security_phrase,comments,called_count,last_local_call_time,rank,owner from vicidial_list where lead_id=$lead_id;";
$rslt=mysql_to_mysqli($stmt, $link);
if ($DB) {echo "$stmt\n";}
$lead_to_list = mysqli_num_rows($rslt);
if ($lead_to_list > 0)
{
$row=mysqli_fetch_row($rslt);
$LEADstatus = $row[0];
$LEADuser = $row[1];
$LEADvendor_lead_code = $row[2];
$LEADsource_id = $row[3];
$LEADlist_id = $row[4];
$LEADgmt_offset_now = $row[5];
$LEADphone_code = $row[6];
$LEADphone_number = $row[7];
$LEADtitle = $row[8];
$LEADfirst_name = $row[9];
$LEADmiddle_initial = $row[10];
$LEADlast_name = $row[11];
$LEADaddress1 = $row[12];
$LEADaddress2 = $row[13];
$LEADaddress3 = $row[14];
$LEADcity = $row[15];
$LEADstate = $row[16];
$LEADprovince = $row[17];
$LEADpostal_code = $row[18];
$LEADcountry_code = $row[19];
$LEADgender = $row[20];
$LEADdate_of_birth = $row[21];
$LEADalt_phone = $row[22];
$LEADemail = $row[23];
$LEADsecurity_phrase = $row[24];
$LEADcomments = $row[25];
$LEADcalled_count = $row[26];
$LEADlast_local_call_time = $row[27];
$LEADrank = $row[28];
$LEADowner = $row[29];
if ( (strlen($LOGallowed_campaignsSQL) > 3) and ($api_list_restrict > 0) )
{
$stmt="SELECT count(*) from vicidial_lists where list_id='$LEADlist_id' $LOGallowed_campaignsSQL;";
$rslt=mysql_to_mysqli($stmt, $link);
$row=mysqli_fetch_row($rslt);
$allowed_list=$row[0];
if ($allowed_list < 1)
{
$result = 'ERROR';
$result_reason = "ccc_lead_info LEAD NOT FOUND";
echo "$result: $result_reason: |$user|$allowed_user|\n";
$data = "$allowed_user";
api_log($link,$api_logging,$api_script,$user,$agent_user,$function,$value,$result,$result_reason,$source,$data);
exit;
}
}
$output .= "$LEADstatus$DL$LEADuser$DL$LEADvendor_lead_code$DL$LEADsource_id$DL$LEADlist_id$DL$LEADgmt_offset_now$DL$LEADphone_code$DL$LEADphone_number$DL$LEADtitle$DL$LEADfirst_name$DL$LEADmiddle_initial$DL$LEADlast_name$DL$LEADaddress1$DL$LEADaddress2$DL$LEADaddress3$DL$LEADcity$DL$LEADstate$DL$LEADprovince$DL$LEADpostal_code$DL$LEADcountry_code$DL$LEADgender$DL$LEADdate_of_birth$DL$LEADalt_phone$DL$LEADemail$DL$LEADsecurity_phrase$DL$LEADcomments$DL$LEADcalled_count$DL$LEADlast_local_call_time$DL$LEADrank$DL$LEADowner\n";
echo "$output";
$result = 'SUCCESS';
$data = "$user|$call_id|$stage";
$result_reason = "ccc_lead_info $output";
api_log($link,$api_logging,$api_script,$user,$agent_user,$function,$value,$result,$result_reason,$source,$data);
}
else
{
$result = 'ERROR';
$result_reason = "ccc_lead_info LEAD NOT FOUND";
$data = "$user|$agent_user";
echo "$result: $result_reason: $data\n";
api_log($link,$api_logging,$api_script,$user,$agent_user,$function,$value,$result,$result_reason,$source,$data);
exit;
}
}
else
{
$result = 'ERROR';
$result_reason = "ccc_lead_info CALL NOT FOUND";
$data = "$user|$agent_user";
echo "$result: $result_reason: $data\n";
api_log($link,$api_logging,$api_script,$user,$agent_user,$function,$value,$result,$result_reason,$source,$data);
exit;
}
}
}
}
exit;
}
################################################################################
### ccc_lead_info - outputs lead data for cross-cluster-communication call
################################################################################
################################################################################
### lead_field_info - pulls the value of one field of a lead
################################################################################