diff --git a/bin/AST_VDauto_dial.pl b/bin/AST_VDauto_dial.pl index ec79df48..0280aebc 100644 --- a/bin/AST_VDauto_dial.pl +++ b/bin/AST_VDauto_dial.pl @@ -158,9 +158,10 @@ # 231116-0911 - Added hopper_hold_inserts option # 231129-0901 - Added vicidial_phone_number_call_daily_counts updates/inserts # 240219-1524 - Added daily_limit in-group parameter +# 240225-0951 - Added AUTONEXT hopper_hold_inserts option # -$build='240219-1524'; +$build='240225-0951'; $script='AST_VDauto_dial'; ### begin parsing run-time options ### if (length($ARGV[0])>1) @@ -3297,7 +3298,7 @@ while($one_day_interval > 0) if ($passed_24hour_call_count > 0) { $hopper_status='READY'; - if ($VD_hopper_hold_inserts =~ /ENABLED/) {$hopper_status='RHOLD';} + if ($VD_hopper_hold_inserts =~ /ENABLED|AUTONEXT/) {$hopper_status='RHOLD';} $stmtA = "INSERT INTO vicidial_hopper SET lead_id='$CLlead_id',campaign_id='$CLcampaign_id',status='$hopper_status',list_id='$VD_list_id',gmt_offset_now='$VD_gmt_offset_now',state='$VD_state',alt_dial='ALT',user='',priority='25',source='A';"; $affected_rows = $dbhA->do($stmtA); $event_string = "-- VDH record inserted: |$affected_rows| |$stmtA|"; &event_logger; @@ -3403,7 +3404,7 @@ while($one_day_interval > 0) if ($passed_24hour_call_count > 0) { $hopper_status='READY'; - if ($VD_hopper_hold_inserts =~ /ENABLED/) {$hopper_status='RHOLD';} + if ($VD_hopper_hold_inserts =~ /ENABLED|AUTONEXT/) {$hopper_status='RHOLD';} $stmtA = "INSERT INTO vicidial_hopper SET lead_id='$CLlead_id',campaign_id='$CLcampaign_id',status='$hopper_status',list_id='$VD_list_id',gmt_offset_now='$VD_gmt_offset_now',state='$VD_state',alt_dial='ADDR3',user='',priority='20',source='A';"; $affected_rows = $dbhA->do($stmtA); $event_string = "-- VDH record inserted: |$affected_rows| |$stmtA|"; &event_logger; @@ -3555,7 +3556,7 @@ while($one_day_interval > 0) if ($passed_24hour_call_count > 0) { $hopper_status='READY'; - if ($VD_hopper_hold_inserts =~ /ENABLED/) {$hopper_status='RHOLD';} + if ($VD_hopper_hold_inserts =~ /ENABLED|AUTONEXT/) {$hopper_status='RHOLD';} $stmtA = "INSERT INTO vicidial_hopper SET lead_id='$CLlead_id',campaign_id='$CLcampaign_id',status='$hopper_status',list_id='$VD_list_id',gmt_offset_now='$VD_gmt_offset_now',state='$VD_state',alt_dial='X$Xlast',user='',priority='15',source='A';"; $affected_rows = $dbhA->do($stmtA); $event_string = "-- VDH record inserted: |$affected_rows| |$stmtA|X$Xlast|$VD_altdial_id|"; &event_logger; diff --git a/bin/AST_VDhopper.pl b/bin/AST_VDhopper.pl index 42ecc574..48450d2b 100644 --- a/bin/AST_VDhopper.pl +++ b/bin/AST_VDhopper.pl @@ -22,7 +22,7 @@ # - S = Standard hopper load # - D = Campaign Drop-Run # -# Copyright (C) 2023 Matt Florell LICENSE: AGPLv2 +# Copyright (C) 2024 Matt Florell LICENSE: AGPLv2 # # CHANGELOG # 50810-1613 - Added database server variable definitions lookup @@ -110,10 +110,11 @@ # 231116-0821 - Added hopper_hold_inserts system and campaign settings options # 231126-1748 - Added RQUEUE hopper status # 231129-1051 - Added daily_phone_number_call_limit campaign setting +# 240225-0954 - Added AUTONEXT hopper_hold_inserts campaign option # # constants -$build = '231129-1051'; +$build = '240225-0954'; $script='AST_VDhopper'; $DB=0; # Debug flag, set to 0 for no debug messages. Can be overriden with CLI --debug flag $US='__'; @@ -761,7 +762,7 @@ if ($CBHOLD_count > 0) &event_logger; $hopper_statusSQL=''; - if ($VD_hopper_hold_inserts =~ /ENABLED/) {$hopper_statusSQL = ",status='RHOLD'";} + if ($VD_hopper_hold_inserts =~ /ENABLED|AUTONEXT/) {$hopper_statusSQL = ",status='RHOLD'";} $stmtA = "INSERT INTO $vicidial_hopper SET lead_id='$CA_lead_id[$CAu]',campaign_id='$CA_campaign_id[$CAu]',list_id='$CA_list_id[$CAu]',gmt_offset_now='$CA_gmt_offset_now[$CAu]',user='',state=\"$CA_state[$CAu]\",priority='50',source='C',vendor_lead_code=\"$CA_vendor_lead_code[$CAu]\"$hopper_statusSQL;"; $affected_rows = $dbhA->do($stmtA); if ($DB) {print "ANYONE Scheduled Callback Inserted into hopper: $affected_rows|$CA_lead_id[$CAu]\n";} @@ -958,7 +959,7 @@ if ($hopper_dnc_count > 0) if ($passed_24hour_call_count > 0) { $hopper_status='READY'; - if ($VD_hopper_hold_inserts =~ /ENABLED/) {$hopper_status='RHOLD';} + if ($VD_hopper_hold_inserts =~ /ENABLED|AUTONEXT/) {$hopper_status='RHOLD';} $stmtA = "UPDATE $vicidial_hopper SET status='$hopper_status',list_id='$VD_list_id',gmt_offset_now='$VD_gmt_offset_now',state='$VD_state',alt_dial='ALT',user='',priority='25' where hopper_id='$AAD_hopper_id[$aad]';"; $affected_rows = $dbhA->do($stmtA); if ($DB) {$event_string = "-- VDH record updated: |$affected_rows| |$stmtA|"; &event_logger;} @@ -1068,7 +1069,7 @@ if ($hopper_dnc_count > 0) if ($passed_24hour_call_count > 0) { $hopper_status='READY'; - if ($VD_hopper_hold_inserts =~ /ENABLED/) {$hopper_status='RHOLD';} + if ($VD_hopper_hold_inserts =~ /ENABLED|AUTONEXT/) {$hopper_status='RHOLD';} $stmtA = "UPDATE $vicidial_hopper SET status='$hopper_status',list_id='$VD_list_id',gmt_offset_now='$VD_gmt_offset_now',state='$VD_state',alt_dial='ADDR3',user='',priority='20' where hopper_id='$AAD_hopper_id[$aad]';"; $affected_rows = $dbhA->do($stmtA); if ($DB) {$event_string = "-- VDH record updated: |$affected_rows| |$stmtA|"; &event_logger;} @@ -1222,7 +1223,7 @@ if ($hopper_dnc_count > 0) if ($passed_24hour_call_count > 0) { $hopper_status='READY'; - if ($VD_hopper_hold_inserts =~ /ENABLED/) {$hopper_status='RHOLD';} + if ($VD_hopper_hold_inserts =~ /ENABLED|AUTONEXT/) {$hopper_status='RHOLD';} $stmtA = "UPDATE $vicidial_hopper SET status='$hopper_status',list_id='$VD_list_id',gmt_offset_now='$VD_gmt_offset_now',state='$VD_state',alt_dial='X$Xlast',user='',priority='15' where hopper_id='$AAD_hopper_id[$aad]';"; $affected_rows = $dbhA->do($stmtA); if ($DB) {$event_string = "-- VDH record updated: |$affected_rows| |$stmtA|X$Xlast|$VD_altdial_id|"; &event_logger;} @@ -3659,7 +3660,7 @@ foreach(@campaign_id) if ( ($DCCLlead == '0') && ($TFHCCLlead == '0') ) { $hopper_status='READY'; - if ($hopper_hold_inserts[$i] =~ /ENABLED/) {$hopper_status='RHOLD';} + if ($hopper_hold_inserts[$i] =~ /ENABLED|AUTONEXT/) {$hopper_status='RHOLD';} $stmtA = "INSERT INTO $vicidial_hopper (lead_id,campaign_id,status,user,list_id,gmt_offset_now,state,priority,source,vendor_lead_code) values('$leads_to_hopper[$h]','$campaign_id[$i]','$hopper_status','','$lists_to_hopper[$h]','$gmt_to_hopper[$h]',\"$state_to_hopper[$h]\",'$hopperPRIORITY','$source_to_hopper[$h]',\"$vlc_to_hopper[$h]\");"; $affected_rows = $dbhA->do($stmtA); $DBinserted = ($DBinserted + $affected_rows); diff --git a/bin/AST_inbound_email_parser.pl b/bin/AST_inbound_email_parser.pl index 5250afe2..6949ab85 100644 --- a/bin/AST_inbound_email_parser.pl +++ b/bin/AST_inbound_email_parser.pl @@ -10,7 +10,7 @@ use Encode qw(from_to decode encode); use MIME::Base64; use MIME::QuotedPrint; -# Copyright (C) 2017 Matt Florell, Joe Johnson LICENSE: AGPLv2 +# Copyright (C) 2024 Matt Florell, Joe Johnson LICENSE: AGPLv2 # # AST_inbound_email_parser.pl - This script is essential for periodically checking any active POP3 or IMAP # email accounts set up through the Vicidial admin. @@ -66,6 +66,7 @@ use MIME::QuotedPrint; # 161014-2200 - Bug patch for " " string in email message # 170523-1319 - file attachment patch, issue #1014 # 171026-0106 - Added optional queue_log logging +# 240225-1442 - Changes for perl module compatibility and attachment compatibility # # default path to astguiclient configuration file: @@ -291,7 +292,7 @@ while (@row=$rslt->fetchrow_array) { ( Proto => 'tcp', PeerAddr => "$VARemail_server", PeerPort => 993, # IMAP over SSL standard port - SSL_verify_mode => 'SSL_VERIFY_NONE', + SSL_verify_mode => SSL_VERIFY_NONE, ), ); } @@ -479,6 +480,30 @@ while (@row=$rslt->fetchrow_array) { case "text/plain" {$attachment_fulltype="TXT";} case "application/vnd.oasis.opendocument.text" {$attachment_fulltype="ODT";} case "application/vnd.oasis.opendocument.spreadsheet" {$attachment_fulltype="ODS";} + case "application/vnd.ms-excel.sheet.binary.macroenabled.12" {$attachment_fulltype="XLSB";} + case "application/vnd.ms-excel.sheet.macroenabled.12" {$attachment_fulltype="XLSM";} + case "application/vnd.ms-excel.template.macroenabled.12" {$attachment_fulltype="XLTM";} + case "application/vnd.ms-word.document.macroenabled.12" {$attachment_fulltype="DOCM";} + case "application/vnd.ms-word.template.macroenabled.12" {$attachment_fulltype="DOTM";} + case "application/vnd.openxmlformats-officedocument.presentationml.presentation" {$attachment_fulltype="PPTX";} + case "application/vnd.openxmlformats-officedocument.presentationml.slideshow" {$attachment_fulltype="PPSX";} + case "application/vnd.openxmlformats-officedocument.presentationml.template" {$attachment_fulltype="POTX";} + case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" {$attachment_fulltype="XLSX";} + case "application/vnd.openxmlformats-officedocument.spreadsheetml.template" {$attachment_fulltype="XLTX";} + case "application/vnd.openxmlformats-officedocument.wordprocessingml.document" {$attachment_fulltype="DOCX";} + case "application/vnd.openxmlformats-officedocument.wordprocessingml.template" {$attachment_fulltype="DOTX";} + case "application/vnd.visio" {$attachment_fulltype="VSD";} + case "application/x-7z-compressed" {$attachment_fulltype="7Z";} + case "application/xhtml+xml" {$attachment_fulltype="XHTML";} + case "application/xml" {$attachment_fulltype="XML";} + case "application/x-msaccess" {$attachment_fulltype="MDB";} + case "application/x-mspublisher" {$attachment_fulltype="PUB";} + case "application/x-rar-compressed" {$attachment_fulltype="RAR";} + case "image/emf" {$attachment_fulltype="EMF";} + case "image/tiff" {$attachment_fulltype="TIF";} + case "image/wmf" {$attachment_fulltype="WMF";} + case "text/html" {$attachment_fulltype="HTML";} + case "text/vcard-contact" {$attachment_fulltype="VCF";} } if ($sub_content_disposition=~/filename\=\"?(.*?)\"?$|filename=\"[^\"]+\"/i) {$attachment_filename=$&;} if (length($attachment_filename)==0) { @@ -507,7 +532,7 @@ while (@row=$rslt->fetchrow_array) { if ($DB) {print "!!!!WARNING - Found valid attachment, type $attachment_type \n Attachment does not have file name. Skipping...\n";} } } else { - if ($DB) {print "!!!!WARNING - Found attachment $attachment_filename, but is NOT a valid file type \n Attachment type is $attachment_type. Skipping...\n";} + if ($DB) {print "!!!!WARNING - Found attachment $attachment_filename, but is NOT a valid file type \n Attachment type is $attachment_type ($attachment_fulltype). Skipping...\n";} } } # print "\n"; @@ -600,7 +625,10 @@ while (@row=$rslt->fetchrow_array) { my @lead_id_row=$vicidial_lead_check_rslt->fetchrow_array; $lead_id=$lead_id_row[0]; } else { - my $vicidial_list_stmt="insert into vicidial_list(list_id, email, comments, status, entry_date, phone_code) values('$default_list_id', '$email_from', '".substr($message,0,255)."', '$status', NOW(), '$SSdefault_phone_code')"; + StripHTML(); + $vl_message=substr($message,0,255); + $vl_message=~s/\\+$//gi; + my $vicidial_list_stmt="insert into vicidial_list(list_id, email, comments, status, entry_date, phone_code) values('$default_list_id', '$email_from', '$vl_message', '$status', NOW(), '$SSdefault_phone_code')"; if ($DBX) {print $vicidial_list_stmt;} my $vicidial_list_rslt=$dbhA->prepare($vicidial_list_stmt); if ($vicidial_list_rslt->execute()) { @@ -843,6 +871,30 @@ while (@row=$rslt->fetchrow_array) { case "text/plain" {$attachment_fulltype="TXT";} case "application/vnd.oasis.opendocument.text" {$attachment_fulltype="ODT";} case "application/vnd.oasis.opendocument.spreadsheet" {$attachment_fulltype="ODS";} + case "application/vnd.ms-excel.sheet.binary.macroenabled.12" {$attachment_fulltype="XLSB";} + case "application/vnd.ms-excel.sheet.macroenabled.12" {$attachment_fulltype="XLSM";} + case "application/vnd.ms-excel.template.macroenabled.12" {$attachment_fulltype="XLTM";} + case "application/vnd.ms-word.document.macroenabled.12" {$attachment_fulltype="DOCM";} + case "application/vnd.ms-word.template.macroenabled.12" {$attachment_fulltype="DOTM";} + case "application/vnd.openxmlformats-officedocument.presentationml.presentation" {$attachment_fulltype="PPTX";} + case "application/vnd.openxmlformats-officedocument.presentationml.slideshow" {$attachment_fulltype="PPSX";} + case "application/vnd.openxmlformats-officedocument.presentationml.template" {$attachment_fulltype="POTX";} + case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" {$attachment_fulltype="XLSX";} + case "application/vnd.openxmlformats-officedocument.spreadsheetml.template" {$attachment_fulltype="XLTX";} + case "application/vnd.openxmlformats-officedocument.wordprocessingml.document" {$attachment_fulltype="DOCX";} + case "application/vnd.openxmlformats-officedocument.wordprocessingml.template" {$attachment_fulltype="DOTX";} + case "application/vnd.visio" {$attachment_fulltype="VSD";} + case "application/x-7z-compressed" {$attachment_fulltype="7Z";} + case "application/xhtml+xml" {$attachment_fulltype="XHTML";} + case "application/xml" {$attachment_fulltype="XML";} + case "application/x-msaccess" {$attachment_fulltype="MDB";} + case "application/x-mspublisher" {$attachment_fulltype="PUB";} + case "application/x-rar-compressed" {$attachment_fulltype="RAR";} + case "image/emf" {$attachment_fulltype="EMF";} + case "image/tiff" {$attachment_fulltype="TIF";} + case "image/wmf" {$attachment_fulltype="WMF";} + case "text/html" {$attachment_fulltype="HTML";} + case "text/vcard-contact" {$attachment_fulltype="VCF";} } if ($sub_content_disposition=~/filename\=\"?(.*?)\"?$|filename=\"[^\"]+\"/i) {$attachment_filename=$&;} if (length($attachment_filename)==0) { @@ -974,7 +1026,10 @@ while (@row=$rslt->fetchrow_array) { my @lead_id_row=$vicidial_lead_check_rslt->fetchrow_array; $lead_id=$lead_id_row[0]; } else { - my $vicidial_list_stmt="insert into vicidial_list(list_id, email, comments, status, entry_date, phone_code) values('$default_list_id', '$email_from', '".substr($message,0,255)."', '$status', NOW(), '$SSdefault_phone_code')"; + StripHTML(); + $vl_message=substr($message, 0, 255); + $vl_message=~s/\\+$//gi; + my $vicidial_list_stmt="insert into vicidial_list(list_id, email, comments, status, entry_date, phone_code) values('$default_list_id', '$email_from', '$vl_message', '$status', NOW(), '$SSdefault_phone_code')"; if ($DBX) {print $vicidial_list_stmt."\n";} my $vicidial_list_rslt=$dbhA->prepare($vicidial_list_stmt); if ($vicidial_list_rslt->execute()) { diff --git a/bin/FastAGI_log.pl b/bin/FastAGI_log.pl index e9ed5b58..849b18f4 100644 --- a/bin/FastAGI_log.pl +++ b/bin/FastAGI_log.pl @@ -25,7 +25,7 @@ # exten => h,1,DeadAGI(agi://127.0.0.1:4577/call_log--HVcauses--PRI-----NODEBUG-----${HANGUPCAUSE}-----${DIALSTATUS}-----${DIALEDTIME}-----${ANSWEREDTIME}) # # -# Copyright (C) 2023 Matt Florell LICENSE: AGPLv2 +# Copyright (C) 2024 Matt Florell LICENSE: AGPLv2 # # CHANGELOG: # 61010-1007 - First test build @@ -99,6 +99,7 @@ # 230120-1557 - Added CAMPDTO dialplan variable for ^DC 3-way agent screen calls # 231116-0846 - Added hopper_hold_inserts option # 231118-1054 - Added hangup processing of 3-way press outside-agent calls +# 240225-0957 - Added AUTONEXT hopper_hold_inserts campaign option # # defaults for PreFork @@ -2290,7 +2291,7 @@ sub process_request if ($passed_24hour_call_count > 0) { $hopper_status='READY'; - if ($VD_hopper_hold_inserts =~ /ENABLED/) {$hopper_status='RHOLD';} + if ($VD_hopper_hold_inserts =~ /ENABLED|AUTONEXT/) {$hopper_status='RHOLD';} $stmtA = "INSERT INTO vicidial_hopper SET lead_id='$VD_lead_id',campaign_id='$VD_campaign_id',status='$hopper_status',list_id='$VD_list_id',gmt_offset_now='$VD_gmt_offset_now',state='$VD_state',alt_dial='ALT',user='',priority='25',source='A';"; $affected_rows = $dbhA->do($stmtA); if ($AGILOG) {$agi_string = "-- VDH record inserted: |$affected_rows| |$stmtA|"; &agi_output;} @@ -2398,7 +2399,7 @@ sub process_request if ($passed_24hour_call_count > 0) { $hopper_status='READY'; - if ($VD_hopper_hold_inserts =~ /ENABLED/) {$hopper_status='RHOLD';} + if ($VD_hopper_hold_inserts =~ /ENABLED|AUTONEXT/) {$hopper_status='RHOLD';} $stmtA = "INSERT INTO vicidial_hopper SET lead_id='$VD_lead_id',campaign_id='$VD_campaign_id',status='$hopper_status',list_id='$VD_list_id',gmt_offset_now='$VD_gmt_offset_now',state='$VD_state',alt_dial='ADDR3',user='',priority='20',source='A';"; $affected_rows = $dbhA->do($stmtA); if ($AGILOG) {$agi_string = "-- VDH record inserted: |$affected_rows| |$stmtA|"; &agi_output;} @@ -2548,7 +2549,7 @@ sub process_request if ($passed_24hour_call_count > 0) { $hopper_status='READY'; - if ($VD_hopper_hold_inserts =~ /ENABLED/) {$hopper_status='RHOLD';} + if ($VD_hopper_hold_inserts =~ /ENABLED|AUTONEXT/) {$hopper_status='RHOLD';} $stmtA = "INSERT INTO vicidial_hopper SET lead_id='$VD_lead_id',campaign_id='$VD_campaign_id',status='$hopper_status',list_id='$VD_list_id',gmt_offset_now='$VD_gmt_offset_now',state='$VD_state',alt_dial='X$Xlast',user='',priority='15',source='A';"; $affected_rows = $dbhA->do($stmtA); if ($AGILOG) {$agi_string = "-- VDH record inserted: |$affected_rows| |$stmtA|X$Xlast|$VD_altdial_id|"; &agi_output;} diff --git a/docs/HCI_Human_Call_Indicator_screen.txt b/docs/HCI_Human_Call_Indicator_screen.txt index d745a9e4..171e69a7 100644 --- a/docs/HCI_Human_Call_Indicator_screen.txt +++ b/docs/HCI_Human_Call_Indicator_screen.txt @@ -1,10 +1,12 @@ -HUMAN CALL INDICATOR(HCI) DOC Started: 2023-11-08 Updated: 2023-11-27 +HUMAN CALL INDICATOR(HCI) DOC Started: 2023-11-08 Updated: 2024-02-25 This document will go over how to set up the Human Call Indicator screen on your system, with Hopper Hold Inserts for campaigns. NOTE: This requires svn/trunk revision 3779 or higher!!! +NOTE: AUTONEXT mode was added in svn/trunk revision 3808. + What is an Human Call Indicator screen? @@ -15,7 +17,7 @@ On the admin side, to enable the HCI screen, the System Settings "Lead Hopper Ho For a user to log into the HCI screen, they must have their User's "HCI Enabled" option enabled. -The user can get to the HCI screen from the link on the Welcome page(HOME). Once logged in to the HCI screen, the user must select the campaign that they want to initiate calls from, then they will see the active HCI screen with phone numbers to click on (on the left side), and a summary screen (on the right side). When an agent clicks on one of the phone numbers, they will see a confirmation pop-up panel asking them to confirm that they want this number to be called. If the user confirms this propt, then the call can be placed by the system and the phone number's button will disappear from the left side of the screen and the other phone numbers will shift to fill in the empty space. +The user can get to the HCI screen from the link on the Welcome page(HOME). Once logged in to the HCI screen, the user must select the campaign that they want to initiate calls from, then they will see the active HCI screen with phone numbers to click on (on the left side), and a summary screen (on the right side). When an agent clicks on one of the phone numbers, they will see a confirmation pop-up panel asking them to confirm that they want this number to be called (in AUTONEXT mode, the confimation panel will pop-up automatically). If the user confirms this propt, then the call can be placed by the system and the phone number's button will disappear from the left side of the screen and the other phone numbers will shift to fill in the empty space. In AUTONEXT mode, the agent does not need to click on the next phone number, as soon as they confirm a phone number the next phone number's confirmation panel will automaticaly pop-up. The statistics on the right side of the screen show the following metrics: 1. Calls in Progress - the number of dialed but not-yet-answered calls active at this moment, does not include calls where agents are talking to customers @@ -33,15 +35,17 @@ How do I configure this on my system? No configuration is needed other than activating Hopper Hold Inserts for the system and campaigns, as well as activating the HCI Enabled setting for the users that you want to access the HCI screen. +You can also enable the AUTONEXT mode of the HCI screen by setting the System Setting "Hopper Hold Inserts" to '2', the campaign "Hopper Hold Inserts" setting to 'AUTONEXT' and the Users' "HCI Enabled" setting to '2'. + What are the limitations of the HCI screen? -The HCI screen will reserve leads from the hopper that are on HOLD for each user that is logged into the HCI screen, these HOLD hopper leads are refreshed as the HCI screen user confirms phone calls, and no more than 40 calls can be initiated within 4 seconds, although in our testing we've never been able to get anywhere close to that rate. +The HCI screen will reserve leads from the hopper that are on HOLD for each user that is logged into the HCI screen, these HOLD hopper leads are refreshed as the HCI screen user confirms phone calls, and no more than 40 calls can be initiated within 4 seconds (or 120 calls in 2 seconds in AUTONEXT mode), although in our testing we've never been able to get anywhere close to that rate. If the HCI screen user does not confirm any phone calls for 5 minutes, the system will reset their reserved hopper leads and allow their HCI screen to reserve new ones. This is done to ensure the freshness of the hopper leads being confirmed through the HCI screen. -Since the HCI screen will reserve 40 hopper HOLD leads for each logged-in HCI screen user, you may need to raise your campaign Hopper Level depending on how many HCI screen users you will want to have logged in at any one time. +Since the HCI screen will reserve 40 hopper HOLD leads for each logged-in HCI screen user (or 120 leads in AUTONEXT mode), you may need to raise your campaign Hopper Level depending on how many HCI screen users you will want to have logged in at any one time. @@ -59,7 +63,7 @@ DATABASE CHANGES FOR REFERENCE ONLY!!!!!!!!! ALTER TABLE system_settings ADD hopper_hold_inserts ENUM('0','1','2','3','4','5','6','7') default '0'; -ALTER TABLE vicidial_campaigns ADD hopper_hold_inserts ENUM('ENABLED','DISABLED') default 'DISABLED'; +ALTER TABLE vicidial_campaigns ADD hopper_hold_inserts ENUM('ENABLED','DISABLED','AUTONEXT') default 'DISABLED'; ALTER TABLE vicidial_hopper MODIFY status ENUM('READY','QUEUE','INCALL','DONE','HOLD','DNC','RHOLD','RQUEUE') default 'READY'; diff --git a/extras/MySQL_AST_CREATE_tables.sql b/extras/MySQL_AST_CREATE_tables.sql index 318d0859..e7c12403 100644 --- a/extras/MySQL_AST_CREATE_tables.sql +++ b/extras/MySQL_AST_CREATE_tables.sql @@ -1122,7 +1122,7 @@ dead_stop_recording ENUM('DISABLED','ALL_CALLS','OUTBOUND_ONLY','INBOUND_ONLY',' manual_vm_status_updates ENUM('ENABLED','DISABLED') default 'ENABLED', force_per_call_notes ENUM('DISABLED','ENABLED','5_CHARACTERS','15_CHARACTERS','30_CHARACTERS','100_CHARACTERS') default 'DISABLED', agent_search_ingroup_list ENUM('DISABLED','ENABLED','ENABLED_OVERRIDE') default 'DISABLED', -hopper_hold_inserts ENUM('ENABLED','DISABLED') default 'DISABLED', +hopper_hold_inserts ENUM('ENABLED','DISABLED','AUTONEXT') default 'DISABLED', daily_phone_number_call_limit TINYINT(3) UNSIGNED default '0', state_descriptions VARCHAR(40) default '---DISABLED---' ) ENGINE=MyISAM; @@ -5631,4 +5631,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='1708',db_schema_update_date=NOW(),reload_timestamp=NOW(); +UPDATE system_settings SET db_schema_version='1709',db_schema_update_date=NOW(),reload_timestamp=NOW(); diff --git a/extras/upgrade_2.14.sql b/extras/upgrade_2.14.sql index e967d20c..3d6a41bc 100644 --- a/extras/upgrade_2.14.sql +++ b/extras/upgrade_2.14.sql @@ -2436,7 +2436,7 @@ ALTER TABLE system_settings ADD highest_lead_id VARCHAR(20) default '0'; ALTER TABLE system_settings ADD hopper_hold_inserts ENUM('0','1','2','3','4','5','6','7') default '0'; -ALTER TABLE vicidial_campaigns ADD hopper_hold_inserts ENUM('ENABLED','DISABLED') default 'DISABLED'; +ALTER TABLE vicidial_campaigns ADD hopper_hold_inserts ENUM('ENABLED','DISABLED','AUTONEXT') default 'DISABLED'; ALTER TABLE vicidial_hopper MODIFY status ENUM('READY','QUEUE','INCALL','DONE','HOLD','DNC','RHOLD','RQUEUE') default 'READY'; @@ -2661,3 +2661,7 @@ unique index livepartitions (server_ip, partition_path) ) ENGINE=MyISAM; UPDATE system_settings SET db_schema_version='1708',db_schema_update_date=NOW() where db_schema_version < 1708; + +ALTER TABLE vicidial_campaigns MODIFY hopper_hold_inserts ENUM('ENABLED','DISABLED','AUTONEXT') default 'DISABLED'; + +UPDATE system_settings SET db_schema_version='1709',db_schema_update_date=NOW() where db_schema_version < 1709; diff --git a/www/vicidial/admin.php b/www/vicidial/admin.php index 3dd60b61..37ff6eab 100644 --- a/www/vicidial/admin.php +++ b/www/vicidial/admin.php @@ -6131,12 +6131,13 @@ if ($SSscript_remove_js > 0) # 240214-2120 - Added STATE_DESCRIPTIONS container type and state_descriptions campaign and in-group settings, change year to 2024 # 240221-0331 - Changes for in-group daily limits, small changes for stats_descriptions # 240223-0854 - Added INBOUND_DID In-Group populate option +# 240225-0933 - Added the AUTONEXT hopper_hold_inserts campaign option # # make sure you have added a user to the vicidial_users MySQL table with at least user_level 9 to access this page the first time -$admin_version = '2.14-908a'; -$build = '240223-0854'; +$admin_version = '2.14-909a'; +$build = '240225-0933'; $STARTtime = date("U"); $SQLdate = date("Y-m-d H:i:s"); @@ -25744,7 +25745,13 @@ if ($ADD==3) if ($SShopper_hold_inserts > 0) { - echo ""._QXZ("HCI Enabled").": $NWB#users-hci_enabled$NWE\n"; + echo ""._QXZ("HCI Enabled").": $NWB#users-hci_enabled$NWE\n"; + } else { @@ -27305,7 +27312,12 @@ if ($ADD==31) if ($SShopper_hold_inserts > 0) { - echo ""._QXZ("Hopper Hold Inserts").": $NWB#campaigns-hopper_hold_inserts$NWE\n"; + echo ""._QXZ("Hopper Hold Inserts").": $NWB#campaigns-hopper_hold_inserts$NWE\n"; } else { @@ -44238,7 +44250,7 @@ if ($ADD==311111111111111) echo ""._QXZ("Outbound Auto-Dial Active").": $NWB#settings-outbound_autodial_active$NWE\n"; - echo ""._QXZ("Lead Hopper Hold Inserts Allowed").": $NWB#settings-hopper_hold_inserts$NWE\n"; + echo ""._QXZ("Lead Hopper Hold Inserts Allowed").": $NWB#settings-hopper_hold_inserts$NWE\n"; echo ""._QXZ("Shared Agent Campaign Dialing").": $NWB#settings-allow_shared_dial$NWE\n"; diff --git a/www/vicidial/hci_screen.php b/www/vicidial/hci_screen.php index 676dfb36..00bd5eac 100644 --- a/www/vicidial/hci_screen.php +++ b/www/vicidial/hci_screen.php @@ -1,20 +1,23 @@ LICENSE: AGPLv2 +# Copyright (C) 2024 Matt Florell LICENSE: AGPLv2 # # This script is designed to allow agents to work with the hopper_hold_inserts features and allow leads in the hopper to be changed from RHOLD to READY status so they can be called. # # changes: # 231119-1508 - First build +# 240225-1000 - Added AUTONEXT hopper_hold_inserts campaign option # $startMS = microtime(); -$hci_version = '2.14-1h'; -$build = '231119-1508'; +$hci_version = '2.14-2h'; +$build = '240225-1000'; $php_script='hci_screen.php'; $zi=0; +$default_batch_size=40; +$refresh_sec=4000; require("dbconnect_mysqli.php"); require("functions.php"); @@ -29,6 +32,8 @@ if (isset($_GET["phone_number"])) {$phone_number=$_GET["phone_number"];} elseif (isset($_POST["phone_number"])) {$phone_number=$_POST["phone_number"];} if (isset($_GET["campaign_id"])) {$campaign_id=$_GET["campaign_id"];} elseif (isset($_POST["campaign_id"])) {$campaign_id=$_POST["campaign_id"];} +if (isset($_GET["batch_size"])) {$batch_size=$_GET["batch_size"];} + elseif (isset($_POST["batch_size"])) {$batch_size=$_POST["batch_size"];} if (isset($_GET["stage"])) {$stage=$_GET["stage"];} elseif (isset($_POST["stage"])) {$stage=$_POST["stage"];} if (isset($_GET["DB"])) {$DB=$_GET["DB"];} @@ -66,6 +71,7 @@ if ($SSallow_web_debug < 1) {$DB=0;} ########################################### $phone_number = preg_replace('/[^0-9]/','',$phone_number); +$batch_size = preg_replace('/[^0-9]/','',$batch_size); $stage = preg_replace('/[^-_0-9a-zA-Z]/','',$stage); if ($non_latin < 1) @@ -87,6 +93,8 @@ else $SUBMIT = preg_replace('/[^- 0-9\p{L}]/u','',$SUBMIT); } +if ( ($batch_size < 10) or (strlen($batch_size) < 2) ) + {$batch_size = $default_batch_size;} $STARTtime = date("U"); $defaultappointment = date("Y-m-d"); @@ -300,7 +308,7 @@ if ( ($stage == 'LOGOUT') and (strlen($campaign_id) > 0) ) if ( ($stage == 'chosen_campaign') and (strlen($campaign_id) > 0) ) { $valid_campaign=0; - $stmt="SELECT count(*) from vicidial_campaigns where campaign_id='$campaign_id' and active='Y' and hopper_hold_inserts='ENABLED' $LOGallowed_campaignsSQL;"; + $stmt="SELECT count(*) from vicidial_campaigns where campaign_id='$campaign_id' and active='Y' and hopper_hold_inserts IN('ENABLED','AUTONEXT') $LOGallowed_campaignsSQL;"; $rslt=mysql_to_mysqli($stmt, $link); $camps_to_parse = mysqli_num_rows($rslt); if ($camps_to_parse > 0) @@ -310,6 +318,15 @@ if ( ($stage == 'chosen_campaign') and (strlen($campaign_id) > 0) ) } if ($valid_campaign > 0) { + $autonext_campaign=0; + $stmt="SELECT count(*) from vicidial_campaigns where campaign_id='$campaign_id' and hopper_hold_inserts='AUTONEXT';"; + $rslt=mysql_to_mysqli($stmt, $link); + $campANs_to_parse = mysqli_num_rows($rslt); + if ($campANs_to_parse > 0) + { + $rowx=mysqli_fetch_row($rslt); + $autonext_campaign = $rowx[0]; + } $stmt="INSERT INTO vicidial_hci_live_agents SET user='$PHP_AUTH_USER',campaign_id='$campaign_id',user_ip='$ip',login_time=NOW(),last_call_time=NOW(),last_update_time=NOW(),status='LOGIN',lead_id=0,phone_number='',random_id=0;"; $rslt=mysql_to_mysqli($stmt, $link); @@ -327,7 +344,7 @@ if ( ($stage == 'chosen_campaign') and (strlen($campaign_id) > 0) ) } if ($hopper_hold_count > 0) { - $stmt="UPDATE vicidial_hopper SET user='$PHP_AUTH_USER',status='RQUEUE' WHERE campaign_id='$campaign_id' and status='RHOLD' and user='' order by priority desc,hopper_id limit 40;"; + $stmt="UPDATE vicidial_hopper SET user='$PHP_AUTH_USER',status='RQUEUE' WHERE campaign_id='$campaign_id' and status='RHOLD' and user='' order by priority desc,hopper_id limit $batch_size;"; $rslt=mysql_to_mysqli($stmt, $link); $vh_affected_rows = mysqli_affected_rows($link); @@ -364,7 +381,7 @@ if ( ($stage == 'chosen_campaign') and (strlen($campaign_id) > 0) ) } } - $notes = "$campaign_id $ip $vh_affected_rows $vhr_to_parse $vhr_ct $vhr_insert"; + $notes = "$campaign_id $ip $vh_affected_rows $vhr_to_parse $vhr_ct $vhr_insert $autonext_campaign"; vicidial_ajax_log($NOW_TIME,$startMS,$link,$stage,$php_script,$PHP_AUTH_USER,$notes,$lead_id,$session_name,$stmt); } } @@ -379,7 +396,7 @@ if ( ($stage == 'chosen_campaign') and (strlen($campaign_id) > 0) ) if ( ($stage == 'switch_campaign') and (strlen($campaign_id) > 0) ) { $valid_campaign=0; - $stmt="SELECT count(*) from vicidial_campaigns where campaign_id='$campaign_id' and active='Y' and hopper_hold_inserts='ENABLED' $LOGallowed_campaignsSQL;"; + $stmt="SELECT count(*) from vicidial_campaigns where campaign_id='$campaign_id' and active='Y' and hopper_hold_inserts IN('ENABLED','AUTONEXT') $LOGallowed_campaignsSQL;"; $rslt=mysql_to_mysqli($stmt, $link); $camps_to_parse = mysqli_num_rows($rslt); if ($camps_to_parse > 0) @@ -389,6 +406,15 @@ if ( ($stage == 'switch_campaign') and (strlen($campaign_id) > 0) ) } if ($valid_campaign > 0) { + $autonext_campaign=0; + $stmt="SELECT count(*) from vicidial_campaigns where campaign_id='$campaign_id' and hopper_hold_inserts='AUTONEXT';"; + $rslt=mysql_to_mysqli($stmt, $link); + $campANs_to_parse = mysqli_num_rows($rslt); + if ($campANs_to_parse > 0) + { + $rowx=mysqli_fetch_row($rslt); + $autonext_campaign = $rowx[0]; + } $stmt="SELECT campaign_id,status from vicidial_hci_live_agents where user='$PHP_AUTH_USER';"; $rslt=mysql_to_mysqli($stmt, $link); $users_to_parse = mysqli_num_rows($rslt); @@ -443,7 +469,7 @@ if ( ($stage == 'switch_campaign') and (strlen($campaign_id) > 0) ) } if ($hopper_hold_count > 0) { - $stmt="UPDATE vicidial_hopper SET user='$PHP_AUTH_USER',status='RQUEUE' WHERE campaign_id='$campaign_id' and status='RHOLD' and user='' order by priority desc,hopper_id limit 40;"; + $stmt="UPDATE vicidial_hopper SET user='$PHP_AUTH_USER',status='RQUEUE' WHERE campaign_id='$campaign_id' and status='RHOLD' and user='' order by priority desc,hopper_id limit $batch_size;"; $rslt=mysql_to_mysqli($stmt, $link); $vh_affected_rows = mysqli_affected_rows($link); @@ -480,7 +506,7 @@ if ( ($stage == 'switch_campaign') and (strlen($campaign_id) > 0) ) } } - $notes = "$campaign_id $old_campaign_id $VHLAstatus $vh_clear $vhr_clear $vh_affected_rows $vhr_insert"; + $notes = "$campaign_id $old_campaign_id $VHLAstatus $vh_clear $vhr_clear $vh_affected_rows $vhr_insert $autonext_campaign"; vicidial_ajax_log($NOW_TIME,$startMS,$link,$stage,$php_script,$PHP_AUTH_USER,$notes,$lead_id,$session_name,$stmt); } else @@ -689,9 +715,9 @@ if ($stage == 'lead_display') $rowx=mysqli_fetch_row($rslt); $reserved_ct = $rowx[0]; } - if ($reserved_ct < 40) + if ($reserved_ct < $batch_size) { - $reserve_more_hopper_leads = (40 - $reserved_ct); + $reserve_more_hopper_leads = ($batch_size - $reserved_ct); if ($reserve_more_hopper_leads > 0) { @@ -780,6 +806,7 @@ if ($stage == 'lead_display') } else { + $lead_phone_list=''; $stmt="SELECT lead_id,phone_number from vicidial_hci_reserve WHERE campaign_id='$campaign_id' and user='$PHP_AUTH_USER' order by reserve_date,lead_id;"; $rslt=mysql_to_mysqli($stmt, $link); $vhr_to_parse = mysqli_num_rows($rslt); @@ -791,9 +818,11 @@ if ($stage == 'lead_display') $rowx=mysqli_fetch_row($rslt); $Elead_id[$vhr_ct] = $rowx[0]; $Ephone[$vhr_ct] = $rowx[1]; + $lead_phone_list .= $vhr_ct."_".$rowx[0]."_".$rowx[1]."|"; $vhr_ct++; } + echo "\n"; echo ""._QXZ("Call Confirmation").":
"; $row_ct=0; @@ -898,7 +927,7 @@ $camp_panel_code=''; $camp_form_code = "