Added VIDPROMPTSPECIAL... Call Menu In-Group routing feature, Added CM_VIDPROMPT_SPECIAL Container Type

Added additional in-group second-alert settings

git-svn-id: svn://192.168.202.10@3737 3d104415-ff17-0410-8863-d5cf3c621b8a
This commit is contained in:
mattf
2023-06-14 21:34:22 +00:00
parent d6634c33d7
commit 338086fa43
12 changed files with 1344 additions and 72 deletions
+5
View File
@@ -806,6 +806,11 @@ OTHER CHANGES:
226. Added Second Agent Alert Trigger In-Group settings, allowing for a second
audio alert to be played to the agent on repeat calls.
227. Added VIDPROMPTSPECIAL Call Menu Handle Methods when sending calls to
In-Groups. Allows for list-based In-Group routing based on settings in
a Settings Container. Also allows for separate routing of not-found
leads.
+94 -41
View File
@@ -254,6 +254,7 @@
# 230309-0950 - Added abandon_check_queue feature
# 230523-0824 - Added User inbound_credits feature
# 230606-2231 - Added second_alert_trigger features
# 230612-2044 - Added second_alert_container, second_alert_only and second_alert_trigger TIMEOUT options
#
$script = 'agi-VDAD_ALL_inbound.agi';
@@ -265,7 +266,7 @@ $wait_prompt_runs=0;
$at='@';
$S='*';
$mel=1; # Mysql Error Log enabled = 1
$mysql_log_count=272;
$mysql_log_count=275;
$one_mysql_log=0;
$dial_ingroup_flag=0;
$called_count=1;
@@ -881,7 +882,7 @@ $affected_rows = $dbhA->do($stmtA);
### Grab inbound groups values from the database
$cbc=0;
$stmtA = "SELECT call_time_id,after_hours_action,after_hours_message_filename,after_hours_exten,after_hours_voicemail,welcome_message_filename,moh_context,onhold_prompt_filename,prompt_interval,agent_alert_exten,agent_alert_delay,drop_call_seconds,drop_action,drop_exten,next_agent_call,voicemail_ext,queue_priority,drop_inbound_group,afterhours_xfer_group,play_place_in_line,play_estimate_hold_time,hold_time_option,hold_time_option_seconds,hold_time_option_exten,hold_time_option_voicemail,hold_time_option_xfer_group,hold_time_option_callback_filename,hold_time_option_callback_list_id,hold_recall_xfer_group,no_delay_call_route,play_welcome_message,no_agent_no_queue,no_agent_action,no_agent_action_value,extension_appended_cidname,uniqueid_status_display,uniqueid_status_prefix,hold_time_option_minimum,hold_time_option_press_filename,hold_time_option_callmenu,onhold_prompt_no_block,onhold_prompt_seconds,hold_time_option_no_block,hold_time_option_prompt_seconds,hold_time_second_option,hold_time_third_option,wait_hold_option_priority,wait_time_option,wait_time_second_option,wait_time_third_option,wait_time_option_seconds,wait_time_option_exten,wait_time_option_voicemail,wait_time_option_xfer_group,wait_time_option_callmenu,wait_time_option_callback_filename,wait_time_option_callback_list_id,wait_time_option_press_filename,wait_time_option_no_block,wait_time_option_prompt_seconds,active,calculate_estimated_hold_seconds,add_lead_url,eht_minimum_prompt_filename,eht_minimum_prompt_no_block,eht_minimum_prompt_seconds,on_hook_ring_time,ingroup_recording_override,ingroup_rec_filename,on_hook_cid,action_xfer_cid,drop_callmenu,after_hours_callmenu,max_calls_method,max_calls_count,max_calls_action,populate_lead_ingroup,na_call_url,drop_lead_reset,after_hours_lead_reset,nanq_lead_reset,wait_time_lead_reset,hold_time_lead_reset,routing_initiated_recordings,on_hook_cid_number,populate_lead_province,areacode_filter,areacode_filter_seconds,areacode_filter_action,areacode_filter_action_value,populate_state_areacode,inbound_survey,inbound_survey_filename,inbound_survey_accept_digit,closing_time_action,closing_time_now_trigger,closing_time_filename,closing_time_end_filename,closing_time_lead_reset,closing_time_option_exten,closing_time_option_callmenu,closing_time_option_voicemail,closing_time_option_xfer_group,closing_time_option_callback_list_id,add_lead_timezone,populate_lead_source,populate_lead_vendor,enter_ingroup_url,cid_cb_confirm_number,cid_cb_invalid_filter_phone_group,cid_cb_valid_length,cid_cb_valid_filename,cid_cb_confirmed_filename,cid_cb_enter_filename,cid_cb_you_entered_filename,cid_cb_press_to_confirm_filename,cid_cb_invalid_filename,cid_cb_reenter_filename,cid_cb_error_filename,place_in_line_caller_number_filename,place_in_line_you_next_filename,answer_signal,no_agent_delay,agent_search_method,populate_lead_comments,drop_call_seconds_override,populate_lead_owner,in_queue_nanque,in_queue_nanque_exceptions,second_alert_trigger,second_alert_trigger_seconds,second_alert_filename,second_alert_delay FROM vicidial_inbound_groups where group_id = '$channel_group';";
$stmtA = "SELECT call_time_id,after_hours_action,after_hours_message_filename,after_hours_exten,after_hours_voicemail,welcome_message_filename,moh_context,onhold_prompt_filename,prompt_interval,agent_alert_exten,agent_alert_delay,drop_call_seconds,drop_action,drop_exten,next_agent_call,voicemail_ext,queue_priority,drop_inbound_group,afterhours_xfer_group,play_place_in_line,play_estimate_hold_time,hold_time_option,hold_time_option_seconds,hold_time_option_exten,hold_time_option_voicemail,hold_time_option_xfer_group,hold_time_option_callback_filename,hold_time_option_callback_list_id,hold_recall_xfer_group,no_delay_call_route,play_welcome_message,no_agent_no_queue,no_agent_action,no_agent_action_value,extension_appended_cidname,uniqueid_status_display,uniqueid_status_prefix,hold_time_option_minimum,hold_time_option_press_filename,hold_time_option_callmenu,onhold_prompt_no_block,onhold_prompt_seconds,hold_time_option_no_block,hold_time_option_prompt_seconds,hold_time_second_option,hold_time_third_option,wait_hold_option_priority,wait_time_option,wait_time_second_option,wait_time_third_option,wait_time_option_seconds,wait_time_option_exten,wait_time_option_voicemail,wait_time_option_xfer_group,wait_time_option_callmenu,wait_time_option_callback_filename,wait_time_option_callback_list_id,wait_time_option_press_filename,wait_time_option_no_block,wait_time_option_prompt_seconds,active,calculate_estimated_hold_seconds,add_lead_url,eht_minimum_prompt_filename,eht_minimum_prompt_no_block,eht_minimum_prompt_seconds,on_hook_ring_time,ingroup_recording_override,ingroup_rec_filename,on_hook_cid,action_xfer_cid,drop_callmenu,after_hours_callmenu,max_calls_method,max_calls_count,max_calls_action,populate_lead_ingroup,na_call_url,drop_lead_reset,after_hours_lead_reset,nanq_lead_reset,wait_time_lead_reset,hold_time_lead_reset,routing_initiated_recordings,on_hook_cid_number,populate_lead_province,areacode_filter,areacode_filter_seconds,areacode_filter_action,areacode_filter_action_value,populate_state_areacode,inbound_survey,inbound_survey_filename,inbound_survey_accept_digit,closing_time_action,closing_time_now_trigger,closing_time_filename,closing_time_end_filename,closing_time_lead_reset,closing_time_option_exten,closing_time_option_callmenu,closing_time_option_voicemail,closing_time_option_xfer_group,closing_time_option_callback_list_id,add_lead_timezone,populate_lead_source,populate_lead_vendor,enter_ingroup_url,cid_cb_confirm_number,cid_cb_invalid_filter_phone_group,cid_cb_valid_length,cid_cb_valid_filename,cid_cb_confirmed_filename,cid_cb_enter_filename,cid_cb_you_entered_filename,cid_cb_press_to_confirm_filename,cid_cb_invalid_filename,cid_cb_reenter_filename,cid_cb_error_filename,place_in_line_caller_number_filename,place_in_line_you_next_filename,answer_signal,no_agent_delay,agent_search_method,populate_lead_comments,drop_call_seconds_override,populate_lead_owner,in_queue_nanque,in_queue_nanque_exceptions,second_alert_trigger,second_alert_trigger_seconds,second_alert_filename,second_alert_delay,second_alert_container,second_alert_only FROM vicidial_inbound_groups where group_id = '$channel_group';";
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
$sthArows=$sthA->rows;
@@ -1029,6 +1030,8 @@ if ($sthArows > 0)
$second_alert_trigger_seconds = $aryA[130];
$second_alert_filename = $aryA[131];
$second_alert_delay = $aryA[132];
$second_alert_container = $aryA[133];
$second_alert_only = $aryA[134];
if ( (length($place_in_line_caller_number_filename) < 1) || ($place_in_line_caller_number_filename =~ /^NULL$/i) )
{$place_in_line_caller_number_filename='queue-thereare';}
@@ -1102,7 +1105,8 @@ if ( ($inbound_answer_config > 0) and ($answer_signal !~ /NONE|ROUTE/i) )
}
# When VID or VIDPROMPT, methods are not used, no Vendor Lead Code can be supplied. Fill it with inbound_number
if ($call_handle_method !~ /^VID/)
$igvendorid = $AGI->get_variable('igvendorid');
if ( ($call_handle_method !~ /^VID/) && (length($igvendorid) < 1) )
{
if ($populate_lead_vendor =~ /INBOUND_NUMBER/)
{$vendor_id = $inbound_number;}
@@ -1689,9 +1693,9 @@ else
$affected_rows = $dbhA->do($stmtA);
$dbhP=$dbhA; $mysql_count='02014'; $MEL_aff_rows=$affected_rows; &mysql_error_logging;
$cbc=0;
$stmtA = "SELECT LAST_INSERT_ID() LIMIT 1;";
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
$stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;";
$sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr;
$sthA->execute or die "executing: $stmtB ", $dbhA->errstr;
$sthArows=$sthA->rows;
$dbhP=$dbhA; $mysql_count='02015'; $MEL_aff_rows=$sthArows; &mysql_error_logging;
if ($sthArows > 0)
@@ -1701,6 +1705,7 @@ else
$cbc++;
}
$sthA->finish();
if ($AGILOG) {$agi_string = "VL vicidial_list insert |$insert_lead_id|$list_id|$stmtA|"; &agi_output;}
### BEGIN the Add-Lead-URL get process
if (length($add_lead_url) > 5)
@@ -3860,8 +3865,77 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override
### END if did agent log is active, update the user ###
### if second agent alert is not disabled, then trigger the alert and wait
$play_second_alert=0;
$disable_first_alert=0;
if ( ($second_alert_trigger =~ /PHONE|LEAD_ID/i) && (length($second_alert_filename)>0) && ($no_delay_call_route !~ /Y/i) && ($VDADextension !~ /^R\//) )
{
$second_alert_containerSQL="and campaign_id='$channel_group'";
if ( (length($second_alert_container)>0) && ($second_alert_container !~ /^DISABLED$/i) )
{
$second_alert_container_entry='';
$stmtA = "SELECT container_entry FROM vicidial_settings_containers where container_id='$second_alert_container';";
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
$sthArows=$sthA->rows;
$dbhP=$dbhA; $mysql_count='02273'; $MEL_aff_rows=$sthArows; &mysql_error_logging;
if ($AGILOG) {$agi_string = "-- VDCL 2nd alert container: |$sthArows|$stmtA|"; &agi_output;}
if ($sthArows > 0)
{
@aryA = $sthA->fetchrow_array;
$second_alert_container_entry = $aryA[0];
$second_alert_container_entry =~ s/\n/','/gi;
$second_alert_container_entry =~ s/\r|\t| |''|,$|^,//gi;
$second_alert_container_entry =~ s/,,/,/gi;
$second_alert_container_entry =~ s/,''//gi;
$second_alert_container_entry =~ s/','$//gi;
if (length($second_alert_container_entry) > 0)
{$second_alert_containerSQL = "and campaign_id IN('$second_alert_container_entry')";}
}
$sthA->finish();
}
$VCL_count=0;
$second_alert_trigger_seconds =~ s/\D//gi;
if (length($second_alert_trigger_seconds) < 1) {$second_alert_trigger_seconds=0;}
$dropSQL='';
$drop_statuses='';
if ($second_alert_trigger =~ /TO|TIMEOUT/i) {$drop_statuses .= "TIMEOT|";}
if ($second_alert_trigger =~ /NQ/i) {$drop_statuses .= "NANQUE|";}
if ($second_alert_trigger =~ /HT/i) {$drop_statuses .= "HOLDTO|";}
if ($second_alert_trigger =~ /WT/i) {$drop_statuses .= "WAITTO|";}
if (length($drop_statuses) > 1)
{
$drop_statuses =~ s/\|/','/gi;
$drop_statuses =~ s/','$//gi;
$dropSQL="and status IN('$drop_statuses')";
}
$searchSQL="lead_id='$insert_lead_id'";
if ($second_alert_trigger =~ /PHONE/i)
{$searchSQL="phone_number='$phone_number'";}
$stmtA = "SELECT count(*) FROM vicidial_closer_log where $searchSQL $second_alert_containerSQL and call_date >= NOW()-INTERVAL $second_alert_trigger_seconds SECOND $dropSQL;";
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
$sthArowsMIC=$sthA->rows;
$dbhP=$dbhA; $mysql_count='02274'; $MEL_aff_rows=$sthArows; &mysql_error_logging;
if ($sthArowsMIC > 0)
{
@aryA = $sthA->fetchrow_array;
$VCL_count = $aryA[0];
}
if ($AGILOG) {$agi_string = "-- VDCL 2nd alert check: |$VCL_count|$stmtA|"; &agi_output;}
if ( ($VCL_count > 1) || ( (length($dropSQL) > 5) && ($VCL_count > 0) ) )
{
$play_second_alert=1;
if ($second_alert_only =~ /ENABLED/i)
{$disable_first_alert=1;}
if ($AGILOG) {$agi_string = "-- VDCL 2nd agent alert triggered: |$play_second_alert|disable first alert: $disable_first_alert|"; &agi_output;}
}
}
### if agent alert exten is not disabled, then trigger the alert and wait
if ( ($agent_alert_exten !~ /^X$/i) && (length($agent_alert_exten)>0) && ($no_delay_call_route !~ /Y/i) && ($VDADextension !~ /^R\//) )
if ( ($agent_alert_exten !~ /^X$/i) && (length($agent_alert_exten)>0) && ($no_delay_call_route !~ /Y/i) && ($VDADextension !~ /^R\//) && ($disable_first_alert < 1) )
{
if ($agent_alert_exten =~ /^8304$/)
{$agent_alert_exten = 'ding';}
@@ -3878,46 +3952,25 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override
}
### if second agent alert is not disabled, then trigger the alert and wait
if ( ($second_alert_trigger =~ /PHONE_NUMBER|LEAD_ID/i) && (length($second_alert_filename)>0) && ($no_delay_call_route !~ /Y/i) && ($VDADextension !~ /^R\//) )
# if second alert is to be played, play it now
if ($play_second_alert > 0)
{
$VCL_count=0;
$second_alert_trigger_seconds =~ s/\D//gi;
if (length($second_alert_trigger_seconds) < 1) {$second_alert_trigger_seconds=0;}
$stmtA = "SELECT count(*) FROM vicidial_closer_log where lead_id='$insert_lead_id' and campaign_id='$channel_group' and call_date >= NOW()-INTERVAL $second_alert_trigger_seconds SECOND;";
if ($second_alert_trigger =~ /PHONE_NUMBER/i)
{
$stmtA = "SELECT count(*) FROM vicidial_closer_log where phone_number='$phone_number' and campaign_id='$channel_group' and call_date >= NOW()-INTERVAL $second_alert_trigger_seconds SECOND;";
}
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
$sthArowsMIC=$sthA->rows;
$dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging;
if ($sthArowsMIC > 0)
{
@aryA = $sthA->fetchrow_array;
$VCL_count = $aryA[0];
}
if ($AGILOG) {$agi_string = "-- VDCL 2nd alert check: |$VCL_count|$stmtA|"; &agi_output;}
$VSqueryCID = "VS$CIDdate$VDADconf_exten";
$alertCIDstring = "\"$second_alert_filename\" <$second_alert_filename>";
if ($VCL_count > 1)
{
$VSqueryCID = "VS$CIDdate$VDADconf_exten";
$alertCIDstring = "\"$second_alert_filename\" <$second_alert_filename>";
### insert a NEW record to the vicidial_manager table to play the alert message to the agent
$stmtA = "INSERT INTO vicidial_manager values('','','$SQLdate','NEW','N','$VDADserver_ip','','Originate','$VSqueryCID','Exten: 83047777777777','Context: vicidial-auto','Channel: Local/$alertVDADremDIALstr$at$ext_context','Priority: 1','Callerid: $alertCIDstring','Timeout: 10','','','','')";
$affected_rows = $dbhA->do($stmtA);
$dbhP=$dbhA; $mysql_count='02275'; $MEL_aff_rows=$affected_rows; &mysql_error_logging;
if ($AGILOG) {$agi_string = "-- VDCL 2nd agent alert: |$VCL_count|$VSqueryCID|$alertVDADremDIALstr|$agent_alert_exten|$alertCIDstring|$channel|insert to vicidial_manager"; &agi_output;}
### insert a NEW record to the vicidial_manager table to play the alert message to the agent
$stmtA = "INSERT INTO vicidial_manager values('','','$SQLdate','NEW','N','$VDADserver_ip','','Originate','$VSqueryCID','Exten: 83047777777777','Context: vicidial-auto','Channel: Local/$alertVDADremDIALstr$at$ext_context','Priority: 1','Callerid: $alertCIDstring','Timeout: 10','','','','')";
$affected_rows = $dbhA->do($stmtA);
$dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging;
if ($AGILOG) {$agi_string = "-- VDCL 2nd agent alert: |$VSqueryCID|$alertVDADremDIALstr|$agent_alert_exten|$alertCIDstring|$channel|insert to vicidial_manager"; &agi_output;}
$second_alert_delay =~ s/\D//gi;
if (length($second_alert_delay) < 1) {$second_alert_delay=1;}
usleep(1 * $second_alert_delay * 1000);
}
$second_alert_delay =~ s/\D//gi;
if (length($second_alert_delay) < 1) {$second_alert_delay=1;}
usleep(1 * $second_alert_delay * 1000);
}
if ($AGILOG) {$agi_string = "exiting VDAD app, transferring call to $VDADremDIALstr"; &agi_output;}
if ($no_delay_call_route =~ /N/)
+913
View File
@@ -0,0 +1,913 @@
#!/usr/bin/perl
#
# cm_VID_SPECIAL.agi version 2.14
#
# runs when a call comes from a Call Menu VIDPROMPTSPECIAL... INGROUP option.
# This script will send calls to various In-Groups or Call Menu options based
# on settings in a Settings Container and results of a lead search.
#
#
# You need to put lines similar to those below in your extensions.conf file:
# ; Below are the parameters needed for the script to be run properly
# ; 1. the method of call handling for the script:
# ; - VIDPROMPTSPECIALLOOKUP - Prompt Vendor Lead Code to User with IVR to find record in whole system
# ; - VIDPROMPTSPECIALLOOKUPRL - Restrict lookup to one list
# ; - VIDPROMPTSPECIALLOOKUPRC - Restrict lookup to one campaign's lists
# ; 2. the method of searching for an available agent:
# ; - LO - Load Balance Overflow only (priority to home server)
# ; - LB - <default> Load Balance total system
# ; - SO - Home server only
# ; 3. the list_id to insert the new lead under if it is new (and CID/ANI available)
# ; 4. the phone dialing code to insert with the new lead if new (and CID/ANI available)
# ; 5. the campaign_id to search within lists if CIDLOOKUPRC
# ; 6. VID enter prompt filename to play if method is set to a VID* option
# ; 7. VID you-have-entered filename to play if method is set to a VID* option
# ; 8. VID confirm prompt filename to play if method is set to a VID* option
# ; 9. VID digit length validation to use if method is set to a VID* option, set to empty or X to disable
# ; 10. Settings Container to use for settings for this script, must be CM_VIDPROMPT_SPECIAL container type
#
# ;inbound VICIDIAL calls:
#exten => 1234,1,Answer ; Answer the line
#exten => 1234,2,AGI(cm_VID_SPECIAL.agi,VIDPROMPTSPECIALLOOKUP---LB---999---1---TESTCAMP---x---y---z---X---VID_special_test)
#exten => 1234,3,Hangup
#
#
# Copyright (C) 2023 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
#
# changes:
# 230613-2255 - First Build
#
$script = 'cm_VID_SPECIAL.agi';
$dtmf_silent_prefix = '7';
$DROP_TIME = 720; ### default number of seconds to wait until you drop a waiting call
$start_moh=1;
$wait_prompt_runs=0;
$at='@';
$S='*';
$mel=1; # Mysql Error Log enabled = 1
$mysql_log_count=272;
$one_mysql_log=0;
$dial_ingroup_flag=0;
$called_count=1;
$entry_list_id=0;
$areacode_filter_run=0;
$no_agent_no_queue_checked=0;
$MT[0]='';
$now_date_epoch = time();
($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);
$epochFOURhoursAGO = ($now_date_epoch - 14400);
($Ssec,$Smin,$Shour,$Smday,$Smon,$Syear,$Swday,$Syday,$Sisdst) = localtime($epochFOURhoursAGO);
$Smon++; $Syear = ($Syear + 1900);
if ($Smon < 10) {$Smon = "0$Smon";}
if ($Smday < 10) {$Smday = "0$Smday";}
if ($Shour < 10) {$Shour = "0$Shour";}
if ($Smin < 10) {$Smin = "0$Smin";}
if ($Ssec < 10) {$Ssec = "0$Ssec";}
$timeFOURhoursAGO = "$Syear-$Smon-$Smday $Shour:$Smin:$Ssec";
$epochTWENTYFOURhoursAGO = ($now_date_epoch - 86400);
($Ssec,$Smin,$Shour,$Smday,$Smon,$Syear,$Swday,$Syday,$Sisdst) = localtime($epochTWENTYFOURhoursAGO);
$Smon++; $Syear = ($Syear + 1900);
if ($Smon < 10) {$Smon = "0$Smon";}
if ($Smday < 10) {$Smday = "0$Smday";}
if ($Shour < 10) {$Shour = "0$Shour";}
if ($Smin < 10) {$Smin = "0$Smin";}
if ($Ssec < 10) {$Ssec = "0$Ssec";}
$timeTWENTYFOURhoursAGO = "$Syear-$Smon-$Smday $Shour:$Smin:$Ssec";
$start_epoch = $now_date_epoch;
$now_date = "$year-$mon-$mday $hour:$min:$sec";
$CLInow_date = "$year-$mon-$mday\\ $hour:$min:$sec";
$YMD = "$year-$mon-$mday";
$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;
$ORIGINAL_call_time = $SQLdate;
while (length($CIDdate) > 9) {$CIDdate =~ s/^.//gi;} # 0902235959 changed to 902235959
if ($wday == '0') {$now_weekday = 'SUNDAY';}
if ($wday == '1') {$now_weekday = 'MONDAY';}
if ($wday == '2') {$now_weekday = 'TUESDAY';}
if ($wday == '3') {$now_weekday = 'WEDNESDAY';}
if ($wday == '4') {$now_weekday = 'THURSDAY';}
if ($wday == '5') {$now_weekday = 'FRIDAY';}
if ($wday == '6') {$now_weekday = 'SATURDAY';}
$BDtarget = ($now_date_epoch - 7);
($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";
# 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";}
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 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='02001'; $MEL_aff_rows=$sthArows; &mysql_error_logging;
$rec_count=0;
while ($sthArows > $rec_count)
{
$AGILOG = '0';
@aryA = $sthA->fetchrow_array;
$DBagi_output = $aryA[0];
$local_gmt = $aryA[1];
if ($isdst) {$local_gmt++;}
if ($DBagi_output =~ /STDERR/) {$AGILOG = '1';}
if ($DBagi_output =~ /FILE/) {$AGILOG = '2';}
if ($DBagi_output =~ /BOTH/) {$AGILOG = '3';}
$rec_count++;
}
$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,queuemetrics_pe_phone_append,did_agent_log,alt_log_server_ip,alt_log_dbname,alt_log_login,alt_log_pass,tables_use_alt_log_db,did_ra_extensions_enabled,queuemetrics_socket,queuemetrics_socket_url,enable_did_entry_list_id,enable_drop_lists,inbound_answer_config,agent_search_method,abandon_check_queue,inbound_credits FROM system_settings;";
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
$sthArows=$sthA->rows;
$dbhP=$dbhA; $mysql_count='02026'; $MEL_aff_rows=$sthArows; &mysql_error_logging;
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];
$queuemetrics_pe_phone_append = $aryA[7];
$did_agent_log = $aryA[8];
$alt_log_server_ip = $aryA[9];
$alt_log_dbname = $aryA[10];
$alt_log_login = $aryA[11];
$alt_log_pass = $aryA[12];
$tables_use_alt_log_db = $aryA[13];
$did_ra_extensions_enabled = $aryA[14];
$queuemetrics_socket = $aryA[15];
$queuemetrics_socket_url = $aryA[16];
$enable_did_entry_list_id = $aryA[17];
$enable_drop_lists = $aryA[18];
$inbound_answer_config = $aryA[19];
$SSagent_search_method = $aryA[20];
$SSabandon_check_queue = $aryA[21];
$SSinbound_credits = $aryA[22];
}
$sthA->finish();
##### END SYSTEM SETTINGS LOOKUP #####
###########################################
### 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]);
$call_handle_method = $ARGV_vars[0];
$search_method = $ARGV_vars[1];
$list_id = $ARGV_vars[2];
$phone_code = $ARGV_vars[3];
$Scampaign_id = $ARGV_vars[4];
$vid_enter_filename = $ARGV_vars[5];
$vid_id_number_filename = $ARGV_vars[6];
$vid_confirm_filename = $ARGV_vars[7];
$vid_validate_digits = $ARGV_vars[8];
$vid_special_container = $ARGV_vars[9];
}
$|=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 (/^agi_context\:\s+(.*)$/) {$context = $1;}
}
$callerid =~ s/\'|\\\\|\\\|\\|\\;|\\\;|\;|;//gi;
$calleridname =~ s/\'|\\\\|\\\|\\|\\;|\\\;|\;|;//gi;
$extension =~ s/\'|\"|\\\\|\\\|\\|\\;|\\\;|\;|;//gi;
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/)
{$callerid = $calleridname;}
if ( ($callerid =~ /\".*\"/) && ( (!$calleridname) or ($calleridname =~ /unknown/) ) )
{
$calleridname = $callerid;
$calleridname =~ s/\<\d\d\d\d\d\d\d\d\d\d\>//gi;
$calleridname =~ s/\"|\" //gi;
}
if ($callerid !~ /^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/)
{
$callerid =~ s/\D|\'//gi;
$calleridname =~ s/unknown|\'//gi;
if ( (!$callerid) or ($callerid =~ /unknown/) )
{$callerid = $calleridname;}
}
$prev_callerid = $callerid;
if ($calleridname =~ /^J\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d/)
{$prev_callerid = $calleridname;}
if ( ($phone_code =~ /^1$/) && ($callerid =~ /^1/) && (length($callerid) > 10) )
{
$callerid =~ s/^1//gi;
if ($AGILOG) {$agi_string = "North America CID Check: $phone_code|$callerid|"; &agi_output;}
}
$originalCID = $callerid;
if ( ($call_handle_method =~ /^CID/) || ($call_handle_method =~ /^VID/) )
{
if (length($callerid)>0) {$phone_number = $callerid;}
else {$phone_number = '';}
if (length($calleridname)>0) {$VLcomments = $calleridname;}
else {$VLcomments = '';}
}
if (length($callerid)<10) {$callerid = $parked_by;}
if (length($pin)>0) {$callerid = $pin;}
foreach $i (sort keys %AGI)
{
if ($AGILOG) {$agi_string = " -- $i = $AGI{$i}"; &agi_output;}
}
if ($AGILOG) {$agi_string = "AGI Variables: |$unique_id|$channel|$extension|$type|$callerid|"; &agi_output;}
if (length($pin) < 1) {$pin=$inbound_number;}
$fronter = $pin;
if ($AGILOG) {$agi_string = "+++++ VID PROMPT SPECIAL STARTED : |$channel_group|$callerid-$pin|$now_date"; &agi_output;}
$VDADphone='';
$VDADphone_code='';
$VCcallerid = $channel_group;
$VD_campaign_id = $channel_group;
if (length($VCcallerid)<2)
{$VCcallerid = 'ViciDial Inbound';}
### Grab Server values from the database
$cbc=0;
$stmtA = "SELECT voicemail_dump_exten,ext_context,answer_transfer_agent,local_gmt,asterisk_version,max_vicidial_trunks,voicemail_dump_exten_no_inst,routing_prefix 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='02004'; $MEL_aff_rows=$sthArows; &mysql_error_logging;
while ($sthArows > $cbc)
{
@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];
$voicemail_dump_exten_no_inst = $aryA[6];
$routing_prefix = $aryA[7];
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;}
$LOCAL_GMT_OFF = $SERVER_GMT;
$LOCAL_GMT_OFF_STD = $SERVER_GMT;
if ($isdst) {$LOCAL_GMT_OFF++;}
if ($DB) {print "SEED TIME $now_date_epoch : $year-$mon-$mday $hour:$min:$sec LOCAL GMT OFFSET NOW: $LOCAL_GMT_OFF\n";}
$cbc++;
}
$sthA->finish();
### Gather contents of VID-SPECIAL settings container, send back to main prompt if invalid
# example settings container:
#
# list_ingroup => 102,TEST_IN2
# list_ingroup => 103,TEST_IN3
# list_ingroup => 104,TEST_IN4
# default_ingroup => TEST_IN5
# not_found_action => new_lead
# new_lead_ingroup => TEST_IN
#
$not_found_action='s';
$new_lead_ingroup='';
$default_ingroup='';
$match_ingroup='';
$container_lines=0;
@container_array=@MT;
if (length($vid_special_container) > 0)
{
$stmtA = "SELECT container_entry FROM vicidial_settings_containers where container_id='$vid_special_container' and container_type='CM_VIDPROMPT_SPECIAL';";
if ($DBX) {print " |$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;
$VIDScontainer_entry = $aryA[0];
$VIDScontainer_entry =~ s/\r|\t|\'|\"//gi;
@VIDScontainer_array = split(/\n/,$VIDScontainer_entry);
$VIDSc=0;
foreach(@VIDScontainer_array)
{
if ( ($VIDScontainer_array[$VIDSc] !~ /^;/) && (length($VIDScontainer_array[$VIDSc]) > 0) )
{
$container_array[$container_lines] = "$VIDScontainer_array[$VIDSc]";
$container_lines++;
if ($VIDScontainer_array[$VIDSc] =~ /not_found_action => |not_found_action=>/)
{
$not_found_action = $VIDScontainer_array[$VIDSc];
$not_found_action =~ s/not_found_action => |not_found_action=>//gi;
$not_found_action =~ s/[^-_0-9a-zA-Z]//gi;
if (length($not_found_action) < 1) {$not_found_action='S';}
}
if ($VIDScontainer_array[$VIDSc] =~ /new_lead_ingroup => |new_lead_ingroup=>/)
{
$new_lead_ingroup = $VIDScontainer_array[$VIDSc];
$new_lead_ingroup =~ s/new_lead_ingroup => |new_lead_ingroup=>//gi;
$new_lead_ingroup =~ s/[^-_0-9a-zA-Z]//gi;
}
if ($VIDScontainer_array[$VIDSc] =~ /default_ingroup => |default_ingroup=>/)
{
$default_ingroup = $VIDScontainer_array[$VIDSc];
$default_ingroup =~ s/default_ingroup => |default_ingroup=>//gi;
$default_ingroup =~ s/[^-_0-9a-zA-Z]//gi;
}
}
$VIDSc++;
}
}
$sthA->finish();
}
if ($container_lines < 2)
{
if ($AGILOG) {$agi_string = "VID-SPECIAL container invalid! transferring to 's' |$vid_special_container|$channel|$callerid|"; &agi_output;}
print "SET CONTEXT $context\n";
$result = <STDIN>;
checkresult($result);
print "SET EXTENSION s\n";
$result = <STDIN>;
checkresult($result);
print "SET PRIORITY 1\n";
$result = <STDIN>;
checkresult($result);
}
if ( (length($new_lead_ingroup) < 1) && (length($default_ingroup) > 0) )
{$new_lead_ingroup = $default_ingroup;}
$LOGuser='VDCL';
$AGI->stream_file('sip-silence');
$AGI->stream_file('sip-silence');
if ($call_handle_method =~ /^VIDPROMPT/)
{
$vendor_lead_code = $AGI->get_variable('vendor_lead_code');
if ( ($AGILOG) && (length($vendor_lead_code)>0) ) {$agi_string = "vendor id AGI variable: |$vendor_lead_code|"; &agi_output;}
if (length($vendor_lead_code)>2)
{
$vendor_id = $vendor_lead_code;
}
else
{
&enter_id_number;
}
}
if ($call_handle_method =~ /LOOKUP/)
{
$listSQL = '';
if ($call_handle_method =~ /LOOKUPRL/)
{$listSQL = "and list_id='$list_id'";}
else
{
if ($call_handle_method =~ /LOOKUPRC/)
{
### Grab all lists associated with Scampaign_id
$cbc=0;
$SlistsSQL='';
$stmtA = "SELECT list_id FROM vicidial_lists where campaign_id='$Scampaign_id' limit 1000;";
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
$sthArows=$sthA->rows;
$dbhP=$dbhA; $mysql_count='02009'; $MEL_aff_rows=$sthArows; &mysql_error_logging;
while ($sthArows > $cbc)
{
@aryA = $sthA->fetchrow_array;
$SlistsSQL .= "'$aryA[0]',";
$cbc++;
}
$sthA->finish();
chop($SlistsSQL);
if (length($SlistsSQL)>3)
{$listSQL = "and list_id IN($SlistsSQL)";}
}
}
$stmtA= "SELECT lead_id,called_count,list_id,phone_number from vicidial_list where vendor_lead_code='$vendor_id' $listSQL order by last_local_call_time desc limit 1;";
if ($AGILOG) {$agi_string = "VDAD vicidial_list search |$vendor_id|$stmtA|"; &agi_output;}
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
$sthArows=$sthA->rows;
$dbhP=$dbhA; $mysql_count='02010'; $MEL_aff_rows=$sthArows; &mysql_error_logging;
if ($sthArows > 0)
{
@aryA = $sthA->fetchrow_array;
$insert_lead_id = $aryA[0];
$called_count = $aryA[1];
$list_id = $aryA[2];
$phone_number = $aryA[3];
$sthA->finish();
if ($AGILOG) {$agi_string = "VID-SPECIAL vicidial_list found |$insert_lead_id|$called_count|$list_id|$vendor_id|$stmtA|"; &agi_output;}
# lead found, now check for match in container for list_id
$i=0;
while ($i < $container_lines)
{
if ($container_array[$i] =~ /^list_ingroup/i)
{
$temp_line = $container_array[$i];
$temp_line =~ s/list_ingroup => |list_ingroup=>| //gi;
@temp_array = split(/,/,$temp_line);
if ($temp_array[0] =~ /^$list_id$/)
{
$match_ingroup = $temp_array[1];
if ($AGILOG) {$agi_string = "VID-SPECIAL list in-group match found |$match_ingroup|$insert_lead_id|$list_id|$vendor_id|$stmtA|"; &agi_output;}
}
}
$i++;
}
if (length($match_ingroup) < 1)
{
if (length($default_ingroup) > 0)
{
$match_ingroup = $default_ingroup;
if ($AGILOG) {$agi_string = "VID-SPECIAL list in-group match not found, using default |$match_ingroup|$insert_lead_id|$list_id|$vendor_id|$stmtA|"; &agi_output;}
}
else
{
if ($AGILOG) {$agi_string = "VID-SPECIAL no list match found and no default ingroup defined, going to 's' |$list_id|$channel|$callerid|$vendor_id|"; &agi_output;}
print "SET CONTEXT $context\n";
$result = <STDIN>;
checkresult($result);
print "SET EXTENSION s\n";
$result = <STDIN>;
checkresult($result);
print "SET PRIORITY 1\n";
$result = <STDIN>;
checkresult($result);
exit;
}
}
# change CIDname to found lead_id
$PADlead_id = sprintf("%010s", $insert_lead_id); while (length($PADlead_id) > 10) {chop($PADlead_id);}
$VIDqueryCID = "Y$CIDdate$PADlead_id";
$newcallerid = "\"$VIDqueryCID <$phone_number>\"";
$AGI->set_callerid($newcallerid);
print STDERR "Setting CID \"$newcallerid\"\n";
checkresult($result);
if ($AGILOG) {$agi_string = "VID-SPECIAL callerID changed: \"$VIDqueryCID\" \<$phone_number\>"; &agi_output;}
# send call to special extension with lead_id defined and handle_method set to CLOSER
$AGI->exec("EXEC Set(_ingroupvar=$match_ingroup)");
$AGI->exec("EXEC Set(_igsearchmethod=$search_method)");
$AGI->exec("EXEC Set(_iglistid=$list_id)");
$AGI->exec("EXEC Set(_igphonecode=$phone_code)");
$AGI->exec("EXEC Set(_igcampaignid=$Scampaign_id)");
$ingroup_exten_string = "A1B1C123";
if ($AGILOG) {$agi_string = "VID-SPECIAL sending to in-group |$ingroup_exten_string|$channel|$callerid|$vendor_id|"; &agi_output;}
print "SET CONTEXT $context\n";
$result = <STDIN>;
checkresult($result);
print "SET EXTENSION $ingroup_exten_string\n";
$result = <STDIN>;
checkresult($result);
print "SET PRIORITY 1\n";
$result = <STDIN>;
checkresult($result);
exit;
}
else
{
if ( ($not_found_action =~ /new_lead/) && (length($new_lead_ingroup) > 0) )
{
# send call to special extension for new lead creation
$AGI->exec("EXEC Set(_ingroupvar=$new_lead_ingroup)");
$AGI->exec("EXEC Set(_igsearchmethod=$search_method)");
$AGI->exec("EXEC Set(_iglistid=$list_id)");
$AGI->exec("EXEC Set(_igphonecode=$phone_code)");
$AGI->exec("EXEC Set(_igcampaignid=$Scampaign_id)");
$AGI->exec("EXEC Set(_igvendorid=$vendor_id)");
$ingroup_exten_string = "A2B2C234";
if ($AGILOG) {$agi_string = "VID-SPECIAL sending new lead to in-group |$ingroup_exten_string|$channel|$callerid|$vendor_id|"; &agi_output;}
print "SET CONTEXT $context\n";
$result = <STDIN>;
checkresult($result);
print "SET EXTENSION $ingroup_exten_string\n";
$result = <STDIN>;
checkresult($result);
print "SET PRIORITY 1\n";
$result = <STDIN>;
checkresult($result);
exit;
}
else
{
if ($AGILOG) {$agi_string = "VID-SPECIAL lead not found going to '$not_found_action' |$vid_special_container|$channel|$callerid|$vendor_id|"; &agi_output;}
print "SET CONTEXT $context\n";
$result = <STDIN>;
checkresult($result);
print "SET EXTENSION $not_found_action\n";
$result = <STDIN>;
checkresult($result);
print "SET PRIORITY 1\n";
$result = <STDIN>;
checkresult($result);
exit;
}
}
}
$dbhA->disconnect();
exit;
### BEGIN VIDPROMPT gather of ID section ###
sub enter_id_number
{
# DEFAULT PROMPTS USED:
# please_enter_id_number - "Please enter your ID Number followed by the # key
# id_number - "Your ID number is"
# confirm_id_number - "Press 1 if it is correct. Press 2 to repeat entry"
$vid_validate_length=1;
$vendor_id='';
if (length($vid_enter_filename) < 1) {$vid_enter_filename = 'please_enter_id_number';}
if (length($vid_id_number_filename) < 1){$vid_id_number_filename = 'id_number';}
if (length($vid_confirm_filename) < 1) {$vid_confirm_filename = 'confirm_id_number';}
if (length($vid_validate_digits) < 1) {$vid_validate_digits = 'X'; $vid_validate_length=0;}
if ($vid_validate_digits =~ /X/) {$vid_validate_digits=99; $vid_validate_length=0;}
if ($AGILOG) {$agi_string = "$call_handle_method method: |$vid_enter_filename|$vid_id_number_filename|$vid_confirm_filename|$vid_validate_digits|$vid_validate_length|"; &agi_output;}
$confirmation=0;
$confirmation_chances=0;
while ( ($confirmation_chances < 3) && ($confirmation < 1) )
{
$entry_chances=0;
$Lvendor_id=0;
if ($AGILOG) {$agi_string = "DEBUG------------------( ($entry_chances < 3) && ( ( ($Lvendor_id < 1) && ($vid_validate_length < 1) ) || ( ($Lvendor_id != $vid_validate_digits) && ($vid_validate_length > 0) ) ) )"; &agi_output;}
while ( ($entry_chances < 3) && ( ( ($Lvendor_id < 1) && ($vid_validate_length < 1) ) || ( ($Lvendor_id != $vid_validate_digits) && ($vid_validate_length > 0) ) ) )
{
$entry_chances++;
$digits_being_entered=1;
$id_number='';
$interrupt_digit='';
$interrupt_digit = $AGI->stream_file("$vid_enter_filename",'0123456789');
if ($AGILOG) {$agi_string = "interrupt_digit |$interrupt_digit|"; &agi_output;}
if ($interrupt_digit > 0)
{
# if ($interrupt_digit == 35) {$interrupt_digit='#';}
# if ($interrupt_digit == 42) {$interrupt_digit='*';}
if ($interrupt_digit == 48) {$interrupt_digit=0;}
if ($interrupt_digit == 49) {$interrupt_digit=1;}
if ($interrupt_digit == 50) {$interrupt_digit=2;}
if ($interrupt_digit == 51) {$interrupt_digit=3;}
if ($interrupt_digit == 52) {$interrupt_digit=4;}
if ($interrupt_digit == 53) {$interrupt_digit=5;}
if ($interrupt_digit == 54) {$interrupt_digit=6;}
if ($interrupt_digit == 55) {$interrupt_digit=7;}
if ($interrupt_digit == 56) {$interrupt_digit=8;}
if ($interrupt_digit == 57) {$interrupt_digit=9;}
$id_number=$interrupt_digit;
}
$digit_loop_counter=0;
while ($digits_being_entered > 0)
{
$digit = chr($AGI->wait_for_digit('5000')); # wait 5 seconds for input or until the pound key is pressed
if ($digit =~ /\d/)
{
$id_number = "$id_number$digit";
if ($AGILOG) {$agi_string = "digit |$digit| id_number |$id_number|"; &agi_output;}
undef $digit;
}
else
{
$digits_being_entered=0;
}
$Lid_number = length($id_number);
if ($Lid_number >= $vid_validate_digits)
{
$digits_being_entered=0;
}
$digit_loop_counter++;
}
$id_number =~ s/\D//gi;
$vendor_id = $id_number;
$Lvendor_id = length($vendor_id);
}
$AGI->stream_file("$vid_id_number_filename");
$AGI->say_digits("$vendor_id");
### if vendor_id has been set, ask to confirm it
if (length($vendor_id) > 0)
{
$interrupt_digit = $AGI->stream_file("$vid_confirm_filename",'12');
if ($AGILOG) {$agi_string = "interrupt_digit |$interrupt_digit|"; &agi_output;}
$digits_being_entered=1;
$ANSWER_confirm='';
if ($interrupt_digit > 0)
{
if ($interrupt_digit == 49) {$interrupt_digit=1;}
if ($interrupt_digit == 50) {$interrupt_digit=2;}
$ANSWER_confirm=$interrupt_digit;
}
if (length($ANSWER_confirm) < 1)
{
$digit_loop_counter=0;
while ( ($digits_being_entered > 0) && ($digit_loop_counter < 1) )
{
$digit = chr($AGI->wait_for_digit('5000')); # wait 5 seconds for input
if ($digit =~ /\d/)
{
$ANSWER_confirm = "$ANSWER_confirm$digit";
if ($AGILOG) {$agi_string = "digit |$digit| ANSWER_confirm |$ANSWER_confirm|"; &agi_output;}
undef $digit;
}
else
{
$digits_being_entered=0;
}
$digit_loop_counter++;
}
}
$ANSWER_confirm =~ s/\D//gi;
if ($ANSWER_confirm > 1)
{$vendor_id='';}
if ( ($ANSWER_confirm > 0) && ($ANSWER_confirm < 2) )
{$confirmation=1;}
}
if ($confirmation < 1)
{
$AGI->stream_file('buzz');
}
$confirmation_chances++;
}
}
### END VIDPROMPT gather of ID section ###
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++;
}
}
sub leading_zero($)
{
$_ = $_[0];
s/^(\d)$/0$1/;
s/^(\d\d)$/0$1/;
return $_;
} # End of the leading_zero() routine.
sub agi_output
{
($Lsec,$Lmin,$Lhour,$Lmday,$Lmon,$Lyear,$Lwday,$Lyday,$Lisdst) = localtime(time);
if ($Lhour < 10) {$Lhour = "0$Lhour";}
if ($Lmin < 10) {$Lmin = "0$Lmin";}
if ($Lsec < 10) {$Lsec = "0$Lsec";}
$LOGtime = "$Lhour:$Lmin:$Lsec";
if ($AGILOG >=2)
{
### open the log file for writing ###
open(Lout, ">>$AGILOGfile")
|| die "Can't open $AGILOGfile: $!\n";
print Lout "$now_date|$LOGtime|$script|$agi_string\n";
close(Lout);
}
### send to STDERR writing ###
if ( ($AGILOG == '1') || ($AGILOG == '3') )
{print STDERR "$now_date|$LOGtime|$script|$agi_string\n";}
$agi_string='';
}
sub mysql_error_logging
{
($Lsec,$Lmin,$Lhour,$Lmday,$Lmon,$Lyear,$Lwday,$Lyday,$Lisdst) = localtime(time);
if ($Lhour < 10) {$Lhour = "0$Lhour";}
if ($Lmin < 10) {$Lmin = "0$Lmin";}
if ($Lsec < 10) {$Lsec = "0$Lsec";}
$LOGtime = "$Lhour:$Lmin:$Lsec";
$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|$LOGtime|$script|$mysql_count|$MEL_aff_rows|$errno|$error|$stmtA|$callerid|$insert_lead_id|\n";
close(Eout);
}
}
$one_mysql_log=0;
}
# 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 );
}
+21 -4
View File
@@ -165,9 +165,10 @@
# 230420-2321 - Added latency live agent detail updates and log rolling nightly
# 230511-0825 - Added log_latency_gaps trigger, demographic_quotas trigger
# 230524-2144 - Added weekday_resets
# 230609-1137 - Added VIDPROMPTSPECIAL call menu In-Group dialplan entries
#
$build = '230524-2144';
$build = '230609-1137';
$DB=0; # Debug flag
$teodDB=0; # flag to log Timeclock End of Day processes to log file
@@ -4069,6 +4070,7 @@ if ( ($active_asterisk_server =~ /Y/) && ($generate_vicidial_conf =~ /Y/) && ($r
$call_menu_options_ext = '';
$cm_invalid_set=0;
$cm_timeout_set=0;
$VIDSPECIAL_flag=0;
if ($DBX>0) {print "$sthArowsJ|$stmtA\n";}
while ($sthArowsJ > $j)
{
@@ -4225,16 +4227,25 @@ if ( ($active_asterisk_server =~ /Y/) && ($generate_vicidial_conf =~ /Y/) && ($r
$IGvid_id_number_filename = $IGoption_route_value_context[6];
$IGvid_confirm_filename = $IGoption_route_value_context[7];
$IGvid_validate_digits = $IGoption_route_value_context[8];
$IGvid_container = $IGoption_route_value_context[9];
if ($dtmf_log[$i] > 0)
{$call_menu_line .= "exten => $option_value[$j],$PRI,AGI(cm.agi,$tracking_group[$i]-----$option_value[$j]-----$dtmf_field[$i]-----$alt_dtmf_log[$i]-----$question[$i])\n"; $PRI++;}
if ($option_route_value[$j] =~ /DYNAMIC_INGROUP_VAR/)
if ($IGhandle_method =~ /VIDPROMPTSPECIAL/)
{
$call_menu_line .= "exten => $option_value[$j],$PRI,AGI(agi-VDAD_ALL_inbound.agi,$IGhandle_method-----$IGsearch_method-----\$\{ingroupvar\}-----$menu_id[$i]--------------------$IGlist_id-----$IGphone_code-----$IGcampaign_id---------------$IGvid_enter_filename-----$IGvid_id_number_filename-----$IGvid_confirm_filename-----$IGvid_validate_digits)\n"; $PRI++;
$call_menu_line .= "exten => $option_value[$j],$PRI,AGI(cm_VID_SPECIAL.agi,$IGhandle_method---$IGsearch_method---$IGlist_id---$IGphone_code---$IGcampaign_id---$IGvid_enter_filename---$IGvid_id_number_filename---$IGvid_confirm_filename---$IGvid_validate_digits---$IGvid_container)\n"; $PRI++;
$VIDSPECIAL_flag++;
}
else
{
$call_menu_line .= "exten => $option_value[$j],$PRI,AGI(agi-VDAD_ALL_inbound.agi,$IGhandle_method-----$IGsearch_method-----$option_route_value[$j]-----$menu_id[$i]--------------------$IGlist_id-----$IGphone_code-----$IGcampaign_id---------------$IGvid_enter_filename-----$IGvid_id_number_filename-----$IGvid_confirm_filename-----$IGvid_validate_digits)\n"; $PRI++;
if ($option_route_value[$j] =~ /DYNAMIC_INGROUP_VAR/)
{
$call_menu_line .= "exten => $option_value[$j],$PRI,AGI(agi-VDAD_ALL_inbound.agi,$IGhandle_method-----$IGsearch_method-----\$\{ingroupvar\}-----$menu_id[$i]--------------------$IGlist_id-----$IGphone_code-----$IGcampaign_id---------------$IGvid_enter_filename-----$IGvid_id_number_filename-----$IGvid_confirm_filename-----$IGvid_validate_digits)\n"; $PRI++;
}
else
{
$call_menu_line .= "exten => $option_value[$j],$PRI,AGI(agi-VDAD_ALL_inbound.agi,$IGhandle_method-----$IGsearch_method-----$option_route_value[$j]-----$menu_id[$i]--------------------$IGlist_id-----$IGphone_code-----$IGcampaign_id---------------$IGvid_enter_filename-----$IGvid_id_number_filename-----$IGvid_confirm_filename-----$IGvid_validate_digits)\n"; $PRI++;
}
}
$call_menu_line .= "exten => $option_value[$j],$PRI,Hangup()\n";
}
@@ -4466,6 +4477,12 @@ if ( ($active_asterisk_server =~ /Y/) && ($generate_vicidial_conf =~ /Y/) && ($r
$call_menu_ext .= "$call_menu_options_ext";
$call_menu_ext .= "\n";
if ($VIDSPECIAL_flag > 0)
{
$call_menu_ext .= "exten => A1B1C123,1,AGI(agi-VDAD_ALL_inbound.agi,CLOSER-----\$\{igsearchmethod\}-----\$\{ingroupvar\}-----$menu_id[$i]--------------------\$\{iglistid\}-----\$\{igphonecode\}-----\$\{igcampaignid\}------------------------------)\n"; $PRI++;
$call_menu_ext .= "exten => A2B2C234,1,AGI(agi-VDAD_ALL_inbound.agi,CID-----\$\{igsearchmethod\}-----\$\{ingroupvar\}-----$menu_id[$i]--------------------\$\{iglistid\}-----\$\{igphonecode\}-----\$\{igcampaignid\}----------\$\{igvendorid\}--------------------)\n"; $PRI++;
}
if (length($call_menu_timeout_ext) < 1)
{
if ( (length($menu_timeout_prompt[$i])>0) && ($menu_timeout_prompt[$i] !~ /NONE/) )
@@ -1,4 +1,4 @@
2FA - TWO FACTOR AUTHENTICATION Updated: 2021-03-12
2FA - TWO FACTOR AUTHENTICATION Updated: 2023-06-10
This document covers the 2FA(Two-Factor-Authentication) features in VICIdial as
of admin.php build 210312-1239(svn/trunk revision 3373).
@@ -62,6 +62,11 @@ USER MODIFY:
3. There is also a User option "Two Factor Auth Override" which allows an administrator to disable 2FA for a specific user account.
Notes:
Upon activating 2FA in the System Settings, if you get the following message, it means that your user account does not have an Email address and Mobile Phone number filled in:
"Your User account is not configured for Two-Factor-Authentication. Please contact your system administrator"
@@ -1432,7 +1432,9 @@ custom_five TEXT,
second_alert_trigger VARCHAR(20) default 'DISABLED',
second_alert_trigger_seconds INT(6) default '600',
second_alert_filename VARCHAR(100) default '',
second_alert_delay INT(6) default '1000'
second_alert_delay INT(6) default '1000',
second_alert_container VARCHAR(40) default 'DISABLED',
second_alert_only VARCHAR(40) default 'DISABLED'
) ENGINE=MyISAM;
CREATE TABLE vicidial_stations (
@@ -5415,6 +5417,7 @@ INSERT INTO vicidial_settings_containers(container_id,container_notes,container_
INSERT INTO vicidial_settings_containers(container_id,container_notes,container_type,user_group,container_entry) VALUES ('HOPPER_CLI_FLAGS', 'Comand-line flags for hopper process', 'PERL_CLI', '---ALL---', '');
INSERT INTO vicidial_settings_containers(container_id,container_notes,container_type,user_group,container_entry) VALUES ('AGENT_LATENCY_LOGGING','Default agent latency logging settings','PERL_CLI','---ALL---','minimum_gap => 30\r\nemail_sender => \r\nemail_list => \r\nemail_subject => Agent Network Alert');
INSERT INTO vicidial_settings_containers(container_id,container_notes,container_type,user_group,container_entry) VALUES ('EXAMPLE_LIST_WEEKDAY_RESETS','Example Weekday List Resets Container settings','LIST_WEEKDAY_RESETS','---ALL---','; weekday => reset-times in 24-hour time separated by dashes\r\nmonday => 0830-1230-1800\r\ntuesday => 0900-1400-1830\r\nwednesday => 0930-1200-1730-1900\r\nthursday => 1030-1330-1900\r\nfriday => 0800-1300-1530\r\nsaturday => 0930-1100\r\nsunday => 1000');
INSERT INTO vicidial_settings_containers(container_id,container_notes,container_type,user_group,container_entry) VALUES ('EXAMPLE_VID_PROMPT_SPECIAL','Example Call Menu VID Special Container settings','CM_VIDPROMPT_SPECIAL','---ALL---','list_ingroup => 102,TEST_IN2\r\nlist_ingroup => 103,TEST_IN3\r\nlist_ingroup => 104,TEST_IN4\r\ndefault_ingroup => TEST_IN5\r\nnot_found_action => new_lead\r\nnew_lead_ingroup => TEST_IN');
INSERT INTO `vicidial_settings_containers` VALUES ('VERM_STATUS_NAMES_OVERRIDE','Override dialer status names in enhanced reporting','OTHER','---ALL---','; For each status name you want overridden, type the status followed by\r\n; a pipe, then the new status name\r\n; Ex:\r\n; NZ|Taumatawhakatangihangakoauauotamateaturipukakapikimaungahoronukupoka\r\n201214|Request To Cancel\r\n210200|No Answer-Incomplete Call\r\n210201|Contact Established\r\n210202|Provider Review - HB\r\n210203|Promise to Pay\r\n210204|Setup Payment Plan\r\n210205|Research-Inquiry\r\n210206|Voice Mail Left - HB\r\n210207|Do Not Call\r\n210208|Appeal Verification\r\n210209|Bad Phone\r\n210210|Bad Address\r\n210211|Direct Pay Verification\r\n210213|Provider Approved\r\n210215|Update Notes Only\r\n210216|Voicemail-No Status Change\r\n210217|Sent Letter Request - HB\r\n210218|Auto VoiceMail Left - HB\r\n210219|Auto VoiceMail-No Status Change\r\n210302|Provider Review - LB\r\n210306|Voice Mail Left - LB\r\n210317|Sent Letter Request - LB\r\n210318|Auto VoiceMail Left - LB\r\n211503|Provider - COVID-19\r\n211603|Transferred Call to MLA\r\n'), ('VERM_REPORT_OPTIONS','Container for customizing VERM report output','OTHER','---ALL---','; This is the report queue used if none is chosen by the user\r\n; It\'s preloaded in some forms as well\r\nVERM_default_report_queue => ALL\r\n\r\n; If there are statuses to exclude from reports, list them here\r\n; Separate with commas. Default is AFTHRS\r\nexc_addtl_statuses => AFTHRS\r\n\r\n; Set the below value to 1 (or anything non-blank/non-zero) in order to \r\n; show the agents ID in addition to their full name in the report results\r\nshow_full_agent_info => 1\r\n\r\n; Some reports count \"lost\" calls - which are defined by the below variable\r\n; listing what you define as \"lost\" dispos. Separate with commas.\r\nlost_statuses => LOST,210208,DISPO\r\n\r\n; You can create a detailed IVR survey report for ingroups by defining\r\n; \"ivr_survey_ingroups_detail\" and \"ivr_survey_ingroups_voicemails.\"\r\n; For \"details\", supply an ingroup used as a tracking group on call menus.\r\n; Then, add a pipe and after that list all call menus that use the ingroup\r\n; as the tracking group, separating each with a comma\r\n; To track whether the calls went to voicemail, list every call menu/option\r\n; combination that goes to voicemail, separating the call menu from the \r\n; option with a pipe. One callmenu/option combo per line.\r\nivr_survey_ingroups_detail => 521205|561401,561402,561403,561404,561505\r\nivr_survey_ingroups_voicemails => 561505|t\r\n\r\n; #####################################################\r\n; # ALL of the below are used in the wallboard report #\r\n; #####################################################\r\nVERM_default_outb_widget_queue => ALL_OUT\r\nVERM_default_inb_widget_queue1 => 514915v_USA_Shared\r\nVERM_default_inb_widget_queue2 => 515915v_MLA_Shared\r\n\r\n; Used specifically for the SLA widget\r\n; Uses ingroups - separate multiple ingroups by commas\r\n; Comment out or leave blank to count all ingroups\r\nSLA_LEVEL_PCT_ingroups => 514915v,515915v\r\n\r\n; This removes remote agents from the wallboard reports\r\n; Comment out to include remote agents (or set to zero)\r\nomit_remote_agents => 1\r\n\r\n\r\n; #### AUTO DOWNLOAD ####\r\n; If the "total calls" value on any report requested exceeds the below \r\n; limit, automatically download the three "DETAILS" reports instead\r\n; of attempting to display that many records on-screen\r\nauto_download_limit => 50000\r\n\r\n; #### OUTCOMES report overrides ####\r\n; Use "outcome_lagged_status_overrides" for conditions where the call \r\n; record in the vicidial_log or vicidial_closer_log table has no uniqueid\r\n; value despite having a status/outcome, which can indicate a call \r\n; affected by network lag for certain statuses. This will change the call \r\n; status to "LAGGED". Separate statuses with commas. Default is the \r\n; automatic "PU" status.\r\noutcome_lagged_status_overrides => PU\r\n\r\n; Use "unknown_network_statuses" to change call statuses to read "Network/\r\n; LAGGED" on the OUTCOMES report. Separate statuses with commas.\r\n; IMPORTANT: if you are using the outcome_lagged_status_overrides option \r\n; above, make sure "LAGGED" is one of the unknown_network_statuses here\r\n; unknown_network_statuses => LAGGED\r\n\r\n; Use "outcome_status_overrides" to change one status to another on the \r\n; OUTCOMES report. Overrides are comma-separated pairs of dispositions \r\n; where the first disposition is the disposition to change, and the second\r\n; is the disposition to change to. Separate pairs with a pipe character as\r\n; in the below example. Off by default.\r\n; outcome_status_overrides => CBHOLD,DISPO|XFER,AL');
INSERT INTO `wallboard_widgets` VALUES ('queues_widget_1','AGENTS_AND_QUEUES','queues','','TEXT',5,'N',1,'Queue Information','','',NULL,'','',NULL,2),('queues_widget_0','AGENTS_AND_QUEUES','queues','','LOGO',2,'N',1,NULL,'','',NULL,'','',NULL,1),('queues_widget_2','AGENTS_AND_QUEUES','queues','SLA Level %','SLA_LEVEL_PCT',1,'N',1,NULL,'','>60',NULL,'','',NULL,3),('queues_widget_3','AGENTS_AND_QUEUES','queues','Outbound calls','LIVE_QUEUE_INFO',1,'N',1,'','201201','','','','','yellow_alarm,|red_alarm,',4),('queues_widget_4','AGENTS_AND_QUEUES','queues','USA Ded Inbound','LIVE_QUEUE_INFO',1,'N',1,'','ALL_IN','','','','','yellow_alarm,|red_alarm,',5),('queues_widget_5','AGENTS_AND_QUEUES','queues','MLA Ded Inbound','LIVE_QUEUE_INFO',1,'N',1,'','514911','','','','','yellow_alarm,|red_alarm,',6),('queues_widget_6','AGENTS_AND_QUEUES','queues','N Waiting Calls','N_WAITING_CALLS',1,'N',1,NULL,'','',NULL,'','',NULL,7),('queues_widget_7','AGENTS_AND_QUEUES','queues','Offered Calls','OFFERED_CALLS',1,'N',1,NULL,'','',NULL,'','',NULL,8),('queues_widget_8','AGENTS_AND_QUEUES','queues','Answered Calls','ANSWERED_CALLS',1,'N',1,NULL,'','',NULL,'','',NULL,9),('queues_widget_9','AGENTS_AND_QUEUES','queues','Lost Calls','LOST_CALLS',1,'N',1,NULL,'','',NULL,'','',NULL,10),('queues_widget_10','AGENTS_AND_QUEUES','queues','Longest Wait','LONGEST_WAIT',1,'N',1,NULL,'','',NULL,'','',NULL,11),('queues_widget_11','AGENTS_AND_QUEUES','queues','Live Queues','LIVE_QUEUES',1,'Y',1,NULL,'','',NULL,'','',NULL,12),('queues_widget_12','AGENTS_AND_QUEUES','queues','Live Calls','LIVE_CALLS',1,'Y',2,NULL,'','',NULL,'','',NULL,13),('agent_widget_0','AGENTS_AND_QUEUES','agents','','LOGO',2,'N',1,NULL,'','',NULL,'','',NULL,1),('agent_widget_1','AGENTS_AND_QUEUES','agents','N Waiting Calls','N_WAITING_CALLS',1,'N',1,NULL,'','',NULL,'','',NULL,2),('agent_widget_2','AGENTS_AND_QUEUES','agents','Agents Ready','AGENTS_READY',1,'N',1,NULL,'','',NULL,'','',NULL,3),('agent_widget_3','AGENTS_AND_QUEUES','agents','Agents On Call','N_AGENTS_ON_CALL',1,'N',1,NULL,'','',NULL,'','',NULL,4),('agent_widget_4','AGENTS_AND_QUEUES','agents','N Answered Calls','N_ANSWERED_CALLS',1,'N',1,NULL,'','',NULL,'','',NULL,5),('agent_widget_5','AGENTS_AND_QUEUES','agents','Clock','CLOCK',1,'N',1,NULL,'','',NULL,'','',NULL,6),('agent_widget_6','AGENTS_AND_QUEUES','agents','Live Agents','LIVE_AGENTS',1,'Y',3,NULL,'','',NULL,'','',NULL,7);
@@ -5423,4 +5426,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 db_schema_version='1688',db_schema_update_date=NOW(),reload_timestamp=NOW();
UPDATE system_settings SET db_schema_version='1689',db_schema_update_date=NOW(),reload_timestamp=NOW();
+7
View File
@@ -2377,3 +2377,10 @@ ALTER TABLE vicidial_inbound_groups ADD second_alert_filename VARCHAR(100) defau
ALTER TABLE vicidial_inbound_groups ADD second_alert_delay INT(6) default '1000';
UPDATE system_settings SET db_schema_version='1688',db_schema_update_date=NOW() where db_schema_version < 1688;
ALTER TABLE vicidial_inbound_groups ADD second_alert_container VARCHAR(40) default 'DISABLED';
ALTER TABLE vicidial_inbound_groups ADD second_alert_only VARCHAR(40) default 'DISABLED';
INSERT INTO vicidial_settings_containers(container_id,container_notes,container_type,user_group,container_entry) VALUES ('EXAMPLE_VID_PROMPT_SPECIAL','Example Call Menu VID Special Container settings','CM_VIDPROMPT_SPECIAL','---ALL---','list_ingroup => 102,TEST_IN2\r\nlist_ingroup => 103,TEST_IN3\r\nlist_ingroup => 104,TEST_IN4\r\ndefault_ingroup => TEST_IN5\r\nnot_found_action => new_lead\r\nnew_lead_ingroup => TEST_IN');
UPDATE system_settings SET db_schema_version='1688',db_schema_update_date=NOW() where db_schema_version < 1689;
+19 -3
View File
@@ -8137,7 +8137,19 @@ if ($stage == "start")
echo "LOG NOT ENTERED\n";
}
$stmt = "UPDATE vicidial_auto_calls SET uniqueid='$uniqueid' where lead_id='$lead_id';";
$lead_callerid='';
$stmt="SELECT callerid FROM vicidial_live_agents WHERE user='$user';";
$rslt=mysql_to_mysqli($stmt, $link);
if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00XXX',$user,$server_ip,$session_name,$one_mysql_log);}
if ($DB) {echo "$stmt\n";}
$CID_exists_ct = mysqli_num_rows($rslt);
if ($CID_exists_ct > 0)
{
$row=mysqli_fetch_row($rslt);
$lead_callerid = $row[0];
}
$stmt = "UPDATE vicidial_auto_calls SET uniqueid='$uniqueid' where lead_id='$lead_id' and callerid='$lead_callerid';";
if ($DB) {echo "$stmt\n";}
$rslt=mysql_to_mysqli($stmt, $link);
if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00058',$user,$server_ip,$session_name,$one_mysql_log);}
@@ -16540,11 +16552,15 @@ if ( ($ACTION == 'VDADpause') or ($ACTION == 'VDADready') or ($pause_trigger ==
{
$vla_autodialSQL='';
$vla_pausecodeSQL='';
$vla_statusSQL='';
if (preg_match('/INBOUND_MAN/',$dial_method))
{$vla_autodialSQL = ",outbound_autodial='N'";}
if ($ACTION == 'VDADready')
{$vla_pausecodeSQL = ",pause_code='',external_pause_code=''";}
$stmt="UPDATE vicidial_live_agents set uniqueid=0,callerid='',channel='', random_id='$random',comments='',last_state_change='$NOW_TIME' $vla_autodialSQL $vla_pausecodeSQL where user='$user' and server_ip='$server_ip';";
{
$vla_pausecodeSQL = ",pause_code='',external_pause_code=''";
$vla_statusSQL = "and status != 'QUEUE'";
}
$stmt="UPDATE vicidial_live_agents set uniqueid=0,callerid='',channel='', random_id='$random',comments='',last_state_change='$NOW_TIME' $vla_autodialSQL $vla_pausecodeSQL where user='$user' and server_ip='$server_ip' $vla_statusSQL;";
if ($format=='debug') {echo "\n<!-- $stmt -->";}
$rslt=mysql_to_mysqli($stmt, $link);
if ($mel > 0) {$errno = mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00165',$user,$server_ip,$session_name,$one_mysql_log);}
File diff suppressed because one or more lines are too long
+32 -3
View File
@@ -97,6 +97,7 @@
# 221214-1321 - Added HTML color chooser
# 221230-2230 - Added Postal Codes Cities submenu
# 230118-0835 - Added Agent Call Hangup Change function
# 230613-1835 - Added VIDPROMPTSPECIAL options
#
$HTMLcolors = 'IndianRed,CD5C5C|LightCoral,F08080|Salmon,FA8072|DarkSalmon,E9967A|LightSalmon,FFA07A|Crimson,DC143C|Red,FF0000|FireBrick,B22222|DarkRed,8B0000|Pink,FFC0CB|LightPink,FFB6C1|HotPink,FF69B4|DeepPink,FF1493|MediumVioletRed,C71585|PaleVioletRed,DB7093|LightSalmon,FFA07A|Coral,FF7F50|Tomato,FF6347|OrangeRed,FF4500|DarkOrange,FF8C00|Orange,FFA500|Gold,FFD700|Yellow,FFFF00|LightYellow,FFFFE0|LemonChiffon,FFFACD|LightGoldenrodYellow,FAFAD2|PapayaWhip,FFEFD5|Moccasin,FFE4B5|PeachPuff,FFDAB9|PaleGoldenrod,EEE8AA|Khaki,F0E68C|DarkKhaki,BDB76B|Lavender,E6E6FA|Thistle,D8BFD8|Plum,DDA0DD|Violet,EE82EE|Orchid,DA70D6|Fuchsia,FF00FF|Magenta,FF00FF|MediumOrchid,BA55D3|MediumPurple,9370DB|RebeccaPurple,663399|BlueViolet,8A2BE2|DarkViolet,9400D3|DarkOrchid,9932CC|DarkMagenta,8B008B|Purple,800080|Indigo,4B0082|SlateBlue,6A5ACD|DarkSlateBlue,483D8B|MediumSlateBlue,7B68EE|GreenYellow,ADFF2F|Chartreuse,7FFF00|LawnGreen,7CFC00|Lime,00FF00|LimeGreen,32CD32|PaleGreen,98FB98|LightGreen,90EE90|MediumSpringGreen,00FA9A|SpringGreen,00FF7F|MediumSeaGreen,3CB371|SeaGreen,2E8B57|ForestGreen,228B22|Green,008000|DarkGreen,006400|YellowGreen,9ACD32|OliveDrab,6B8E23|Olive,808000|DarkOliveGreen,556B2F|MediumAquamarine,66CDAA|DarkSeaGreen,8FBC8B|LightSeaGreen,20B2AA|DarkCyan,008B8B|Teal,008080|Aqua,00FFFF|Cyan,00FFFF|LightCyan,E0FFFF|PaleTurquoise,AFEEEE|Aquamarine,7FFFD4|Turquoise,40E0D0|MediumTurquoise,48D1CC|DarkTurquoise,00CED1|CadetBlue,5F9EA0|SteelBlue,4682B4|LightSteelBlue,B0C4DE|PowderBlue,B0E0E6|LightBlue,ADD8E6|SkyBlue,87CEEB|LightSkyBlue,87CEFA|DeepSkyBlue,00BFFF|DodgerBlue,1E90FF|CornflowerBlue,6495ED|MediumSlateBlue,7B68EE|RoyalBlue,4169E1|Blue,0000FF|MediumBlue,0000CD|DarkBlue,00008B|Navy,000080|MidnightBlue,191970|Cornsilk,FFF8DC|BlanchedAlmond,FFEBCD|Bisque,FFE4C4|NavajoWhite,FFDEAD|Wheat,F5DEB3|BurlyWood,DEB887|Tan,D2B48C|RosyBrown,BC8F8F|SandyBrown,F4A460|Goldenrod,DAA520|DarkGoldenrod,B8860B|Peru,CD853F|Chocolate,D2691E|SaddleBrown,8B4513|Sienna,A0522D|Brown,A52A2A|Maroon,800000|White,FFFFFF|Snow,FFFAFA|HoneyDew,F0FFF0|MintCream,F5FFFA|Azure,F0FFFF|AliceBlue,F0F8FF|GhostWhite,F8F8FF|WhiteSmoke,F5F5F5|SeaShell,FFF5EE|Beige,F5F5DC|OldLace,FDF5E6|FloralWhite,FFFAF0|Ivory,FFFFF0|AntiqueWhite,FAEBD7|Linen,FAF0E6|LavenderBlush,FFF0F5|MistyRose,FFE4E1|Gainsboro,DCDCDC|LightGray,D3D3D3|Silver,C0C0C0|DarkGray,A9A9A9|Gray,808080|DimGray,696969|LightSlateGray,778899|SlateGray,708090|DarkSlateGray,2F4F4F|Black,000000';
@@ -952,6 +953,22 @@ else
document.getElementById("audio_chooser_span").innerHTML = Iframe_content;
}
function launch_container_chooser(fieldname,stage,type)
{
var h = window.innerHeight;
var vposition=mouseY;
var apilistURL = "./non_agent_api.php";
var apilistQuery = "source=admin&function=container_list&user=" + user + "&pass=" + pass + "&format=selectframe&stage=" + stage + "&comments=" + fieldname + "&type=" + type;
var Iframe_content = '<IFRAME SRC="' + apilistURL + '?' + apilistQuery + '" style="width:740;height:440;background-color:white;" scrolling="NO" frameborder="0" allowtransparency="true" id="audio_chooser_frame' + epoch + '" name="audio_chooser_frame" width="740" height="460" STYLE="z-index:2"> </IFRAME>';
document.getElementById("audio_chooser_span").style.position = "absolute";
document.getElementById("audio_chooser_span").style.left = "220px";
document.getElementById("audio_chooser_span").style.top = vposition + "px";
document.getElementById("audio_chooser_span").style.visibility = 'visible';
document.getElementById("audio_chooser_span").innerHTML = Iframe_content;
}
function launch_vm_chooser(fieldname,stage)
{
var h = window.innerHeight;
@@ -1220,7 +1237,7 @@ if ( ($ADD==3511) or ($ADD==2511) or ($ADD==2611) or ($ADD==4511) or ($ADD==5511
$i++;
}
$IGhandle_method_list = '<option>CID</option><option>CIDLOOKUP</option><option>CIDLOOKUPRL</option><option>CIDLOOKUPRC</option><option>CIDLOOKUPALT</option><option>CIDLOOKUPRLALT</option><option>CIDLOOKUPRCALT</option><option>CIDLOOKUPADDR3</option><option>CIDLOOKUPRLADDR3</option><option>CIDLOOKUPRCADDR3</option><option>CIDLOOKUPALTADDR3</option><option>CIDLOOKUPRLALTADDR3</option><option>CIDLOOKUPRCALTADDR3</option><option>ANI</option><option>ANILOOKUP</option><option>ANILOOKUPRL</option><option>VIDPROMPT</option><option>VIDPROMPTLOOKUP</option><option>VIDPROMPTLOOKUPRL</option><option>VIDPROMPTLOOKUPRC</option><option>CLOSER</option><option>3DIGITID</option><option>4DIGITID</option><option>5DIGITID</option><option>10DIGITID</option><option>CIDLOOKUPOWNERCUSTOMX</option><option>CIDLOOKUPRLOWNERCUSTOMX</option><option>CIDLOOKUPRCOWNERCUSTOMX</option><option>CIDLOOKUPALTOWNERCUSTOMX</option><option>CIDLOOKUPRLALTOWNERCUSTOMX</option><option>CIDLOOKUPRCALTOWNERCUSTOMX</option><option>CIDLOOKUPADDR3OWNERCUSTOMX</option><option>CIDLOOKUPRLADDR3OWNERCUSTOMX</option><option>CIDLOOKUPRCADDR3OWNERCUSTOMX</option><option>CIDLOOKUPALTADDR3OWNERCUSTOMX</option><option>CIDLOOKUPRLALTADDR3OWNERCUSTOMX</option><option>CIDLOOKUPRCALTADDR3OWNERCUSTOMX</option>';
$IGhandle_method_list = '<option>CID</option><option>CIDLOOKUP</option><option>CIDLOOKUPRL</option><option>CIDLOOKUPRC</option><option>CIDLOOKUPALT</option><option>CIDLOOKUPRLALT</option><option>CIDLOOKUPRCALT</option><option>CIDLOOKUPADDR3</option><option>CIDLOOKUPRLADDR3</option><option>CIDLOOKUPRCADDR3</option><option>CIDLOOKUPALTADDR3</option><option>CIDLOOKUPRLALTADDR3</option><option>CIDLOOKUPRCALTADDR3</option><option>ANI</option><option>ANILOOKUP</option><option>ANILOOKUPRL</option><option>VIDPROMPT</option><option>VIDPROMPTLOOKUP</option><option>VIDPROMPTLOOKUPRL</option><option>VIDPROMPTLOOKUPRC</option><option>VIDPROMPTSPECIALLOOKUP</option><option>VIDPROMPTSPECIALLOOKUPRL</option><option>VIDPROMPTSPECIALLOOKUPRC</option><option>CLOSER</option><option>3DIGITID</option><option>4DIGITID</option><option>5DIGITID</option><option>10DIGITID</option><option>CIDLOOKUPOWNERCUSTOMX</option><option>CIDLOOKUPRLOWNERCUSTOMX</option><option>CIDLOOKUPRCOWNERCUSTOMX</option><option>CIDLOOKUPALTOWNERCUSTOMX</option><option>CIDLOOKUPRLALTOWNERCUSTOMX</option><option>CIDLOOKUPRCALTOWNERCUSTOMX</option><option>CIDLOOKUPADDR3OWNERCUSTOMX</option><option>CIDLOOKUPRLADDR3OWNERCUSTOMX</option><option>CIDLOOKUPRCADDR3OWNERCUSTOMX</option><option>CIDLOOKUPALTADDR3OWNERCUSTOMX</option><option>CIDLOOKUPRLALTADDR3OWNERCUSTOMX</option><option>CIDLOOKUPRCALTADDR3OWNERCUSTOMX</option>';
$IGsearch_method_list = '<option value=\\"LB\\">LB - '._QXZ("Load Balanced").'</option><option value=\\"LO\\">LO - '._QXZ("Load Balanced Overflow").'</option><option value=\\"SO\\">SO - '._QXZ("Server Only").'</option>';
@@ -1272,7 +1289,7 @@ if ( ($ADD==3511) or ($ADD==2511) or ($ADD==2611) or ($ADD==4511) or ($ADD==5511
if (selected_route=='INGROUP')
{
if (value_context.length < 10)
{value_context = 'CID,LB,998,TESTCAMP,1,,,,';}
{value_context = 'CID,LB,998,TESTCAMP,1,,,,,';}
var value_context_split = value_context.split(",");
var IGhandle_method = value_context_split[0];
var IGsearch_method = value_context_split[1];
@@ -1283,6 +1300,7 @@ if ( ($ADD==3511) or ($ADD==2511) or ($ADD==2611) or ($ADD==4511) or ($ADD==5511
var IGvid_id_number_filename = value_context_split[6];
var IGvid_confirm_filename = value_context_split[7];
var IGvid_validate_digits = value_context_split[8];
var IGvid_container = value_context_split[9];
if (route == selected_route)
{
@@ -1307,6 +1325,8 @@ if ( ($ADD==3511) or ($ADD==2511) or ($ADD==2611) or ($ADD==4511) or ($ADD==5511
new_content = new_content + "<BR> &nbsp; <?php echo _QXZ("VID ID Number Filename"); ?>: <input type=text name=IGvid_id_number_filename_" + option + " id=IGvid_id_number_filename_" + option + " size=40 maxlength=255 value=\"" + IGvid_id_number_filename + "\"> <a href=\"javascript:launch_chooser('IGvid_id_number_filename_" + option + "','date');\"><?php echo _QXZ("audio chooser"); ?></a>";
new_content = new_content + "<BR> &nbsp; <?php echo _QXZ("VID Confirm Filename"); ?>: <input type=text name=IGvid_confirm_filename_" + option + " id=IGvid_confirm_filename_" + option + " size=40 maxlength=255 value=\"" + IGvid_confirm_filename + "\"> <a href=\"javascript:launch_chooser('IGvid_confirm_filename_" + option + "','date');\"><?php echo _QXZ("audio chooser"); ?></a>";
new_content = new_content + " &nbsp; <?php echo _QXZ("VID Digits"); ?>: <input type=text size=3 maxlength=3 name=IGvid_validate_digits_" + option + ' id=IGvid_validate_digits_' + option + ' value="' + IGvid_validate_digits + '">';
new_content = new_content + "<BR> &nbsp; <?php echo _QXZ("VID Container"); ?>: <input type=text size=40 maxlength=40 name=IGvid_container_" + option + ' id=IGvid_container_' + option + ' value="' + IGvid_container + '">';
new_content = new_content + " &nbsp; <IMG SRC=\"help.png\" onClick=\"FillAndShowHelpDiv(event, 'call_menu-ingroup_vid_container')\" WIDTH=20 HEIGHT=20 BORDER=0 ALT=\"HELP\" ALIGN=TOP> <a href=\"javascript:launch_container_chooser('IGvid_container_" + option + "','date','CM_VIDPROMPT_SPECIAL');\"><?php echo _QXZ("container chooser"); ?></a>";
}
if (selected_route=='DID')
{
@@ -1625,6 +1645,13 @@ if ( ($ADD==3511) or ($ADD==2511) or ($ADD==2611) or ($ADD==4511) or ($ADD==5511
var temp10_optionVal = document.getElementById(temp10);
var temp10_prev_optionVal = document.getElementById(temp10_prev);
temp10_optionVal.value = temp10_prev_optionVal.value;
// In-Group VID Container
var temp11 = 'IGvid_container_' + item_number;
var temp11_prev = 'IGvid_container_' + prev_item_number;
var temp11_optionVal = document.getElementById(temp11);
var temp11_prev_optionVal = document.getElementById(temp11_prev);
temp11_optionVal.value = temp11_prev_optionVal.value;
}
}
<?php
@@ -1665,7 +1692,7 @@ if ( ($ADD==2811) or ($ADD==3811) or ($ADD==3111) or ($ADD==2111) or ($ADD==2011
if (selected_route=='INGROUP')
{
if ( (route != selected_route) || (value.length < 10) )
{value = 'SALESLINE,CID,LB,998,TESTCAMP,1,,,,';}
{value = 'SALESLINE,CID,LB,998,TESTCAMP,1,,,,,';}
var value_split = value.split(",");
var IGgroup_id = value_split[0];
var IGhandle_method = value_split[1];
@@ -1677,6 +1704,7 @@ if ( ($ADD==2811) or ($ADD==3811) or ($ADD==3111) or ($ADD==2111) or ($ADD==2011
var IGvid_id_number_filename = value_split[7];
var IGvid_confirm_filename = value_split[8];
var IGvid_validate_digits = value_split[9];
var IGvid_container = value_split[10];
if (route == selected_route)
{
@@ -1698,6 +1726,7 @@ if ( ($ADD==2811) or ($ADD==3811) or ($ADD==3111) or ($ADD==2111) or ($ADD==2011
// new_content = new_content + "<BR> &nbsp; <?php echo _QXZ("VID ID Number Filename"); ?>: <input type=text name=IGvid_id_number_filename_" + option + " id=IGvid_id_number_filename_" + option + " size=40 maxlength=255 value=\"" + IGvid_id_number_filename + "\"> <a href=\"javascript:launch_chooser('IGvid_id_number_filename_" + option + "','date');\"><?php echo _QXZ("audio chooser"); ?></a>";
// new_content = new_content + "<BR> &nbsp; <?php echo _QXZ("VID Confirm Filename"); ?>: <input type=text name=IGvid_confirm_filename_" + option + " id=IGvid_confirm_filename_" + option + " size=40 maxlength=255 value=\"" + IGvid_confirm_filename + "\"> <a href=\"javascript:launch_chooser('IGvid_confirm_filename_" + option + "','date');\"><?php echo _QXZ("audio chooser"); ?></a>";
// new_content = new_content + ' &nbsp; <?php echo _QXZ("VID Digits"); ?>: <input type=text size=3 maxlength=3 name=IGvid_validate_digits_' + option + ' id=IGvid_validate_digits_' + option + ' value="' + IGvid_validate_digits + '">';
// new_content = new_content + '<BR> &nbsp; <?php echo _QXZ("VID Container"); ?>: <input type=text size=40 maxlength=40 name=IGvid_container_' + option + ' id=IGvid_container_' + option + ' value="' + IGvid_container_ + '">';
}
if (selected_route=='DID')
@@ -1,4 +1,4 @@
# version: 20230607092501
# version: 20230614161401
users-user User ID <QXZ>This field is where you put the users ID number, can be up to 20 digits in length, Must be at least 2 characters in length. We strongly recommend not reusing user accounts for different users, for reporting accuracy. To disable a user account, set the Active option to -N-.</QXZ>
users-pass Password <QXZ>This field is where you put the users password. Must be at least 2 characters in length. Only letters and numbers are allowed in user passwords. A medium strength user password will be at least 10 characters in length, and a strong user password will be at least 20 characters in length and have letters as well as at least one number. It is recommended that you use a longer password if possible, stringing together several unrelated words with no spaces, and a number somewhere in the string. The maximum size of a password is 100 characters.</QXZ>
users-force_change_password Force Change Password <QXZ>If this option is set to Y then the user will be prompted to change their password the next time they log in to the administration webpage or the agent screen. Default is N.</QXZ>
@@ -181,7 +181,7 @@ campaigns-queue_priority Queue Priority <QXZ>This setting is used to define the
campaigns-shared_dial_rank Shared Dial Rank <QXZ>For campaigns that are set to a SHARED dial method, this setting will indicate the dialing priority among all of the SHARED dial method campaigns in the system for this specific campaign. The smaller the Shared Dial Rank number for a campaign, the sooner a call will be placed for that campaign. Default is 99.</QXZ>
campaigns-drop_rate_group Multiple Campaign Drop Rate Group <QXZ>This feature allows you to set a campaign as a member of a Campaign Drop Rate Group, or a group of campaigns whose Human Answered calls and Drop calls for all campaigns in the group will be combined into a shared drop percentage, or abandon rate. This allows you to to run multiple campaigns at once and more easily control your drop rate. This is particularly useful in the UK where regulations permit this drop rate calculation method with campaign grouping for the same company even if there are several campaigns that company is running during the same day. To enable this for a campaign, just select a group from the list. There are 10 groups defined in the system by default, you can contact your system administrator to add more. Default is DISABLED.</QXZ>
campaigns-inbound_queue_no_dial Inbound Queue No Dial <QXZ>This feature if set to ENABLED allows you to prevent outbound auto-dialing of this campaign if there are any inbound calls waiting in queue that are part of the allowed inbound groups set in this campaign. Setting this to ALL_SERVERS will change the algorithm to calculate all inbound calls as active calls on this server even if they are on another server which will reduce the chance of placing unnecessary outbound calls if you have calls coming in on another server. Default is DISABLED.</QXZ> <QXZ>If the selected option includes CHAT, then no outbound auto-dialing will take place while an inbound customer chat is waiting.</QXZ>
campaigns-inbound_no_agents_no_dial_container Inbound No-Agents No-Dial <QXZ>If set to something other than ---DISABLED---, the selected INGROUP_LIST type of Settings Container will be used to determine if any agents are ready and waiting for phone calls from at least one of the listed In-Groups. If there are less inbound agents available than the Threshold setting below, then no outbound calls will be placed for this campaign. Default is DISABLED.</QXZ>
campaigns-inbound_no_agents_no_dial_container Inbound No-Agents No-Dial <QXZ>If set to something other than ---DISABLED---, the selected INGROUP_LIST type of Settings Container will be used to determine if any agents are ready and waiting for phone calls from at least one of the listed In-Groups. The Container should have one line per In-Group. If there are less inbound agents available than the Threshold setting below, then no outbound calls will be placed for this campaign. Default is DISABLED.</QXZ>
campaigns-inbound_no_agents_no_dial_threshold Inbound No-Agents No-Dial Threshold <QXZ>If the Inbound No-Agents No-Dial option is enabled above, then this setting will be used to determine if the campaign will be allowed to place outbound auto-dial calls, if this number is greater than the number of inbound agents available. Default is 0, for disabled.</QXZ>
campaigns-auto_alt_dial Auto Alt-Number Dialing <QXZ>This setting is used to automatically dial alternate number fields while dialing in the RATIO and ADAPT dial methods when there is no contact at the main phone number for a lead, the statuses to trigger alt dial can be set in the Auto Alt Dial page. This setting is not used by the MANUAL dial method. EXTENDED alternate numbers are numbers loaded into the system outside of the standard lead information screen. Using EXTENDED you can have hundreds of phone numbers for a single customer record. Using MULTI_LEAD allows you to use a separate lead for each number on a customer account that all share a common vendor_lead_code, and the type of phone number for each is defined with a label in the Owner field. This option will disable some options on the Modify Campaign screen and show a link to the Multi-Alt Settings page which allows you to set which phone number types, defined by the label of each lead, will be dialed and in what order. This will create a special lead filter and will alter the Rank field of all of the leads inside the lists set to this campaign in order to call them in the order you have specified.</QXZ>
campaigns-auto_alt_threshold Auto Alt-Number Dialing Threshold <QXZ>If Auto Alt-Number Dialing is enabled, and not set to MULTI_LEAD, then this setting will specify the number of call attempts to the lead after which the Auto Alt dialing will no longer place alternate number calls for a specific lead, if the lead is called after this number of attempts then only the main phone number will be called. There is also a List Override option for this feature. Default is 0 for the threshold being disabled.</QXZ>
@@ -629,10 +629,12 @@ inbound_groups-closing_time_option_xfer_group Closing Time Option Transfer In-Gr
inbound_groups-closing_time_option_callback_list_id Closing Time Option Callback List ID <QXZ>If Closing Time Option is set to CALLERID_CALLBACK, this is the List ID the call is added to as a new lead if the Closing Time is reached.</QXZ>
inbound_groups-agent_alert_exten Agent Alert Filename <QXZ>The audio file to play to an agent to announce that a call is coming to the agent. To not use this function set this to X. Default is ding.</QXZ>
inbound_groups-agent_alert_delay Agent Alert Delay <QXZ>The length of time in milliseconds to wait before sending the call to the agent after playing the on Agent Alert Extension. Default is 1000.</QXZ>
inbound_groups-second_alert_trigger Second Agent Alert Trigger <QXZ>If enabled, this feature will play an audio alert if the trigger conditions are met. The PHONE_NUMBER option will check for a previous phone call from the same customer phone number being handled in this In-Group within a specified recent timeframe, defined by the Second Agent Alert Trigger Seconds setting below. The LEAD_ID option will check for a previous phone call by the same specific customer lead being handled in this In-Group within a specified recent timeframe. Default is DISABLED.</QXZ>
inbound_groups-second_alert_trigger Second Agent Alert Trigger <QXZ>If enabled, this feature will play an audio alert if the trigger conditions are met. The PHONE option will check for a previous phone call from the same customer phone number being handled in this In-Group within a specified recent timeframe, defined by the Second Agent Alert Trigger Seconds setting below. The LEAD_ID option will check for a previous phone call by the same specific customer lead being handled in this In-Group within a specified recent timeframe. If the option has TO in it, then only calls that reached the end of their Drop Seconds timeout will be counted for the trigger. If the option has NQ in it, then calls that were handled No-Agent-No-Queue will also be counted for the trigger. Default is DISABLED.</QXZ>
inbound_groups-second_alert_trigger_seconds Second Agent Alert Trigger Seconds <QXZ>If the Second Agent Alert Trigger option above is enabled, this is the number of seconds into the past that the logs will be checked for a previous call. Default is 600 seconds, which is 10 minutes.</QXZ>
inbound_groups-second_alert_filename Second Agent Alert Filename <QXZ>The second audio file to play to an agent to announce that a call is coming to the agent. default is empty.</QXZ>
inbound_groups-second_alert_delay Second Agent Alert Delay <QXZ>The length of time in milliseconds to wait before sending the call to the agent after playing the on Second Agent Alert. Default is 1000.</QXZ>
ingroups-second_alert_container Second Agent Alert Container <QXZ>If set to something other than DISABLED, the selected INGROUP_LIST type of Settings Container will be used to search for a previous call in a list of In-Groups instead of just this In-Group. The Container should have one line per In-Group. Default is DISABLED.</QXZ>
inbound_groups-second_alert_only Second Agent Alert Only <QXZ>If enabled, and the second alert is to be played to the agent, this option will disabled the first agent alert. Default is DISABLED.</QXZ>
inbound_groups-default_xfer_group Default Transfer Group <QXZ>This field is the default In-Group that will be automatically selected when the agent goes to the transfer-conference frame in their agent interface.</QXZ>
inbound_groups-ingroup_recording_override In-Group Recording Override <QXZ>This field allows for the overriding of the campaign call recording setting. This setting can be overridden by the user recording override setting. DISABLED will not override the campaign recording setting. NEVER will disable recording on the client. ONDEMAND is the default and allows the agent to start and stop recording as needed. ALLCALLS will start recording on the client whenever a call is sent to an agent. ALLFORCE will start recording on the client whenever a call is sent to an agent giving the agent no option to stop recording.</QXZ>
inbound_groups-routing_initiated_recordings Routing Initiated Recording <QXZ>This option, if enabled, allows you to have the call routing script for Inbound calls trigger the agent call recording instead of the agent screen. This option will only work if the recording option is set to ALLCALLS or ALLFORCE. This will not work with inbound on-hook agents. Default is N for disabled.</QXZ>
@@ -741,6 +743,7 @@ call_menu-option_route Option Route <QXZ>This menu contains the options for wher
call_menu-option_route_value Option Route Value <QXZ>This field is where you enter the value that defines where in the selected Option Route that the call is to be directed to.</QXZ>
call_menu-option_route_value_context Option Route Value Context <QXZ>This field is optional and only used for EXTENSION Option Routes.</QXZ>
call_menu-ingroup_settings Call Menu In-Group Settings <QXZ>If the route is set to INGROUP then there are many options that you can set to define how the call is sent to into the queue. In-Group is the inbound group that you want the call to go to. Handle Method is the way you want the call to be handled,</QXZ> <a href='#' onClick="FillAndShowHelpDiv(event, 'inbound_dids-call_handle_method')"><QXZ>Click here to see a list of the available handle methods</QXZ></a>. <QXZ>Search Method defines how the queue will find the next agent, recommend leave this on LB. List ID is the list that the new lead is inserted into, also if the Method is not a LOOKUP method and the lead is not found. Campaign ID is the campaign to search lists through if one of the RC methods is used. Phone Code is the phone_code field entry for the lead that is inserted with. VID Enter Filename is used if the Method is set to one of the VIDPROMPT methods, it is the audio prompt played to ask the customer to enter their ID. VID ID Number Filename is used if the Method is set to one of the VIDPROMPT methods, it is the audio prompt played after customer enters their ID, something like YOU HAVE ENTERED. VID Confirm Filename is used if the Method is set to one of the VIDPROMPT methods, it is the audio prompt played to confirm their ID, something like PRESS 1 TO CONFIRM AND 2 TO REENTER. VID Digits is used if the Method is set to one of the VIDPROMPT methods, if it is set to a number it is the number of digits that must be entered by the customer when prompted for their ID, if set to empty or X then the customer will have to press pound or hash to finish their entry of their ID.</QXZ> <QXZ>If you are using the cm_phonesearch.agi in this Call Menu, you can set the B option to use the special DYNAMIC_INGROUP_VAR in-group for that script to work properly.</QXZ>
call_menu-ingroup_vid_container Call Menu In-Group VID Container <QXZ>If the Call Menu Option Handle Method is set to one of the VIDPROMPTSPECIALLOOKUP options, then this field must be set to a valid Settings Container with a CM_VIDPROMPT_SPECIAL Container Type. Within this settings container you can define the In-Group that a call is routed to based on the list that the lead is in using the list_ingroup setting for each list and in-group pair, for example: list_ingroup => 102,TEST_IN2. The default_ingroup option can be used if the lead is found but the lead is not within any of the defined lists. The not_found_action option will allow you to define what happens when no vendor_lead_code match is found. The options for that setting are either new_lead or one of the Call Menu options, for instance: 1,2,3... If new_lead is used, then you need to define the In-Group that those calls are to be directed to, you can do that with the new_lead_ingroup setting. Here is an example container:<br>list_ingroup => 102,TEST_IN2<br>list_ingroup => 103,TEST_IN3<br>list_ingroup => 104,TEST_IN4<br>default_ingroup => TEST_IN5<br>not_found_action => new_lead<br>new_lead_ingroup => TEST_IN</QXZ>
call_menu-custom_dialplan_entry Custom Dialplan Entry <QXZ>This field allows you to enter in any dialplan elements that you want for the Call Menu.</QXZ>
call_menu-qualify_sql Qualify SQL <QXZ>This field allows you to input SQL - Structured Query Language - database fragments, like with Filters, to determine whether this call menu should play for the caller or not. This feature only works if the call has the callerIDname set prior to being sent to this call menu, either as an outbound survey transfer, or through the use of a drop call menu for an In-Group call. If there is a match, the call will proceed as normal. If there is no match, the call will go to the D option or the invalid option if no D option is set. You cannot use single-quotes in this field, only double-quotes if they are needed. Default is empty for disabled.</QXZ>
filter_phone_groups-filter_phone_group_id Filter Phone Group ID <QXZ>This is the ID of the Filter Phone Group that is the container for a group of phone numbers that you can have automatically searched through when a call comes into a DID and send to an alternate route if there is a match. This field should be between 2 and 20 characters and have no punctuation except for underscore.</QXZ>
+137 -4
View File
@@ -201,10 +201,11 @@
# 230118-0833 - Added ingroup_list and callmenu_list functions
# 230122-1821 - Added reset_password option to update_user function
# 230308-1758 - Fix for update_lead list-restrict phone number update issue
# 230614-0828 - Added container_list function
#
$version = '2.14-178';
$build = '230308-1758';
$version = '2.14-179';
$build = '230614-0828';
$php_script='non_agent_api.php';
$api_url_log = 0;
@@ -837,7 +838,7 @@ $dial_method = preg_replace('/[^-_0-9a-zA-Z]/','',$dial_method);
$dial_timeout = preg_replace('/[^0-9]/','',$dial_timeout);
$lookup_state = preg_replace('/[^A-Z]/','',$lookup_state);
$detail = preg_replace('/[^A-Z]/','',$detail);
$type = preg_replace('/[^A-Z]/','',$type);
$type = preg_replace('/[^-_0-9a-zA-Z]/','',$type);
$force_entry_list_id = preg_replace('/[^0-9]/','',$force_entry_list_id);
$file_download = preg_replace('/[^0-9]/','',$file_download);
$agent_choose_ingroups = preg_replace('/[^0-9]/','',$agent_choose_ingroups);
@@ -2078,7 +2079,7 @@ if ($function == 'ingroup_list')
################################################################################
### callmenu_list - sends a list of the inbound groups in the system
### callmenu_list - sends a list of the call menus in the system
################################################################################
if ($function == 'callmenu_list')
{
@@ -2201,6 +2202,138 @@ if ($function == 'callmenu_list')
################################################################################
### container_list - sends a list of the settings containers in the system
################################################################################
if ($function == 'container_list')
{
if (strlen($type) < 1)
{
$result = 'ERROR';
$result_reason = "container_list NO CONTAINER TYPE DEFINED";
echo "$result: $result_reason: |$user|$type|\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 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 = "container_list USER DOES NOT HAVE PERMISSION TO VIEW CALL MENUS LIST";
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
{
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 allowed_campaigns,admin_viewable_groups from vicidial_user_groups where user_group='$LOGuser_group';";
if ($DB>0) {echo "|$stmt|\n";}
$rslt=mysql_to_mysqli($stmt, $link);
$row=mysqli_fetch_row($rslt);
$LOGallowed_campaigns = $row[0];
$LOGadmin_viewable_groups = $row[1];
$LOGadmin_viewable_groupsSQL='';
$whereLOGadmin_viewable_groupsSQL='';
if ( (!preg_match('/\-\-ALL\-\-/i',$LOGadmin_viewable_groups)) and (strlen($LOGadmin_viewable_groups) > 3) )
{
$rawLOGadmin_viewable_groupsSQL = preg_replace("/ -/",'',$LOGadmin_viewable_groups);
$rawLOGadmin_viewable_groupsSQL = preg_replace("/ /","','",$rawLOGadmin_viewable_groupsSQL);
$LOGadmin_viewable_groupsSQL = "and user_group IN('---ALL---','$rawLOGadmin_viewable_groupsSQL')";
$whereLOGadmin_viewable_groupsSQL = "where user_group IN('---ALL---','$rawLOGadmin_viewable_groupsSQL')";
}
$server_name = getenv("SERVER_NAME");
$server_port = getenv("SERVER_PORT");
if (preg_match("/443/i",$server_port)) {$HTTPprotocol = 'https://';}
else {$HTTPprotocol = 'http://';}
$admDIR = "$HTTPprotocol$server_name:$server_port";
echo "\n";
echo "<HTML><head><title>NON-AGENT API</title>\n";
echo "<script language=\"Javascript\">\n";
echo "function choose_file(filename,fieldname)\n";
echo " {\n";
echo " if (filename.length > 0)\n";
echo " {\n";
echo " parent.document.getElementById(fieldname).value = filename;\n";
echo " document.getElementById(\"selectframe\").innerHTML = '';\n";
echo " document.getElementById(\"selectframe\").style.visibility = 'hidden';\n";
echo " parent.close_chooser();\n";
echo " }\n";
echo " }\n";
echo "function close_file()\n";
echo " {\n";
echo " document.getElementById(\"selectframe\").innerHTML = '';\n";
echo " document.getElementById(\"selectframe\").style.visibility = 'hidden';\n";
echo " parent.close_chooser();\n";
echo " }\n";
echo "</script>\n";
echo "</head>\n\n";
echo "<body>\n";
echo "<a href=\"javascript:close_file();\"><font size=1 face=\"Arial,Helvetica\">"._QXZ("close frame")."</font></a>\n";
echo "<div id='selectframe' style=\"height:400px;width:710px;overflow:scroll;\">\n";
echo "<table border=0 cellpadding=1 cellspacing=2 width=690 bgcolor=white><tr>\n";
echo "<td width=30>#</td>\n";
echo "<td colspan=2>"._QXZ("Settings Containers").": <br>"._QXZ("$type")." "._QXZ("type")."</td>\n";
echo "<td>"._QXZ("Container Notes")."</td>\n";
# echo "<td>"._QXZ("Color")."</td>\n";
echo "</tr>\n";
$rowx=array();
$group_id=array();
$fullname=array();
$stmt="SELECT container_id,container_notes from vicidial_settings_containers where container_type='$type' $LOGadmin_viewable_groupsSQL order by container_id";
$rslt=mysql_to_mysqli($stmt, $link);
$vm_to_print = mysqli_num_rows($rslt);
$k=0;
$sf=0;
while ($vm_to_print > $k)
{
$rowx=mysqli_fetch_row($rslt);
$group_id[$k] = $rowx[0];
$fullname[$k] = $rowx[1];
$sf++;
if (preg_match("/1$|3$|5$|7$|9$/i", $sf))
{$bgcolor='bgcolor="#E6E6E6"';}
else
{$bgcolor='bgcolor="#F6F6F6"';}
echo "<tr $bgcolor><td width=30><font size=1 face=\"Arial,Helvetica\">$sf</td>\n";
echo "<td colspan=2><a href=\"javascript:choose_file('$group_id[$k]','$comments');\"><font size=2 face=\"Arial,Helvetica\">$group_id[$k]</a></td>\n";
echo "<td><font size=2 face=\"Arial,Helvetica\">$fullname[$k]</td></tr>\n";
$k++;
}
# echo "<tr><td>$stmt</td></tr\n";
echo "</table></div></body></HTML>\n";
exit;
}
}
################################################################################
### END container_list
################################################################################
################################################################################
### agent_ingroup_info - displays agent in-group info in an HTML form allowing for changes
################################################################################