From 5635ce98865ad517002bf865afea0691755b9958 Mon Sep 17 00:00:00 2001 From: Mattf Date: Fri, 19 Sep 2025 17:23:26 +0000 Subject: [PATCH 01/12] Stereo Call Recording commit git-svn-id: svn://svn.eflo.net/agc_2-X/trunk@3941 3d104415-ff17-0410-8863-d5cf3c621b8a --- agi/VD_amd.agi | 2 +- agi/agi-VDAD_ALL_inbound.agi | 711 +++++++- agi/agi-VDAD_ALL_outbound.agi | 1531 +++++++++++++++-- bin/ADMIN_archive_log_tables.pl | 101 +- bin/ADMIN_keepalive_ALL.pl | 54 +- bin/AST_CRON_audio_1_move_VDonly.pl | 88 +- bin/AST_CRON_audio_1_move_mix.pl | 4 +- bin/AST_CRON_audio_1_stereo.pl | 970 +++++++++++ bin/AST_CRON_audio_2_compress.pl | 34 +- bin/AST_flush_DBqueue.pl | 118 +- docs/AGENT_API.txt | 43 +- docs/CALLER_ID_NAME_CODES.txt | 5 +- docs/STEREO_CALL_RECORDINGS.txt | 368 ++++ extras/MySQL_AST_CREATE_tables.sql | 124 +- extras/upgrade_2.14.sql | 124 +- install.pl | 10 + www/agc/api.php | 142 +- www/agc/images/vdc_LB_STstartrecording.gif | Bin 0 -> 1704 bytes .../images/vdc_LB_STstartrecording_OFF.gif | Bin 0 -> 1709 bytes .../images/vdc_LB_STstartrecording_alt.gif | Bin 0 -> 1655 bytes .../vdc_LB_STstartrecording_alt_OFF.gif | Bin 0 -> 1638 bytes .../images/vdc_LB_STstartrecording_altx2.gif | Bin 0 -> 1891 bytes .../vdc_LB_STstartrecording_altx2_OFF.gif | Bin 0 -> 1857 bytes www/agc/images/vdc_LB_STstoprecording.gif | Bin 0 -> 1680 bytes www/agc/images/vdc_LB_STstoprecording_OFF.gif | Bin 0 -> 1692 bytes www/agc/images/vdc_LB_STstoprecording_alt.gif | Bin 0 -> 1583 bytes .../images/vdc_LB_STstoprecording_alt_OFF.gif | Bin 0 -> 1558 bytes .../images/vdc_LB_STstoprecording_altx2.gif | Bin 0 -> 1786 bytes .../vdc_LB_STstoprecording_altx2_OFF.gif | Bin 0 -> 1762 bytes www/agc/manager_send.php | 391 ++++- www/agc/vdc_db_query.php | 523 +++++- www/agc/vicidial.php | 245 ++- www/vicidial/AST_timeonVDADall.php | 148 +- www/vicidial/admin.php | 212 ++- www/vicidial/admin_modify_lead.php | 23 +- www/vicidial/help_documentation.txt | 18 +- 36 files changed, 5664 insertions(+), 325 deletions(-) create mode 100644 bin/AST_CRON_audio_1_stereo.pl create mode 100644 docs/STEREO_CALL_RECORDINGS.txt create mode 100644 www/agc/images/vdc_LB_STstartrecording.gif create mode 100644 www/agc/images/vdc_LB_STstartrecording_OFF.gif create mode 100644 www/agc/images/vdc_LB_STstartrecording_alt.gif create mode 100644 www/agc/images/vdc_LB_STstartrecording_alt_OFF.gif create mode 100644 www/agc/images/vdc_LB_STstartrecording_altx2.gif create mode 100644 www/agc/images/vdc_LB_STstartrecording_altx2_OFF.gif create mode 100644 www/agc/images/vdc_LB_STstoprecording.gif create mode 100644 www/agc/images/vdc_LB_STstoprecording_OFF.gif create mode 100644 www/agc/images/vdc_LB_STstoprecording_alt.gif create mode 100644 www/agc/images/vdc_LB_STstoprecording_alt_OFF.gif create mode 100644 www/agc/images/vdc_LB_STstoprecording_altx2.gif create mode 100644 www/agc/images/vdc_LB_STstoprecording_altx2_OFF.gif diff --git a/agi/VD_amd.agi b/agi/VD_amd.agi index 009faaf1b..2ac7053d8 100644 --- a/agi/VD_amd.agi +++ b/agi/VD_amd.agi @@ -69,7 +69,7 @@ # 220411-0833 - Added FHG(file-http-get) message playback option to download file from website # 230412-1023 - Added Code to dispo NOAUDIODATA as ADAIR (Dead Air Auto) with Settings Container option, Issue #1459 # 230726-0932 - Added manual_vm_status_updates campaign option -# 250906-2228 - Added AMD minimum length handling to increase short call durations +# 240906-2228 - Added AMD minimum length handling to increase short call durations # $script = 'VD_amd.agi'; diff --git a/agi/agi-VDAD_ALL_inbound.agi b/agi/agi-VDAD_ALL_inbound.agi index 77e33171b..1caa561e9 100644 --- a/agi/agi-VDAD_ALL_inbound.agi +++ b/agi/agi-VDAD_ALL_inbound.agi @@ -265,6 +265,7 @@ # 240723-1632 - Small fix for ConfBridge # 240906-1032 - Added testing for stereo_recording in-group option *NOT PRODUCTION READY* # 250325-1724 - Fix for possible daily_limit issue +# 250825-1824 - Added stereo_recording code # $script = 'agi-VDAD_ALL_inbound.agi'; @@ -395,6 +396,11 @@ if (!$PRSLOGfile) {$PRSLOGfile = "$PATHlogs/prsout.$year-$mon-$mday";} if (!$PRSTESTfile) {$PRSTESTfile = "$PATHlogs/prstest.$year-$mon-$mday";} if (!$ERRLOGfile) {$ERRLOGfile = "$PATHlogs/MySQLerror.$year-$mon-$mday";} +# generate paths to asterisk stereo recordings directories: +$PATHmonitorS = $PATHmonitor."S"; +$PATHmonitorP = $PATHmonitor."P"; +$PATHmonitorTRASH = $PATHmonitor."TRASH"; + use DBI; use Time::HiRes ('gettimeofday','usleep','sleep'); # necessary to have perl sleep command of less than one second use Asterisk::AGI; @@ -428,7 +434,7 @@ $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;"; +$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,stereo_recording,stereo_parallel_recording FROM system_settings;"; $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; $sthArows=$sthA->rows; @@ -459,6 +465,8 @@ if ($sthArows > 0) $SSagent_search_method = $aryA[20]; $SSabandon_check_queue = $aryA[21]; $SSinbound_credits = $aryA[22]; + $SSstereo_recording = $aryA[23]; + $SSstereo_parallel_recording = $aryA[24]; } $sthA->finish(); ##### END SYSTEM SETTINGS LOOKUP ##### @@ -897,7 +905,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,second_alert_container,second_alert_only,third_alert_trigger,third_alert_trigger_seconds,third_alert_filename,third_alert_delay,third_alert_container,third_alert_only,stereo_recording 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,third_alert_trigger,third_alert_trigger_seconds,third_alert_filename,third_alert_delay,third_alert_container,third_alert_only,stereo_recording,stereo_recording_agent,stereo_rec_filename,stereo_parallel_recording,parallel_rec_co_filename,parallel_rec_cm_filename,parallel_rec_fr_filename 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; @@ -1054,6 +1062,12 @@ if ($sthArows > 0) $third_alert_container = $aryA[139]; $third_alert_only = $aryA[140]; $stereo_recording = $aryA[141]; + $stereo_recording_agent = $aryA[142]; + $stereo_rec_filename = $aryA[143]; + $stereo_parallel_recording = $aryA[144]; + $parallel_rec_co_filename = $aryA[145]; + $parallel_rec_cm_filename = $aryA[146]; + $parallel_rec_fr_filename = $aryA[147]; 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';} @@ -2673,11 +2687,11 @@ if ( ($CLchannel_group =~ /DID_INBOUND/) && (length($CLend_epoch) < 5) ) %ast_ver_str = parse_asterisk_version($asterisk_version); if (( $ast_ver_str{major} = 1 ) && ($ast_ver_str{minor} < 6)) { - $AGI->exec("StopMonitor wav|/var/spool/asterisk/monitor/MIX/$CLfilename"); + $AGI->exec("StopMonitor wav|$PATHmonitor/MIX/$CLfilename"); } else { - $AGI->exec("StopMonitor","wav,/var/spool/asterisk/monitor/MIX/$CLfilename"); + $AGI->exec("StopMonitor","wav,$PATHmonitor/MIX/$CLfilename"); } @@ -3319,9 +3333,11 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override my $LOCKaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02060'; $MEL_aff_rows=$LOCKaffected_rows; &mysql_error_logging; - if ( ($routing_initiated_recordings =~ /Y/) && ($found_agents > 0) && ($VDADon_hook_agent !~ /Y/) && ($CAMP_callorder !~ /ring_all$/i) && ($VDADextension !~ /^R\//)) + # if ($AGILOG) {$agi_string = "-- DEBUG RECORDING: |$stereo_recording|$conf_engine|$SSstereo_recording|$stereo_rec_filename|$stereo_parallel_recording|$uniqueid|$channel|$insert_lead_id| |$routing_initiated_recordings|$found_agents|$VDADon_hook_agent|$CAMP_callorder|$VDADextension|"; &agi_output;} + + if ( ( ($routing_initiated_recordings =~ /Y/) || ( ($stereo_recording =~ /CUSTOMER|BOTH/i) && ($conf_engine eq "CONFBRIDGE") && ($SSstereo_recording > 0) ) ) && ($found_agents > 0) && ($VDADon_hook_agent !~ /Y/) && ($CAMP_callorder !~ /ring_all$/i) && ($VDADextension !~ /^R\//)) { - ### BEGIN routing-initiated agent call recording for ALLCALLS/ALLFORCE ### + ### BEGIN routing-initiated agent call recording for ALLCALLS/ALLFORCE for non-remote and non-on-hook agents ### ### get the recording settings for the campaign that this user is logged into if (length($log_campaign) > 0) @@ -3363,7 +3379,7 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override $sthA->finish(); } - ### if recording is enabled then start recording on this call before sending to a remote agent + ### if recording is enabled then start recording on this call before sending to an agent if ($ingroup_recording_override =~ /ALLCALLS|ALLFORCE/) { $stmtA = "SELECT vendor_lead_code FROM vicidial_list where lead_id='$insert_lead_id';"; @@ -3434,18 +3450,6 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override $dbhP=$dbhA; $mysql_count='02214'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; } - if ( ($stereo_recording =~ /CUSTOMER/i) && ($conf_engine eq "CONFBRIDGE") ) - { - $retval_stop = $AGI->exec("StopMixMonitor",""); - $retval = $AGI->exec("MixMonitor",",r(/var/spool/asterisk/monitorS/$campaign_rec_filename-in.wav)t(/var/spool/asterisk/monitorS/$campaign_rec_filename-out.wav)"); - - ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log) values('$recording_id','$VDADserver_ip','$now_date','0','$campaign_rec_filename','$insert_lead_id','$stereo_recording $channel_group','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|');"; - $SRaffected_rows = $dbhA->do($stmtA); - $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - if ($AGILOG) {$agi_string = "-- REMOTE STEREO RECORDING STARTED : |$retval|$retval_stop|$SRaffected_rows|$recording_id|$stmtA|"; &agi_output;} - } - $vmgr_callerid = substr($campaign_rec_filename, 0, 17) . '...'; $stmtA="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VDADserver_ip','','Originate','$vmgr_callerid','Channel: $channelrec','Context: $ext_context','Exten: $recording_exten','Priority: 1','Callerid: $campaign_rec_filename','','','','','');"; $affected_rows = $dbhA->do($stmtA); @@ -3459,9 +3463,333 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override $affected_rowsC = $dbhA->do($stmtC); $dbhP=$dbhA; $mysql_count='02217'; $MEL_aff_rows=$affected_rowsC; &mysql_error_logging; - if ($AGILOG) {$agi_string = "-- ROUTING INITIATED RECORDING STARTED : |$affected_rows|$recording_id|$campaign_rec_filename|$stmtA| |$affected_rowsB|$stmtB| |$affected_rowsC|$stmtC|"; &agi_output;} + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','MONO_LEGACY_RIR','$VARserver_ip','$now_date','$channel','$campaign_rec_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + if ($AGILOG) {$agi_string = "-- ROUTING INITIATED RECORDING STARTED : |$affected_rows|$recording_id|$campaign_rec_filename|$stmtA| |$affected_rowsB|$stmtB| |$affected_rowsC|$stmtC| |$rLIVEaffected_rows|$stmtD|"; &agi_output;} + } + ### END routing-initiated agent call recording for ALLCALLS/ALLFORCE for non-remote and non-on-hook agents ### + + ### BEGIN stereo call recording for ALLCALLS/ALLFORCE and for all parallel stereo recording in-groups ### + if ( ($stereo_recording =~ /CUSTOMER|BOTH/i) && ($conf_engine eq "CONFBRIDGE") && ($SSstereo_recording > 0) ) + { + $stereo_rec_filename =~ s/CAMPAIGN/$log_campaign/gi; + $stereo_rec_filename =~ s/INGROUP/$channel_group/gi; + $stereo_rec_filename =~ s/CUSTPHONE/$phone_number/gi; + $stereo_rec_filename =~ s/FULLDATE/$recdate/gi; + $stereo_rec_filename =~ s/TINYDATE/$tinydate/gi; + $stereo_rec_filename =~ s/EPOCH/$now_date_epoch/gi; + $stereo_rec_filename =~ s/AGENT/$VDADuser/gi; + $stereo_rec_filename =~ s/VENDORLEADCODE/$vendor_lead_code/gi; + $stereo_rec_filename =~ s/LEADID/$insert_lead_id/gi; + $stereo_rec_filename =~ s/CALLID/$callerid/gi; + $stereo_rec_filename =~ s/\"|\'//gi; + + $PATHmonitorT = $PATHmonitorS; + if ( ($SSstereo_parallel_recording > 0) && ($stereo_parallel_recording =~ /CUSTOMER|FULL/) ) + { + $PATHmonitorT = $PATHmonitorP; + + ### insert record into recording_log_parallel table ### + $stmtA = "INSERT INTO recording_log_parallel (channel,server_ip,extension,start_time,length_in_sec,filename,lead_id,user,vicidial_id,recording_status) values('$channel','$VDADserver_ip','','$now_date','0','PL$stereo_rec_filename','$insert_lead_id','$VDADuser','$insert_close_id','START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $parallel_recording_id = $aryA[0]; + } + $sthA->finish(); + + ### start the parallel recording + $retval_stop = $AGI->exec("StopMixMonitor",""); + $retval = $AGI->exec("MixMonitor",",r($PATHmonitorT/PL$stereo_rec_filename-out.wav)t($PATHmonitorT/PL$stereo_rec_filename-in.wav)"); + + if ($AGILOG) {$agi_string = "-- PARALLEL STEREO STARTED: |$retval|$retval_stop|$SRaffected_rows|$parallel_recording_id|$stmtA|"; &agi_output;} + + if ($stereo_parallel_recording =~ /CUSTOMER-ONLY/) + { + $temp_parallel_rec_co_filename = "CO".$stereo_rec_filename; + if (length($parallel_rec_co_filename) > 0) + { + $temp_parallel_rec_co_filename = $parallel_rec_co_filename; + $temp_parallel_rec_co_filename =~ s/CAMPAIGN/$log_campaign/gi; + $temp_parallel_rec_co_filename =~ s/INGROUP/$channel_group/gi; + $temp_parallel_rec_co_filename =~ s/CUSTPHONE/$phone_number/gi; + $temp_parallel_rec_co_filename =~ s/FULLDATE/$recdate/gi; + $temp_parallel_rec_co_filename =~ s/TINYDATE/$tinydate/gi; + $temp_parallel_rec_co_filename =~ s/EPOCH/$now_date_epoch/gi; + $temp_parallel_rec_co_filename =~ s/AGENT/$VDADuser/gi; + $temp_parallel_rec_co_filename =~ s/VENDORLEADCODE/$vendor_lead_code/gi; + $temp_parallel_rec_co_filename =~ s/LEADID/$insert_lead_id/gi; + $temp_parallel_rec_co_filename =~ s/CALLID/$callerid/gi; + $temp_parallel_rec_co_filename =~ s/\"|\'//gi; + } + ### insert a record into the recording_log table + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPCO','$now_date','$now_date_epoch','$temp_parallel_rec_co_filename','$insert_lead_id','$VDADuser','$insert_close_id')"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($temp_parallel_rec_co_filename =~ /RECID/) + { + $temp_parallel_rec_co_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$temp_parallel_rec_co_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + ### insert record into recording_log_stereo table ### + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_co_filename','$insert_lead_id','$channel_group STEREO_PARALLEL CUSTOMER-ONLY $stereo_recording','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL CUSTOMER-ONLY','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_co_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + if ($AGILOG) {$agi_string = "-- PARALLEL CO STEREO RECORDING LOG INSERT : |$SRaffected_rows|$recording_id|$parallel_recording_id|$rLIVEaffected_rows|$stmtA|"; &agi_output;} + } + + if ($stereo_parallel_recording =~ /CUSTOMER-MUTED/) + { + $temp_parallel_rec_cm_filename = "CM".$stereo_rec_filename; + if (length($parallel_rec_cm_filename) > 0) + { + $temp_parallel_rec_cm_filename = $parallel_rec_cm_filename; + $temp_parallel_rec_cm_filename =~ s/CAMPAIGN/$log_campaign/gi; + $temp_parallel_rec_cm_filename =~ s/INGROUP/$channel_group/gi; + $temp_parallel_rec_cm_filename =~ s/CUSTPHONE/$phone_number/gi; + $temp_parallel_rec_cm_filename =~ s/FULLDATE/$recdate/gi; + $temp_parallel_rec_cm_filename =~ s/TINYDATE/$tinydate/gi; + $temp_parallel_rec_cm_filename =~ s/EPOCH/$now_date_epoch/gi; + $temp_parallel_rec_cm_filename =~ s/AGENT/$VDADuser/gi; + $temp_parallel_rec_cm_filename =~ s/VENDORLEADCODE/$vendor_lead_code/gi; + $temp_parallel_rec_cm_filename =~ s/LEADID/$insert_lead_id/gi; + $temp_parallel_rec_cm_filename =~ s/CALLID/$callerid/gi; + $temp_parallel_rec_cm_filename =~ s/\"|\'//gi; + } + ### insert a record into the recording_log table + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPCM','$now_date','$now_date_epoch','$temp_parallel_rec_cm_filename','$insert_lead_id','$VDADuser','$insert_close_id')"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($temp_parallel_rec_cm_filename =~ /RECID/) + { + $temp_parallel_rec_cm_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$temp_parallel_rec_cm_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + ### insert record into recording_log_stereo table ### + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_cm_filename','$insert_lead_id','$channel_group STEREO_PARALLEL CUSTOMER-MUTED $stereo_recording','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL CUSTOMER-MUTED','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_cm_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + if ($AGILOG) {$agi_string = "-- PARALLEL CM STEREO RECORDING LOG INSERT : |$SRaffected_rows|$recording_id|$parallel_recording_id|$rLIVEaffected_rows|$stmtA|"; &agi_output;} + } + + if ($stereo_parallel_recording =~ /FULL-RECORDING/) + { + $temp_parallel_rec_fr_filename = "FR".$stereo_rec_filename; + if (length($parallel_rec_fr_filename) > 0) + { + $temp_parallel_rec_fr_filename = $parallel_rec_fr_filename; + $temp_parallel_rec_fr_filename =~ s/CAMPAIGN/$log_campaign/gi; + $temp_parallel_rec_fr_filename =~ s/INGROUP/$channel_group/gi; + $temp_parallel_rec_fr_filename =~ s/CUSTPHONE/$phone_number/gi; + $temp_parallel_rec_fr_filename =~ s/FULLDATE/$recdate/gi; + $temp_parallel_rec_fr_filename =~ s/TINYDATE/$tinydate/gi; + $temp_parallel_rec_fr_filename =~ s/EPOCH/$now_date_epoch/gi; + $temp_parallel_rec_fr_filename =~ s/AGENT/$VDADuser/gi; + $temp_parallel_rec_fr_filename =~ s/VENDORLEADCODE/$vendor_lead_code/gi; + $temp_parallel_rec_fr_filename =~ s/LEADID/$insert_lead_id/gi; + $temp_parallel_rec_fr_filename =~ s/CALLID/$callerid/gi; + $temp_parallel_rec_fr_filename =~ s/\"|\'//gi; + } + ### insert a record into the recording_log table + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPFR','$now_date','$now_date_epoch','$temp_parallel_rec_fr_filename','$insert_lead_id','$VDADuser','$insert_close_id')"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($temp_parallel_rec_fr_filename =~ /RECID/) + { + $temp_parallel_rec_fr_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$temp_parallel_rec_fr_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + ### insert record into recording_log_stereo table ### + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_fr_filename','$insert_lead_id','$channel_group STEREO_PARALLEL FULL-RECORDING $stereo_recording','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL FULL-RECORDING','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_fr_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + if ($AGILOG) {$agi_string = "-- PARALLEL FR STEREO RECORDING LOG INSERT : |$SRaffected_rows|$recording_id|$parallel_recording_id|$rLIVEaffected_rows|$stmtA|"; &agi_output;} + } + + # insert logs for agent-controlled stereo call recordings while parallel recordings are enabled + if ($stereo_recording_agent =~ /ALLCALLS|ALLFORCE/) + { + $temp_parallel_rec_ag_filename = $stereo_rec_filename; + ### insert a record into the recording_log table + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPACI','$now_date','$now_date_epoch','$temp_parallel_rec_ag_filename','$insert_lead_id','$VDADuser','$insert_close_id')"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($temp_parallel_rec_ag_filename =~ /RECID/) + { + $temp_parallel_rec_ag_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$temp_parallel_rec_ag_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + ### insert record into recording_log_stereo table ### + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_ag_filename','$insert_lead_id','$channel_group STEREO_PARALLEL AGENT-CONTROLLED RIR $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + + $stmtB = "INSERT INTO routing_initiated_recordings (recording_id,filename,launch_time,lead_id,vicidial_id,user,processed,rir_type) values('$recording_id','$temp_parallel_rec_ag_filename','$now_date','$insert_lead_id','$insert_close_id','$VDADuser','0','S')"; + $affected_rowsB = $dbhA->do($stmtB); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rowsB; &mysql_error_logging; + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL AGENT-CONTROLLED RIR','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_ag_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + if ($AGILOG) {$agi_string = "-- PARALLEL AG STEREO RECORDING LOG INSERT : |$SRaffected_rows|$recording_id|$parallel_recording_id|$affected_rowsB|$rLIVEaffected_rows|$stmtA|"; &agi_output;} + } + } + else + { + ## Start NON-parallel stereo call recording ## + if ($stereo_recording_agent =~ /ALLCALLS|ALLFORCE/) + { + # insert a record into the recording_log table + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SACI','$now_date','$now_date_epoch','$stereo_rec_filename','$insert_lead_id','$VDADuser','$insert_close_id')"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($stereo_rec_filename =~ /RECID/) + { + $stereo_rec_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$stereo_rec_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + $retval_stop = $AGI->exec("StopMixMonitor",""); + $retval = $AGI->exec("MixMonitor",",r($PATHmonitorT/$stereo_rec_filename-out.wav)t($PATHmonitorT/$stereo_rec_filename-in.wav)"); + + ### insert record into recording_log_stereo table ### + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$stereo_rec_filename','$insert_lead_id','$channel_group STEREO AGENT-CONTROLLED $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|','STEREO START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + + $stmtB = "INSERT INTO routing_initiated_recordings (recording_id,filename,launch_time,lead_id,vicidial_id,user,processed,rir_type) values('$recording_id','$stereo_rec_filename','$now_date','$insert_lead_id','$insert_close_id','$VDADuser','0','S')"; + $affected_rowsB = $dbhA->do($stmtB); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rowsB; &mysql_error_logging; + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO AGENT-CONTROLLED RIR','$VARserver_ip','$now_date','$channel','$stereo_rec_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + $mLIVEaffected_rows=0; + if ($stereo_recording =~ /CUSTOMER_ONLY/i) + { + $vmgr_callerid = substr($stereo_rec_filename, 0, 16) . 'M...'; + $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VDADserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: write','State: 1','','','','','','');"; + $mLIVEaffected_rows = $dbhA->do($stmtE); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$mLIVEaffected_rows; &mysql_error_logging; + } + if ($stereo_recording =~ /CUSTOMER_MUTE/i) + { + $vmgr_callerid = substr($stereo_rec_filename, 0, 16) . 'M...'; + $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VDADserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: read','State: 1','','','','','','');"; + $mLIVEaffected_rows = $dbhA->do($stmtE); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$mLIVEaffected_rows; &mysql_error_logging; + } + + if ($AGILOG) {$agi_string = "-- AGENT STEREO RECORDING STARTED : |$retval|$retval_stop|$SRaffected_rows|$recording_id|$affected_rowsB|$rLIVEaffected_rows|$mLIVEaffected_rows|$stmtA|"; &agi_output;} + } + } } - ### END routing-initiated agent call recording for ALLCALLS/ALLFORCE ### + ### END stereo call recording for ALLCALLS/ALLFORCE and for all parallel stereo recording in-groups ### } } @@ -4693,21 +5021,20 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override $campaign_rec_filename =~ s/CALLID/$callerid/gi; $campaign_rec_filename =~ s/\"|\'//gi; - if ( ($stereo_recording =~ /CUSTOMER/i) && ($conf_engine eq "CONFBRIDGE") ) + if ( ($stereo_recording =~ /CUSTOMER|BOTH/i) && ($conf_engine eq "CONFBRIDGE") && ($SSstereo_recording > 0) ) { - $retval_stop = $AGI->exec("StopMixMonitor",""); - $retval = $AGI->exec("MixMonitor",",r(/var/spool/asterisk/monitorS/$campaign_rec_filename-in.wav)t(/var/spool/asterisk/monitorS/$campaign_rec_filename-out.wav)"); + # do nothing can't record more than 1 stream on the same channel, stereo call recording processing is right below this section } else { %ast_ver_str = parse_asterisk_version($asterisk_version); if (( $ast_ver_str{major} = 1 ) && ($ast_ver_str{minor} < 6)) { - $retval = $AGI->exec("Monitor wav|/var/spool/asterisk/monitor/MIX/$campaign_rec_filename"); + $retval = $AGI->exec("Monitor wav|$PATHmonitor/MIX/$campaign_rec_filename"); } else { - $retval = $AGI->exec("Monitor","wav,/var/spool/asterisk/monitor/MIX/$campaign_rec_filename"); + $retval = $AGI->exec("Monitor","wav,$PATHmonitor/MIX/$campaign_rec_filename"); } } @@ -4715,27 +5042,341 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,length_in_sec,filename,lead_id,user,location,vicidial_id) values('$channel','$VARserver_ip','$phone_number','$now_date','$now_date_epoch','0','$campaign_rec_filename','$insert_lead_id','$VDADuser','$campaign_rec_filename','$insert_close_id');"; $RLRAaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01173'; $MEL_aff_rows=$RLRAaffected_rows; &mysql_error_logging; - if ($AGILOG) {$agi_string = "-- REMOTE RECORDING STARTED : |$retval|$RLRAaffected_rows|$campaign_rec_filename|$stmtA|"; &agi_output;} + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02213'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + if ($campaign_rec_filename =~ /RECID/) + { + $campaign_rec_filename =~ s/RECID/$recording_id/gi; - if ( ($stereo_recording =~ /CUSTOMER/i) && ($conf_engine eq "CONFBRIDGE") ) + $stmtA = "UPDATE recording_log SET filename='$campaign_rec_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02214'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','MONO_LEGACY_REMOTE','$VARserver_ip','$now_date','$channel','$campaign_rec_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + if ($AGILOG) {$agi_string = "-- REMOTE RECORDING STARTED : |$retval|$RLRAaffected_rows|$campaign_rec_filename|$recording_id|$rLIVEaffected_rows|$stmtA|"; &agi_output;} + } + + ### BEGIN stereo call recording for ALLCALLS/ALLFORCE and for all parallel stereo recording in-groups ### + if ( ($stereo_recording =~ /CUSTOMER|BOTH/i) && ($conf_engine eq "CONFBRIDGE") && ($SSstereo_recording > 0) ) + { + $stereo_rec_filename =~ s/CAMPAIGN/$log_campaign/gi; + $stereo_rec_filename =~ s/INGROUP/$channel_group/gi; + $stereo_rec_filename =~ s/CUSTPHONE/$phone_number/gi; + $stereo_rec_filename =~ s/FULLDATE/$recdate/gi; + $stereo_rec_filename =~ s/TINYDATE/$tinydate/gi; + $stereo_rec_filename =~ s/EPOCH/$now_date_epoch/gi; + $stereo_rec_filename =~ s/AGENT/$VDADuser/gi; + $stereo_rec_filename =~ s/VENDORLEADCODE/$vendor_lead_code/gi; + $stereo_rec_filename =~ s/LEADID/$insert_lead_id/gi; + $stereo_rec_filename =~ s/CALLID/$callerid/gi; + $stereo_rec_filename =~ s/\"|\'//gi; + + $PATHmonitorT = $PATHmonitorS; + if ( ($SSstereo_parallel_recording > 0) && ($stereo_parallel_recording =~ /CUSTOMER|FULL/) ) { + $PATHmonitorT = $PATHmonitorP; + + ### insert record into recording_log_parallel table ### + $stmtA = "INSERT INTO recording_log_parallel (channel,server_ip,extension,start_time,length_in_sec,filename,lead_id,user,vicidial_id,recording_status) values('$channel','$VDADserver_ip','','$now_date','0','PL$stereo_rec_filename','$insert_lead_id','$VDADuser','$insert_close_id','START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; $sthArows=$sthA->rows; - $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='01XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; if ($sthArows > 0) { @aryA = $sthA->fetchrow_array; - $recording_id = $aryA[0]; + $parallel_recording_id = $aryA[0]; } $sthA->finish(); - ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log) values('$recording_id','$VDADserver_ip','$now_date','0','$campaign_rec_filename','$insert_lead_id','$stereo_recording $channel_group','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|');"; - $SRaffected_rows = $dbhA->do($stmtA); - $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - if ($AGILOG) {$agi_string = "-- REMOTE STEREO RECORDING STARTED : |$retval|$SRaffected_rows|$recording_id|$stmtA|"; &agi_output;} + ### start the parallel recording + $retval_stop = $AGI->exec("StopMixMonitor",""); + $retval = $AGI->exec("MixMonitor",",r($PATHmonitorT/PL$stereo_rec_filename-out.wav)t($PATHmonitorT/PL$stereo_rec_filename-in.wav)"); + + if ($AGILOG) {$agi_string = "-- REMOTE PARALLEL STEREO STARTED: |$retval|$retval_stop|$SRaffected_rows|$parallel_recording_id|$stmtA|"; &agi_output;} + + if ($stereo_parallel_recording =~ /CUSTOMER-ONLY/) + { + $temp_parallel_rec_co_filename = "CO".$stereo_rec_filename; + if (length($parallel_rec_co_filename) > 0) + { + $temp_parallel_rec_co_filename = $parallel_rec_co_filename; + $temp_parallel_rec_co_filename =~ s/CAMPAIGN/$log_campaign/gi; + $temp_parallel_rec_co_filename =~ s/INGROUP/$channel_group/gi; + $temp_parallel_rec_co_filename =~ s/CUSTPHONE/$phone_number/gi; + $temp_parallel_rec_co_filename =~ s/FULLDATE/$recdate/gi; + $temp_parallel_rec_co_filename =~ s/TINYDATE/$tinydate/gi; + $temp_parallel_rec_co_filename =~ s/EPOCH/$now_date_epoch/gi; + $temp_parallel_rec_co_filename =~ s/AGENT/$VDADuser/gi; + $temp_parallel_rec_co_filename =~ s/VENDORLEADCODE/$vendor_lead_code/gi; + $temp_parallel_rec_co_filename =~ s/LEADID/$insert_lead_id/gi; + $temp_parallel_rec_co_filename =~ s/CALLID/$callerid/gi; + $temp_parallel_rec_co_filename =~ s/\"|\'//gi; + } + ### insert a record into the recording_log table + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPCOR','$now_date','$now_date_epoch','$temp_parallel_rec_co_filename','$insert_lead_id','$VDADuser','$insert_close_id')"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($temp_parallel_rec_co_filename =~ /RECID/) + { + $temp_parallel_rec_co_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$temp_parallel_rec_co_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + ### insert record into recording_log_stereo table ### + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_co_filename','$insert_lead_id','$channel_group STEREO_PARALLEL CUSTOMER-ONLY REMOTE $stereo_recording','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL CUSTOMER-ONLY REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_co_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + if ($AGILOG) {$agi_string = "-- REMOTE PARALLEL CO STEREO RECORDING LOG INSERT : |$SRaffected_rows|$recording_id|$parallel_recording_id|$rLIVEaffected_rows|$stmtA|"; &agi_output;} + } + + if ($stereo_parallel_recording =~ /CUSTOMER-MUTED/) + { + $temp_parallel_rec_cm_filename = "CM".$stereo_rec_filename; + if (length($parallel_rec_cm_filename) > 0) + { + $temp_parallel_rec_cm_filename = $parallel_rec_cm_filename; + $temp_parallel_rec_cm_filename =~ s/CAMPAIGN/$log_campaign/gi; + $temp_parallel_rec_cm_filename =~ s/INGROUP/$channel_group/gi; + $temp_parallel_rec_cm_filename =~ s/CUSTPHONE/$phone_number/gi; + $temp_parallel_rec_cm_filename =~ s/FULLDATE/$recdate/gi; + $temp_parallel_rec_cm_filename =~ s/TINYDATE/$tinydate/gi; + $temp_parallel_rec_cm_filename =~ s/EPOCH/$now_date_epoch/gi; + $temp_parallel_rec_cm_filename =~ s/AGENT/$VDADuser/gi; + $temp_parallel_rec_cm_filename =~ s/VENDORLEADCODE/$vendor_lead_code/gi; + $temp_parallel_rec_cm_filename =~ s/LEADID/$insert_lead_id/gi; + $temp_parallel_rec_cm_filename =~ s/CALLID/$callerid/gi; + $temp_parallel_rec_cm_filename =~ s/\"|\'//gi; + } + ### insert a record into the recording_log table + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPCMR','$now_date','$now_date_epoch','$temp_parallel_rec_cm_filename','$insert_lead_id','$VDADuser','$insert_close_id')"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($temp_parallel_rec_cm_filename =~ /RECID/) + { + $temp_parallel_rec_cm_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$temp_parallel_rec_cm_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + ### insert record into recording_log_stereo table ### + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_cm_filename','$insert_lead_id','$channel_group STEREO_PARALLEL CUSTOMER-MUTED REMOTE $stereo_recording','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL CUSTOMER-MUTED REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_cm_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + if ($AGILOG) {$agi_string = "-- REMOTE PARALLEL CM STEREO RECORDING LOG INSERT : |$SRaffected_rows|$recording_id|$parallel_recording_id|$rLIVEaffected_rows|$stmtA|"; &agi_output;} + } + + if ($stereo_parallel_recording =~ /FULL-RECORDING/) + { + $temp_parallel_rec_fr_filename = "FR".$stereo_rec_filename; + if (length($parallel_rec_fr_filename) > 0) + { + $temp_parallel_rec_fr_filename = $parallel_rec_fr_filename; + $temp_parallel_rec_fr_filename =~ s/CAMPAIGN/$log_campaign/gi; + $temp_parallel_rec_fr_filename =~ s/INGROUP/$channel_group/gi; + $temp_parallel_rec_fr_filename =~ s/CUSTPHONE/$phone_number/gi; + $temp_parallel_rec_fr_filename =~ s/FULLDATE/$recdate/gi; + $temp_parallel_rec_fr_filename =~ s/TINYDATE/$tinydate/gi; + $temp_parallel_rec_fr_filename =~ s/EPOCH/$now_date_epoch/gi; + $temp_parallel_rec_fr_filename =~ s/AGENT/$VDADuser/gi; + $temp_parallel_rec_fr_filename =~ s/VENDORLEADCODE/$vendor_lead_code/gi; + $temp_parallel_rec_fr_filename =~ s/LEADID/$insert_lead_id/gi; + $temp_parallel_rec_fr_filename =~ s/CALLID/$callerid/gi; + $temp_parallel_rec_fr_filename =~ s/\"|\'//gi; + } + ### insert a record into the recording_log table + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPFRR','$now_date','$now_date_epoch','$temp_parallel_rec_fr_filename','$insert_lead_id','$VDADuser','$insert_close_id')"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($temp_parallel_rec_fr_filename =~ /RECID/) + { + $temp_parallel_rec_fr_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$temp_parallel_rec_fr_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + ### insert record into recording_log_stereo table ### + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_fr_filename','$insert_lead_id','$channel_group STEREO_PARALLEL FULL-RECORDING REMOTE $stereo_recording','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL FULL-RECORDING REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_fr_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + if ($AGILOG) {$agi_string = "-- REMOTE PARALLEL FR STEREO RECORDING LOG INSERT : |$SRaffected_rows|$recording_id|$parallel_recording_id|$rLIVEaffected_rows|$stmtA|"; &agi_output;} + } + + # insert logs for agent-controlled stereo call recordings while parallel recordings are enabled + if ($stereo_recording_agent =~ /ALLCALLS|ALLFORCE/) + { + $temp_parallel_rec_ag_filename = $stereo_rec_filename; + ### insert a record into the recording_log table + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPACR','$now_date','$now_date_epoch','$temp_parallel_rec_ag_filename','$insert_lead_id','$VDADuser','$insert_close_id')"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($temp_parallel_rec_ag_filename =~ /RECID/) + { + $temp_parallel_rec_ag_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$temp_parallel_rec_ag_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + ### insert record into recording_log_stereo table ### + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_ag_filename','$insert_lead_id','$channel_group STEREO_PARALLEL AGENT-CONTROLLED REMOTE $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL AGENT-CONTROLLED REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_ag_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + if ($AGILOG) {$agi_string = "-- REMOTE PARALLEL AG STEREO RECORDING LOG INSERT : |$SRaffected_rows|$recording_id|$parallel_recording_id|$affected_rowsB|$rLIVEaffected_rows|$stmtA|"; &agi_output;} + } + } + else + { + ## Start NON-parallel stereo call recording ## + if ($stereo_recording_agent =~ /ALLCALLS|ALLFORCE/) + { + # insert a record into the recording_log table + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SACR','$now_date','$now_date_epoch','$stereo_rec_filename','$insert_lead_id','$VDADuser','$insert_close_id')"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($stereo_rec_filename =~ /RECID/) + { + $stereo_rec_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$stereo_rec_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + $retval_stop = $AGI->exec("StopMixMonitor",""); + $retval = $AGI->exec("MixMonitor",",r($PATHmonitorT/$stereo_rec_filename-out.wav)t($PATHmonitorT/$stereo_rec_filename-in.wav)"); + + ### insert record into recording_log_stereo table ### + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$stereo_rec_filename','$insert_lead_id','$channel_group STEREO AGENT-CONTROLLED REMOTE RIR $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|','STEREO START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO AGENT-CONTROLLED REMOTE','$VARserver_ip','$now_date','$channel','$stereo_rec_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + $mLIVEaffected_rows=0; + if ($stereo_recording =~ /CUSTOMER_ONLY/i) + { + $vmgr_callerid = substr($stereo_rec_filename, 0, 16) . 'M...'; + $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VDADserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: write','State: 1','','','','','','');"; + $mLIVEaffected_rows = $dbhA->do($stmtE); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$mLIVEaffected_rows; &mysql_error_logging; + } + if ($stereo_recording =~ /CUSTOMER_MUTE/i) + { + $vmgr_callerid = substr($stereo_rec_filename, 0, 16) . 'M...'; + $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VDADserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: read','State: 1','','','','','','');"; + $mLIVEaffected_rows = $dbhA->do($stmtE); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$mLIVEaffected_rows; &mysql_error_logging; + } + + if ($AGILOG) {$agi_string = "-- REMOTE AGENT STEREO RECORDING STARTED : |$retval|$retval_stop|$SRaffected_rows|$recording_id|$affected_rowsB|$rLIVEaffected_rows|$mLIVEaffected_rows|$stmtA|"; &agi_output;} + } } } } diff --git a/agi/agi-VDAD_ALL_outbound.agi b/agi/agi-VDAD_ALL_outbound.agi index a46c80f2f..1402190a4 100644 --- a/agi/agi-VDAD_ALL_outbound.agi +++ b/agi/agi-VDAD_ALL_outbound.agi @@ -45,7 +45,7 @@ #exten => 8366,4,AGI(agi-VDAD_ALL_outbound.agi,SURVEY-----LB-----US_pol_survey_hello-----1238-----8-----US_pol_survey_transfer-----US_thanks_no_contact-----OPTOUT-----DNC) #exten => 8366,5,Hangup # -# Copyright (C) 2024 Matt Florell LICENSE: AGPLv2 +# Copyright (C) 2025 Matt Florell LICENSE: AGPLv2 # # changes: # 80218-2027 - First Build @@ -132,6 +132,7 @@ # 240906-1021 - Added testing for stereo_recording campaign option *NOT PRODUCTION READY* # 241001-2222 - Fixes for Khomp call processing # 241020-1928 - Added khomp campaign settings options +# 250827-1556 - Added stereo_recording code # $script = 'agi-VDAD_ALL_outbound.agi'; @@ -275,6 +276,11 @@ if (!$PRSTESTfile) {$PRSTESTfile = "$PATHlogs/prstest.$year-$mon-$mday";} if (!$ERRLOGfile) {$ERRLOGfile = "$PATHlogs/MySQLerror.$year-$mon-$mday";} if (!$CEPLOGfile) {$CEPLOGfile = "$PATHlogs/Cepstral.$year-$mon-$mday";} +# generate paths to asterisk stereo recordings directories: +$PATHmonitorS = $PATHmonitor."S"; +$PATHmonitorP = $PATHmonitor."P"; +$PATHmonitorTRASH = $PATHmonitor."TRASH"; + use DBI; use Asterisk::AGI; $AGI = new Asterisk::AGI; @@ -284,7 +290,7 @@ $dbhA = DBI->connect("DBI:mysql:$VARDB_database:$VARDB_server:$VARDB_port", "$VA ############################################# ##### Gather system_settings ##### -$stmtA = "SELECT sip_event_logging,call_quota_lead_ranking,agent_search_method,abandon_check_queue FROM system_settings;"; +$stmtA = "SELECT sip_event_logging,call_quota_lead_ranking,agent_search_method,abandon_check_queue,stereo_recording,stereo_parallel_recording FROM system_settings;"; $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; $sthArows=$sthA->rows; @@ -295,6 +301,8 @@ if ($sthArows > 0) $SScall_quota_lead_ranking = $aryA[1]; $SSagent_search_method = $aryA[2]; $SSabandon_check_queue = $aryA[3]; + $SSstereo_recording = $aryA[4]; + $SSstereo_parallel_recording = $aryA[5]; } $sthA->finish(); ########################################### @@ -828,7 +836,7 @@ if ($VDACaffected_rows > 0) ##### END - Max call stats ### Grab campaign values from the database - $stmtA = "SELECT drop_call_seconds,drop_action,safe_harbor_exten,concurrent_transfers,next_agent_call,voicemail_ext,drop_inbound_group,use_internal_dnc,use_campaign_dnc,cpd_amd_action,am_message_exten,three_way_call_cid,campaign_cid,survey_first_audio_file,survey_opt_in_audio_file,survey_ni_audio_file,survey_third_audio_file,survey_fourth_audio_file,extension_appended_cidname,queue_priority,closer_campaigns,queuemetrics_phone_environment,campaign_recording,campaign_rec_filename,safe_harbor_audio,safe_harbor_menu_id,survey_recording,safe_harbor_audio_field,use_other_campaign_dnc,cpd_unknown_action,routing_initiated_recordings,campaign_rec_exten,call_quota_lead_ranking,sip_event_logging,amd_type,agent_search_method,dial_method,stereo_recording,khomp_settings_container FROM vicidial_campaigns where campaign_id = '$VDADcampaign';"; + $stmtA = "SELECT drop_call_seconds,drop_action,safe_harbor_exten,concurrent_transfers,next_agent_call,voicemail_ext,drop_inbound_group,use_internal_dnc,use_campaign_dnc,cpd_amd_action,am_message_exten,three_way_call_cid,campaign_cid,survey_first_audio_file,survey_opt_in_audio_file,survey_ni_audio_file,survey_third_audio_file,survey_fourth_audio_file,extension_appended_cidname,queue_priority,closer_campaigns,queuemetrics_phone_environment,campaign_recording,campaign_rec_filename,safe_harbor_audio,safe_harbor_menu_id,survey_recording,safe_harbor_audio_field,use_other_campaign_dnc,cpd_unknown_action,routing_initiated_recordings,campaign_rec_exten,call_quota_lead_ranking,sip_event_logging,amd_type,agent_search_method,dial_method,stereo_recording,khomp_settings_container,stereo_recording_agent,stereo_rec_filename,stereo_parallel_recording,parallel_rec_co_filename,parallel_rec_cm_filename,parallel_rec_fr_filename FROM vicidial_campaigns where campaign_id = '$VDADcampaign';"; $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; $sthArows=$sthA->rows; @@ -878,6 +886,13 @@ if ($VDACaffected_rows > 0) $campaign_dial_method = $aryA[36]; $stereo_recording = $aryA[37]; $khomp_settings_container = $aryA[38]; + $stereo_recording_agent = $aryA[39]; + $stereo_rec_filename = $aryA[40]; + $stereo_parallel_recording = $aryA[41]; + $parallel_rec_co_filename = $aryA[42]; + $parallel_rec_cm_filename = $aryA[43]; + $parallel_rec_fr_filename = $aryA[44]; + if (length($closer_campaigns) > 2) { $closer_campaigns =~ s/^ | -$//gi; @@ -1193,18 +1208,43 @@ if ($VDACaffected_rows > 0) %ast_ver_str = parse_asterisk_version($asterisk_version); if (( $ast_ver_str{major} = 1 ) && ($ast_ver_str{minor} < 6)) { - $AGI->exec("Monitor wav|/var/spool/asterisk/monitor/MIX/$campaign_rec_filename"); + $AGI->exec("Monitor wav|$PATHmonitor/MIX/$campaign_rec_filename"); } else { - $AGI->exec("Monitor","wav,/var/spool/asterisk/monitor/MIX/$campaign_rec_filename"); + $AGI->exec("Monitor","wav,$PATHmonitor/MIX/$campaign_rec_filename"); } ### insert record into recording_log table ### $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,length_in_sec,filename,lead_id,user,location,vicidial_id) values('$channel','$VARserver_ip','$VDADphone','$now_date','$now_date_epoch','0','$campaign_rec_filename','$CIDlead_id','VDAD','$campaign_rec_filename','$uniqueid');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01078'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - if ($AGILOG) {$agi_string = "-- SURVEY RECORDING STARTED : |$SRaffected_rows|$campaign_rec_filename|$stmtA|"; &agi_output;} + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($campaign_rec_filename =~ /RECID/) + { + $campaign_rec_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$campaign_rec_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02214'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','MONO_LEGACY_SURVEY','$VARserver_ip','$now_date','$channel','$campaign_rec_filename','$CIDlead_id','VDAD','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + if ($AGILOG) {$agi_string = "-- SURVEY RECORDING STARTED : |$SRaffected_rows|$campaign_rec_filename|$rLIVEaffected_rows|$stmtA|"; &agi_output;} } @@ -3174,20 +3214,21 @@ while ($drop_timer <= $DROP_TIME) $campaign_rec_filename =~ s/CALLID/$callerid/gi; $campaign_rec_filename =~ s/\"|\'//gi; - if ( ($stereo_recording =~ /CUSTOMER/i) && ($conf_engine eq "CONFBRIDGE") ) + if ( ($stereo_recording =~ /CUSTOMER|BOTH/i) && ($conf_engine eq "CONFBRIDGE") && ($SSstereo_recording > 0) ) { - $retval = $AGI->exec("MixMonitor",",r(/var/spool/asterisk/monitorS/$campaign_rec_filename-in.wav)t(/var/spool/asterisk/monitorS/$campaign_rec_filename-out.wav)"); + # do nothing can't record more than 1 stream on the same channel, stereo call recording processing is right below this section + # $retval = $AGI->exec("MixMonitor",",r($PATHmonitorS/$campaign_rec_filename-in.wav)t($PATHmonitorS/$campaign_rec_filename-out.wav)"); } else { %ast_ver_str = parse_asterisk_version($asterisk_version); if (( $ast_ver_str{major} = 1 ) && ($ast_ver_str{minor} < 6)) { - $retval = $AGI->exec("Monitor wav|/var/spool/asterisk/monitor/MIX/$campaign_rec_filename"); + $retval = $AGI->exec("Monitor wav|$PATHmonitor/MIX/$campaign_rec_filename"); } else { - $retval = $AGI->exec("Monitor","wav,/var/spool/asterisk/monitor/MIX/$campaign_rec_filename"); + $retval = $AGI->exec("Monitor","wav,$PATHmonitor/MIX/$campaign_rec_filename"); } } @@ -3196,28 +3237,346 @@ while ($drop_timer <= $DROP_TIME) $RLRAaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01074'; $MEL_aff_rows=$RLRAaffected_rows; &mysql_error_logging; if ($AGILOG) {$agi_string = "-- REMOTE RECORDING STARTED : |$retval|$RLRAaffected_rows|$campaign_rec_filename|$stmtA|"; &agi_output;} + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($campaign_rec_filename =~ /RECID/) + { + $campaign_rec_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$campaign_rec_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02214'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } - if ( ($stereo_recording =~ /CUSTOMER/i) && ($conf_engine eq "CONFBRIDGE") ) + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','MONO_LEGACY_REMOTE','$VARserver_ip','$now_date','$channel','$campaign_rec_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + if ($AGILOG) {$agi_string = "-- REMOTE RECORDING STARTED : |$RLRAaffected_rows|$campaign_rec_filename|$rLIVEaffected_rows|$stmtA|"; &agi_output;} + } + ### stereo recording stuff goes here for remote agents + + ### BEGIN stereo call recording for ALLCALLS/ALLFORCE and for all parallel stereo recording campaigns for remote agents ### + if ( ($stereo_recording =~ /CUSTOMER|BOTH/i) && ($conf_engine eq "CONFBRIDGE") && ($SSstereo_recording > 0) ) + { + $stereo_rec_filename =~ s/CAMPAIGN/$VDADcampaign/gi; + $stereo_rec_filename =~ s/INGROUP/$VDADcampaign/gi; + $stereo_rec_filename =~ s/CUSTPHONE/$VDADphone/gi; + $stereo_rec_filename =~ s/FULLDATE/$recdate/gi; + $stereo_rec_filename =~ s/TINYDATE/$tinydate/gi; + $stereo_rec_filename =~ s/EPOCH/$now_date_epoch/gi; + $stereo_rec_filename =~ s/AGENT/$VDADuser/gi; + $stereo_rec_filename =~ s/VENDORLEADCODE/$vendor_lead_code/gi; + $stereo_rec_filename =~ s/LEADID/$CIDlead_id/gi; + $stereo_rec_filename =~ s/CALLID/$callerid/gi; + $stereo_rec_filename =~ s/\"|\'//gi; + + $PATHmonitorT = $PATHmonitorS; + if ( ($SSstereo_parallel_recording > 0) && ($stereo_parallel_recording =~ /CUSTOMER|FULL/) ) { + $PATHmonitorT = $PATHmonitorP; + + ### insert record into recording_log_parallel table ### + $stmtA = "INSERT INTO recording_log_parallel (channel,server_ip,extension,start_time,length_in_sec,filename,lead_id,user,vicidial_id,recording_status) values('$channel','$VDADserver_ip','','$now_date','0','PL$stereo_rec_filename','$CIDlead_id','$VDADuser','$uniqueid','START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; $sthArows=$sthA->rows; - $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='01XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; if ($sthArows > 0) { @aryA = $sthA->fetchrow_array; - $recording_id = $aryA[0]; + $parallel_recording_id = $aryA[0]; } $sthA->finish(); - ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log) values('$recording_id','$VARserver_ip','$now_date','0','$campaign_rec_filename','$CIDlead_id','$stereo_recording $VDADcampaign','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|');"; - $SRaffected_rows = $dbhA->do($stmtA); - $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - if ($AGILOG) {$agi_string = "-- REMOTE STEREO RECORDING STARTED : |$retval|$SRaffected_rows|$recording_id|$stmtA|"; &agi_output;} + ### start the parallel recording + $retval_stop = $AGI->exec("StopMixMonitor",""); + $retval = $AGI->exec("MixMonitor",",r($PATHmonitorT/PL$stereo_rec_filename-out.wav)t($PATHmonitorT/PL$stereo_rec_filename-in.wav)"); + + if ($AGILOG) {$agi_string = "-- REMOTE PARALLEL STEREO STARTED: |$retval|$retval_stop|$SRaffected_rows|$parallel_recording_id|$stmtA|"; &agi_output;} + + if ($stereo_parallel_recording =~ /CUSTOMER-ONLY/) + { + $temp_parallel_rec_co_filename = "CO".$stereo_rec_filename; + if (length($parallel_rec_co_filename) > 0) + { + $temp_parallel_rec_co_filename = $parallel_rec_co_filename; + $temp_parallel_rec_co_filename =~ s/CAMPAIGN/$VDADcampaign/gi; + $temp_parallel_rec_co_filename =~ s/INGROUP/$VDADcampaign/gi; + $temp_parallel_rec_co_filename =~ s/CUSTPHONE/$VDADphone/gi; + $temp_parallel_rec_co_filename =~ s/FULLDATE/$recdate/gi; + $temp_parallel_rec_co_filename =~ s/TINYDATE/$tinydate/gi; + $temp_parallel_rec_co_filename =~ s/EPOCH/$now_date_epoch/gi; + $temp_parallel_rec_co_filename =~ s/AGENT/$VDADuser/gi; + $temp_parallel_rec_co_filename =~ s/VENDORLEADCODE/$vendor_lead_code/gi; + $temp_parallel_rec_co_filename =~ s/LEADID/$CIDlead_id/gi; + $temp_parallel_rec_co_filename =~ s/CALLID/$callerid/gi; + $temp_parallel_rec_co_filename =~ s/\"|\'//gi; + } + ### insert a record into the recording_log table + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPCOR','$now_date','$now_date_epoch','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($temp_parallel_rec_co_filename =~ /RECID/) + { + $temp_parallel_rec_co_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$temp_parallel_rec_co_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + ### insert record into recording_log_stereo table ### + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL CUSTOMER-ONLY REMOTE $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL CUSTOMER-ONLY REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + if ($AGILOG) {$agi_string = "-- REMOTE PARALLEL CO STEREO RECORDING LOG INSERT : |$SRaffected_rows|$recording_id|$parallel_recording_id|$rLIVEaffected_rows|$stmtA|"; &agi_output;} + } + + if ($stereo_parallel_recording =~ /CUSTOMER-MUTED/) + { + $temp_parallel_rec_cm_filename = "CM".$stereo_rec_filename; + if (length($parallel_rec_cm_filename) > 0) + { + $temp_parallel_rec_cm_filename = $parallel_rec_cm_filename; + $temp_parallel_rec_cm_filename =~ s/CAMPAIGN/$VDADcampaign/gi; + $temp_parallel_rec_cm_filename =~ s/INGROUP/$VDADcampaign/gi; + $temp_parallel_rec_cm_filename =~ s/CUSTPHONE/$VDADphone/gi; + $temp_parallel_rec_cm_filename =~ s/FULLDATE/$recdate/gi; + $temp_parallel_rec_cm_filename =~ s/TINYDATE/$tinydate/gi; + $temp_parallel_rec_cm_filename =~ s/EPOCH/$now_date_epoch/gi; + $temp_parallel_rec_cm_filename =~ s/AGENT/$VDADuser/gi; + $temp_parallel_rec_cm_filename =~ s/VENDORLEADCODE/$vendor_lead_code/gi; + $temp_parallel_rec_cm_filename =~ s/LEADID/$CIDlead_id/gi; + $temp_parallel_rec_cm_filename =~ s/CALLID/$callerid/gi; + $temp_parallel_rec_cm_filename =~ s/\"|\'//gi; + } + ### insert a record into the recording_log table + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPCMR','$now_date','$now_date_epoch','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($temp_parallel_rec_cm_filename =~ /RECID/) + { + $temp_parallel_rec_cm_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$temp_parallel_rec_cm_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + ### insert record into recording_log_stereo table ### + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL CUSTOMER-MUTED REMOTE $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL CUSTOMER-MUTED REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + if ($AGILOG) {$agi_string = "-- REMOTE PARALLEL CM STEREO RECORDING LOG INSERT : |$SRaffected_rows|$recording_id|$parallel_recording_id|$rLIVEaffected_rows|$stmtA|"; &agi_output;} + } + + if ($stereo_parallel_recording =~ /FULL-RECORDING/) + { + $temp_parallel_rec_fr_filename = "FR".$stereo_rec_filename; + if (length($parallel_rec_fr_filename) > 0) + { + $temp_parallel_rec_fr_filename = $parallel_rec_fr_filename; + $temp_parallel_rec_fr_filename =~ s/CAMPAIGN/$VDADcampaign/gi; + $temp_parallel_rec_fr_filename =~ s/INGROUP/$VDADcampaign/gi; + $temp_parallel_rec_fr_filename =~ s/CUSTPHONE/$VDADphone/gi; + $temp_parallel_rec_fr_filename =~ s/FULLDATE/$recdate/gi; + $temp_parallel_rec_fr_filename =~ s/TINYDATE/$tinydate/gi; + $temp_parallel_rec_fr_filename =~ s/EPOCH/$now_date_epoch/gi; + $temp_parallel_rec_fr_filename =~ s/AGENT/$VDADuser/gi; + $temp_parallel_rec_fr_filename =~ s/VENDORLEADCODE/$vendor_lead_code/gi; + $temp_parallel_rec_fr_filename =~ s/LEADID/$CIDlead_id/gi; + $temp_parallel_rec_fr_filename =~ s/CALLID/$callerid/gi; + $temp_parallel_rec_fr_filename =~ s/\"|\'//gi; + } + ### insert a record into the recording_log table + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPFRR','$now_date','$now_date_epoch','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($temp_parallel_rec_fr_filename =~ /RECID/) + { + $temp_parallel_rec_fr_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$temp_parallel_rec_fr_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + ### insert record into recording_log_stereo table ### + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL FULL-RECORDING REMOTE $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL FULL-RECORDING REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + if ($AGILOG) {$agi_string = "-- REMOTE PARALLEL FR STEREO RECORDING LOG INSERT : |$SRaffected_rows|$recording_id|$parallel_recording_id|$rLIVEaffected_rows|$stmtA|"; &agi_output;} + } + + # insert logs for agent-controlled stereo call recordings while parallel recordings are enabled + if ($stereo_recording_agent =~ /ALLCALLS|ALLFORCE/) + { + $temp_parallel_rec_ag_filename = $stereo_rec_filename; + ### insert a record into the recording_log table + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPACR','$now_date','$now_date_epoch','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($temp_parallel_rec_ag_filename =~ /RECID/) + { + $temp_parallel_rec_ag_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$temp_parallel_rec_ag_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + ### insert record into recording_log_stereo table ### + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL AGENT-CONTROLLED REMOTE $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL AGENT-CONTROLLED REMOTE','$VARserver_ip','$now_date','$channel','$stereo_recording_agent','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + if ($AGILOG) {$agi_string = "-- REMOTE PARALLEL AG STEREO RECORDING LOG INSERT : |$SRaffected_rows|$recording_id|$parallel_recording_id|$rLIVEaffected_rows|$stmtA|"; &agi_output;} + } + } + else + { + ## Start NON-parallel stereo call recording ## + if ($stereo_recording_agent =~ /ALLCALLS|ALLFORCE/) + { + # insert a record into the recording_log table + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SACR','$now_date','$now_date_epoch','$stereo_rec_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($stereo_rec_filename =~ /RECID/) + { + $stereo_rec_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$stereo_rec_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + $retval_stop = $AGI->exec("StopMixMonitor",""); + $retval = $AGI->exec("MixMonitor",",r($PATHmonitorT/$stereo_rec_filename-out.wav)t($PATHmonitorT/$stereo_rec_filename-in.wav)"); + + ### insert record into recording_log_stereo table ### + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$stereo_rec_filename','$CIDlead_id','$VDADcampaign STEREO AGENT-CONTROLLED REMOTE $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','STEREO START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO AGENT-CONTROLLED REMOTE','$VARserver_ip','$now_date','$channel','$stereo_rec_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + $mLIVEaffected_rows=0; + if ($stereo_recording =~ /CUSTOMER_ONLY/i) + { + $vmgr_callerid = substr($stereo_rec_filename, 0, 16) . 'M...'; + $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VDADserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: write','State: 1','','','','','','');"; + $mLIVEaffected_rows = $dbhA->do($stmtE); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$mLIVEaffected_rows; &mysql_error_logging; + } + if ($stereo_recording =~ /CUSTOMER_MUTE/i) + { + $vmgr_callerid = substr($stereo_rec_filename, 0, 16) . 'M...'; + $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VDADserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: read','State: 1','','','','','','');"; + $mLIVEaffected_rows = $dbhA->do($stmtE); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$mLIVEaffected_rows; &mysql_error_logging; + } + + if ($AGILOG) {$agi_string = "-- REMOTE AGENT STEREO RECORDING STARTED : |$retval|$retval_stop|$SRaffected_rows|$recording_id|$rLIVEaffected_rows|$mLIVEaffected_rows|$stmtA|"; &agi_output;} + } } } + ### END stereo call recording for ALLCALLS/ALLFORCE and for all parallel stereo recording campaigns for Remote Agents ### } ### END REMOTE AGENT SECTION else @@ -3315,17 +3674,6 @@ while ($drop_timer <= $DROP_TIME) $dbhP=$dbhA; $mysql_count='02125'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; } - if ( ($stereo_recording =~ /CUSTOMER/i) && ($conf_engine eq "CONFBRIDGE") ) - { - $retval = $AGI->exec("MixMonitor",",r(/var/spool/asterisk/monitorS/$campaign_rec_filename-in.wav)t(/var/spool/asterisk/monitorS/$campaign_rec_filename-out.wav)"); - - ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log) values('$recording_id','$VARserver_ip','$now_date','0','$campaign_rec_filename','$CIDlead_id','$stereo_recording $VDADcampaign','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|');"; - $SRaffected_rows = $dbhA->do($stmtA); - $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - if ($AGILOG) {$agi_string = "-- REMOTE STEREO RECORDING STARTED : |$retval|$SRaffected_rows|$recording_id|$stmtA|"; &agi_output;} - } - $vmgr_callerid = substr($campaign_rec_filename, 0, 17) . '...'; $stmtA="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VDADserver_ip','','Originate','$vmgr_callerid','Channel: $channelrec','Context: $ext_context','Exten: $campaign_rec_exten','Priority: 1','Callerid: $campaign_rec_filename','','','','','');"; $affected_rows = $dbhA->do($stmtA); @@ -3339,80 +3687,406 @@ while ($drop_timer <= $DROP_TIME) $affected_rowsC = $dbhA->do($stmtC); $dbhP=$dbhA; $mysql_count='02128'; $MEL_aff_rows=$affected_rowsC; &mysql_error_logging; - if ($AGILOG) {$agi_string = "-- ROUTING INITIATED RECORDING STARTED : |$affected_rows|$recording_id|$campaign_rec_filename|$stmtA| |$affected_rowsB|$stmtB| |$affected_rowsC|$stmtC|"; &agi_output;} + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','MONO_LEGACY_RIR','$VARserver_ip','$now_date','$channel','$campaign_rec_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + if ($AGILOG) {$agi_string = "-- ROUTING INITIATED RECORDING STARTED : |$affected_rows|$recording_id|$campaign_rec_filename|$rLIVEaffected_rows|$stmtA| |$affected_rowsB|$stmtB| |$affected_rowsC|$stmtC|"; &agi_output;} } ### END routing-initiated agent call recording for ALLCALLS/ALLFORCE ### } - if ($extension_appended_cidname =~ /Y|USER/) + + + ### BEGIN stereo call recording for ALLCALLS/ALLFORCE and for all parallel stereo recording campaigns ### + if ( ($stereo_recording =~ /CUSTOMER|BOTH/i) && ($conf_engine eq "CONFBRIDGE") && ($SSstereo_recording > 0) ) { - $eac_extension=''; - $stmtA = "SELECT extension,campaign_id FROM vicidial_live_agents where user='$VDADuser' order by last_call_time limit 1;"; - if ($AGILOG) {$agi_string = "|$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='01068'; $MEL_aff_rows=$sthArows; &mysql_error_logging; - if ($sthArows > 0) + $stereo_rec_filename =~ s/CAMPAIGN/$VDADcampaign/gi; + $stereo_rec_filename =~ s/INGROUP/$VDADcampaign/gi; + $stereo_rec_filename =~ s/CUSTPHONE/$VDADphone/gi; + $stereo_rec_filename =~ s/FULLDATE/$recdate/gi; + $stereo_rec_filename =~ s/TINYDATE/$tinydate/gi; + $stereo_rec_filename =~ s/EPOCH/$now_date_epoch/gi; + $stereo_rec_filename =~ s/AGENT/$VDADuser/gi; + $stereo_rec_filename =~ s/VENDORLEADCODE/$vendor_lead_code/gi; + $stereo_rec_filename =~ s/LEADID/$CIDlead_id/gi; + $stereo_rec_filename =~ s/CALLID/$callerid/gi; + $stereo_rec_filename =~ s/\"|\'//gi; + + $PATHmonitorT = $PATHmonitorS; + if ( ($SSstereo_parallel_recording > 0) && ($stereo_parallel_recording =~ /CUSTOMER|FULL/) ) { - @aryA = $sthA->fetchrow_array; - if ($extension_appended_cidname =~ /USER/) + $PATHmonitorT = $PATHmonitorP; + + ### insert record into recording_log_parallel table ### + $stmtA = "INSERT INTO recording_log_parallel (channel,server_ip,extension,start_time,length_in_sec,filename,lead_id,user,vicidial_id,recording_status) values('$channel','$VDADserver_ip','','$now_date','0','PL$stereo_rec_filename','$CIDlead_id','$VDADuser','$uniqueid','START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) { - $eac_extension = $VDADuser; + @aryA = $sthA->fetchrow_array; + $parallel_recording_id = $aryA[0]; } - else + $sthA->finish(); + + ### start the parallel recording + $retval_stop = $AGI->exec("StopMixMonitor",""); + $retval = $AGI->exec("MixMonitor",",r($PATHmonitorT/PL$stereo_rec_filename-out.wav)t($PATHmonitorT/PL$stereo_rec_filename-in.wav)"); + + if ($AGILOG) {$agi_string = "-- PARALLEL STEREO STARTED: |$retval|$retval_stop|$SRaffected_rows|$parallel_recording_id|$stmtA|"; &agi_output;} + + if ($stereo_parallel_recording =~ /CUSTOMER-ONLY/) { - $eac_extension = $aryA[0]; - $eac_extension =~ s/SIP\/|IAX2\/|Zap\/|DAHDI\/|Local\///gi; - } - if ($extension_appended_cidname =~ /WITH_CAMPAIGN/) - {$eac_extension .= " $aryA[1]";} - } - $sthA->finish(); - - $newcallerid = "\"$callerid $eac_extension <$VDADphone>\""; - $AGI->set_callerid($newcallerid); - } - else - { - $newcallerid = "\"$callerid <$VDADphone>\""; - $AGI->set_callerid($newcallerid); - } - } + $temp_parallel_rec_co_filename = "CO".$stereo_rec_filename; + if (length($parallel_rec_co_filename) > 0) + { + $temp_parallel_rec_co_filename = $parallel_rec_co_filename; + $temp_parallel_rec_co_filename =~ s/CAMPAIGN/$VDADcampaign/gi; + $temp_parallel_rec_co_filename =~ s/INGROUP/$VDADcampaign/gi; + $temp_parallel_rec_co_filename =~ s/CUSTPHONE/$VDADphone/gi; + $temp_parallel_rec_co_filename =~ s/FULLDATE/$recdate/gi; + $temp_parallel_rec_co_filename =~ s/TINYDATE/$tinydate/gi; + $temp_parallel_rec_co_filename =~ s/EPOCH/$now_date_epoch/gi; + $temp_parallel_rec_co_filename =~ s/AGENT/$VDADuser/gi; + $temp_parallel_rec_co_filename =~ s/VENDORLEADCODE/$vendor_lead_code/gi; + $temp_parallel_rec_co_filename =~ s/LEADID/$CIDlead_id/gi; + $temp_parallel_rec_co_filename =~ s/CALLID/$callerid/gi; + $temp_parallel_rec_co_filename =~ s/\"|\'//gi; + } + ### insert a record into the recording_log table + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPCO','$now_date','$now_date_epoch','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); - $stmtA = "UPDATE vicidial_auto_calls set status='XFER', stage='XFER-$drop_timer', extension='$VDADconf_exten' where callerid='$callerid';"; - $affected_rows = $dbhA->do($stmtA); - $dbhP=$dbhA; $mysql_count='01038'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; - if ($AGILOG) {$agi_string = "-- VDAD XFER : |$affected_rows|update of vac table: $callerid\n|$stmtA|"; &agi_output;} + if ($temp_parallel_rec_co_filename =~ /RECID/) + { + $temp_parallel_rec_co_filename =~ s/RECID/$recording_id/gi; - if ($SSabandon_check_queue > 0) - { - ### check for ACTIVE vicidial_abandon_check_queue records and set to CONNECTED if they exist - $stmtA = "UPDATE vicidial_abandon_check_queue SET check_status='CONNECTED' where lead_id = '$CIDlead_id' and check_status IN('NEW','QUEUE','PROCESSING') and abandon_time > \"$timeTWENTYFOURhoursAGO\" order by abandon_time desc limit 1;"; - $affected_rows = $dbhA->do($stmtA); - $dbhP=$dbhA; $mysql_count='02068'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; - if ($AGILOG) {$agi_string = "-- VACQ connected 1: |$CIDlead_id|$affected_rows|$stmtA"; &agi_output;} + $stmtA = "UPDATE recording_log SET filename='$temp_parallel_rec_co_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } - if ($affected_rows < 1) - { - ### check for INACTIVE vicidial_abandon_check_queue records and set to CONNECTED if they exist - $stmtA = "UPDATE vicidial_abandon_check_queue SET check_status='CONNECTED' where lead_id = '$CIDlead_id' and check_status IN('COMPLETE','REJECT','CONNECTED') and abandon_time > \"$timeTWENTYFOURhoursAGO\" order by abandon_time desc limit 1;"; - $affected_rows = $dbhA->do($stmtA); - $dbhP=$dbhA; $mysql_count='02068'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; - if ($AGILOG) {$agi_string = "-- VACQ connected 2: |$CIDlead_id|$affected_rows|$stmtA"; &agi_output;} - } - } + ### insert record into recording_log_stereo table ### + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL CUSTOMER-ONLY $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - if ($enable_queuemetrics_logging > 0) - { - $dbhB = DBI->connect("DBI:mysql:$queuemetrics_dbname:$queuemetrics_server_ip:3306", "$queuemetrics_login", "$queuemetrics_pass") - or die "Couldn't connect to database: " . DBI->errstr; + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL CUSTOMER-ONLY','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; - if ($DBX) {print "CONNECTED TO DATABASE: $queuemetrics_server_ip|$queuemetrics_dbname\n";} + if ($AGILOG) {$agi_string = "-- PARALLEL CO STEREO RECORDING LOG INSERT : |$SRaffected_rows|$recording_id|$parallel_recording_id|$rLIVEaffected_rows|$stmtA|"; &agi_output;} + } - $pe_append=''; - if ( ($queuemetrics_pe_phone_append > 0) && (length($queuemetrics_phone_environment)>0) ) - { - @qm_extension = split(/\//,$VDADextension); + if ($stereo_parallel_recording =~ /CUSTOMER-MUTED/) + { + $temp_parallel_rec_cm_filename = "CM".$stereo_rec_filename; + if (length($parallel_rec_cm_filename) > 0) + { + $temp_parallel_rec_cm_filename = $parallel_rec_cm_filename; + $temp_parallel_rec_cm_filename =~ s/CAMPAIGN/$VDADcampaign/gi; + $temp_parallel_rec_cm_filename =~ s/INGROUP/$VDADcampaign/gi; + $temp_parallel_rec_cm_filename =~ s/CUSTPHONE/$VDADphone/gi; + $temp_parallel_rec_cm_filename =~ s/FULLDATE/$recdate/gi; + $temp_parallel_rec_cm_filename =~ s/TINYDATE/$tinydate/gi; + $temp_parallel_rec_cm_filename =~ s/EPOCH/$now_date_epoch/gi; + $temp_parallel_rec_cm_filename =~ s/AGENT/$VDADuser/gi; + $temp_parallel_rec_cm_filename =~ s/VENDORLEADCODE/$vendor_lead_code/gi; + $temp_parallel_rec_cm_filename =~ s/LEADID/$CIDlead_id/gi; + $temp_parallel_rec_cm_filename =~ s/CALLID/$callerid/gi; + $temp_parallel_rec_cm_filename =~ s/\"|\'//gi; + } + ### insert a record into the recording_log table + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPCM','$now_date','$now_date_epoch','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($temp_parallel_rec_cm_filename =~ /RECID/) + { + $temp_parallel_rec_cm_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$temp_parallel_rec_cm_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + ### insert record into recording_log_stereo table ### + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL CUSTOMER-MUTED $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL CUSTOMER-MUTED','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + if ($AGILOG) {$agi_string = "-- PARALLEL CM STEREO RECORDING LOG INSERT : |$SRaffected_rows|$recording_id|$parallel_recording_id|$rLIVEaffected_rows|$stmtA|"; &agi_output;} + } + + if ($stereo_parallel_recording =~ /FULL-RECORDING/) + { + $temp_parallel_rec_fr_filename = "FR".$stereo_rec_filename; + if (length($parallel_rec_fr_filename) > 0) + { + $temp_parallel_rec_fr_filename = $parallel_rec_fr_filename; + $temp_parallel_rec_fr_filename =~ s/CAMPAIGN/$VDADcampaign/gi; + $temp_parallel_rec_fr_filename =~ s/INGROUP/$VDADcampaign/gi; + $temp_parallel_rec_fr_filename =~ s/CUSTPHONE/$VDADphone/gi; + $temp_parallel_rec_fr_filename =~ s/FULLDATE/$recdate/gi; + $temp_parallel_rec_fr_filename =~ s/TINYDATE/$tinydate/gi; + $temp_parallel_rec_fr_filename =~ s/EPOCH/$now_date_epoch/gi; + $temp_parallel_rec_fr_filename =~ s/AGENT/$VDADuser/gi; + $temp_parallel_rec_fr_filename =~ s/VENDORLEADCODE/$vendor_lead_code/gi; + $temp_parallel_rec_fr_filename =~ s/LEADID/$CIDlead_id/gi; + $temp_parallel_rec_fr_filename =~ s/CALLID/$callerid/gi; + $temp_parallel_rec_fr_filename =~ s/\"|\'//gi; + } + ### insert a record into the recording_log table + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPFR','$now_date','$now_date_epoch','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($temp_parallel_rec_fr_filename =~ /RECID/) + { + $temp_parallel_rec_fr_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$temp_parallel_rec_fr_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + ### insert record into recording_log_stereo table ### + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL FULL-RECORDING $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL FULL-RECORDING','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + if ($AGILOG) {$agi_string = "-- PARALLEL FR STEREO RECORDING LOG INSERT : |$SRaffected_rows|$recording_id|$parallel_recording_id|$rLIVEaffected_rows|$stmtA|"; &agi_output;} + } + + # insert logs for agent-controlled stereo call recordings while parallel recordings are enabled + if ($stereo_recording_agent =~ /ALLCALLS|ALLFORCE/) + { + $temp_parallel_rec_ag_filename = $stereo_rec_filename; + ### insert a record into the recording_log table + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPACI','$now_date','$now_date_epoch','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($temp_parallel_rec_ag_filename =~ /RECID/) + { + $temp_parallel_rec_ag_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$temp_parallel_rec_ag_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + ### insert record into recording_log_stereo table ### + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL AGENT-CONTROLLED RIR $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + + $stmtB = "INSERT INTO routing_initiated_recordings (recording_id,filename,launch_time,lead_id,vicidial_id,user,processed) values('$recording_id','$temp_parallel_rec_ag_filename','$now_date','$CIDlead_id','$uniqueid','$VDADuser','0')"; + $affected_rowsB = $dbhA->do($stmtB); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rowsB; &mysql_error_logging; + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL AGENT-CONTROLLED RIR','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + if ($AGILOG) {$agi_string = "-- PARALLEL AG STEREO RECORDING LOG INSERT : |$SRaffected_rows|$recording_id|$parallel_recording_id|$rLIVEaffected_rows|$stmtA|"; &agi_output;} + } + } + else + { + ## Start NON-parallel stereo call recording ## + if ($stereo_recording_agent =~ /ALLCALLS|ALLFORCE/) + { + # insert a record into the recording_log table + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SACI','$now_date','$now_date_epoch','$stereo_rec_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($stereo_rec_filename =~ /RECID/) + { + $stereo_rec_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$stereo_rec_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + $retval_stop = $AGI->exec("StopMixMonitor",""); + $retval = $AGI->exec("MixMonitor",",r($PATHmonitorT/$stereo_rec_filename-out.wav)t($PATHmonitorT/$stereo_rec_filename-in.wav)"); + + ### insert record into recording_log_stereo table ### + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$stereo_rec_filename','$CIDlead_id','$VDADcampaign STEREO AGENT-CONTROLLED RIR $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','STEREO START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + + $stmtB = "INSERT INTO routing_initiated_recordings (recording_id,filename,launch_time,lead_id,vicidial_id,user,processed) values('$recording_id','$stereo_rec_filename','$now_date','$CIDlead_id','$uniqueid','$VDADuser','0')"; + $affected_rowsB = $dbhA->do($stmtB); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rowsB; &mysql_error_logging; + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO AGENT-CONTROLLED RIR','$VARserver_ip','$now_date','$channel','$stereo_rec_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + $mLIVEaffected_rows=0; + if ($stereo_recording =~ /CUSTOMER_ONLY/i) + { + $vmgr_callerid = substr($stereo_rec_filename, 0, 16) . 'M...'; + $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VDADserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: write','State: 1','','','','','','');"; + $mLIVEaffected_rows = $dbhA->do($stmtE); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$mLIVEaffected_rows; &mysql_error_logging; + } + if ($stereo_recording =~ /CUSTOMER_MUTE/i) + { + $vmgr_callerid = substr($stereo_rec_filename, 0, 16) . 'M...'; + $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VDADserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: read','State: 1','','','','','','');"; + $mLIVEaffected_rows = $dbhA->do($stmtE); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$mLIVEaffected_rows; &mysql_error_logging; + } + + if ($AGILOG) {$agi_string = "-- AGENT STEREO RECORDING STARTED : |$retval|$retval_stop|$SRaffected_rows|$recording_id|$rLIVEaffected_rows|$mLIVEaffected_rows|$stmtA|"; &agi_output;} + } + } + } + ### END stereo call recording for ALLCALLS/ALLFORCE and for all parallel stereo recording campaigns ### + + if ($extension_appended_cidname =~ /Y|USER/) + { + $eac_extension=''; + $stmtA = "SELECT extension,campaign_id FROM vicidial_live_agents where user='$VDADuser' order by last_call_time limit 1;"; + if ($AGILOG) {$agi_string = "|$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='01068'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + if ($extension_appended_cidname =~ /USER/) + { + $eac_extension = $VDADuser; + } + else + { + $eac_extension = $aryA[0]; + $eac_extension =~ s/SIP\/|IAX2\/|Zap\/|DAHDI\/|Local\///gi; + } + if ($extension_appended_cidname =~ /WITH_CAMPAIGN/) + {$eac_extension .= " $aryA[1]";} + } + $sthA->finish(); + + $newcallerid = "\"$callerid $eac_extension <$VDADphone>\""; + $AGI->set_callerid($newcallerid); + } + else + { + $newcallerid = "\"$callerid <$VDADphone>\""; + $AGI->set_callerid($newcallerid); + } + } + + $stmtA = "UPDATE vicidial_auto_calls set status='XFER', stage='XFER-$drop_timer', extension='$VDADconf_exten' where callerid='$callerid';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01038'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + if ($AGILOG) {$agi_string = "-- VDAD XFER : |$affected_rows|update of vac table: $callerid\n|$stmtA|"; &agi_output;} + + if ($SSabandon_check_queue > 0) + { + ### check for ACTIVE vicidial_abandon_check_queue records and set to CONNECTED if they exist + $stmtA = "UPDATE vicidial_abandon_check_queue SET check_status='CONNECTED' where lead_id = '$CIDlead_id' and check_status IN('NEW','QUEUE','PROCESSING') and abandon_time > \"$timeTWENTYFOURhoursAGO\" order by abandon_time desc limit 1;"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02068'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + if ($AGILOG) {$agi_string = "-- VACQ connected 1: |$CIDlead_id|$affected_rows|$stmtA"; &agi_output;} + + if ($affected_rows < 1) + { + ### check for INACTIVE vicidial_abandon_check_queue records and set to CONNECTED if they exist + $stmtA = "UPDATE vicidial_abandon_check_queue SET check_status='CONNECTED' where lead_id = '$CIDlead_id' and check_status IN('COMPLETE','REJECT','CONNECTED') and abandon_time > \"$timeTWENTYFOURhoursAGO\" order by abandon_time desc limit 1;"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02068'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + if ($AGILOG) {$agi_string = "-- VACQ connected 2: |$CIDlead_id|$affected_rows|$stmtA"; &agi_output;} + } + } + + if ($enable_queuemetrics_logging > 0) + { + $dbhB = DBI->connect("DBI:mysql:$queuemetrics_dbname:$queuemetrics_server_ip:3306", "$queuemetrics_login", "$queuemetrics_pass") + or die "Couldn't connect to database: " . DBI->errstr; + + if ($DBX) {print "CONNECTED TO DATABASE: $queuemetrics_server_ip|$queuemetrics_dbname\n";} + + $pe_append=''; + if ( ($queuemetrics_pe_phone_append > 0) && (length($queuemetrics_phone_environment)>0) ) + { + @qm_extension = split(/\//,$VDADextension); $pe_append = "-$qm_extension[1]"; } $stmtB = "INSERT INTO queue_log SET `partition`='P01',time_id='$now_date_epoch',call_id='$callerid',queue='$VDADcampaign',agent='Agent/$VDADuser',verb='CONNECT',data1='$drop_timer',serverid='$queuemetrics_log_id',data4='$queuemetrics_phone_environment$pe_append';"; @@ -3954,20 +4628,21 @@ while ($drop_timer <= $DROP_TIME) $campaign_rec_filename =~ s/CALLID/$callerid/gi; $campaign_rec_filename =~ s/\"|\'//gi; - if ( ($stereo_recording =~ /CUSTOMER/i) && ($conf_engine eq "CONFBRIDGE") ) + if ( ($stereo_recording =~ /CUSTOMER|BOTH/i) && ($conf_engine eq "CONFBRIDGE") && ($SSstereo_recording > 0) ) { - $retval = $AGI->exec("MixMonitor",",r(/var/spool/asterisk/monitorS/$campaign_rec_filename-in.wav)t(/var/spool/asterisk/monitorS/$campaign_rec_filename-out.wav)"); + # do nothing can't record more than 1 stream on the same channel, stereo call recording processing is right below this section + # $retval = $AGI->exec("MixMonitor",",r($PATHmonitorS/$campaign_rec_filename-in.wav)t($PATHmonitorS/$campaign_rec_filename-out.wav)"); } else { %ast_ver_str = parse_asterisk_version($asterisk_version); if (( $ast_ver_str{major} = 1 ) && ($ast_ver_str{minor} < 6)) { - $retval = $AGI->exec("Monitor wav|/var/spool/asterisk/monitor/MIX/$campaign_rec_filename"); + $retval = $AGI->exec("Monitor wav|$PATHmonitor/MIX/$campaign_rec_filename"); } else { - $retval = $AGI->exec("Monitor","wav,/var/spool/asterisk/monitor/MIX/$campaign_rec_filename"); + $retval = $AGI->exec("Monitor","wav,$PATHmonitor/MIX/$campaign_rec_filename"); } } @@ -3976,29 +4651,345 @@ while ($drop_timer <= $DROP_TIME) $RLRAaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01076'; $MEL_aff_rows=$RLRAaffected_rows; &mysql_error_logging; if ($AGILOG) {$agi_string = "-- REMOTE RECORDING STARTED : |$retval|$RLRAaffected_rows|$campaign_rec_filename|$stmtA|"; &agi_output;} + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); - if ( ($stereo_recording =~ /CUSTOMER/i) && ($conf_engine eq "CONFBRIDGE") ) + if ($campaign_rec_filename =~ /RECID/) { + $campaign_rec_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$campaign_rec_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02214'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','MONO_LEGACY_REMOTE','$VARserver_ip','$now_date','$channel','$campaign_rec_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + if ($AGILOG) {$agi_string = "-- REMOTE2 RECORDING STARTED : |$RLRAaffected_rows|$campaign_rec_filename|$rLIVEaffected_rows|$stmtA|"; &agi_output;} + } + + ### BEGIN stereo call recording for ALLCALLS/ALLFORCE and for all parallel stereo recording campaigns for remote agents ### + if ( ($stereo_recording =~ /CUSTOMER|BOTH/i) && ($conf_engine eq "CONFBRIDGE") && ($SSstereo_recording > 0) ) + { + $stereo_rec_filename =~ s/CAMPAIGN/$VDADcampaign/gi; + $stereo_rec_filename =~ s/INGROUP/$VDADcampaign/gi; + $stereo_rec_filename =~ s/CUSTPHONE/$VDADphone/gi; + $stereo_rec_filename =~ s/FULLDATE/$recdate/gi; + $stereo_rec_filename =~ s/TINYDATE/$tinydate/gi; + $stereo_rec_filename =~ s/EPOCH/$now_date_epoch/gi; + $stereo_rec_filename =~ s/AGENT/$VDADuser/gi; + $stereo_rec_filename =~ s/VENDORLEADCODE/$vendor_lead_code/gi; + $stereo_rec_filename =~ s/LEADID/$CIDlead_id/gi; + $stereo_rec_filename =~ s/CALLID/$callerid/gi; + $stereo_rec_filename =~ s/\"|\'//gi; + + $PATHmonitorT = $PATHmonitorS; + if ( ($SSstereo_parallel_recording > 0) && ($stereo_parallel_recording =~ /CUSTOMER|FULL/) ) + { + $PATHmonitorT = $PATHmonitorP; + + ### insert record into recording_log_parallel table ### + $stmtA = "INSERT INTO recording_log_parallel (channel,server_ip,extension,start_time,length_in_sec,filename,lead_id,user,vicidial_id,recording_status) values('$channel','$VDADserver_ip','','$now_date','0','PL$stereo_rec_filename','$CIDlead_id','$VDADuser','$uniqueid','START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; $sthArows=$sthA->rows; - $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='01XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; if ($sthArows > 0) { @aryA = $sthA->fetchrow_array; - $recording_id = $aryA[0]; + $parallel_recording_id = $aryA[0]; } $sthA->finish(); - ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log) values('$recording_id','$VARserver_ip','$now_date','0','$campaign_rec_filename','$CIDlead_id','$stereo_recording $VDADcampaign','start: $now_date|vicidial_id: $uniqueid|channel: $channel|');"; - $SRaffected_rows = $dbhA->do($stmtA); - $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - if ($AGILOG) {$agi_string = "-- REMOTE2 STEREO RECORDING STARTED : |$retval|$SRaffected_rows|$recording_id|$stmtA|"; &agi_output;} + ### start the parallel recording + $retval_stop = $AGI->exec("StopMixMonitor",""); + $retval = $AGI->exec("MixMonitor",",r($PATHmonitorT/PL$stereo_rec_filename-out.wav)t($PATHmonitorT/PL$stereo_rec_filename-in.wav)"); + + if ($AGILOG) {$agi_string = "-- REMOTE2 PARALLEL STEREO STARTED: |$retval|$retval_stop|$SRaffected_rows|$parallel_recording_id|$stmtA|"; &agi_output;} + + if ($stereo_parallel_recording =~ /CUSTOMER-ONLY/) + { + $temp_parallel_rec_co_filename = "CO".$stereo_rec_filename; + if (length($parallel_rec_co_filename) > 0) + { + $temp_parallel_rec_co_filename = $parallel_rec_co_filename; + $temp_parallel_rec_co_filename =~ s/CAMPAIGN/$VDADcampaign/gi; + $temp_parallel_rec_co_filename =~ s/INGROUP/$VDADcampaign/gi; + $temp_parallel_rec_co_filename =~ s/CUSTPHONE/$VDADphone/gi; + $temp_parallel_rec_co_filename =~ s/FULLDATE/$recdate/gi; + $temp_parallel_rec_co_filename =~ s/TINYDATE/$tinydate/gi; + $temp_parallel_rec_co_filename =~ s/EPOCH/$now_date_epoch/gi; + $temp_parallel_rec_co_filename =~ s/AGENT/$VDADuser/gi; + $temp_parallel_rec_co_filename =~ s/VENDORLEADCODE/$vendor_lead_code/gi; + $temp_parallel_rec_co_filename =~ s/LEADID/$CIDlead_id/gi; + $temp_parallel_rec_co_filename =~ s/CALLID/$callerid/gi; + $temp_parallel_rec_co_filename =~ s/\"|\'//gi; + } + ### insert a record into the recording_log table + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPCOR','$now_date','$now_date_epoch','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($temp_parallel_rec_co_filename =~ /RECID/) + { + $temp_parallel_rec_co_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$temp_parallel_rec_co_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + ### insert record into recording_log_stereo table ### + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL CUSTOMER-ONLY REMOTE $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL CUSTOMER-ONLY REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + if ($AGILOG) {$agi_string = "-- REMOTE2 PARALLEL CO STEREO RECORDING LOG INSERT : |$SRaffected_rows|$recording_id|$parallel_recording_id|$rLIVEaffected_rows|$stmtA|"; &agi_output;} + } + + if ($stereo_parallel_recording =~ /CUSTOMER-MUTED/) + { + $temp_parallel_rec_cm_filename = "CM".$stereo_rec_filename; + if (length($parallel_rec_cm_filename) > 0) + { + $temp_parallel_rec_cm_filename = $parallel_rec_cm_filename; + $temp_parallel_rec_cm_filename =~ s/CAMPAIGN/$VDADcampaign/gi; + $temp_parallel_rec_cm_filename =~ s/INGROUP/$VDADcampaign/gi; + $temp_parallel_rec_cm_filename =~ s/CUSTPHONE/$VDADphone/gi; + $temp_parallel_rec_cm_filename =~ s/FULLDATE/$recdate/gi; + $temp_parallel_rec_cm_filename =~ s/TINYDATE/$tinydate/gi; + $temp_parallel_rec_cm_filename =~ s/EPOCH/$now_date_epoch/gi; + $temp_parallel_rec_cm_filename =~ s/AGENT/$VDADuser/gi; + $temp_parallel_rec_cm_filename =~ s/VENDORLEADCODE/$vendor_lead_code/gi; + $temp_parallel_rec_cm_filename =~ s/LEADID/$CIDlead_id/gi; + $temp_parallel_rec_cm_filename =~ s/CALLID/$callerid/gi; + $temp_parallel_rec_cm_filename =~ s/\"|\'//gi; + } + ### insert a record into the recording_log table + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPCMR','$now_date','$now_date_epoch','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($temp_parallel_rec_cm_filename =~ /RECID/) + { + $temp_parallel_rec_cm_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$temp_parallel_rec_cm_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + ### insert record into recording_log_stereo table ### + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL CUSTOMER-MUTED REMOTE $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL CUSTOMER-MUTED REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + if ($AGILOG) {$agi_string = "-- REMOTE2 PARALLEL CM STEREO RECORDING LOG INSERT : |$SRaffected_rows|$recording_id|$parallel_recording_id|$rLIVEaffected_rows|$stmtA|"; &agi_output;} + } + + if ($stereo_parallel_recording =~ /FULL-RECORDING/) + { + $temp_parallel_rec_fr_filename = "FR".$stereo_rec_filename; + if (length($parallel_rec_fr_filename) > 0) + { + $temp_parallel_rec_fr_filename = $parallel_rec_fr_filename; + $temp_parallel_rec_fr_filename =~ s/CAMPAIGN/$VDADcampaign/gi; + $temp_parallel_rec_fr_filename =~ s/INGROUP/$VDADcampaign/gi; + $temp_parallel_rec_fr_filename =~ s/CUSTPHONE/$VDADphone/gi; + $temp_parallel_rec_fr_filename =~ s/FULLDATE/$recdate/gi; + $temp_parallel_rec_fr_filename =~ s/TINYDATE/$tinydate/gi; + $temp_parallel_rec_fr_filename =~ s/EPOCH/$now_date_epoch/gi; + $temp_parallel_rec_fr_filename =~ s/AGENT/$VDADuser/gi; + $temp_parallel_rec_fr_filename =~ s/VENDORLEADCODE/$vendor_lead_code/gi; + $temp_parallel_rec_fr_filename =~ s/LEADID/$CIDlead_id/gi; + $temp_parallel_rec_fr_filename =~ s/CALLID/$callerid/gi; + $temp_parallel_rec_fr_filename =~ s/\"|\'//gi; + } + ### insert a record into the recording_log table + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPRFR','$now_date','$now_date_epoch','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($temp_parallel_rec_fr_filename =~ /RECID/) + { + $temp_parallel_rec_fr_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$temp_parallel_rec_fr_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + ### insert record into recording_log_stereo table ### + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL FULL-RECORDING REMOTE $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL FULL-RECORDING REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + if ($AGILOG) {$agi_string = "-- REMOTE2 PARALLEL FR STEREO RECORDING LOG INSERT : |$SRaffected_rows|$recording_id|$parallel_recording_id|$rLIVEaffected_rows|$stmtA|"; &agi_output;} + } + + # insert logs for agent-controlled stereo call recordings while parallel recordings are enabled + if ($stereo_recording_agent =~ /ALLCALLS|ALLFORCE/) + { + $temp_parallel_rec_ag_filename = $stereo_rec_filename; + ### insert a record into the recording_log table + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPACR','$now_date','$now_date_epoch','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($temp_parallel_rec_ag_filename =~ /RECID/) + { + $temp_parallel_rec_ag_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$temp_parallel_rec_ag_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + ### insert record into recording_log_stereo table ### + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL AGENT-CONTROLLED REMOTE $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL AGENT-CONTROLLED REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + if ($AGILOG) {$agi_string = "-- REMOTE2 PARALLEL AG STEREO RECORDING LOG INSERT : |$SRaffected_rows|$recording_id|$parallel_recording_id|$rLIVEaffected_rows|$stmtA|"; &agi_output;} + } } + else + { + ## Start NON-parallel stereo call recording ## + if ($stereo_recording_agent =~ /ALLCALLS|ALLFORCE/) + { + # insert a record into the recording_log table + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SACR','$now_date','$now_date_epoch','$stereo_rec_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($stereo_rec_filename =~ /RECID/) + { + $stereo_rec_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$stereo_rec_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + $retval_stop = $AGI->exec("StopMixMonitor",""); + $retval = $AGI->exec("MixMonitor",",r($PATHmonitorT/$stereo_rec_filename-out.wav)t($PATHmonitorT/$stereo_rec_filename-in.wav)"); + + ### insert record into recording_log_stereo table ### + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$stereo_rec_filename','$CIDlead_id','$VDADcampaign STEREO AGENT-CONTROLLED REMOTE $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','STEREO START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO AGENT-CONTROLLED REMOTE','$VARserver_ip','$now_date','$channel','$stereo_rec_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + $mLIVEaffected_rows=0; + if ($stereo_recording =~ /CUSTOMER_ONLY/i) + { + $vmgr_callerid = substr($stereo_rec_filename, 0, 16) . 'M...'; + $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VDADserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: write','State: 1','','','','','','');"; + $mLIVEaffected_rows = $dbhA->do($stmtE); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$mLIVEaffected_rows; &mysql_error_logging; + } + if ($stereo_recording =~ /CUSTOMER_MUTE/i) + { + $vmgr_callerid = substr($stereo_rec_filename, 0, 16) . 'M...'; + $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VDADserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: read','State: 1','','','','','','');"; + $mLIVEaffected_rows = $dbhA->do($stmtE); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$mLIVEaffected_rows; &mysql_error_logging; + } + + if ($AGILOG) {$agi_string = "-- REMOTE2 AGENT STEREO RECORDING STARTED : |$retval|$retval_stop|$SRaffected_rows|$recording_id|$rLIVEaffected_rows|$mLIVEaffected_rows|$stmtA|"; &agi_output;} + } + } } + ### END stereo call recording for ALLCALLS/ALLFORCE and for all parallel stereo recording campaigns for Remote Agents ### } ### END REMOTE AGENT SECTION else @@ -4095,18 +5086,6 @@ while ($drop_timer <= $DROP_TIME) $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02133'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; } - - if ( ($stereo_recording =~ /CUSTOMER/i) && ($conf_engine eq "CONFBRIDGE") ) - { - $retval = $AGI->exec("MixMonitor",",r(/var/spool/asterisk/monitorS/$campaign_rec_filename-in.wav)t(/var/spool/asterisk/monitorS/$campaign_rec_filename-out.wav)"); - - ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log) values('$recording_id','$VARserver_ip','$now_date','0','$campaign_rec_filename','$CIDlead_id','$stereo_recording $VDADcampaign','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|');"; - $SRaffected_rows = $dbhA->do($stmtA); - $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - if ($AGILOG) {$agi_string = "-- REMOTE STEREO RECORDING STARTED : |$retval|$SRaffected_rows|$recording_id|$stmtA|"; &agi_output;} - } - $vmgr_callerid = substr($campaign_rec_filename, 0, 17) . '...'; $stmtA="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VDADserver_ip','','Originate','$vmgr_callerid','Channel: $channelrec','Context: $ext_context','Exten: $campaign_rec_exten','Priority: 1','Callerid: $campaign_rec_filename','','','','','');"; $affected_rows = $dbhA->do($stmtA); @@ -4120,11 +5099,335 @@ while ($drop_timer <= $DROP_TIME) $affected_rowsC = $dbhA->do($stmtC); $dbhP=$dbhA; $mysql_count='02136'; $MEL_aff_rows=$affected_rowsC; &mysql_error_logging; - if ($AGILOG) {$agi_string = "-- ROUTING INITIATED RECORDING STARTED : |$affected_rows|$recording_id|$campaign_rec_filename|$stmtA| |$affected_rowsB|$stmtB| |$affected_rowsC|$stmtC|"; &agi_output;} + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','MONO_LEGACY_RIR','$VARserver_ip','$now_date','$channel','$campaign_rec_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + if ($AGILOG) {$agi_string = "-- ROUTING INITIATED RECORDING STARTED : |$affected_rows|$recording_id|$campaign_rec_filename|$rLIVEaffected_rows|$stmtA| |$affected_rowsB|$stmtB| |$affected_rowsC|$stmtC|"; &agi_output;} } ### END routing-initiated agent call recording for ALLCALLS/ALLFORCE ### } + ### BEGIN stereo call recording for ALLCALLS/ALLFORCE and for all parallel stereo recording campaigns ### + if ( ($stereo_recording =~ /CUSTOMER|BOTH/i) && ($conf_engine eq "CONFBRIDGE") && ($SSstereo_recording > 0) ) + { + $stereo_rec_filename =~ s/CAMPAIGN/$VDADcampaign/gi; + $stereo_rec_filename =~ s/INGROUP/$VDADcampaign/gi; + $stereo_rec_filename =~ s/CUSTPHONE/$VDADphone/gi; + $stereo_rec_filename =~ s/FULLDATE/$recdate/gi; + $stereo_rec_filename =~ s/TINYDATE/$tinydate/gi; + $stereo_rec_filename =~ s/EPOCH/$now_date_epoch/gi; + $stereo_rec_filename =~ s/AGENT/$VDADuser/gi; + $stereo_rec_filename =~ s/VENDORLEADCODE/$vendor_lead_code/gi; + $stereo_rec_filename =~ s/LEADID/$CIDlead_id/gi; + $stereo_rec_filename =~ s/CALLID/$callerid/gi; + $stereo_rec_filename =~ s/\"|\'//gi; + + $PATHmonitorT = $PATHmonitorS; + if ( ($SSstereo_parallel_recording > 0) && ($stereo_parallel_recording =~ /CUSTOMER|FULL/) ) + { + $PATHmonitorT = $PATHmonitorP; + + ### insert record into recording_log_parallel table ### + $stmtA = "INSERT INTO recording_log_parallel (channel,server_ip,extension,start_time,length_in_sec,filename,lead_id,user,vicidial_id,recording_status) values('$channel','$VDADserver_ip','','$now_date','0','PL$stereo_rec_filename','$CIDlead_id','$VDADuser','$uniqueid','START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $parallel_recording_id = $aryA[0]; + } + $sthA->finish(); + + ### start the parallel recording + $retval_stop = $AGI->exec("StopMixMonitor",""); + $retval = $AGI->exec("MixMonitor",",r($PATHmonitorT/PL$stereo_rec_filename-out.wav)t($PATHmonitorT/PL$stereo_rec_filename-in.wav)"); + + if ($AGILOG) {$agi_string = "-- PARALLEL STEREO STARTED: |$retval|$retval_stop|$SRaffected_rows|$parallel_recording_id|$stmtA|"; &agi_output;} + + if ($stereo_parallel_recording =~ /CUSTOMER-ONLY/) + { + $temp_parallel_rec_co_filename = "CO".$stereo_rec_filename; + if (length($parallel_rec_co_filename) > 0) + { + $temp_parallel_rec_co_filename = $parallel_rec_co_filename; + $temp_parallel_rec_co_filename =~ s/CAMPAIGN/$VDADcampaign/gi; + $temp_parallel_rec_co_filename =~ s/INGROUP/$VDADcampaign/gi; + $temp_parallel_rec_co_filename =~ s/CUSTPHONE/$VDADphone/gi; + $temp_parallel_rec_co_filename =~ s/FULLDATE/$recdate/gi; + $temp_parallel_rec_co_filename =~ s/TINYDATE/$tinydate/gi; + $temp_parallel_rec_co_filename =~ s/EPOCH/$now_date_epoch/gi; + $temp_parallel_rec_co_filename =~ s/AGENT/$VDADuser/gi; + $temp_parallel_rec_co_filename =~ s/VENDORLEADCODE/$vendor_lead_code/gi; + $temp_parallel_rec_co_filename =~ s/LEADID/$CIDlead_id/gi; + $temp_parallel_rec_co_filename =~ s/CALLID/$callerid/gi; + $temp_parallel_rec_co_filename =~ s/\"|\'//gi; + } + ### insert a record into the recording_log table + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPCO','$now_date','$now_date_epoch','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($temp_parallel_rec_co_filename =~ /RECID/) + { + $temp_parallel_rec_co_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$temp_parallel_rec_co_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + ### insert record into recording_log_stereo table ### + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL CUSTOMER-ONLY $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL CUSTOMER-ONLY','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + if ($AGILOG) {$agi_string = "-- PARALLEL CO STEREO RECORDING LOG INSERT : |$SRaffected_rows|$recording_id|$parallel_recording_id|$rLIVEaffected_rows|$stmtA|"; &agi_output;} + } + + if ($stereo_parallel_recording =~ /CUSTOMER-MUTED/) + { + $temp_parallel_rec_cm_filename = "CM".$stereo_rec_filename; + if (length($parallel_rec_cm_filename) > 0) + { + $temp_parallel_rec_cm_filename = $parallel_rec_cm_filename; + $temp_parallel_rec_cm_filename =~ s/CAMPAIGN/$VDADcampaign/gi; + $temp_parallel_rec_cm_filename =~ s/INGROUP/$VDADcampaign/gi; + $temp_parallel_rec_cm_filename =~ s/CUSTPHONE/$VDADphone/gi; + $temp_parallel_rec_cm_filename =~ s/FULLDATE/$recdate/gi; + $temp_parallel_rec_cm_filename =~ s/TINYDATE/$tinydate/gi; + $temp_parallel_rec_cm_filename =~ s/EPOCH/$now_date_epoch/gi; + $temp_parallel_rec_cm_filename =~ s/AGENT/$VDADuser/gi; + $temp_parallel_rec_cm_filename =~ s/VENDORLEADCODE/$vendor_lead_code/gi; + $temp_parallel_rec_cm_filename =~ s/LEADID/$CIDlead_id/gi; + $temp_parallel_rec_cm_filename =~ s/CALLID/$callerid/gi; + $temp_parallel_rec_cm_filename =~ s/\"|\'//gi; + } + ### insert a record into the recording_log table + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPCM','$now_date','$now_date_epoch','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($temp_parallel_rec_cm_filename =~ /RECID/) + { + $temp_parallel_rec_cm_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$temp_parallel_rec_cm_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + ### insert record into recording_log_stereo table ### + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL CUSTOMER-MUTED $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL CUSTOMER-MUTED','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + if ($AGILOG) {$agi_string = "-- PARALLEL CM STEREO RECORDING LOG INSERT : |$SRaffected_rows|$recording_id|$parallel_recording_id|$rLIVEaffected_rows|$stmtA|"; &agi_output;} + } + + if ($stereo_parallel_recording =~ /FULL-RECORDING/) + { + $temp_parallel_rec_fr_filename = "FR".$stereo_rec_filename; + if (length($parallel_rec_fr_filename) > 0) + { + $temp_parallel_rec_fr_filename = $parallel_rec_fr_filename; + $temp_parallel_rec_fr_filename =~ s/CAMPAIGN/$VDADcampaign/gi; + $temp_parallel_rec_fr_filename =~ s/INGROUP/$VDADcampaign/gi; + $temp_parallel_rec_fr_filename =~ s/CUSTPHONE/$VDADphone/gi; + $temp_parallel_rec_fr_filename =~ s/FULLDATE/$recdate/gi; + $temp_parallel_rec_fr_filename =~ s/TINYDATE/$tinydate/gi; + $temp_parallel_rec_fr_filename =~ s/EPOCH/$now_date_epoch/gi; + $temp_parallel_rec_fr_filename =~ s/AGENT/$VDADuser/gi; + $temp_parallel_rec_fr_filename =~ s/VENDORLEADCODE/$vendor_lead_code/gi; + $temp_parallel_rec_fr_filename =~ s/LEADID/$CIDlead_id/gi; + $temp_parallel_rec_fr_filename =~ s/CALLID/$callerid/gi; + $temp_parallel_rec_fr_filename =~ s/\"|\'//gi; + } + ### insert a record into the recording_log table + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPFR','$now_date','$now_date_epoch','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($temp_parallel_rec_fr_filename =~ /RECID/) + { + $temp_parallel_rec_fr_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$temp_parallel_rec_fr_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + ### insert record into recording_log_stereo table ### + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL FULL-RECORDING $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL FULL-RECORDING','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + if ($AGILOG) {$agi_string = "-- PARALLEL FR STEREO RECORDING LOG INSERT : |$SRaffected_rows|$recording_id|$parallel_recording_id|$rLIVEaffected_rows|$stmtA|"; &agi_output;} + } + + # insert logs for agent-controlled stereo call recordings while parallel recordings are enabled + if ($stereo_recording_agent =~ /ALLCALLS|ALLFORCE/) + { + $temp_parallel_rec_ag_filename = $stereo_rec_filename; + ### insert a record into the recording_log table + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPACI','$now_date','$now_date_epoch','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($temp_parallel_rec_ag_filename =~ /RECID/) + { + $temp_parallel_rec_ag_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$temp_parallel_rec_ag_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + ### insert record into recording_log_stereo table ### + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL AGENT-CONTROLLED RIR $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + + $stmtB = "INSERT INTO routing_initiated_recordings (recording_id,filename,launch_time,lead_id,vicidial_id,user,processed) values('$recording_id','$temp_parallel_rec_ag_filename','$now_date','$CIDlead_id','$uniqueid','$VDADuser','0')"; + $affected_rowsB = $dbhA->do($stmtB); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rowsB; &mysql_error_logging; + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL AGENT-CONTROLLED RIR','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + if ($AGILOG) {$agi_string = "-- PARALLEL AG STEREO RECORDING LOG INSERT : |$SRaffected_rows|$recording_id|$parallel_recording_id|$rLIVEaffected_rows|$stmtA|"; &agi_output;} + } + } + else + { + ## Start NON-parallel stereo call recording ## + if ($stereo_recording_agent =~ /ALLCALLS|ALLFORCE/) + { + # insert a record into the recording_log table + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SACI','$now_date','$now_date_epoch','$stereo_rec_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + $dbhP=$dbhA; $stmtA=$stmtB; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ($stereo_rec_filename =~ /RECID/) + { + $stereo_rec_filename =~ s/RECID/$recording_id/gi; + + $stmtA = "UPDATE recording_log SET filename='$stereo_rec_filename' where recording_id='$recording_id';"; + $affected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; + } + + $retval_stop = $AGI->exec("StopMixMonitor",""); + $retval = $AGI->exec("MixMonitor",",r($PATHmonitorT/$stereo_rec_filename-out.wav)t($PATHmonitorT/$stereo_rec_filename-in.wav)"); + + ### insert record into recording_log_stereo table ### + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$stereo_rec_filename','$CIDlead_id','$VDADcampaign STEREO AGENT-CONTROLLED RIR $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','STEREO START');"; + $SRaffected_rows = $dbhA->do($stmtA); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; + + $stmtB = "INSERT INTO routing_initiated_recordings (recording_id,filename,launch_time,lead_id,vicidial_id,user,processed) values('$recording_id','$stereo_rec_filename','$now_date','$CIDlead_id','$uniqueid','$VDADuser','0')"; + $affected_rowsB = $dbhA->do($stmtB); + $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rowsB; &mysql_error_logging; + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO AGENT-CONTROLLED RIR','$VARserver_ip','$now_date','$channel','$stereo_rec_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; + + $mLIVEaffected_rows=0; + if ($stereo_recording =~ /CUSTOMER_ONLY/i) + { + $vmgr_callerid = substr($stereo_rec_filename, 0, 16) . 'M...'; + $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VDADserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: write','State: 1','','','','','','');"; + $mLIVEaffected_rows = $dbhA->do($stmtE); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$mLIVEaffected_rows; &mysql_error_logging; + } + if ($stereo_recording =~ /CUSTOMER_MUTE/i) + { + $vmgr_callerid = substr($stereo_rec_filename, 0, 16) . 'M...'; + $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VDADserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: read','State: 1','','','','','','');"; + $mLIVEaffected_rows = $dbhA->do($stmtE); + $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$mLIVEaffected_rows; &mysql_error_logging; + } + + if ($AGILOG) {$agi_string = "-- AGENT STEREO RECORDING STARTED : |$retval|$retval_stop|$SRaffected_rows|$recording_id|$rLIVEaffected_rows|$mLIVEaffected_rows|$stmtA|"; &agi_output;} + } + } + } + ### END stereo call recording for ALLCALLS/ALLFORCE and for all parallel stereo recording campaigns ### + if ($extension_appended_cidname =~ /Y|USER/) { $eac_extension=''; diff --git a/bin/ADMIN_archive_log_tables.pl b/bin/ADMIN_archive_log_tables.pl index d5da35013..2eb270301 100644 --- a/bin/ADMIN_archive_log_tables.pl +++ b/bin/ADMIN_archive_log_tables.pl @@ -20,7 +20,7 @@ # Based on perl scripts in ViciDial from Matt Florell and post: # http://www.vicidial.org/VICIDIALforum/viewtopic.php?p=22506&sid=ca5347cffa6f6382f56ce3db9fb3d068#22506 # -# Copyright (C) 2024 I. Taushanov, Matt Florell LICENSE: AGPLv2 +# Copyright (C) 2025 I. Taushanov, Matt Florell LICENSE: AGPLv2 # # CHANGES # 90615-1701 - First version @@ -73,6 +73,7 @@ # 231126-2227 - Added vicidial_hci_log archiving # 240916-2159 - Added --extended-log-only # 240924-2041 - Added --vicidial-log-only +# 250914-1537 - Added archiving of recording_log_stereo and recording_log_parallel tables # $CALC_TEST=0; @@ -4037,6 +4038,104 @@ $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; } + + ##### recording_log_stereo + $stmtA = "SELECT count(*) from recording_log_stereo;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_log_stereo_count = $aryA[0]; + } + $sthA->finish(); + + $stmtA = "SELECT count(*) from recording_log_stereo_archive;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_log_stereo_archive_count = $aryA[0]; + } + $sthA->finish(); + + if (!$Q) {print "\nProcessing recording_log_stereo table... ($recording_log_stereo_count|$recording_log_stereo_archive_count)\n";} + $stmtA = "INSERT IGNORE INTO recording_log_stereo_archive SELECT * from recording_log_stereo;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + + $sthArows = $sthA->rows; + if (!$Q) {print "$sthArows rows inserted into recording_log_stereo_archive table \n";} + + $rv = $sthA->err(); + if (!$rv) + { + $stmtA = "DELETE FROM recording_log_stereo WHERE start_time < '$RECdel_time';"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows = $sthA->rows; + if (!$Q) {print "$sthArows rows deleted from recording_log_stereo table \n";} + + $stmtA = "optimize table recording_log_stereo;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + + $stmtA = "optimize table recording_log_stereo_archive;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + } + + ##### recording_log_parallel + $stmtA = "SELECT count(*) from recording_log_parallel;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_log_parallel_count = $aryA[0]; + } + $sthA->finish(); + + $stmtA = "SELECT count(*) from recording_log_parallel_archive;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_log_parallel_archive_count = $aryA[0]; + } + $sthA->finish(); + + if (!$Q) {print "\nProcessing recording_log_parallel table... ($recording_log_parallel_count|$recording_log_parallel_archive_count)\n";} + $stmtA = "INSERT IGNORE INTO recording_log_parallel_archive SELECT * from recording_log_parallel;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + + $sthArows = $sthA->rows; + if (!$Q) {print "$sthArows rows inserted into recording_log_parallel_archive table \n";} + + $rv = $sthA->err(); + if (!$rv) + { + $stmtA = "DELETE FROM recording_log_parallel WHERE start_time < '$RECdel_time';"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows = $sthA->rows; + if (!$Q) {print "$sthArows rows deleted from recording_log_parallel table \n";} + + $stmtA = "optimize table recording_log_parallel;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + + $stmtA = "optimize table recording_log_parallel_archive;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + } } diff --git a/bin/ADMIN_keepalive_ALL.pl b/bin/ADMIN_keepalive_ALL.pl index 668565aba..58044cf65 100644 --- a/bin/ADMIN_keepalive_ALL.pl +++ b/bin/ADMIN_keepalive_ALL.pl @@ -173,9 +173,10 @@ # 240401-1810 - Added purging of vicidial_pending_ar records older than 7 days # 240420-2209 - Added Conference Updater option # 250103-0932 - Added ConfBridge code and enhanced_agent_monitoring system setting code +# 250914-1601 - Added pruning of recording_live table entries over 7 days old, deletion of parallel recording source files 3+ days # -$build = '250103-0932'; +$build = '250914-1601'; $DB=0; # Debug flag $teodDB=0; # flag to log Timeclock End of Day processes to log file @@ -444,6 +445,8 @@ {$PATHlogs = $line; $PATHlogs =~ s/.*=//gi;} if ( ($line =~ /^PATHsounds/) && ($CLIsounds < 1) ) {$PATHsounds = $line; $PATHsounds =~ s/.*=//gi;} + if ( ($line =~ /^PATHmonitor/) && ($CLImonitor < 1) ) + {$PATHmonitor = $line; $PATHmonitor =~ s/.*=//gi;} if ( ($line =~ /^VARactive_keepalives/) && ($CLIactive_keepalives < 1) ) {$VARactive_keepalives = $line; $VARactive_keepalives =~ s/.*=//gi;} if ( ($line =~ /^VARserver_ip/) && ($CLIserver_ip < 1) ) @@ -496,7 +499,7 @@ ##### Get the settings from system_settings ##### -$stmtA = "SELECT sounds_central_control_active,active_voicemail_server,custom_dialplan_entry,default_codecs,generate_cross_server_exten,voicemail_timezones,default_voicemail_timezone,call_menu_qualify_enabled,allow_voicemail_greeting,reload_timestamp,meetme_enter_login_filename,meetme_enter_leave3way_filename,allow_chats,enable_auto_reports,enable_drop_lists,expired_lists_inactive,sip_event_logging,call_quota_lead_ranking,inbound_answer_config,log_latency_gaps,demographic_quotas,weekday_resets,highest_lead_id,hopper_hold_inserts FROM system_settings;"; +$stmtA = "SELECT sounds_central_control_active,active_voicemail_server,custom_dialplan_entry,default_codecs,generate_cross_server_exten,voicemail_timezones,default_voicemail_timezone,call_menu_qualify_enabled,allow_voicemail_greeting,reload_timestamp,meetme_enter_login_filename,meetme_enter_leave3way_filename,allow_chats,enable_auto_reports,enable_drop_lists,expired_lists_inactive,sip_event_logging,call_quota_lead_ranking,inbound_answer_config,log_latency_gaps,demographic_quotas,weekday_resets,highest_lead_id,hopper_hold_inserts,stereo_recording,stereo_parallel_recording FROM system_settings;"; # print "$stmtA\n"; $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; @@ -528,6 +531,8 @@ $SSweekday_resets = $aryA[21]; $SShighest_lead_id = $aryA[22]; $SShopper_hold_inserts = $aryA[23]; + $SSstereo_recording = $aryA[24]; + $SSstereo_parallel_recording = $aryA[25]; } $sthA->finish(); if ($DBXXX > 0) {print "SYSTEM SETTINGS: $sounds_central_control_active|$active_voicemail_server|$SScustom_dialplan_entry|$SSdefault_codecs\n";} @@ -1216,6 +1221,36 @@ } if ($teodDB) {$event_string = "Empty $vicidial_conf_table entries cleared: $conf_cleared"; &teod_logger;} + ### If stereo parallel recording is enabled on this system, delete parallel source files over 3 days old every night + if ( ($SSstereo_recording > 0) && ($SSstereo_parallel_recording > 0) ) + { + ### find 'find' to gather the list of files to delete + $findbin = ''; + if ( -e ('/usr/bin/find')) {$findbin = '/usr/bin/find';} + else + { + if ( -e ('/bin/find')) {$findbin = '/bin/find';} + else + { + if ( -e ('/usr/sbin/find')) {$findbin = '/usr/sbin/find';} + else + { + if ($DB) {print "Can't find -find- binary! No file deletions will be possible...\n";} + } + } + } + + $PATHmonitorTRASH = $PATHmonitor.'TRASH'; + $now_epoch = int(time()); + # command to trigger old stereo parallel source file deletion: + $parallel_delete_command = "$findbin $PATHmonitorTRASH -maxdepth 2 -type f -mtime +3 | xargs rm -f "; + if (!$Q) {print "Triggering old Parallel source recording file deletion... |$parallel_delete_command| \n";} + `/usr/bin/screen -d -m -S PD$reset_test $parallel_delete_command `; + $end_epoch = int(time()); + $run_length = ($end_epoch - $now_epoch); + if (!$Q) {print " Parallel source recording file deletion complete ($run_length sec) \n";} + if ($teodDB) {$event_string = "Old Parallel source recording file deletion complete ($run_length sec): $parallel_delete_command"; &teod_logger;} + } ### Only run the following on one server in the cluster, the one set as the active voicemail server ### if ( ($active_voicemail_server =~ /$server_ip/) && ((length($active_voicemail_server)) eq (length($server_ip))) ) @@ -2308,6 +2343,21 @@ ##### END vicidial_lead_24hour_calls end of day process removing records older than 1 day ##### + ##### BEGIN recording_live_log end of day process removing records older than 7 days ##### + $stmtA = "DELETE FROM recording_live_log WHERE start_time < \"$SDSQLdate\";"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows = $sthA->rows; + $event_string = "$sthArows rows deleted from recording_live_log table"; + if (!$Q) {print "$event_string \n";} + if ($teodDB) {&teod_logger;} + + $stmtA = "optimize table recording_live_log;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + ##### END recording_live_log end of day process removing records older than 7 days ##### + + ##### START latency log summary log inserts ##### gather vicidial_agent_latency_log ##### diff --git a/bin/AST_CRON_audio_1_move_VDonly.pl b/bin/AST_CRON_audio_1_move_VDonly.pl index 481af7384..e09a06497 100644 --- a/bin/AST_CRON_audio_1_move_VDonly.pl +++ b/bin/AST_CRON_audio_1_move_VDonly.pl @@ -15,8 +15,8 @@ # ### recording mixing/compressing/ftping scripts ##0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57 * * * * /usr/share/astguiclient/AST_CRON_audio_1_move_mix.pl # 0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57 * * * * /usr/share/astguiclient/AST_CRON_audio_1_move_VDonly.pl -# 1,4,7,10,13,16,19,22,25,28,31,34,37,40,43,46,49,52,55,58 * * * * /usr/share/astguiclient/AST_CRON_audio_2_compress.pl --GSM -# 2,5,8,11,14,17,20,23,26,29,32,35,38,41,44,47,50,53,56,59 * * * * /usr/share/astguiclient/AST_CRON_audio_3_ftp.pl --GSM +# 1,4,7,10,13,16,19,22,25,28,31,34,37,40,43,46,49,52,55,58 * * * * /usr/share/astguiclient/AST_CRON_audio_2_compress.pl --MP3 +# 2,5,8,11,14,17,20,23,26,29,32,35,38,41,44,47,50,53,56,59 * * * * /usr/share/astguiclient/AST_CRON_audio_3_ftp.pl --MP3 # # make sure that the following directories exist: # /var/spool/asterisk/monitor # default Asterisk recording directory @@ -36,6 +36,7 @@ # 190311-0105 - Added code to check for agent-muted recordings # 231019-2202 - Changed sleep time between directory scans from 5 to 15 seconds # 250430-0850 - Added --POST options for skipping over recordings for leads with active calls, and using logs for statuss +# 250909-0845 - Added trigger for stereo recording script, if enabled and raw audio files present # $HTTPS=0; @@ -227,14 +228,16 @@ ##### Get the settings from system_settings ##### $SSmute_recordings=0; -$stmtA = "SELECT mute_recordings FROM system_settings;"; +$stmtA = "SELECT mute_recordings,stereo_recording,stereo_parallel_recording FROM system_settings;"; $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; $sthArows=$sthA->rows; if ($sthArows > 0) { @aryA = $sthA->fetchrow_array; - $SSmute_recordings = $aryA[0]; + $SSmute_recordings = $aryA[0]; + $SSstereo_recording = $aryA[1]; + $SSstereo_parallel_recording = $aryA[2]; } $sthA->finish(); @@ -268,6 +271,22 @@ } } +# time variable definitions +($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); +$year = ($year + 1900); +$mon++; +$wtoday = $wday; +if ($mon < 10) {$mon = "0$mon";} +if ($mday < 10) {$mday = "0$mday";} +if ($hour < 10) {$hour = "0$hour";} +if ($min < 10) {$min = "0$min";} +if ($sec < 10) {$sec = "0$sec";} +$now_date = "$year-$mon-$mday $hour:$min:$sec"; +$dateint = "$year$mon$mday$hour$min$sec"; +$today_start = "$year-$mon-$mday 00:00:00"; +$today_date = "$year-$mon-$mday"; +$hm = "$hour$min"; + ### directory where in/out recordings are saved to by Asterisk $dir1 = "$PATHmonitor"; $dir2 = "$PATHDONEmonitor"; @@ -660,6 +679,10 @@ if($DBX){print STDERR "\n|$stmtA|\n";} $affected_rows = $dbhA->do($stmtA); # or die "Couldn't execute query:|$stmtA|\n"; + $stmtA = "UPDATE recording_live set end_time=NOW(),recording_status='FINISHED FILE-MERGE' where recording_id='$recording_id' and recording_status='STARTED';"; + if($DBX){print STDERR "\n|$stmtA|\n";} + $affected_rows = $dbhA->do($stmtA); # or die "Couldn't execute query:|$stmtA|\n"; + ### sleep for twenty hundredths of a second to not flood the server with disk activity usleep(1*200*1000); @@ -687,6 +710,63 @@ print "Run time: $run_length seconds \n"; } +if ($SSstereo_recording > 0) + { + $PATHmonitorS = $PATHmonitor.'S'; + $PATHmonitorP = $PATHmonitor.'P'; + + if($DBX) + {print "Checking for Stereo Call Recordings in $PATHmonitorS \n";} + + opendir(sFILE, "$PATHmonitorS/"); + @sFILES = readdir(sFILE); + + ### Loop through files first to gather filesizes + $trigger_stereo=0; + $i=0; + foreach(@sFILES) + { + if ( (length($sFILES[$i]) > 4) && (!-d "$dir1/$sFILES[$i]") && ($sFILES[$i] =~ /\.wav$/i) ) + { + $trigger_stereo++; + if ($DBX) {print "Stereo file found! $sFILES[$i] \n";} + last; + } + $i++; + } + + if ( ($SSstereo_parallel_recording > 0) && ($trigger_stereo < 1) ) + { + if($DBX) + {print "Checking for Stereo Parallel Call Recordings in $PATHmonitorP \n";} + + opendir(pFILE, "$PATHmonitorP/"); + @pFILES = readdir(pFILE); + + ### Loop through files first to gather filesizes + $trigger_stereo=0; + $i=0; + foreach(@pFILES) + { + if ( (length($pFILES[$i]) > 4) && (!-d "$dir1/$pFILES[$i]") && ($pFILES[$i] =~ /\.wav$/i) ) + { + $trigger_stereo++; + if ($DBX) {print "Stereo Parallel file found! $pFILES[$i] \n";} + last; + } + $i++; + } + } + + if ($trigger_stereo > 0) + { + # command to trigger stereo call file processing, preserving flags from this script: + $stereo_command = "$PATHhome/AST_CRON_audio_1_stereo.pl $args "; + if ($DBX) {print "Triggering Stereo call file processing... |$stereo_command| \n";} + `/usr/bin/screen -d -m -S SP$hm $stereo_command `; + } + } + if ($DB) {print "DONE... EXITING\n\n";} $sthA->finish(); diff --git a/bin/AST_CRON_audio_1_move_mix.pl b/bin/AST_CRON_audio_1_move_mix.pl index 409355f58..9557187fe 100644 --- a/bin/AST_CRON_audio_1_move_mix.pl +++ b/bin/AST_CRON_audio_1_move_mix.pl @@ -14,8 +14,8 @@ # ### recording mixing/compressing/ftping scripts # 0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57 * * * * /usr/share/astguiclient/AST_CRON_audio_1_move_mix.pl --MIX ##0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57 * * * * /usr/share/astguiclient/AST_CRON_audio_1_move_VDonly.pl -# 1,4,7,10,13,16,19,22,25,28,31,34,37,40,43,46,49,52,55,58 * * * * /usr/share/astguiclient/AST_CRON_audio_2_compress.pl --GSM -# 2,5,8,11,14,17,20,23,26,29,32,35,38,41,44,47,50,53,56,59 * * * * /usr/share/astguiclient/AST_CRON_audio_3_ftp.pl --GSM +# 1,4,7,10,13,16,19,22,25,28,31,34,37,40,43,46,49,52,55,58 * * * * /usr/share/astguiclient/AST_CRON_audio_2_compress.pl --MP3 +# 2,5,8,11,14,17,20,23,26,29,32,35,38,41,44,47,50,53,56,59 * * * * /usr/share/astguiclient/AST_CRON_audio_3_ftp.pl --MP3 # # make sure that the following directories exist: # /var/spool/asterisk/monitor # default Asterisk recording directory diff --git a/bin/AST_CRON_audio_1_stereo.pl b/bin/AST_CRON_audio_1_stereo.pl new file mode 100644 index 000000000..f0aaf63ba --- /dev/null +++ b/bin/AST_CRON_audio_1_stereo.pl @@ -0,0 +1,970 @@ +#!/usr/bin/perl +# +# AST_CRON_audio_1_stereo.pl +# +# This is a STEP-1 program in the audio archival process +# +# IMPORTANT!!! ONLY TO BE USED WHEN STEREO VICIDIAL CALL RECORDINGS ARE ON THE SYSTEM! +# +# runs every 3 minutes if there are stereo call recording files to process. +# Processes audio and moves to other directories for further processing. +# +# Do NOT put this script in the crontab! It is launched as needed by the +# "AST_CRON_audio_1_move_VDonly.pl" script, which should be run every 3 minutes +# +# make sure that the following directories exist: +# /var/spool/asterisk/monitorS # default Asterisk stereo recording directory +# /var/spool/asterisk/monitorP # default Asterisk stereo parallel recording directory +# /var/spool/asterisk/monitorTRASH # where the used parallel files are put +# /var/spool/asterisk/monitorDONE # where the mixed -all files are put +# /var/spool/asterisk/monitor/ORIG # where the original -in and -out files are put +# +# This program assumes that recordings are saved by Asterisk as .wav +# +# Copyright (C) 2025 Matt Florell LICENSE: AGPLv2 +# +# +# 250909-0955 - First Build +# + +$HTTPS=0; +$status_post_logs=0; +$delay_post_live=0; +$ignore_parallel=0; +$now_epoch = int(time()); + +### begin parsing run-time options ### +if (length($ARGV[0])>1) + { + $i=0; + while ($#ARGV >= $i) + { + $args = "$args $ARGV[$i]"; + $i++; + } + + if ($args =~ /--help/i) + { + print "allowed run time options:\n"; + print " [--help] = this screen\n"; + print " [--quiet] = suppress output, if possible\n"; + print " [--debug] = debug\n"; + print " [--debugX] = super debug\n"; + print " [--test] = test\n"; + print " [--ignore-parallel] = do not process parallel stereo recordings\n"; + print " [--HTTPS] = use https instead of http in local location\n"; + print " [--POST] = post call variable filename replacement, MUST define STATUS and CAMP below\n"; + print " [--STATUS-POST=X] = only run post call variable filename replacement on specific status calls\n"; + print " If multiple statuses, use --- delimiting, i.e.: SALE---PRESALE\n"; + print " For status wildcards, use * flag, i.e.: S* to match SALE and SQUAL\n"; + print " For all statuses, use ----ALL----\n"; + print " \n"; + print " [--CAMP-POST=X] = only run post call variable filename replacement on specific campaigns or ingroups\n"; + print " If multiple campaigns or ingroups, use --- delimiting, i.e.: TESTCAMP---TEST_IN2\n"; + print " For all calls, use ----ALL----\n"; + print " [--CLEAR-POST-NO-MATCH] = clear POST filename variables if no match is found\n"; + print " [--STATUS-POST-LOGS] = use the call logs for POST filename status variable, if found\n"; + print " [--DELAY-POST-LIVE-CALLS] = delay processing of recordings using POST filename variables if any live calls/agents for lead\n"; + print "\n"; + exit; + } + else + { + if ($args =~ /--quiet/) + { + $q=1; + } + if ($args =~ /--debug/i) + { + $DB=1; + print "\n----- DEBUG -----\n\n"; + } + if ($args =~ /--debugX/i) + { + $DBX=1; + print "\n----- SUPER DEBUG -----\n\n"; + } + if ($args =~ /--test/) + { + $T=1; $TEST=1; + if ($q < 1) {print "\n-----TESTING -----\n\n";} + } + if ($args =~ /--ignore-parallel/) + { + $ignore_parallel=1; + if ($q < 1) {print "\n----- IGNORING PARALLEL CALL RECORDINGS -----\n\n";} + } + if ($args =~ /--HTTPS/i) + { + $HTTPS=1; + if ($DB) {print "HTTPS location option enabled\n";} + } + if ($args =~ /--POST/i) + { + $POST=1; + if ($DB) {print "POST post call variable filename replacement\n";} + + if ($args =~ /--STATUS-POST=/i) + { + @data_in = split(/--STATUS-POST=/,$args); + $status_post = $data_in[1]; + $status_post =~ s/ .*//gi; + if ($q < 1) {print "\n----- STATUS POST SET: $status_post -----\n\n";} + } + else + { + $POST=0; + if ($q < 1) {print "\n----- POST disabled, no status set -----\n\n";} + } + + if ($args =~ /--CAMP-POST=/i) + { + @data_in = split(/--CAMP-POST=/,$args); + $camp_post = $data_in[1]; + $camp_post =~ s/ .*//gi; + if ($q < 1) {print "\n----- CAMP POST SET: $camp_post -----\n\n";} + } + else + { + $POST=0; + if ($q < 1) {print "\n----- POST disabled, no campaigns set -----\n\n";} + } + if ($args =~ /--STATUS-POST-LOGS/i) + { + $status_post_logs=1; + if ($q < 1) {print "\n----- STATUS POST LOGS SET: $status_post_logs -----\n\n";} + } + if ($args =~ /--DELAY-POST-LIVE-CALLS/i) + { + $delay_post_live=1; + if ($q < 1) {print "\n----- DELAY POST LIVE SET: $delay_post_live -----\n\n";} + } + } + if ($args =~ /--CLEAR-POST-NO-MATCH/i) + { + $CLEAR_POST=1; + if ($DB) {print "--- CLEAR-POST-NO-MATCH ENABLED ---\n";} + } + } + + if ( ($POST > 0) && ( (length($camp_post) < 1) || (length($status_post) < 1) ) ) + { + $POST=0; + if ($q < 1) {print "\n----- POST disabled, status or campaign invalid: |$camp_post|$status_post| -----\n\n";} + } + } +else + { + #print "no command line options set\n"; + } + + +# default path to astguiclient configuration file: +$PATHconf = '/etc/astguiclient.conf'; + +open(conf, "$PATHconf") || die "can't open $PATHconf: $!\n"; +@conf = ; +close(conf); +$i=0; +foreach(@conf) + { + $line = $conf[$i]; + $line =~ s/ |>|\n|\r|\t|\#.*|;.*//gi; + if ( ($line =~ /^PATHhome/) && ($CLIhome < 1) ) + {$PATHhome = $line; $PATHhome =~ s/.*=//gi;} + if ( ($line =~ /^PATHlogs/) && ($CLIlogs < 1) ) + {$PATHlogs = $line; $PATHlogs =~ s/.*=//gi;} + if ( ($line =~ /^PATHagi/) && ($CLIagi < 1) ) + {$PATHagi = $line; $PATHagi =~ s/.*=//gi;} + if ( ($line =~ /^PATHweb/) && ($CLIweb < 1) ) + {$PATHweb = $line; $PATHweb =~ s/.*=//gi;} + if ( ($line =~ /^PATHsounds/) && ($CLIsounds < 1) ) + {$PATHsounds = $line; $PATHsounds =~ s/.*=//gi;} + if ( ($line =~ /^PATHmonitor/) && ($CLImonitor < 1) ) + {$PATHmonitor = $line; $PATHmonitor =~ s/.*=//gi;} + if ( ($line =~ /^PATHDONEmonitor/) && ($CLIDONEmonitor < 1) ) + {$PATHDONEmonitor = $line; $PATHDONEmonitor =~ s/.*=//gi;} + if ( ($line =~ /^VARserver_ip/) && ($CLIserver_ip < 1) ) + {$VARserver_ip = $line; $VARserver_ip =~ s/.*=//gi;} + if ( ($line =~ /^VARDB_server/) && ($CLIDB_server < 1) ) + {$VARDB_server = $line; $VARDB_server =~ s/.*=//gi;} + if ( ($line =~ /^VARDB_database/) && ($CLIDB_database < 1) ) + {$VARDB_database = $line; $VARDB_database =~ s/.*=//gi;} + if ( ($line =~ /^VARDB_user/) && ($CLIDB_user < 1) ) + {$VARDB_user = $line; $VARDB_user =~ s/.*=//gi;} + if ( ($line =~ /^VARDB_pass/) && ($CLIDB_pass < 1) ) + {$VARDB_pass = $line; $VARDB_pass =~ s/.*=//gi;} + if ( ($line =~ /^VARDB_port/) && ($CLIDB_port < 1) ) + {$VARDB_port = $line; $VARDB_port =~ s/.*=//gi;} + if ( ($line =~ /^VARFTP_host/) && ($CLIFTP_host < 1) ) + {$VARFTP_host = $line; $VARFTP_host =~ s/.*=//gi;} + if ( ($line =~ /^VARFTP_user/) && ($CLIFTP_user < 1) ) + {$VARFTP_user = $line; $VARFTP_user =~ s/.*=//gi;} + if ( ($line =~ /^VARFTP_pass/) && ($CLIFTP_pass < 1) ) + {$VARFTP_pass = $line; $VARFTP_pass =~ s/.*=//gi;} + if ( ($line =~ /^VARFTP_port/) && ($CLIFTP_port < 1) ) + {$VARFTP_port = $line; $VARFTP_port =~ s/.*=//gi;} + if ( ($line =~ /^VARFTP_dir/) && ($CLIFTP_dir < 1) ) + {$VARFTP_dir = $line; $VARFTP_dir =~ s/.*=//gi;} + if ( ($line =~ /^VARHTTP_path/) && ($CLIHTTP_path < 1) ) + {$VARHTTP_path = $line; $VARHTTP_path =~ s/.*=//gi;} + $i++; + } + +# Customized Variables +$server_ip = $VARserver_ip; # Asterisk server IP +if (!$VARDB_port) {$VARDB_port='3306';} + +use Time::HiRes ('gettimeofday','usleep','sleep'); # necessary to have perl sleep command of less than one second +use DBI; + +$dbhA = DBI->connect("DBI:mysql:$VARDB_database:$VARDB_server:$VARDB_port", "$VARDB_user", "$VARDB_pass") + or die "Couldn't connect to database: " . DBI->errstr; + +##### Get the settings from system_settings ##### +$SSmute_recordings=0; +$stmtA = "SELECT mute_recordings,stereo_recording,stereo_parallel_recording FROM system_settings;"; +$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; +$sthA->execute or die "executing: $stmtA ", $dbhA->errstr; +$sthArows=$sthA->rows; +if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $SSmute_recordings = $aryA[0]; + $SSstereo_recording = $aryA[1]; + $SSstereo_parallel_recording = $aryA[2]; + } +$sthA->finish(); + +##### Get the settings from servers ##### +$vicidial_recording_limit=0; +$stmtA = "SELECT vicidial_recording_limit FROM servers where server_ip='$server_ip';"; +$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; + $vicidial_recording_limit = $aryA[0]; + $start_epoch_test = ($now_epoch - ( ($vicidial_recording_limit * 2) * 60) ); + } +$sthA->finish(); + +# calculate server recording limit time, plus 60 minutes +($Rsec,$Rmin,$Rhour,$Rmday,$Rmon,$Ryear,$Rwday,$Ryday,$Risdst) = localtime(time() - (($vicidial_recording_limit + 60) * 60)); +$Ryear = ($Ryear + 1900); +$Ryy = $Ryear; $Ryy =~ s/^..//gi; +$Rmon++; +if ($Rmon < 10) {$Rmon = "0$Rmon";} +if ($Rmday < 10) {$Rmday = "0$Rmday";} +if ($Rhour < 10) {$Rhour = "0$Rhour";} +if ($Rmin < 10) {$Rmin = "0$Rmin";} +if ($Rsec < 10) {$Rsec = "0$Rsec";} +$SQLdate_REC_limit="$Ryear-$Rmon-$Rmday $Rhour:$Rmin:$Rsec"; + +### find soxmix or sox to do the mixing +$soxbin = ''; +if ( -e ('/usr/bin/sox')) {$soxbin = '/usr/bin/sox';} +else + { + if ( -e ('/usr/local/bin/sox')) {$soxbin = '/usr/local/bin/sox';} + else + { + print "Can't find sox binary! Exiting...\n"; + exit; + } + } + +### find soxi to gather the length info if needed +$soxibin = ''; +if ( -e ('/usr/bin/soxi')) {$soxibin = '/usr/bin/soxi';} +else + { + if ( -e ('/usr/local/bin/soxi')) {$soxibin = '/usr/local/bin/soxi';} + else + { + if ( -e ('/usr/sbin/soxi')) {$soxibin = '/usr/sbin/soxi';} + else + { + if ($DB) {print "Can't find soxi binary! No length calculations will be available...\n";} + } + } + } + +if ($SSstereo_recording < 1) + { + if ($DB) {print "Stereo Call Recording is disabled on this system, exiting... |$SSstereo_recording| \n";} + exit; + } + +### directory where in/out recordings are saved to by Asterisk +$dir1 = $PATHmonitor.'S'; +$dir2 = "$PATHDONEmonitor"; +$PATHmonitorP = $PATHmonitor.'P'; +$PATHmonitorTRASH = $PATHmonitor.'TRASH'; + + + +#################################################### +##### BEGIN parallel call recording processing ##### +#################################################### +if ( ($ignore_parallel < 1) && ($SSstereo_parallel_recording > 0) ) + { + if (!-e "$PATHmonitorTRASH/one-sec-silence.wav") + { + # generate 1 second silence file, to be used to create stereo files with only one side having audio + `$soxbin -n -c 1 -r 8k -b 16 "$PATHmonitorTRASH/one-sec-silence.wav" synth 1 sine 0`; + if($DBX){print "Created one-sec-silence.wav audio file. \n";} + } + + opendir(pFILE, "$PATHmonitorP/"); + @pFILES = readdir(pFILE); + + ### Loop through files first to gather filesizes + $parallel_files_ct=0; + $i=0; + foreach(@pFILES) + { + $pFILEsize1[$i] = 0; + if ( (length($pFILES[$i]) > 4) && (!-d "$PATHmonitorP/$pFILES[$i]") ) + { + $parallel_files_ct++; + $pFILEsize1[$i] = (-s "$PATHmonitorP/$pFILES[$i]"); + if ($DBX) {print "$parallel_files_ct $pFILES[$i] $pFILEsize1[$i]\n";} + } + $i++; + } + + if ($parallel_files_ct < 1) + { + if ($DBX) {print "No parallel files found to process: $parallel_files_ct \n";} + } + else + { + sleep(15); + + ### Loop through files a second time to gather filesizes again 5 seconds later + $i=0; + $active_recordings=0; + $delay_ct=0; + $processed_ct=0; + $stereo_rec_made=0; + foreach(@pFILES) + { + $lead_id=0; + $vicidial_id=''; + $pFILEsize2[$i] = 0; + + if ( (length($pFILES[$i]) > 4) && (!-d "$PATHmonitorP/$pFILES[$i]") ) + { + $pFILEsize2[$i] = (-s "$PATHmonitorP/$pFILES[$i]"); + if ($DBX) {print "$pFILES[$i] $pFILEsize2[$i]\n\n";} + + if ( ($pFILES[$i] !~ /out\.wav|out\.gsm|lost\+found/i) && ($pFILEsize1[$i] eq $pFILEsize2[$i]) && (length($pFILES[$i]) > 4)) + { + $process_recording=0; + $INfile = $pFILES[$i]; + $OUTfile = $pFILES[$i]; + $OUTfile =~ s/-in\.wav/-out.wav/gi; + $OUTfile =~ s/-in\.gsm/-out.gsm/gi; + $ALLfile = $pFILES[$i]; + $ALLfile =~ s/-in\.wav/-all.wav/gi; + $ALLfile =~ s/-in\.gsm/-all.gsm/gi; + $SQLpFILE = $pFILES[$i]; + $SQLpFILE =~ s/-in\.wav|-in\.gsm//gi; + $filenameSQL=''; + + $length_in_sec=0; + $rec_ended=0; + $start_epoch=0; + $stmtA = "SELECT parallel_recording_id,channel,length_in_sec,lead_id,vicidial_id,start_time,end_time,user,UNIX_TIMESTAMP(start_time),recording_status from recording_log_parallel where filename='$SQLpFILE' and server_ip='$server_ip' and start_time >= \"$SQLdate_REC_limit\" order by parallel_recording_id desc LIMIT 1;"; + if($DBX){print STDERR "\n|$stmtA|\n";} + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $parallel_recording_id = $aryA[0]; + $channel = $aryA[1]; + $length_in_sec = $aryA[2]; + $lead_id = $aryA[3]; + $vicidial_id = $aryA[4]; + $start_time = $aryA[5]; + $end_time = $aryA[6]; + $user = $aryA[7]; + $start_epoch = $aryA[8]; + $recording_status = $aryA[9]; + if (length($end_time) > 15) {$rec_ended=1;} + $process_recording=1; + } + $sthA->finish(); + + # get the length of the file from soxi + @soxi_output = `$soxibin -D $PATHmonitorP/$pFILES[$i]`; + $soxi_sec = $soxi_output[0]; + $soxi_sec =~ s/\..*|\n|\r| //gi; + + ### process the recording files + if ($process_recording > 0) + { + $stereo_rec_ids='Stereo Rec IDs:'; + if ($DB) {print "|$parallel_recording_id|$length_in_sec($soxi_sec)|$INfile| \n";} + + # Look for stereo recordings using this parallel_recording_id + $stmtA = "SELECT filename,lead_id,recording_id,options,start_time,end_time,UNIX_TIMESTAMP(start_time),UNIX_TIMESTAMP(end_time) FROM recording_log_stereo where start_time >= \"$SQLdate_REC_limit\" and parallel_recording_id='$parallel_recording_id' and server_ip='$server_ip' order by recording_id limit 10;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArowsRECS=$sthA->rows; + if ($DBX) {print "DEBUG: $sthArowsRECS|$stmtA|\n";} + $prc=0; + while ($sthArowsRECS > $prc) + { + @aryA = $sthA->fetchrow_array; + $PR_filenameIN[$prc] = $aryA[0]."-in.wav"; + $PR_filenameOUT[$prc] = $aryA[0]."-out.wav"; + $PR_lead_id[$prc] = $aryA[1]; + $PR_recording_id[$prc] = $aryA[2]; + $PR_options[$prc] = $aryA[3]; + $PR_start_time[$prc] = $aryA[4]; + $PR_end_time[$prc] = $aryA[5]; + $PR_start_epoch[$prc] = $aryA[6]; + $PR_end_epoch[$prc] = $aryA[7]; + if ( ($PR_end_epoch[$prc] =~ /^NULL$/i) || ($PR_end_epoch[$prc] < 1000) || (length($PR_end_epoch[$prc]) < 4) ) + {$PR_end_epoch[$prc] = ($start_epoch + $soxi_sec);} + $prc++; + } + $sthA->finish(); + + $prc=0; + while ($sthArowsRECS > $prc) + { + $stereo_file_processed=0; + if ($PR_options[$prc] =~ /AGENT-CONTROLLED/) + { + $temp_start_test = ($PR_start_epoch[$prc] - $start_epoch); + $temp_ac_length = ($PR_end_epoch[$prc] - $PR_start_epoch[$prc]); + $temp_length_test = ($soxi_sec - $temp_ac_length); + + # if agent-controlled file is shorter than, or starts after parallel file, use sox to create shorter file matching start/stop + if ( ($temp_start_test > 2) || ($temp_length_test > 4) ) + { + if ($PR_options[$prc] =~ /CUSTOMER_ONLY/) + { + # stereo recording is shorter than parallel recording, copy Left(-in/silence) and trim Right channels to stereo mixing directory + $mix_commandA = "cp -f $PATHmonitorTRASH/one-sec-silence.wav $dir1/$PR_filenameIN[$prc]"; + $mix_commandB = "$soxbin \"$PATHmonitorP/$OUTfile\" \"$dir1/$PR_filenameOUT[$prc]\" trim $temp_start_test $temp_ac_length"; + $stereo_file_processed++; + } + if ($PR_options[$prc] =~ /CUSTOMER_MUTE/) + { + # stereo recording is shorter than parallel recording, trim Left and copy Right(-out/silence) channels to stereo mixing directory + $mix_commandA = "$soxbin \"$PATHmonitorP/$INfile\" \"$dir1/$PR_filenameIN[$prc]\" trim $temp_start_test $temp_ac_length"; + $mix_commandB = "cp -f $PATHmonitorTRASH/one-sec-silence.wav $dir1/$PR_filenameOUT[$prc]"; + $stereo_file_processed++; + } + if ( ($stereo_file_processed < 1) || ($PR_options[$prc] =~ /BOTH_CHANNELS/) ) + { + # stereo recording is shorter than parallel recording, merge Left and Right channels into a single Stereo WAV audio file + $mix_commandA = "$soxbin \"$PATHmonitorP/$INfile\" \"$dir1/$PR_filenameIN[$prc]\" trim $temp_start_test $temp_ac_length"; + $mix_commandB = "$soxbin \"$PATHmonitorP/$OUTfile\" \"$dir1/$PR_filenameOUT[$prc]\" trim $temp_start_test $temp_ac_length"; + $stereo_file_processed++; + } + } + else + { + if ($PR_options[$prc] =~ /CUSTOMER_ONLY/) + { + # stereo recording is same length as parallel recording, copy Left(-in/silence) and Right channels to stereo mixing directory + $mix_commandA = "cp -f $PATHmonitorTRASH/one-sec-silence.wav $dir1/$PR_filenameIN[$prc]"; + $mix_commandB = "cp -f $PATHmonitorP/$OUTfile $dir1/$PR_filenameOUT[$prc]"; + $stereo_file_processed++; + } + if ($PR_options[$prc] =~ /CUSTOMER_MUTE/) + { + # stereo recording is same length as parallel recording, copy Left and Right(-out/silence) channels to stereo mixing directory + $mix_commandA = "cp -f $PATHmonitorP/$INfile $dir1/$PR_filenameIN[$prc]"; + $mix_commandB = "cp -f $PATHmonitorTRASH/one-sec-silence.wav $dir1/$PR_filenameOUT[$prc]"; + $stereo_file_processed++; + } + if ( ($stereo_file_processed < 1) || ($PR_options[$prc] =~ /BOTH_CHANNELS/) ) + { + # stereo recording is same length as parallel recording, copy Left and Right channels to stereo mixing directory + $mix_commandA = "cp -f $PATHmonitorP/$INfile $dir1/$PR_filenameIN[$prc]"; + $mix_commandB = "cp -f $PATHmonitorP/$OUTfile $dir1/$PR_filenameOUT[$prc]"; + $stereo_file_processed++; + } + } + } + + if ( ($PR_options[$prc] =~ /CUSTOMER-ONLY/) && ($stereo_file_processed < 1) ) + { + # stereo recording is same length as parallel recording, copy Left(-in/silence) and Right channels to stereo mixing directory + $mix_commandA = "cp -f $PATHmonitorTRASH/one-sec-silence.wav $dir1/$PR_filenameIN[$prc]"; + $mix_commandB = "cp -f $PATHmonitorP/$OUTfile $dir1/$PR_filenameOUT[$prc]"; + $stereo_file_processed++; + } + if ( ($PR_options[$prc] =~ /CUSTOMER-MUTED/) && ($stereo_file_processed < 1) ) + { + # stereo recording is same length as parallel recording, copy Left and Right(-out/silence) channels to stereo mixing directory + $mix_commandA = "cp -f $PATHmonitorP/$INfile $dir1/$PR_filenameIN[$prc]"; + $mix_commandB = "cp -f $PATHmonitorTRASH/one-sec-silence.wav $dir1/$PR_filenameOUT[$prc]"; + $stereo_file_processed++; + } + if ( ($PR_options[$prc] =~ /FULL-RECORDING/) && ($stereo_file_processed < 1) ) + { + # stereo recording is same length as parallel recording, copy Left and Right channels to stereo mixing directory + $mix_commandA = "cp -f $PATHmonitorP/$INfile $dir1/$PR_filenameIN[$prc]"; + $mix_commandB = "cp -f $PATHmonitorP/$OUTfile $dir1/$PR_filenameOUT[$prc]"; + $stereo_file_processed++; + } + + if ($stereo_file_processed > 0) + { + `$mix_commandA`; + `$mix_commandB`; + $stereo_rec_made++; + $stereo_rec_ids .= " $PR_recording_id[$prc]"; + if($DBX){print "Copy commands run: |$stereo_rec_made|$prc|$mix_commandA|$mix_commandB|\n";} + } + else + { + if($DBX){print "ERROR, file cannot be processed: |$prc|$parallel_recording_id|$PR_recording_id[$prc]|$PR_filename[$prc]|\n";} + } + + $prc++; + } + + if (!$T) + { + `mv -f "$PATHmonitorP/$INfile" "$PATHmonitorTRASH/$INfile"`; + `mv -f "$PATHmonitorP/$OUTfile" "$PATHmonitorTRASH/$OUTfile"`; + } + + $lengthSQL=''; + if ( ( ($length_in_sec < 1) || ($length_in_sec =~ /^NULL$/i) || (length($length_in_sec)<1) ) && (length($soxibin) > 3) ) + { + $lengthSQL = ",length_in_sec='$soxi_sec'"; + } + + $stmtA = "UPDATE recording_log_parallel set recording_status='PROCESSED', processing_log=CONCAT(processing_log,' $stereo_rec_ids') $lengthSQL where parallel_recording_id='$parallel_recording_id';"; + if($DBX){print STDERR "\n|$stmtA|\n";} + $affected_rows = $dbhA->do($stmtA); # or die "Couldn't execute query:|$stmtA|\n"; + + ### sleep for twenty hundredths of a second to not flood the server with disk activity + usleep(1*200*1000); + + $processed_ct++; + } + } + else + {$active_recordings++;} + } + $i++; + } + + if($DBX) + { + $end_epoch = int(time()); + $run_length = ($end_epoch - $now_epoch); + + print "\nPARALLEL RECORDING Debug output:\n"; + print "Total parallel files: $i \n"; + print " Active recordings: $active_recordings \n"; + print " Processed files: $processed_ct \n"; + print " Stereo files made: $stereo_rec_made \n"; + print "\n"; + print "Run time: $run_length seconds \n"; + } + } + } +################################################## +##### END parallel call recording processing ##### +################################################## + + + + + +################################################## +##### BEGIN stereo call recording processing ##### +################################################## + +opendir(FILE, "$dir1/"); +@FILES = readdir(FILE); + + +### Loop through files first to gather filesizes +$i=0; +foreach(@FILES) + { + $FILEsize1[$i] = 0; + if ( (length($FILES[$i]) > 4) && (!-d "$dir1/$FILES[$i]") ) + { + $FILEsize1[$i] = (-s "$dir1/$FILES[$i]"); + if ($DBX) {print "$FILES[$i] $FILEsize1[$i]\n";} + } + $i++; + } + +sleep(15); + + +### Loop through files a second time to gather filesizes again 5 seconds later +$i=0; +$active_recordings=0; +$delay_ct=0; +$processed_ct=0; +$post_status_change_ct=0; +foreach(@FILES) + { + $lead_id=0; + $vicidial_id=''; + $FILEsize2[$i] = 0; + + if ( (length($FILES[$i]) > 4) && (!-d "$dir1/$FILES[$i]") ) + { + $FILEsize2[$i] = (-s "$dir1/$FILES[$i]"); + if ($DBX) {print "$FILES[$i] $FILEsize2[$i]\n\n";} + + if ( ($FILES[$i] !~ /out\.wav|out\.gsm|lost\+found/i) && ($FILEsize1[$i] eq $FILEsize2[$i]) && (length($FILES[$i]) > 4)) + { + $INfile = $FILES[$i]; + $OUTfile = $FILES[$i]; + $OUTfile =~ s/-in\.wav/-out.wav/gi; + $OUTfile =~ s/-in\.gsm/-out.gsm/gi; + $ALLfile = $FILES[$i]; + $ALLfile =~ s/-in\.wav/-all.wav/gi; + $ALLfile =~ s/-in\.gsm/-all.gsm/gi; + $SQLFILE = $FILES[$i]; + $SQLFILE =~ s/-in\.wav|-in\.gsm//gi; + $filenameSQL=''; + + $length_in_sec=0; + $rec_ended=0; + $start_epoch=0; + $stmtA = "SELECT recording_id,length_in_sec,lead_id,vicidial_id,start_time,end_time,user,UNIX_TIMESTAMP(start_time) from recording_log where filename='$SQLFILE' order by recording_id desc LIMIT 1;"; + if($DBX){print STDERR "\n|$stmtA|\n";} + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + $length_in_sec = $aryA[1]; + $lead_id = $aryA[2]; + $vicidial_id = $aryA[3]; + $start_time = $aryA[4]; + $end_time = $aryA[5]; + $user = $aryA[6]; + $start_epoch = $aryA[7]; + if (length($end_time) > 15) {$rec_ended=1;} + } + $sthA->finish(); + + $process_recording=1; + ### this is where code for agent-muted recordings went, if found then delay processing(not available for stereo call recordings) + + ### check for POST variables, and delay setting + if ( ($delay_post_live > 0) && ($POST > 0) && ($ALLfile =~ /POSTVLC|POSTSP|POSTADDR3|POSTSTATUS/) ) + { + if ($lead_id > 0) + { + $VLA_count=0; + $VAC_count=0; + if ( ($start_epoch > 0) && ($start_epoch < $start_epoch_test) ) + { + if ($DBX > 0) {print "DEBUG6: delay processing past server limit, process now: ($start_epoch|$start_epoch_test) |$SQLFILE|ended: $rec_ended|\n";} + } + else + { + if ($DBX > 0) {print "DEBUG7: delay processing not past server limit yet: ($start_epoch|$start_epoch_test) |$SQLFILE|ended: $rec_ended|\n";} + + ### check if any live agents are connected to this lead_id right now + $stmtA = "SELECT count(*) from vicidial_live_agents where lead_id='$lead_id';"; + if($DBX){print STDERR "\n|$stmtA|\n";} + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $VLA_count = $aryA[0]; + } + $sthA->finish(); + + ### check if any live calls are tied to this lead_id right now + $stmtA = "SELECT count(*) from vicidial_auto_calls where lead_id='$lead_id';"; + if($DBX){print STDERR "\n|$stmtA|\n";} + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $VAC_count = $aryA[0]; + } + $sthA->finish(); + } + + if ( ($VLA_count > 0) || ($VAC_count > 0) ) + { + if ($DBX > 0) {print "DEBUG4: delay processing active, do not process: ($VLA_count|$VAC_count) |$SQLFILE|ended: $rec_ended|\n";} + $process_recording=0; + $delay_ct++; + } + else + { + if ($DBX > 0) {print "DEBUG5: delay processing - no calls or agents found, OK to process: ($VLA_count|$VAC_count) |$SQLFILE|ended: $rec_ended|\n";} + } + } + } + + ### process the recording files + if ($process_recording > 0) + { + if ($DB) {print "|$recording_id|$length_in_sec|$INfile| |$ALLfile|\n";} + + # merge Left and Right channels into a single Stereo WAV audio file + `$soxbin -M "$dir1/$INfile" "$dir1/$OUTfile" "$dir2/$ALLfile"`; + + if (!$T) + { + `mv -f "$dir1/$INfile" "$dir2/ORIG/$INfile"`; + `mv -f "$dir1/$OUTfile" "$dir2/ORIG/$OUTfile"`; + } + + $lengthSQL=''; + if ( ( ($length_in_sec < 1) || ($length_in_sec =~ /^NULL$/i) || (length($length_in_sec)<1) ) && (length($soxibin) > 3) ) + { + @soxi_output = `$soxibin -D $dir2/$ALLfile`; + $soxi_sec = $soxi_output[0]; + $soxi_sec =~ s/\..*|\n|\r| //gi; + $soxi_min = ($soxi_sec / 60); + $soxi_min = sprintf("%.2f", $soxi_min); + $lengthSQL = ",length_in_sec='$soxi_sec',length_in_min='$soxi_min'"; + } + + ##### BEGIN post call variable replacement ##### + if ($POST > 0) + { + if ($ALLfile =~ /POSTVLC|POSTSP|POSTADDR3|POSTSTATUS/) + { + $origALLfile = $ALLfile; + $origSQLFILE = $SQLFILE; + $vendor_lead_code=''; $security_phrase=''; $address3=''; $status=''; + $status_ALL=0; + $camp_ALL=0; + $camp_status_selected=0; + + if ($status_post =~ /----ALL----/) + { + $status_ALL++; + if($DBX){print "All Statuses: |$status_post|$status_ALL|\n";} + } + + if ($camp_post =~ /----ALL----/) + { + $camp_ALL++; + if($DBX){print "All Campaigs and Ingroups: |$camp_post|$camp_ALL|\n";} + } + + if ( ($camp_ALL < 1) || ($status_ALL < 1) ) + { + $camp_postSQL=''; + if ($camp_ALL < 1) + { + $camp_postSQL = $camp_post; + $camp_postSQL =~ s/---/','/gi; + $camp_postSQL = "and campaign_id IN('$camp_postSQL')"; + } + if ($vicidial_id =~ /\./) + { + $log_lookupSQL = "SELECT status from vicidial_log where uniqueid='$vicidial_id' and lead_id='$lead_id' $camp_postSQL;"; + } + else + { + $log_lookupSQL = "SELECT status from vicidial_closer_log where closecallid='$vicidial_id' and lead_id='$lead_id' $camp_postSQL;"; + } + if($DBX){print STDERR "\n|$log_lookupSQL|\n";} + $sthA = $dbhA->prepare($log_lookupSQL) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $log_lookupSQL ", $dbhA->errstr; + $sthArows=$sthA->rows; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $lead_status = $aryA[0]; + if ($status_ALL > 0) + {$camp_status_selected++;} + else + { + @status_vars = split(/---/,$status_post); + $fc=0; + foreach(@status_vars) + { + $status_temp = $status_vars[$fc]; + if ($status_vars[$fc] =~ /\*/) + { + $status_temp =~ s/\*/.*/gi; + if ( ($lead_status =~ /^$status_temp/) && ($status_vars[$fc] =~ /\*$/) ) + {$camp_status_selected++;} + if ( ($lead_status =~ /$status_temp$/) && ($status_vars[$fc] =~ /^\*/) ) + {$camp_status_selected++;} + } + else + { + if ($lead_status =~ /^$status_temp$/) + {$camp_status_selected++;} + } + if ($DBX) {print " POST processing DEBUG: $fc|$status_temp|$lead_status|$lead_id|$vicidial_id|$ALLfile|\n";} + $fc++; + } + } + if ($DB) {print " POST processing SELECT: |$camp_status_selected|$sthArows|$camp_postSQL|$camp_ALL|$status_post|$status_ALL|$ALLfile|\n";} + } + else + {if ($DB) {print " POST processing ERROR: lead not found: |$lead_id|$ALLfile|\n";} } + $sthA->finish(); + } + + if ( ( ($camp_ALL > 0) && ($status_ALL > 0) ) || ($camp_status_selected > 0) ) + { + $stmtA = "SELECT vendor_lead_code,security_phrase,address3,status from vicidial_list where lead_id='$lead_id' LIMIT 1;"; + if($DBX){print STDERR "\n|$stmtA|\n";} + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $vendor_lead_code = $aryA[0]; + $security_phrase = $aryA[1]; + $address3 = $aryA[2]; + $status = $aryA[3]; + + $vendor_lead_code =~ s/[^a-zA-Z0-9_-]//gi; + $security_phrase =~ s/[^a-zA-Z0-9_-]//gi; + $address3 =~ s/[^a-zA-Z0-9_-]//gi; + $status =~ s/[^a-zA-Z0-9_-]//gi; + } + else + {if ($DB) {print " POST processing ERROR: lead not found: |$lead_id|$ALLfile|\n";} } + $sthA->finish(); + + if ( ($status_post_logs > 0) && ($ALLfile =~ /POSTSTATUS/) ) + { + $log_status = $status; + if ($vicidial_id =~ /\./) + { + $log_lookupSQL = "SELECT status from vicidial_log where uniqueid='$vicidial_id' and lead_id='$lead_id' and user='$user' order by call_date desc limit 1;"; + } + else + { + $log_lookupSQL = "SELECT status from vicidial_closer_log where closecallid='$vicidial_id' and lead_id='$lead_id' and user='$user' order by call_date desc limit 1;"; + } + if($DBX){print STDERR "\n|$log_lookupSQL|\n";} + $sthA = $dbhA->prepare($log_lookupSQL) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $log_lookupSQL ", $dbhA->errstr; + $sthArows=$sthA->rows; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $log_status = $aryA[0]; + } + + if ($log_status ne $status) + {$post_status_change_ct++;} + if ($DB) {print " POST processing Log status override: lead: |$status| log: |$log_status| $post_status_change_ct \n";} + $status = $log_status; + } + $ALLfile =~ s/POSTVLC/$vendor_lead_code/gi; + $ALLfile =~ s/POSTSP/$security_phrase/gi; + $ALLfile =~ s/POSTADDR3/$address3/gi; + $ALLfile =~ s/POSTSTATUS/$status/gi; + $SQLFILE =~ s/POSTVLC/$vendor_lead_code/gi; + $SQLFILE =~ s/POSTSP/$security_phrase/gi; + $SQLFILE =~ s/POSTADDR3/$address3/gi; + $SQLFILE =~ s/POSTSTATUS/$status/gi; + $filenameSQL = ",filename='$SQLFILE'"; + + `mv -f "$dir2/$origALLfile" "$dir2/$ALLfile"`; + + if ($DB) {print " POST processing COMPLETE: old: |$origALLfile| new: |$ALLfile|\n";} + } + else + { + if ($DB) {print " POST processing SKIPPED: |$camp_ALL|$status_ALL|$camp_status_selected|$lead_id|$vicidial_id|$ALLfile|\n";} + + if ($CLEAR_POST > 0) + { + $ALLfile =~ s/POSTVLC//gi; + $ALLfile =~ s/POSTSP//gi; + $ALLfile =~ s/POSTADDR3//gi; + $ALLfile =~ s/POSTSTATUS//gi; + $SQLFILE =~ s/POSTVLC//gi; + $SQLFILE =~ s/POSTSP//gi; + $SQLFILE =~ s/POSTADDR3//gi; + $SQLFILE =~ s/POSTSTATUS//gi; + $filenameSQL = ",filename='$SQLFILE'"; + + `mv -f "$dir2/$origALLfile" "$dir2/$ALLfile"`; + + if ($DB) {print " CLEAR POST COMPLETE: old: |$origALLfile| new: |$ALLfile|\n";} + } + } + } + else + {if ($DB) {print " POST processing ERROR: No variables found: |$ALLfile|\n";} } + } + ##### END post call variable replacement ##### + + $HTTP='http'; + if ($HTTPS > 0) {$HTTP='https';} + $stmtA = "UPDATE recording_log set location='$HTTP://$server_ip/RECORDINGS/$ALLfile' $filenameSQL $lengthSQL where recording_id='$recording_id';"; + if($DBX){print STDERR "\n|$stmtA|\n";} + $affected_rows = $dbhA->do($stmtA); # or die "Couldn't execute query:|$stmtA|\n"; + + $stmtA = "UPDATE recording_live set end_time=NOW(),recording_status='FINISHED FILE-MERGE' where recording_id='$recording_id' and recording_status='STARTED';"; + if($DBX){print STDERR "\n|$stmtA|\n";} + $affected_rows = $dbhA->do($stmtA); # or die "Couldn't execute query:|$stmtA|\n"; + + ### sleep for twenty hundredths of a second to not flood the server with disk activity + usleep(1*200*1000); + + $processed_ct++; + } + } + else + {$active_recordings++;} + } + $i++; + } + +if($DBX) + { + $end_epoch = int(time()); + $run_length = ($end_epoch - $now_epoch); + + print "\nDebug output:\n"; + print "Total files: $i \n"; + print " Active recordings: $active_recordings \n"; + print " Delayed processing: $delay_ct \n"; + print " Processed files: $processed_ct \n"; + print " POST log status diff: $post_status_change_ct \n"; + print "\n"; + print "Run time: $run_length seconds \n"; + } + +################################################ +##### END stereo call recording processing ##### +################################################ + + +if ($DB) {print "DONE... EXITING\n\n";} + +$sthA->finish(); +$dbhA->disconnect(); + + +exit; diff --git a/bin/AST_CRON_audio_2_compress.pl b/bin/AST_CRON_audio_2_compress.pl index e1db5d250..23cf17fe7 100644 --- a/bin/AST_CRON_audio_2_compress.pl +++ b/bin/AST_CRON_audio_2_compress.pl @@ -12,8 +12,8 @@ # ### recording mixing/compressing/ftping scripts ##0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57 * * * * /usr/share/astguiclient/AST_CRON_audio_1_move_mix.pl # 0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57 * * * * /usr/share/astguiclient/AST_CRON_audio_1_move_VDonly.pl -# 1,4,7,10,13,16,19,22,25,28,31,34,37,40,43,46,49,52,55,58 * * * * /usr/share/astguiclient/AST_CRON_audio_2_compress.pl --GSM -# 2,5,8,11,14,17,20,23,26,29,32,35,38,41,44,47,50,53,56,59 * * * * /usr/share/astguiclient/AST_CRON_audio_3_ftp.pl --GSM +# 1,4,7,10,13,16,19,22,25,28,31,34,37,40,43,46,49,52,55,58 * * * * /usr/share/astguiclient/AST_CRON_audio_2_compress.pl --MP3 +# 2,5,8,11,14,17,20,23,26,29,32,35,38,41,44,47,50,53,56,59 * * * * /usr/share/astguiclient/AST_CRON_audio_3_ftp.pl --MP3 # # FLAGS FOR COMPRESSION CODECS # --GSM = GSM 6.10 codec @@ -28,7 +28,7 @@ # # This program assumes that recordings are saved by Asterisk as .wav # -# Copyright (C) 2024 Matt Florell LICENSE: AGPLv2 +# Copyright (C) 2025 Matt Florell LICENSE: AGPLv2 # # # 80302-1958 - First Build @@ -40,6 +40,7 @@ # 170212-0732 - Added --file-sorting option to put files into dated directories (THIS WILL NOT ALLOW FTP ARCHIVING) # 230201-0007 - Allowed for handling of stereo gateway recordings # 240213-1146 - Added --GATEWAY option +# 250909-1030 - Added code to detect stereo audio files for MP3 stereo processing # $GSM=0; $MP3=0; $OGG=0; $GSW=0; @@ -251,6 +252,22 @@ } } +### find soxi to gather the length/channels info if needed +$soxibin = ''; +if ( -e ('/usr/bin/soxi')) {$soxibin = '/usr/bin/soxi';} +else + { + if ( -e ('/usr/local/bin/soxi')) {$soxibin = '/usr/local/bin/soxi';} + else + { + if ( -e ('/usr/sbin/soxi')) {$soxibin = '/usr/sbin/soxi';} + else + { + if ($DB) {print "Can't find soxi binary! No length calculations will be available...\n";} + } + } + } + if ($MP3 > 0) { ### find lame mp3 encoder binary to do the compression @@ -381,9 +398,18 @@ $MP3file =~ s/-all\.wav/-all.mp3/gi; $MP3file =~ s/\.wav|\.gsm/.mp3/gi; + $soxi_channels=1; + if (length($soxibin) > 3) + { + @soxi_output = `$soxibin -c $dir2/$ALLfile`; + $soxi_channels = $soxi_output[0]; + $soxi_channels =~ s/\D//gi; + $soxi_channels = ($soxi_channels + 0); + } + if ($DB) {print "|$recording_id|$ALLfile|$dir2/$location$MP3file| |$SQLfile|\n";} - if ($GATEWAY > 0) + if ( ($GATEWAY > 0) || ($soxi_channels > 1) ) { `$lamebin -b 16 -m s --silent "$dir2/$ALLfile" "$dir2/$location$MP3file"`; } diff --git a/bin/AST_flush_DBqueue.pl b/bin/AST_flush_DBqueue.pl index 2ac246709..e135e3601 100644 --- a/bin/AST_flush_DBqueue.pl +++ b/bin/AST_flush_DBqueue.pl @@ -9,7 +9,7 @@ # !!!!!!!! IMPORTANT !!!!!!!!!!!!!!!!!! # THIS SCRIPT SHOULD ONLY BE RUN ON ONE SERVER ON YOUR CLUSTER # -# Copyright (C) 2024 Matt Florell LICENSE: AGPLv2 +# Copyright (C) 2025 Matt Florell LICENSE: AGPLv2 # # CHANGES # 60717-1214 - changed to DBI by Marin Blu @@ -36,6 +36,7 @@ # 231228-1901 - Added optimizing of vicidial_3way_press_multi records # 240219-0811 - Added optimizing of server_live_... tables # 240709-1300 - Added Validate XFER vicidial_auto_calls: "--check-xfers" flag +# 250914-1537 - Added archiving of recording_live table # $session_flush=0; @@ -44,6 +45,7 @@ $stuck_lists=''; $stuck_listsSQL=''; $check_xfers=0; +$vicidial_recording_limit=60; ### begin parsing run-time options ### if (length($ARGV[0])>1) @@ -293,19 +295,32 @@ or die "Couldn't connect to database: " . DBI->errstr; ### Grab Server values from the database -$stmtA = "SELECT vd_server_logs FROM servers where server_ip = '$VARserver_ip';"; +$stmtA = "SELECT vd_server_logs,vicidial_recording_limit FROM servers where server_ip = '$VARserver_ip';"; $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; $sthArows=$sthA->rows; if ($sthArows > 0) { @aryA = $sthA->fetchrow_array; - $DBvd_server_logs = $aryA[0]; + $DBvd_server_logs = $aryA[0]; + $vicidial_recording_limit = $aryA[1]; if ($DBvd_server_logs =~ /Y/) {$SYSLOG = '1';} else {$SYSLOG = '0';} } $sthA->finish(); +($Rsec,$Rmin,$Rhour,$Rmday,$Rmon,$Ryear,$Rwday,$Ryday,$Risdst) = localtime(time() - ($vicidial_recording_limit * 60)); +$Ryear = ($Ryear + 1900); +$Ryy = $Ryear; $Ryy =~ s/^..//gi; +$Rmon++; +if ($Rmon < 10) {$Rmon = "0$Rmon";} +if ($Rmday < 10) {$Rmday = "0$Rmday";} +if ($Rhour < 10) {$Rhour = "0$Rhour";} +if ($Rmin < 10) {$Rmin = "0$Rmin";} +if ($Rsec < 10) {$Rsec = "0$Rsec";} +$SQLdate_REC_limit="$Ryear-$Rmon-$Rmday $Rhour:$Rmin:$Rsec"; + + ### Grab system_settings values from the database $stmtA = "SELECT sip_event_logging,enable_auto_reports FROM system_settings limit 1;"; $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; @@ -1002,6 +1017,103 @@ } +### BEGIN archive recording_live that are FINISHED ### +$rl_count=0; +$stmtA = "SELECT count(*) FROM recording_live;"; +$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; +$sthA->execute or die "executing: $stmtA ", $dbhA->errstr; +$sthArowsACTIVE=$sthA->rows; +if ($DBX) {print "DEBUG: $sthArowsACTIVE|$stmtA|\n";} +if ($sthArowsACTIVE > 0) + { + @aryA = $sthA->fetchrow_array; + $rl_count = $aryA[0]; + } +$sthA->finish(); + +if ($rl_count > 0) + { + $stmtA = "INSERT IGNORE INTO recording_live_log SELECT * FROM recording_live where end_time <= \"$SQLdate_NOW\" and end_time IS NOT NULL and recording_status LIKE \"FINISHED%\";"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows = $sthA->rows; + if (!$Q) {print "$sthArows rows inserted into recording_live_log table\n";} + + if ($sthArows > 0) + { + $stmtA = "DELETE FROM recording_live where end_time <= \"$SQLdate_NOW\" and end_time IS NOT NULL and recording_status LIKE \"FINISHED%\";"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows = $sthA->rows; + if (!$Q) {print "$sthArows rows deleted from recording_live table\n";} + } + + ### Gather older STARTED recording_live records from the database to confirm they are still active + $stmtA = "SELECT user,lead_id,recording_id FROM recording_live where start_time <= \"$SQLdate_REC_limit\" and recording_status='STARTED';"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArowsRECS=$sthA->rows; + if ($DBX) {print "DEBUG: $sthArowsRECS|$stmtA|\n";} + $orc=0; + while ($sthArowsRECS > $orc) + { + @aryA = $sthA->fetchrow_array; + $OR_user[$orc] = $aryA[0]; + $OR_lead_id[$orc] = $aryA[1]; + $OR_recording_id[$orc] = $aryA[2]; + $orc++; + } + $sthA->finish(); + + $orc=0; + while ($sthArowsRECS > $orc) + { + $al_count=0; + $stmtA = "SELECT count(*) FROM vicidial_live_agents where user='$OR_user[$orc]' and lead_id='$OR_lead_id[$orc]';"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArowsAGNT=$sthA->rows; + if ($DBX) {print "DEBUG: $sthArowsAGNT|$stmtA|\n";} + if ($sthArowsAGNT > 0) + { + @aryA = $sthA->fetchrow_array; + $al_count = $aryA[0]; + } + $sthA->finish(); + + if ($al_count < 1) + { + $stmtA = "UPDATE recording_live SET recording_status='FINISHED CHECK' where recording_id='$OR_recording_id[$orc]';"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows = $sthA->rows; + if ($DBX) {print "$sthArows rows set to finished in recording_live table: |$OR_recording_id[$orc]|$OR_user[$orc]|$OR_lead_id[$orc]|\n";} + + $stmtA = "INSERT IGNORE INTO recording_live_log SELECT * FROM recording_live where recording_id='$OR_recording_id[$orc]';"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows = $sthA->rows; + if (!$Q) {print "$sthArows rows inserted into recording_live_log table: |$OR_recording_id[$orc]|$OR_user[$orc]|$OR_lead_id[$orc]|\n";} + + $stmtA = "DELETE FROM recording_live where recording_id='$OR_recording_id[$orc]';"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows = $sthA->rows; + if (!$Q) {print "$sthArows rows delete from recording_live_log table: |$OR_recording_id[$orc]|$OR_user[$orc]|$OR_lead_id[$orc]|\n";} + } + $orc++; + } + + # optimize recording_live table + $stmtA = "optimize table recording_live;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + + $sthA->finish(); + } +### END archive recording_live that are FINISHED ### + + $dbhA->disconnect(); exit; diff --git a/docs/AGENT_API.txt b/docs/AGENT_API.txt index 57f027710..c2c3a6fa8 100644 --- a/docs/AGENT_API.txt +++ b/docs/AGENT_API.txt @@ -1,4 +1,4 @@ -AGENT API DOCUMENT Started: 2008-07-03 Updated: 2024-06-24 +AGENT API DOCUMENT Started: 2008-07-03 Updated: 2025-08-30 This document describes the functions of an API(Application Programming Interface) for the VICIDIAL Agent screen. This functionality will be rather limited at first @@ -30,6 +30,7 @@ transfer_conference - sends several commands related to the agent transfer-conf park_call - sends command to park customer or grab customer from park or ivr logout - logs the agent out of the agent interface recording - sends a recording start/stop signal or status of agent recording +stereo_recording - send a start or stop stereo agent recording signal to agent screen webserver - display webserver information, very useful for load balanced setups webphone_url - display the webphone url for the current agent's session call_agent - send a call to connect the agent to their session @@ -772,7 +773,7 @@ VALUES: START - sends a "start recording" signal to the agent screen (you can have multiple recordings going at the same time) STOP - sends a "stop recording" signal to the agent screen - (this will stop all active recordings onthe agent screen) + (this will stop all active recordings on the agent screen) STATUS - displays results of active recording and agent session information (returns: user|recording_id|filename|server|start_time|agent_server|session|agent_status) stage - @@ -798,6 +799,44 @@ NOTICE: recording active - 6666|121242|20120810-012008__6666_|192.168.1.5|2012-0 +-------------------------------------------------------------------------------- +stereo_recording - + +DESCRIPTION: +sends a stereo_recording start/stop signal or status of agent-controlled stereo recording + +VALUES: + value - + REQUIRED, choices are below + BEGIN - sends a "start stereo_recording" signal to the agent screen + (you cannot have multiple agent-controlled stereo_recordings going at the same time) + END - sends a "stop stereo_recording" signal to the agent screen + (this will stop all active agent-controlled stereo_recordings on the agent screen) + STATUS - displays results of active stereo_recording and agent session information (Only AGENT-CONTROLLED recordings) + (returns: user|recording_id|filename|server|start_time|agent_server|session|agent_status) + stage - + OPTIONAL, value to append to the stereo_recording filename, limited to 14 characters, if more it will truncate. Only works with BEGIN value + +EXAMPLE URLS: +http://server/agc/api.php?source=test&user=6666&pass=1234&agent_user=1000&function=stereo_recording&value=BEGIN +http://server/agc/api.php?source=test&user=6666&pass=1234&agent_user=1000&function=stereo_recording&value=END +http://server/agc/api.php?source=test&user=6666&pass=1234&agent_user=1000&function=stereo_recording&value=STATUS +http://server/agc/api.php?source=test&user=6666&pass=1234&agent_user=1000&function=stereo_recording&value=BEGIN&stage=_MIDCALL + +RESPONSES: +ERROR: no user found - 6666 +ERROR: agent_user is not logged in - 6666 +ERROR: stop stereo_recording error - 6666|||||192.168.1.5|8600051|PAUSED +SUCCESS: stereo_recording function sent - 6666|END||||192.168.1.5|8600051|PAUSED +SUCCESS: stereo_recording function sent - 6666|BEGIN||||192.168.1.5|8600051|PAUSED +SUCCESS: stereo_recording function sent - 6666|BEGIN_MIDCALL||||192.168.1.5|8600051|PAUSED +NOTICE: not stereo_recording - 6666|||||192.168.1.5|8600051|PAUSED +NOTICE: stereo_recording active - 6666|121242|20120810-012008__6666_|192.168.1.5|2012-08-10 01:20:10|192.168.1.5|8600051|PAUSED + + + + + -------------------------------------------------------------------------------- webphone_url - diff --git a/docs/CALLER_ID_NAME_CODES.txt b/docs/CALLER_ID_NAME_CODES.txt index 92f38b9ee..e192e6d7b 100644 --- a/docs/CALLER_ID_NAME_CODES.txt +++ b/docs/CALLER_ID_NAME_CODES.txt @@ -1,4 +1,4 @@ -CALLER ID NAME CODES DOC Started: 2013-07-15 Updated: 2025-01-03 +CALLER ID NAME CODES DOC Started: 2013-07-15 Updated: 2025-09-08 This document is meant for reference only, and it does not contain all CID name codes possible, but more will be added over time. @@ -24,7 +24,8 @@ XLvdc - Agent Local Closer or ReQueue Call (XLvdcW13739431946666) [epoch + user. XBvdc - Agent blind transfer (XBvdcW14528875091001100110011001) [epoch + user...] AGMON - Remote Agent Monitor (AGMON715224918000001) HLvdcW - Hangup of customer call from agent screen (HLvdcW1475524272tluc) -CH123456 - Hangup of all non-agent channels in meetme session(CH1234614755246080) +CH123456 - Hangup of all non-agent channels in meetme session(CH12345614755246080) +SH1234567 - Stop recording on customer channel(SH12345671475524608) ULGC - Hangup of lone channel in left 3way session (ULGC0010420221616133) ULGH - Clearing of left 3way session after server rec limit (ULGH0010420221618178) ULAL - Clearing of agent session by AST_agent_logout.pl script diff --git a/docs/STEREO_CALL_RECORDINGS.txt b/docs/STEREO_CALL_RECORDINGS.txt new file mode 100644 index 000000000..fc2556aa0 --- /dev/null +++ b/docs/STEREO_CALL_RECORDINGS.txt @@ -0,0 +1,368 @@ +VICIDIAL STEREO CALL RECORDINGS Started: 2025-06-18 Updated: 2025-09-19 + + +TO USE THESE FEATURES, YOU WILL NEED TO HAVE ALL SERVERS IN YOUR CLUSTER USING SVN/TRUNK REVISION 3940(2025-09-19) CODE OR HIGHER!!! + + +This project was designed to allow for additional stereo recording of phone calls at the agent and server levels directly on VICIdial Asterisk servers, with the customer always on one channel(the Right channel) and the agent and all other parties on the other channel(the Left channel). If you are looking for the VICI Gateway Recording Server documentation, please see the GATEWAY_RECORDING_SERVER.txt document. + +Stereo Call Recording is IN-ADDITION-TO the existing Legacy Mono Call Recording within VICIdial. Both can be active at the same time, and Stereo Call Recording is supplemental, not a replacement for Legacy Mono Call Recording. + + +This project has been broken down into 4 phases of development, since it is so large: + +1) Additional agent-initiated stereo-recording(customer-channel on one side) On-Demand, with option to mute customer-channel only. Agent screen and Agent API functions. +***COMPLETE*** + +2) Campaign & in-Group settings for separate automatic whole-call stereo call recording with options for customer-only and customer-muted settings. +***COMPLETE*** + +3) Parallel stereo call recordings with customer on one side, agent & 3rd parties on other side, customer-only, customer-muted, agent-controlled start-stop of recording (this will be done as a post-call process). +***COMPLETE*** + +4) Live recording muting based on DTMF receipt and un-muting after x seconds of being muted(campaign setting), for both new customer-channel-stereo and legacy-mono agent session recordings. +***STILL-IN-DEVELOPMENT*** + + +While the above development phases will be worked-on in the order they are above, there are portions of the later phases that will be implemented as early as the first phase due to shared processes needed for the later phases. + + +------------------------------------------------------------------------------------------------- +NOTES: + +For Stereo Call Recordings to work properly, all Asterisk servers in your VICIdial cluster need to be running Asterisk 18 or higher and they need to all be using the CONFBRIDGE agent session conferencing engine. You will also need to run the "install.pl" script on each Asterisk server so the new stereo recording directories are created. + +All Stereo Call Recordings will have "Customer on the Right and Agent(and 3rd-parties) on the Left". There may be some cases where more than one agent will be on a consultative 3-way conference call with the customer, and by necessity in these cases on the 2nd-agent-initiated stereo recording, the 1st agent will be with the customer on the Right channel while the 2nd agent is on the Left channel, but on the 1st agent recording(which is happening at the same time), the customer will be on the Right channel alone and the 1st and 2nd agent will both be on the Left channel together. + +Stereo Call Recording is not going to replace the existing default mono call recording in VICIdial, it is "in-addition-to" the existing default mono call recording. This means that you can record calls in mono and stereo at the same time in separate recordings. This also means that additional system resources will be used on Stereo recording if the default Mono call recording is still enabled at the same time. One other note related to this: the 6 existing "3way" recording campaign settings and the agent-controlled "Mute Recording" campaign features will only affect the default Mono call recording, and not the new Stereo call recording. Also, each recording method has different "Recording Filename" fields, which cannot be the same, so that recordings won't be overwritten on archive servers or during call recording exports. If you have parallel recording enabled, there are also 3 additional optional "Recording Filename" fields. If these are left blank, then the Stereo Recording Filename will be used with a prefix added to it for each of the different types of parallel recording files. + +If Parallel Stereo Call Recordings is enabled, then every call will be temporarily recorded in it's entirety(from when the agent receives it until it leaves the agent session), since this feature uses a post-call process to create the parallel recordings, there must be full call recordings available to create the separate parallel recordings from. After the post-call process finishes, the original full recordings will be marked for deletion. The options include: CUSTOMER-ONLY, CUSTOMER-MUTED and FULL-RECORDING. If Stereo Recording Agent Control is also enabled, that can itself also result in multiple recordings on a single call. + +For In-groups, the "Stereo Recording" options do NOT default to inherit settings from whatever campaign the agent is logged into when a call arrives at the agent session(which is how default mono call recording works). If you want calls handled through an In-Group to be Stereo Recorded, then that In-Group needs to have those settings enabled. + +For all of Stereo Recording, the agent-controlled Mute Recordings feature will not be available. This is because of all of the complexity already included in the Customer-Only, Customer-Muted and Recording DTMF Muting features that are to be built into Stereo Recording. Also, in the existing default mono call recording, if the Recording DTMF Muting feature is enabled, then the agent-controlled Mute Recordings feature will not be available. + + +For Recording DTMF Muting (STILL BEING DEVELOPED), this is NOT designed to mute 100% of the DTMF audio in a recording, it is meant to trigger a fixed time period of muting of the channel sending the DTMF audio AFTER a DTMF digit is detected. As a note, on many VICIdial systems, audible DTMF is already muted and converted into out-of-band DTMF signalling in many channel types by default, so this feature may not be necessary for all organizations. This setting is a number of seconds to mute the channel, with '0' being disabled. the default is '0'. + + + + +------------------------------------------------------------------------------------------------- +DIFFERENCES BETWEEN LEGACY MONO CALL RECORDING AND THE NEW STEREO CALL RECORDING: + +1. Stereo Call Recording is based upon the customer's bridged phone call channel, not the agent session like Legacy Mono Call Recording does. As such, Stereo Call Recording cannot start until the customer call is answered for outbound calls. This means that for manual-dial calls, the recording cannot start before the ringing of the call starts, like Legacy Mono Call Recording does, it will start after the Answer signal is detected and the call has been bridged. + +2. The 6 existing "3way" recording campaign settings and the agent-controlled "Mute Recording" campaign features will only work with the default Mono call recording, and not the new Stereo call recording. + +3. There are now up to 5 different Recording Filename fields for each campaign and in-group, all of these can be generated at the same time: + Mono Legacy, Agent-Controlled Stereo, Parallel Customer-Only Stereo, Parallel Customer-Muted Stereo, Parallel Full-Recording Stereo + +4. In the Agent Screen, the new Stereo Recording buttons will appear directly below the legacy mono call recording buttons, but the stereo buttons will have a small Stereo logo on the left side of the buttons. + +5. For In-groups, the "Stereo Recording" options do NOT default to inherit settings from whatever campaign the agent is logged into when a call arrives at the agent session(which is how default mono call recording works). If you want calls handled through an In-Group to be Stereo Recorded, then that In-Group needs to have those settings enabled. + +6. With Parallel Stereo Call Recording, the recording is initiated on the back-end, with no agent visibility into the recordings, unlike with Legacy Mono Call Recording, which displays recording information on the agent screen. + +7. In Stereo Recording call recordings, if an agent parks a customer, the recording will follow the customer and you will hear the park message on the stereo recording. With Mono Legacy Recordings, the recording follows the agent, so when a customer is parked, they are no longer heard on the legacy recording until the agent grabs the customer from park. + +8. Stereo Call Recording files are each about double the file size of a single Legacy Mono Call Recording, and if you have all Stereo Recording options enabled, including the three Parallel call recording options, then the file recordings will take up eight times the amount of space total as a single Mono recording file. + +9. In the Modify Lead Page, in the RECORDINGS FOR THIS LEAD section near the bottom, there is a new "STEREO" column that will indicate if a recording is in Stereo or not by the use of a code. If the STEREO field is blank, then the recording is a Mono Legacy Recording, and if the value in that column begins with "S", then that recording is in Stereo. The code used will explain what type of stereo recording it is, and it will be one of the codes listed in the "List of recording_log.extension values" section shown further down in this document. + + + + + +------------------------------------------------------------------------------------------------- +EXAMPLE SETS OF REQUIREMENTS AND THE SETTINGS THAT NEED TO BE CONFIGURED ON VICIDIAL: + + +-------------------------------------------------------------------------------- +EXAMPLE 1 REQUIREMENTS: + +- Must record both sides of each entire customer call in a stereo recording + +EXAMPLE 1 SETTINGS: + +- System Settings -> Allow Stereo Recordings = '1' +- Campaign Detail -> Stereo Call Recordings = 'BOTH_CHANNELS' + -> Stereo Recording Agent Control = 'ALLFORCE' + -> Stereo Rec Filename = 'S_FULLDATE_CUSTPHONE' +- In-Group Modify -> Stereo Call Recordings = 'BOTH_CHANNELS' + -> Stereo Recording Agent Control = 'ALLFORCE' + -> Stereo Rec Filename = 'S_FULLDATE_CUSTPHONE' +NOTE: (For every Campaign and In-Group you want these Stereo Recordings for, they will each need to have the above settings) + + +-------------------------------------------------------------------------------- +EXAMPLE 2 REQUIREMENTS: + +- Must allow for Agent-Controlled stereo recording on-demand, but not started at the beginning of the phone call +- Must also record both sides of the entire call in a separate stereo recording + +EXAMPLE 2 SETTINGS: + +- System Settings -> Allow Stereo Recordings = '1' + -> Enable Stereo Parallel Recordings = '1' +- Campaign Detail -> Stereo Call Recordings = 'BOTH_CHANNELS' + -> Stereo Recording Agent Control = 'ONDEMAND' + -> Stereo Rec Filename = 'S_FULLDATE_CUSTPHONE' + -> Parallel Stereo Recordings = 'FULL-RECORDING' + -> Parallel Full-Recording Rec Filename = 'SFR_FULLDATE_CUSTPHONE' +- In-Group Modify -> Stereo Call Recordings = 'BOTH_CHANNELS' + -> Stereo Recording Agent Control = 'ONDEMAND' + -> Stereo Rec Filename = 'S_FULLDATE_CUSTPHONE' + -> Parallel Stereo Recordings = 'FULL-RECORDING' + -> Parallel Full-Recording Rec Filename = 'SFR_FULLDATE_CUSTPHONE' +NOTE: (For every Campaign and In-Group you want these Stereo Recordings for, they will each need to have the above settings) + + +-------------------------------------------------------------------------------- +EXAMPLE 3 REQUIREMENTS: + +- Must NOT allow for Agent-Controlled stereo recording at all +- Must record customer-side-only of the entire call in a separate stereo recording +- Must record agent-side-only of the entire call in a separate stereo recording + +EXAMPLE 3 SETTINGS: + +- System Settings -> Allow Stereo Recordings = '1' + -> Enable Stereo Parallel Recordings = '1' +- Campaign Detail -> Stereo Call Recordings = 'BOTH_CHANNELS' + -> Stereo Recording Agent Control = 'NEVER' + -> Stereo Rec Filename = 'S_FULLDATE_CUSTPHONE' + -> Parallel Stereo Recordings = 'CUSTOMER-ONLY_CUSTOMER-MUTED' + -> Parallel Customer-Only Rec Filename = 'SCO_FULLDATE_CUSTPHONE' + -> Parallel Customer-Muted Rec Filename = 'SCM_FULLDATE_CUSTPHONE' +- In-Group Modify -> Stereo Call Recordings = 'BOTH_CHANNELS' + -> Stereo Recording Agent Control = 'NEVER' + -> Stereo Rec Filename = 'S_FULLDATE_CUSTPHONE' + -> Parallel Stereo Recordings = 'CUSTOMER-ONLY_CUSTOMER-MUTED' + -> Parallel Customer-Only Rec Filename = 'SCO_FULLDATE_CUSTPHONE' + -> Parallel Customer-Muted Rec Filename = 'SCM_FULLDATE_CUSTPHONE' +NOTE: (For every Campaign and In-Group you want these Stereo Recordings for, they will each need to have the above settings) + + + + + +STEREO CALL RECORDING SCENARIOS AND DB TABLE ACTIONS: +------------------------------------------------------------------------------------------------- + +Parallel stereo call recordings enabled on the system and campaign/in-group: + - Record inserted into recording_log_parallel table and recording started in all cases + If campaign/in-group parallel is set to CUSTOMER-ONLY and/or CUSTOMER-MUTED and/or FULL-RECORDING: + - Records inserted into recording_live, recording_log and recording_log_stereo tables for the whole-call recordings + if campaign/in-group stereo_recording_agent is set to ALLCALLS or ALLFORCE: + - Records inserted into recording_live, recording_log and recording_log_stereo tables for the whole-call recordings + If campaign/in-group Stereo Recording Agent Control is set to ALLCALLS or ONDEMAND and agent starts a recording: + - Records inserted into recording_live, recording_log and recording_log_stereo tables for the partial-call agent recordings + After call is complete, recordings above are processed, original is put into monitorTRASH directory for deletion in 3 days + - Records in the recording_live database table are archived to the recording_live_log table within one hour of being "FINISHED" + + + + +------------------------------------------------------------------------------------------------- +List of recording_log.extension values with recording_log_stereo.recording_type values: + + MONO_LEGACY + MONO_LEGACY_RIR + MONO_LEGACY_REMOTE + MONO_LEGACY_SURVEY + STEREO_AGENT + STEREO_DID +SPACBC STEREO_PARALLEL AGENT-CONTROLLED BOTH_CHANNELS +SPACCO STEREO_PARALLEL AGENT-CONTROLLED CUSTOMER_ONLY +SPACCM STEREO_PARALLEL AGENT-CONTROLLED CUSTOMER_MUTE +SACBC STEREO AGENT-CONTROLLED BOTH_CHANNELS +SACCO STEREO AGENT-CONTROLLED CUSTOMER_ONLY +SACCM STEREO AGENT-CONTROLLED CUSTOMER_MUTE +SPCO STEREO_PARALLEL CUSTOMER-ONLY +SPCM STEREO_PARALLEL CUSTOMER-MUTED +SPFR STEREO_PARALLEL FULL-RECORDING +SPACI STEREO_PARALLEL AGENT-CONTROLLED RIR +SACI STEREO AGENT-CONTROLLED RIR +SPCOR STEREO_PARALLEL CUSTOMER-ONLY REMOTE +SPCMR STEREO_PARALLEL CUSTOMER-MUTED REMOTE +SPFRR STEREO_PARALLEL FULL-RECORDING REMOTE +SPACR STEREO_PARALLEL AGENT-CONTROLLED REMOTE +SACR STEREO AGENT-CONTROLLED REMOTE + + + + +------------------------------------------------------------------------------------------------- +List of scripts modified/created for these new Stereo Call Recording features: +- agc/vicidial.php +- agc/vdc_db_query.php +- agc/manager_send.php +- agc/api.php +- vicidial/admin.php +- vicidial/admin_modify_lead.php +- install.pl +- AST_CRON_audio_1_move_VDonly.pl +- AST_CRON_audio_1_stereo.pl +- AST_CRON_audio_2_compress.pl +- AST_flush_DBqueue.pl +- ADMIN_keepalive_ALL.pl +- ADMIN_archive_log_tables.pl +- agi-VDAD_ALL_inbound.agi +- agi-VDAD_ALL_outbound.agi + + + + + +------------------------------------------------------------------------------------------------- +New Database Tables (FOR REFERENCE ONLY!!!): + + +----------------- EXISTING: + +ALTER TABLE system_settings ADD stereo_recording ENUM('0','1','2','3','4','5','6') default '0'; + +ALTER TABLE vicidial_campaigns ADD stereo_recording ENUM('DISABLED','CUSTOMER','CUSTOMER_MUTE') default 'DISABLED'; + +ALTER TABLE vicidial_inbound_groups ADD stereo_recording ENUM('DISABLED','CUSTOMER','CUSTOMER_MUTE') default 'DISABLED'; + +ALTER TABLE vicidial_manager MODIFY cmd_line_i VARCHAR(50); +ALTER TABLE vicidial_manager MODIFY cmd_line_j VARCHAR(50); +ALTER TABLE vicidial_manager MODIFY cmd_line_d VARCHAR(200); + +CREATE TABLE recording_log_stereo ( +recording_id INT(10) UNSIGNED PRIMARY KEY NOT NULL, +server_ip VARCHAR(15), +start_time DATETIME, +end_time DATETIME, +length_in_sec MEDIUMINT(8) UNSIGNED, +filename VARCHAR(100), +lead_id INT(9) UNSIGNED, +options VARCHAR(100), +processing_log TEXT, +index(filename), +index(lead_id), +index(start_time) +) ENGINE=MyISAM; + +----------------- NEW: + + +ALTER TABLE system_settings ADD recording_dtmf_detection TINYINT(3) UNSIGNED default '0'; +ALTER TABLE system_settings ADD recording_dtmf_muting TINYINT(3) UNSIGNED default '0'; +ALTER TABLE system_settings ADD stereo_parallel_recording ENUM('0','1','2','3','4','5','6') default '0'; + +ALTER TABLE vicidial_campaigns MODIFY stereo_recording ENUM('DISABLED','BOTH_CHANNELS','CUSTOMER_ONLY','CUSTOMER_MUTE') default 'DISABLED'; +ALTER TABLE vicidial_campaigns ADD stereo_recording_agent ENUM('NEVER','ONDEMAND','ALLCALLS','ALLFORCE') default 'ALLFORCE'; +ALTER TABLE vicidial_campaigns ADD stereo_rec_filename VARCHAR(50) default 'S_FULLDATE_CUSTPHONE'; +ALTER TABLE vicidial_campaigns ADD stereo_parallel_recording VARCHAR(50) default 'DISABLED'; +ALTER TABLE vicidial_campaigns ADD parallel_rec_co_filename VARCHAR(50) default ''; +ALTER TABLE vicidial_campaigns ADD parallel_rec_cm_filename VARCHAR(50) default ''; +ALTER TABLE vicidial_campaigns ADD parallel_rec_fr_filename VARCHAR(50) default ''; +ALTER TABLE vicidial_campaigns ADD recording_dtmf_muting SMALLINT(3) UNSIGNED default '0'; + +ALTER TABLE vicidial_inbound_groups MODIFY stereo_recording ENUM('DISABLED','BOTH_CHANNELS','CUSTOMER_ONLY','CUSTOMER_MUTE') default 'DISABLED'; +ALTER TABLE vicidial_inbound_groups ADD stereo_recording_agent ENUM('NEVER','ONDEMAND','ALLCALLS','ALLFORCE','DISABLED') default 'ALLFORCE'; +ALTER TABLE vicidial_inbound_groups ADD stereo_rec_filename VARCHAR(50) default 'S_FULLDATE_CUSTPHONE'; +ALTER TABLE vicidial_inbound_groups ADD stereo_parallel_recording VARCHAR(50) default 'DISABLED'; +ALTER TABLE vicidial_inbound_groups ADD parallel_rec_co_filename VARCHAR(50) default ''; +ALTER TABLE vicidial_inbound_groups ADD parallel_rec_cm_filename VARCHAR(50) default ''; +ALTER TABLE vicidial_inbound_groups ADD parallel_rec_fr_filename VARCHAR(50) default ''; +ALTER TABLE vicidial_inbound_groups ADD recording_dtmf_muting SMALLINT(3) UNSIGNED default '0'; + +ALTER TABLE recording_log_stereo ADD dtmf_detected TINYINT(3) UNSIGNED default '0'; +ALTER TABLE recording_log_stereo ADD dtmf_muting TINYINT(3) UNSIGNED default '0'; +ALTER TABLE recording_log_stereo ADD parallel_recording_id INT(10) UNSIGNED default '0'; +ALTER TABLE recording_log_stereo ADD recording_status VARCHAR(20) default ''; + +CREATE INDEX rls_pr_id on recording_log_stereo(parallel_recording_id); + +ALTER TABLE routing_initiated_recordings ADD rir_type VARCHAR(1) default ''; + +CREATE TABLE recording_log_parallel ( +parallel_recording_id INT(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL, +channel VARCHAR(100), +server_ip VARCHAR(15), +extension VARCHAR(100), +start_time DATETIME, +end_time DATETIME, +length_in_sec MEDIUMINT(8) UNSIGNED, +filename VARCHAR(100), +lead_id INT(9) UNSIGNED, +user VARCHAR(20), +vicidial_id VARCHAR(20), +recording_status VARCHAR(20) default '', +processing_log TEXT, +index(filename), +index(lead_id), +index(start_time), +index(vicidial_id) +) ENGINE=MyISAM; + +CREATE TABLE recording_live ( +recording_id INT(10) UNSIGNED PRIMARY KEY NOT NULL, +recording_type VARCHAR(40) default 'MONO_LEGACY', +server_ip VARCHAR(15), +start_time DATETIME, +end_time DATETIME, +channel VARCHAR(255), +filename VARCHAR(100), +lead_id INT(9) UNSIGNED, +user VARCHAR(20), +dtmf_detected TINYINT(3) UNSIGNED default '0', +dtmf_muting TINYINT(3) UNSIGNED default '0', +dtmf_muting_seconds TINYINT(3) UNSIGNED default '0', +dtmf_muting_end_time DATETIME, +mute_state TINYINT(3) UNSIGNED default '0', +recording_status VARCHAR(20) default '', +index(filename), +index(lead_id), +index(user), +index(recording_id), +index(dtmf_muting_end_time) +) ENGINE=MyISAM; + +CREATE TABLE recording_live_log ( +recording_id INT(10) UNSIGNED PRIMARY KEY NOT NULL, +recording_type VARCHAR(40) default 'MONO_LEGACY', +server_ip VARCHAR(15), +start_time DATETIME, +end_time DATETIME, +channel VARCHAR(255), +filename VARCHAR(100), +lead_id INT(9) UNSIGNED, +user VARCHAR(20), +dtmf_detected TINYINT(3) UNSIGNED default '0', +dtmf_muting TINYINT(3) UNSIGNED default '0', +dtmf_muting_seconds TINYINT(3) UNSIGNED default '0', +dtmf_muting_end_time DATETIME, +mute_state TINYINT(3) UNSIGNED default '0', +recording_status VARCHAR(20) default '', +index(filename), +index(lead_id), +index(user), +index(recording_id), +index(dtmf_muting_end_time) +) ENGINE=MyISAM; + +CREATE TABLE recording_dtmf_log ( +recording_id INT(10) UNSIGNED PRIMARY KEY NOT NULL, +recording_type VARCHAR(40) default 'MONO_LEGACY', +server_ip VARCHAR(15), +channel VARCHAR(255), +filename VARCHAR(100), +lead_id INT(9) UNSIGNED, +dtmf_muting TINYINT(3) UNSIGNED default '0', +dtmf_muting_start_time DATETIME, +dtmf_muting_end_time DATETIME, +dtmf_muting_seconds TINYINT(3) UNSIGNED default '0', +mute_state TINYINT(3) UNSIGNED default '0', +index(filename), +index(lead_id), +index(recording_id), +index(dtmf_muting_end_time) +) ENGINE=MyISAM; + +CREATE TABLE recording_log_parallel_archive LIKE recording_log_parallel; +CREATE TABLE recording_log_stereo_archive LIKE recording_log_stereo; diff --git a/extras/MySQL_AST_CREATE_tables.sql b/extras/MySQL_AST_CREATE_tables.sql index 85987ce19..212f2e17f 100644 --- a/extras/MySQL_AST_CREATE_tables.sql +++ b/extras/MySQL_AST_CREATE_tables.sql @@ -1134,8 +1134,15 @@ leave_3way_stop_recording ENUM('DISABLED','ALL_CALLS') default 'DISABLED', manual_minimum_ring_seconds SMALLINT(5) default '0', manual_minimum_attempt_seconds SMALLINT(5) default '0', manual_minimum_answer_seconds SMALLINT(5) default '0', -stereo_recording ENUM('DISABLED','CUSTOMER','CUSTOMER_MUTE') default 'DISABLED', -khomp_settings_container VARCHAR(40) DEFAULT 'KHOMPSETTINGS' +stereo_recording ENUM('DISABLED','BOTH_CHANNELS','CUSTOMER_ONLY','CUSTOMER_MUTE') default 'DISABLED', +khomp_settings_container VARCHAR(40) DEFAULT 'KHOMPSETTINGS', +stereo_rec_filename VARCHAR(50) default 'S_FULLDATE_CUSTPHONE', +stereo_parallel_recording VARCHAR(50) default 'DISABLED', +parallel_rec_co_filename VARCHAR(50) default '', +parallel_rec_cm_filename VARCHAR(50) default '', +parallel_rec_fr_filename VARCHAR(50) default '' +recording_dtmf_muting SMALLINT(3) UNSIGNED default '0', +stereo_recording_agent ENUM('NEVER','ONDEMAND','ALLCALLS','ALLFORCE') default 'ALLFORCE', ) ENGINE=MyISAM; CREATE TABLE vicidial_lists ( @@ -1463,8 +1470,15 @@ third_alert_container VARCHAR(40) default 'DISABLED', third_alert_only VARCHAR(40) default 'DISABLED', agent_search_list VARCHAR(20) default '', state_descriptions VARCHAR(40) default '---DISABLED---', -stereo_recording ENUM('DISABLED','CUSTOMER','CUSTOMER_MUTE') default 'DISABLED', -modify_stamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +stereo_recording ENUM('DISABLED','BOTH_CHANNELS','CUSTOMER_ONLY','CUSTOMER_MUTE') default 'DISABLED', +modify_stamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, +stereo_rec_filename VARCHAR(50) default 'S_FULLDATE_CUSTPHONE', +stereo_parallel_recording VARCHAR(50) default 'DISABLED', +parallel_rec_co_filename VARCHAR(50) default '', +parallel_rec_cm_filename VARCHAR(50) default '', +parallel_rec_fr_filename VARCHAR(50) default '' +recording_dtmf_muting SMALLINT(3) UNSIGNED default '0', +stereo_recording_agent ENUM('NEVER','ONDEMAND','ALLCALLS','ALLFORCE','DISABLED') default 'ALLFORCE' ) ENGINE=MyISAM; CREATE TABLE vicidial_stations ( @@ -2056,7 +2070,10 @@ stereo_recording ENUM('0','1','2','3','4','5','6') default '0', enhanced_agent_monitoring ENUM('0','1','2','3','4','5','6') default '0', agent_hide_dial_fail ENUM('0','1','2','3','4','5','6') default '0', agent_man_dial_filter VARCHAR(20) default '', -agent_3way_dial_filter VARCHAR(20) default '' +agent_3way_dial_filter VARCHAR(20) default '', +recording_dtmf_detection TINYINT(3) UNSIGNED default '0', +recording_dtmf_muting TINYINT(3) UNSIGNED default '0', +stereo_parallel_recording ENUM('0','1','2','3','4','5','6') default '0' ) ENGINE=MyISAM; CREATE TABLE vicidial_campaigns_list_mix ( @@ -3939,6 +3956,7 @@ lead_id INT(9) UNSIGNED, vicidial_id VARCHAR(20), user VARCHAR(20) DEFAULT NULL, processed TINYINT(1) default '0', +rir_type VARCHAR(1) default '', index(lead_id), index(user), index(processed) @@ -5319,9 +5337,14 @@ filename VARCHAR(100), lead_id INT(9) UNSIGNED, options VARCHAR(100), processing_log TEXT, +dtmf_detected TINYINT(3) UNSIGNED default '0', +dtmf_muting TINYINT(3) UNSIGNED default '0', +parallel_recording_id INT(10) UNSIGNED default '0', +recording_status VARCHAR(20) default '', index(filename), index(lead_id), -index(start_time) +index(start_time), +index(parallel_recording_id) ) ENGINE=MyISAM; CREATE TABLE clr_log ( @@ -5338,6 +5361,90 @@ processing_log TEXT, index(start_time) ) ENGINE=MyISAM; +CREATE TABLE recording_log_parallel ( +parallel_recording_id INT(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL, +channel VARCHAR(100), +server_ip VARCHAR(15), +extension VARCHAR(100), +start_time DATETIME, +end_time DATETIME, +length_in_sec MEDIUMINT(8) UNSIGNED, +filename VARCHAR(100), +lead_id INT(9) UNSIGNED, +user VARCHAR(20), +vicidial_id VARCHAR(20), +recording_status VARCHAR(20) default '', +processing_log TEXT, +index(filename), +index(lead_id), +index(start_time), +index(vicidial_id) +) ENGINE=MyISAM; + +CREATE TABLE recording_live ( +recording_id INT(10) UNSIGNED PRIMARY KEY NOT NULL, +recording_type VARCHAR(40) default 'MONO_LEGACY', +server_ip VARCHAR(15), +start_time DATETIME, +end_time DATETIME, +channel VARCHAR(255), +filename VARCHAR(100), +lead_id INT(9) UNSIGNED, +user VARCHAR(20), +dtmf_detected TINYINT(3) UNSIGNED default '0', +dtmf_muting TINYINT(3) UNSIGNED default '0', +dtmf_muting_seconds TINYINT(3) UNSIGNED default '0', +dtmf_muting_end_time DATETIME, +mute_state TINYINT(3) UNSIGNED default '0', +recording_status VARCHAR(20) default '', +index(filename), +index(lead_id), +index(user), +index(recording_id), +index(dtmf_muting_end_time) +) ENGINE=MyISAM; + +CREATE TABLE recording_live_log ( +recording_id INT(10) UNSIGNED PRIMARY KEY NOT NULL, +recording_type VARCHAR(40) default 'MONO_LEGACY', +server_ip VARCHAR(15), +start_time DATETIME, +end_time DATETIME, +channel VARCHAR(255), +filename VARCHAR(100), +lead_id INT(9) UNSIGNED, +user VARCHAR(20), +dtmf_detected TINYINT(3) UNSIGNED default '0', +dtmf_muting TINYINT(3) UNSIGNED default '0', +dtmf_muting_seconds TINYINT(3) UNSIGNED default '0', +dtmf_muting_end_time DATETIME, +mute_state TINYINT(3) UNSIGNED default '0', +recording_status VARCHAR(20) default '', +index(filename), +index(lead_id), +index(user), +index(recording_id), +index(dtmf_muting_end_time) +) ENGINE=MyISAM; + +CREATE TABLE recording_dtmf_log ( +recording_id INT(10) UNSIGNED PRIMARY KEY NOT NULL, +recording_type VARCHAR(40) default 'MONO_LEGACY', +server_ip VARCHAR(15), +channel VARCHAR(255), +filename VARCHAR(100), +lead_id INT(9) UNSIGNED, +dtmf_muting TINYINT(3) UNSIGNED default '0', +dtmf_muting_start_time DATETIME, +dtmf_muting_end_time DATETIME, +dtmf_muting_seconds TINYINT(3) UNSIGNED default '0', +mute_state TINYINT(3) UNSIGNED default '0', +index(filename), +index(lead_id), +index(recording_id), +index(dtmf_muting_end_time) +) ENGINE=MyISAM; + ALTER TABLE vicidial_email_list MODIFY message text character set utf8; @@ -5550,6 +5657,9 @@ CREATE TABLE recording_log_archive LIKE recording_log; ALTER TABLE recording_log_archive MODIFY recording_id INT(10) UNSIGNED UNIQUE NOT NULL; ALTER TABLE recording_log_archive DROP PRIMARY KEY; +CREATE TABLE recording_log_parallel_archive LIKE recording_log_parallel; +CREATE TABLE recording_log_stereo_archive LIKE recording_log_stereo; + CREATE TABLE vicidial_drop_log_archive LIKE vicidial_drop_log; DROP INDEX drop_date on vicidial_drop_log_archive; CREATE UNIQUE INDEX vicidial_drop_log_archive_key on vicidial_drop_log_archive(drop_date, uniqueid); @@ -5743,4 +5853,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='1728',db_schema_update_date=NOW(),reload_timestamp=NOW(); +UPDATE system_settings SET db_schema_version='1729',db_schema_update_date=NOW(),reload_timestamp=NOW(); diff --git a/extras/upgrade_2.14.sql b/extras/upgrade_2.14.sql index 09f818040..ff395d574 100644 --- a/extras/upgrade_2.14.sql +++ b/extras/upgrade_2.14.sql @@ -2753,10 +2753,10 @@ UPDATE system_settings SET db_schema_version='1718',db_schema_update_date=NOW() ALTER TABLE system_settings ADD stereo_recording ENUM('0','1','2','3','4','5','6') default '0'; -ALTER TABLE vicidial_campaigns ADD stereo_recording ENUM('DISABLED','CUSTOMER','CUSTOMER_MUTE') default 'DISABLED'; +ALTER TABLE vicidial_campaigns ADD stereo_recording ENUM('DISABLED','BOTH_CHANNELS','CUSTOMER_ONLY','CUSTOMER_MUTE') default 'DISABLED'; ALTER TABLE vicidial_campaigns ADD khomp_settings_container VARCHAR(40) DEFAULT 'KHOMPSETTINGS'; -ALTER TABLE vicidial_inbound_groups ADD stereo_recording ENUM('DISABLED','CUSTOMER','CUSTOMER_MUTE') default 'DISABLED'; +ALTER TABLE vicidial_inbound_groups ADD stereo_recording ENUM('DISABLED','BOTH_CHANNELS','CUSTOMER_ONLY','CUSTOMER_MUTE') default 'DISABLED'; ALTER TABLE vicidial_manager MODIFY cmd_line_i VARCHAR(50); ALTER TABLE vicidial_manager MODIFY cmd_line_j VARCHAR(50); @@ -2887,3 +2887,123 @@ ALTER TABLE system_settings ADD agent_man_dial_filter VARCHAR(20) default ''; ALTER TABLE system_settings ADD agent_3way_dial_filter VARCHAR(20) default ''; UPDATE system_settings SET db_schema_version='1728',db_schema_update_date=NOW() where db_schema_version < 1728; + +ALTER TABLE system_settings ADD recording_dtmf_detection TINYINT(3) UNSIGNED default '0'; +ALTER TABLE system_settings ADD recording_dtmf_muting TINYINT(3) UNSIGNED default '0'; +ALTER TABLE system_settings ADD stereo_parallel_recording ENUM('0','1','2','3','4','5','6') default '0'; + +ALTER TABLE vicidial_campaigns MODIFY stereo_recording ENUM('DISABLED','BOTH_CHANNELS','CUSTOMER_ONLY','CUSTOMER_MUTE') default 'DISABLED'; +ALTER TABLE vicidial_campaigns ADD stereo_recording_agent ENUM('NEVER','ONDEMAND','ALLCALLS','ALLFORCE') default 'ALLFORCE'; +ALTER TABLE vicidial_campaigns ADD stereo_rec_filename VARCHAR(50) default 'S_FULLDATE_CUSTPHONE'; +ALTER TABLE vicidial_campaigns ADD stereo_parallel_recording VARCHAR(50) default 'DISABLED'; +ALTER TABLE vicidial_campaigns ADD parallel_rec_co_filename VARCHAR(50) default ''; +ALTER TABLE vicidial_campaigns ADD parallel_rec_cm_filename VARCHAR(50) default ''; +ALTER TABLE vicidial_campaigns ADD parallel_rec_fr_filename VARCHAR(50) default ''; +ALTER TABLE vicidial_campaigns ADD recording_dtmf_muting SMALLINT(3) UNSIGNED default '0'; + +ALTER TABLE vicidial_inbound_groups MODIFY stereo_recording ENUM('DISABLED','BOTH_CHANNELS','CUSTOMER_ONLY','CUSTOMER_MUTE') default 'DISABLED'; +ALTER TABLE vicidial_inbound_groups ADD stereo_recording_agent ENUM('NEVER','ONDEMAND','ALLCALLS','ALLFORCE','DISABLED') default 'ALLFORCE'; +ALTER TABLE vicidial_inbound_groups ADD stereo_rec_filename VARCHAR(50) default 'S_FULLDATE_CUSTPHONE'; +ALTER TABLE vicidial_inbound_groups ADD stereo_parallel_recording VARCHAR(50) default 'DISABLED'; +ALTER TABLE vicidial_inbound_groups ADD parallel_rec_co_filename VARCHAR(50) default ''; +ALTER TABLE vicidial_inbound_groups ADD parallel_rec_cm_filename VARCHAR(50) default ''; +ALTER TABLE vicidial_inbound_groups ADD parallel_rec_fr_filename VARCHAR(50) default ''; +ALTER TABLE vicidial_inbound_groups ADD recording_dtmf_muting SMALLINT(3) UNSIGNED default '0'; + +ALTER TABLE recording_log_stereo ADD dtmf_detected TINYINT(3) UNSIGNED default '0'; +ALTER TABLE recording_log_stereo ADD dtmf_muting TINYINT(3) UNSIGNED default '0'; +ALTER TABLE recording_log_stereo ADD parallel_recording_id INT(10) UNSIGNED default '0'; +ALTER TABLE recording_log_stereo ADD recording_status VARCHAR(20) default ''; + +CREATE INDEX rls_pr_id on recording_log_stereo(parallel_recording_id); + +ALTER TABLE routing_initiated_recordings ADD rir_type VARCHAR(1) default ''; + +CREATE TABLE recording_log_parallel ( +parallel_recording_id INT(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL, +channel VARCHAR(100), +server_ip VARCHAR(15), +extension VARCHAR(100), +start_time DATETIME, +end_time DATETIME, +length_in_sec MEDIUMINT(8) UNSIGNED, +filename VARCHAR(100), +lead_id INT(9) UNSIGNED, +user VARCHAR(20), +vicidial_id VARCHAR(20), +recording_status VARCHAR(20) default '', +processing_log TEXT, +index(filename), +index(lead_id), +index(start_time), +index(vicidial_id) +) ENGINE=MyISAM; + +CREATE TABLE recording_live ( +recording_id INT(10) UNSIGNED PRIMARY KEY NOT NULL, +recording_type VARCHAR(40) default 'MONO_LEGACY', +server_ip VARCHAR(15), +start_time DATETIME, +end_time DATETIME, +channel VARCHAR(255), +filename VARCHAR(100), +lead_id INT(9) UNSIGNED, +user VARCHAR(20), +dtmf_detected TINYINT(3) UNSIGNED default '0', +dtmf_muting TINYINT(3) UNSIGNED default '0', +dtmf_muting_seconds TINYINT(3) UNSIGNED default '0', +dtmf_muting_end_time DATETIME, +mute_state TINYINT(3) UNSIGNED default '0', +recording_status VARCHAR(20) default '', +index(filename), +index(lead_id), +index(user), +index(recording_id), +index(dtmf_muting_end_time) +) ENGINE=MyISAM; + +CREATE TABLE recording_live_log ( +recording_id INT(10) UNSIGNED PRIMARY KEY NOT NULL, +recording_type VARCHAR(40) default 'MONO_LEGACY', +server_ip VARCHAR(15), +start_time DATETIME, +end_time DATETIME, +channel VARCHAR(255), +filename VARCHAR(100), +lead_id INT(9) UNSIGNED, +user VARCHAR(20), +dtmf_detected TINYINT(3) UNSIGNED default '0', +dtmf_muting TINYINT(3) UNSIGNED default '0', +dtmf_muting_seconds TINYINT(3) UNSIGNED default '0', +dtmf_muting_end_time DATETIME, +mute_state TINYINT(3) UNSIGNED default '0', +recording_status VARCHAR(20) default '', +index(filename), +index(lead_id), +index(user), +index(recording_id), +index(dtmf_muting_end_time) +) ENGINE=MyISAM; + +CREATE TABLE recording_dtmf_log ( +recording_id INT(10) UNSIGNED PRIMARY KEY NOT NULL, +recording_type VARCHAR(40) default 'MONO_LEGACY', +server_ip VARCHAR(15), +channel VARCHAR(255), +filename VARCHAR(100), +lead_id INT(9) UNSIGNED, +dtmf_muting TINYINT(3) UNSIGNED default '0', +dtmf_muting_start_time DATETIME, +dtmf_muting_end_time DATETIME, +dtmf_muting_seconds TINYINT(3) UNSIGNED default '0', +mute_state TINYINT(3) UNSIGNED default '0', +index(filename), +index(lead_id), +index(recording_id), +index(dtmf_muting_end_time) +) ENGINE=MyISAM; + +CREATE TABLE recording_log_parallel_archive LIKE recording_log_parallel; +CREATE TABLE recording_log_stereo_archive LIKE recording_log_stereo; + +UPDATE system_settings SET db_schema_version='1729',db_schema_update_date=NOW() where db_schema_version < 1729; diff --git a/install.pl b/install.pl index 10302f4c1..d4a67b2f8 100644 --- a/install.pl +++ b/install.pl @@ -53,6 +53,7 @@ # 230508-0809 - Added Asterisk 18 compatibility # 240704-0830 - Added coldstorage DB entries # 250103-1017 - Added ConfBridge conf files updates +# 250823-1411 - Added stereo recording directories # ############################################ @@ -2780,6 +2781,15 @@ `mkdir -p $PATHmonitor`; `chmod -R 0766 $PATHmonitor`; } + + # generate paths to asterisk stereo recordings directories: + $PATHmonitorS = $PATHmonitor."S"; + $PATHmonitorP = $PATHmonitor."P"; + $PATHmonitorTRASH = $PATHmonitor."TRASH"; + + if (!-e "$PATHmonitorS") {`mkdir -p $PATHmonitorS`; `chmod -R 0766 $PATHmonitorS`;} + if (!-e "$PATHmonitorP") {`mkdir -p $PATHmonitorP`; `chmod -R 0766 $PATHmonitorP`;} + if (!-e "$PATHmonitorTRASH") {`mkdir -p $PATHmonitorTRASH`; `chmod -R 0766 $PATHmonitorTRASH`;} if (!-e "$PATHmonitor/MIX") {`mkdir -p $PATHmonitor/MIX`;} if (!-e "$PATHDONEmonitor") diff --git a/www/agc/api.php b/www/agc/api.php index 634cf359f..65495b6de 100644 --- a/www/agc/api.php +++ b/www/agc/api.php @@ -1,7 +1,7 @@ LICENSE: AGPLv2 +# Copyright (C) 2025 Matt Florell LICENSE: AGPLv2 # # This script is designed as an API(Application Programming Interface) to allow # other programs to interact with the VICIDIAL Agent screen @@ -117,10 +117,11 @@ # 240427-0809 - Added tw_check option for transfer_conference function # 240429-2220 - Added PARK_XFER|GRAB_XFER options for park_call function # 250122-1010 - Allow for letters in phone_number variable, for AGENTDIRECT transfers +# 250830-2102 - Added stereo_recording function # -$version = '2.14-82'; -$build = '250122-1010'; +$version = '2.14-83'; +$build = '250830-2102'; $php_script = 'api.php'; $startMS = microtime(); @@ -319,7 +320,7 @@ ############################################# ##### START SYSTEM_SETTINGS AND USER LANGUAGE LOOKUP ##### -$stmt = "SELECT use_non_latin,enable_languages,language_method,agent_debug_logging,outbound_cid_any,allow_web_debug,agent_notifications FROM system_settings;"; +$stmt = "SELECT use_non_latin,enable_languages,language_method,agent_debug_logging,outbound_cid_any,allow_web_debug,agent_notifications,stereo_recording FROM system_settings;"; $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";} @@ -334,6 +335,7 @@ $SSoutbound_cid_any = $row[4]; $SSallow_web_debug = $row[5]; $SSagent_notifications = $row[6]; + $SSstereo_recording = $row[7]; } if ($SSallow_web_debug < 1) {$DB=0;} @@ -1280,6 +1282,138 @@ +################################################################################ +### BEGIN - stereo_recording - send a start or stop stereo agent recording signal to agent screen +################################################################################ +if ($function == 'stereo_recording') + { + if ( ( (!preg_match("/BEGIN/",$value)) and (!preg_match("/END/",$value)) and (!preg_match("/STATUS/",$value)) ) or ($SSstereo_recording < 1) or ( (strlen($agent_user)<1) and (strlen($alt_user)<2) ) ) + { + $result = _QXZ("ERROR"); + $result_reason = _QXZ("stereo_recording not valid"); + echo "$result: $result_reason - $value|$agent_user\n"; + api_log($link,$api_logging,$api_script,$user,$agent_user,$function,$value,$result,$result_reason,$source,$data); + } + else + { + if ( (!preg_match("/ $function /",$VUapi_allowed_functions)) and (!preg_match("/ALL_FUNCTIONS/",$VUapi_allowed_functions)) ) + { + $result = _QXZ("ERROR"); + $result_reason = _QXZ("auth USER DOES NOT HAVE PERMISSION TO USE THIS FUNCTION"); + echo "$result: $result_reason - $value|$user|$function|$VUuser_group\n"; + api_log($link,$api_logging,$api_script,$user,$agent_user,$function,$value,$result,$result_reason,$source,$data); + exit; + } + if (strlen($alt_user)>1) + { + $stmt = "select count(*) from vicidial_users where custom_three='$alt_user';"; + if ($DB) {echo "$stmt\n";} + $rslt=mysql_to_mysqli($stmt, $link); + $row=mysqli_fetch_row($rslt); + if ($row[0] > 0) + { + $stmt = "select user from vicidial_users where custom_three='$alt_user' order by user;"; + if ($DB) {echo "$stmt\n";} + $rslt=mysql_to_mysqli($stmt, $link); + $row=mysqli_fetch_row($rslt); + $agent_user = $row[0]; + } + else + { + $result = _QXZ("ERROR"); + $result_reason = _QXZ("no user found"); + echo "$result: $result_reason - $alt_user\n"; + api_log($link,$api_logging,$api_script,$user,$agent_user,$function,$value,$result,$result_reason,$source,$data); + } + } + $stmt = "select count(*) from vicidial_live_agents where user='$agent_user';"; + if ($DB) {echo "$stmt\n";} + $rslt=mysql_to_mysqli($stmt, $link); + $row=mysqli_fetch_row($rslt); + if ($row[0] > 0) + { + $stmt = "select external_recording,server_ip,conf_exten,status from vicidial_live_agents where user='$agent_user';"; + if ($DB) {echo "$stmt\n";} + $rslt=mysql_to_mysqli($stmt, $link); + $row=mysqli_fetch_row($rslt); + $AGENTserver_ip = $row[1]; + $AGENTconf_exten = $row[2]; + $AGENTstatus = $row[3]; + + $RECfilename = ''; + $RECserver_ip = ''; + $RECstart_time = ''; + $stmt = "SELECT recording_id,filename,server_ip,start_time FROM recording_live where user='$agent_user' and recording_status='STARTED' and recording_type LIKE \"%AGENT-CONTROLLED%\" and end_time IS NULL order by start_time desc limit 1;"; + $rslt=mysql_to_mysqli($stmt, $link); + $rl_ct = mysqli_num_rows($rslt); + if ($rl_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $recording_id = $row[0]; + $RECfilename = $row[1]; + $RECserver_ip = $row[2]; + $RECstart_time = $row[3]; + } + + if ($value=='STATUS') + { + if ($rl_ct > 0) + { + $result = _QXZ("NOTICE"); + $result_reason = _QXZ("stereo_recording active"); + echo "$result: $result_reason - $agent_user|$recording_id|$RECfilename|$RECserver_ip|$RECstart_time|$AGENTserver_ip|$AGENTconf_exten|$AGENTstatus\n"; + api_log($link,$api_logging,$api_script,$user,$agent_user,$function,$value,$result,$result_reason,$source,$data); + } + else + { + $result = _QXZ("NOTICE"); + $result_reason = _QXZ("not stereo_recording"); + echo "$result: $result_reason - $agent_user|||||$AGENTserver_ip|$AGENTconf_exten|$AGENTstatus\n"; + api_log($link,$api_logging,$api_script,$user,$agent_user,$function,$value,$result,$result_reason,$source,$data); + } + } + else + { + if ( (preg_match("/END/",$value)) and ( ($recording_id=='END') or ($recording_id < 1) ) ) + { + $result = _QXZ("ERROR"); + $result_reason = _QXZ("stop stereo_recording error"); + echo "$result: $result_reason - $agent_user|$recording_id||||$AGENTserver_ip|$AGENTconf_exten|$AGENTstatus\n"; + api_log($link,$api_logging,$api_script,$user,$agent_user,$function,$value,$result,$result_reason,$source,$data); + + exit; + } + if ( (strlen($stage)>0) and (preg_match("/BEGIN/",$value)) ) + { + while (strlen($stage)>14) {$stage = preg_replace("/.$/",'',$stage);} + $value = "$value$stage"; + } + $stmt="UPDATE vicidial_live_agents set external_recording='$value' where user='$agent_user';"; + if ($format=='debug') {echo "\n";} + $rslt=mysql_to_mysqli($stmt, $link); + $result = _QXZ("SUCCESS"); + $result_reason = _QXZ("stereo_recording function sent"); + echo "$result: $result_reason - $agent_user|$value||||$AGENTserver_ip|$AGENTconf_exten|$AGENTstatus\n"; + api_log($link,$api_logging,$api_script,$user,$agent_user,$function,$value,$result,$result_reason,$source,$data); + } + } + else + { + $result = _QXZ("ERROR"); + $result_reason = _QXZ("agent_user is not logged in"); + echo "$result: $result_reason - $agent_user\n"; + api_log($link,$api_logging,$api_script,$user,$agent_user,$function,$value,$result,$result_reason,$source,$data); + } + } + } +################################################################################ +### END - stereo_recording +################################################################################ + + + + + ################################################################################ ### BEGIN - webphone_url - display or launch the webphone url for the current agent's session ################################################################################ diff --git a/www/agc/images/vdc_LB_STstartrecording.gif b/www/agc/images/vdc_LB_STstartrecording.gif new file mode 100644 index 0000000000000000000000000000000000000000..7ecfacb4cb37cf484238d46baa14d331f1a5231d GIT binary patch literal 1704 zcmciB{Xf$Q0KoC@FbrdCY@ux8MII8inbh?)yJp8qo~As+@^mT>BT`2m7I~ zJrrRIP>7l$L=~zAQ`S&dforNjHDH=rFcr9(7D7!`Qv-p3Yin!j=x8C42ozFV7lY8% zMWT1;pwYS*0~E$kS097c--R|X!WbGG7~u>}cN^kNb{d=RGB(4ST3{_Kv6g1WmR2|` z^W9d~#@03_du>c@tj%rh%VL%+x6M<*2Oe zGgmUAuUt8slNpnf6P=qIlb08pf0cEOlfWrFS9m?~`mMy`qVq+U(o=6I-Mo3B_2S6gnD7B?3>YAfKi zaQJP7?OoS9+lxA%-stKm?h+I|?JgEPDG~JC?Cvb>uI5&WN`<|*M1nGr*n94n`hs&PR+Kwn`@n)e)M*RKRy3wVXk9#pz!N-;E)sH=EtHMufqR*ejU;ga<`bF~Bi}BH~eSa^G4E;5* zE+3VyKik+I{I>CYbNkuW_Vew{p{{lCC%X}hq(LK4D4u}MECL}IBl zx(9$;SAwVk+kh4D-G8G1s#`!a%+QrrArbx^TRXD z((8f@BYEWD^aj6&OqT@RQSgC!_zh7p;j}Z4*;u?&UQdH6>R!;eL3!5$(JvGP!JUfF zq(hJwf?qTw=1-<`(?C*zP=#3jg9=MK#Ih8*{}oS?lU}XGj|db6Y@lYZ_2@x=(tgh3 z145jlvMNra4uoZ#(28nIdHqo64I}xnYL;?9ngVm`$rmyhG~M;`gj*3ajVn&IL`jzi z(^QWB>bYf_JQY9FYD6mI7GhOi--R5C4ju?yR?9spp!}j;QjuoyrU~Yq4*~xU25qzH zUOkWwXk>w}nw{L=*$KtF;%tvvMG?zTpi722laZ4x3-n=Qk&_;P3DlX0u*YL;rKSjT zCLFz6HaDo07@VoB%*TpFsM57nG(4u4QUWHUVpVa_nK-|*t=8)mr@iaL^oZYZJ|hsQ z)n%z2j?4gy9`ErAk7oFM60yITjxm!J95WRWqXi1iyJS5Op7#twMd&$l>GW=Mk#S(={JIZ3N)-FHN&A A8UO$Q literal 0 HcmV?d00001 diff --git a/www/agc/images/vdc_LB_STstartrecording_OFF.gif b/www/agc/images/vdc_LB_STstartrecording_OFF.gif new file mode 100644 index 0000000000000000000000000000000000000000..1ce61cccfbc8e1ee7d54f17d533fd4c886b5e140 GIT binary patch literal 1709 zcmd_qi#O8?0KoCzUhIK3p(T%PW;T8_O5U|im`Fu`)KDr%F* z*f4G$r;Cfiyhljrgx=@$aNOIymC~)h<9`2#&)3J-+u7xe1i%8X?gBr8Kp;>k6b6IA z;cx^3p{1pTL?Tfr6dH}jU@*G6x_WwgSS%KY!|ChmZ{NP%z`(%J(9p=pXvdBncszdR z&Yi}_#%5+_=H})E0)a>*T3A?+$z)4QOA3WzWo1RBQfV}rjg1Wmg0{A{c6N5Vckiat z>Gt;a4h{}`_Uzfacdw(PEz^g9p95yu7`=eSCb_Y__kj@1aA7{QUg<{rv+10*)Lx5*QeG^ytx`prGL3 z;Ly;}u&}W3@bHL;h_h$UMn*Vqqp`oF%u~DH=D3!{lrl#iR=9ZQgl}gpx+S=CE*52OU(b3V_+1b_Ab?@H2 z?(XiMo}S*`-v0jnfq{Yh_wNr54h{_s4G#~i)#{OvkkrOIy75L1yl9)RqrBp{(l4nwon9zt%w6-Tlj^1=m z(erm?W0)?;wQ=YmXGMMt=2vxNZjedh7Y5)12`mCn5z;bwBPDH;p+p@AZID6WYY`B%AgDg!bM-rA2C<+ede8%R+R zBk0mA`8PwAx7ZnJa;7og0szs2&q3gdtCr3Jvtk>t4c=}x%h}a=Dz^}O5_#9U1jo;Y zO8W$F4)VJH%u*D7L<)Ee;WrkwaTCke5ru5I=x=nrV*KI~t>ivuj4Pd>Ty+J3I4rjwhJrg5pzJFsa7k%BSLXd1_td=VM+kH zik}2~^f8G#!1_^aBuq9lu&o*1#xreo?uSr>4BikJdOQ$Cv!LR}K&P)Spm=*6rPvry zSk8Ea zhzuhunbhHu+(Dq)JgkX`@{kS&2Z zvuQjn-<3mw;4y%R_WZ5#bbdgwPw#Y9qlh$WSrpRz`DJCx(C1fDq1~6)HRXw4-pH?p zqs)TG*Vv{>59~JI-hGs~`L63#^XB{Rf8TF@XzNTK#HKS=J@wR9Enhdroj!d1OXIWq S+uyUlp6}V9Kfq!ExBmb-6f0KoD8GR%=;ZqQZGf#^Aa=jModd}h zN3z2mwRiM(a16#dkPbS8IyeP8It4f%qTmS;1Xq%W*I5_$SQpPIH_vEyPpX?&jEC0+ zckf?_-m#uO2}IvypMVsg@i^G}A+!@>)K zDHl&i6orHrheVX0icAYXR~mY@f)d3)9bH3-sg8{0Mqdy{#9fV~Hk?loM<+>Q=rxJS zx8i6wscDk<)UFHkt^{UJLdxyL)ZV1DJGAt>$&7v)Q%Yw(NY3cHm@!Ca-AiHJU}p8D zUK&nekECWjNM{c)vicd^N9j3_8JD`Uxlfq6qZyq3tb#EX_Zd6?dDi6-PU*{>!pWSH z@!X=p%e>c|;y-fBra8PBZuvw$?`>YiZ2pzG%azYd`F|BuO&3+p7gfLH2^Nd_?@DSu z71zEm6?`bG{Ze}MBTu+ge)Su#ez~Ge`i~>Nm0H(sGi$u`Jf@q+Eh9tH3v(*fUn6CF_Rv|ss z=O%{YPPgVG2)Vi*ZFR%NrU6sVC5Kuj86==i=NcrS&DkZuk(hO zo}j5VjI(Q#pbR%lBXu;rxE9#H#AUmCJ>{KKuItu%r{(QmA6e#{z#+1nurgrUXMam? zdt*gSG*Z+$aX0bphy&WWAViAMnI@wdAWl#6>WYKc__9T}%r1$9U?U0ol_xW*JgeWw zfLJi7-B?~5xcs4}QkiLKR z#*T+r!PW32TNnE|i=$2DbMcLVi-I5@+`^nG_T_w$8R|B|6RF6Jd#I%l36ce!pAcrs zmSwgv)nPFRcXF7&I6T`HWXm)zNL-)u$tw~!)Ro|9L_n^K#t|};?TvVjuNR;ec$!+S z$rjSxiDPJohy~Oe>pruTTQT<-TCl8X0@=W4JS;*O3TK$RftSl!dooPJG6(pku=d}4 z28B0=-xx)ajll(O^(Tkd{b34KgV_dFh1BdlN7RdkEGW9bAX|*~3jz!bU-eOsFHw%8 zl)z~D4h%f3T2E})c0X}*Lur`~*3o@Ko2%|@h+LN&2$L^Nxzg<0bf+I8>jA0HRW`_^ z8fh>m^#>vJJgIK?Gw(5d@;*B%K}N=Ox%m+WMz(3QT8u)5D+;6)jh)hi)_TeCSf=XN z8?G7});Um3Lu6F#i*X7s_*PzL|5Kuw;9%Rz@3DiuL#Vh{(W{fR`Ic4Zsg%`^c2iZG zeGe>(H>U@tb4*&-X1I1sYi|qOEZ1jCj`O=dx^?>+^za%Z-IPUd+Z~qo{S` MUCrt!0S_Gb7X-vZQ~&?~ literal 0 HcmV?d00001 diff --git a/www/agc/images/vdc_LB_STstartrecording_alt_OFF.gif b/www/agc/images/vdc_LB_STstartrecording_alt_OFF.gif new file mode 100644 index 0000000000000000000000000000000000000000..19f7ddaf23e3d7d5449d3f39cea4cb849f883a77 GIT binary patch literal 1638 zcmeIx`!|yf0KoBQGd!C(o9pH>b0>F3YHI50>KYmvXfzsw!Dwn~YH4X{YisN1=;-R|>gnlW zu~-}qr?0P%$K#ESjR^#TiHV7snVE%!g{7sXm6esPt*xD%oxQ!igM)*kqob3Ple4q4 zi;Ih^t1FR6baQiacXvN_?3jm#ho`6K@#Dw6yu7@2nYxa z3=9ei3JwmYP$(fGA)%q6VPRpXPMr!552sS85fKrmPoJjIXwlKp7cN|gjg5_uk55QQ zU@#a=CNnWHF)1l2IXO8cB_%aAH7zYIBO@a-GczkID?2-z#bV{==H}()<>%)Y6ciK| z7P8swqN1YW;^LB$5-yipR#wL2@hU4T`Fws=RaJF$bxlo8U0q#$eZ4>+Xl!h3YHAV+ zg|}|qx^w4_NF)-A#SjEZB$B&#@3yqGw6?akwY9akw|8`Obar-jb#--jclY%4NTt%= z-rl~xzI*rX-M@dozrX*%g9n3ygF{0@BO@b^A3q))9UU7R8y_E^n3#~sWRsJVQ&UsZ z)6+9EGtZwtpPikZo12@TpI=y5kjv$Zi;GK3OUuj4D=RCjtE+2kYwPRl8yg#&o10r( zTMC8Z<;$1b+uJ)kJ3s#KzXB$Q82>D09E-^yTux?PBm_}TQUQ|#1PlfI0POzVzZQM)FS%TMu_z-*iQUi)?n?1+V-oB zKpNe|x}ZkP7?U?WvNhzaAQYLXI#XLEPbOG|D%r=G(j;VK9sm$A*c`f0TjdDE_jhYw zZbuB6I(=?=zsxN!@FoD{3R>s6f!~bI-#8r-yWrlJ0JX=~sWn zJ9)?XKW>~fkhYTX2zi^4fJo;Sf^@|KWwz#tk7};?b7_M}I|IWN0)FhNhWxtd~$0At( zAizRq*Pwkcj^?*iA-nb^ASa;)AV{c{@Jnzd_1pWs94tg{9@eFzYsalAF;dXn2BAk5q7#hxAj+A{Gl$FKI@eWzsuK zC2+uKItnd;*uBGs(Ax+;sbQtA@?JdB-?(ro|5ASS~JPyk(X)=4&-je z!>{z6&}eXCJOyLlGQKSuWDdy88_Z3?WqPIko^d_@(%$ODmae_EwEmBK>&eFR6H6;cg8lvD_bra9!@h#2m!9_`fi&W8K-nOT?$ic39K5<7m45KLDXIJ5PvK>} LrqpZ@&=Pdo zC`##L5?AA>w#%$`*O;YM!*n#dQ={#a?fi^=pZ71k&r7BTxVpvE0XSfD8UR25I07gE z01^a_z(Hl0f~q16tpry?DygFo8pbDSh$*6x|&(J znSbeFY3*fgOR^#OSrfhSf9r2U46w1I9CM)BI?@QlK!Q_%ol_9e{*=ALDF?Sxj_#)& zor0Y_LY!T`a`8Ote1hTZ&Tw%*BTti8RO|4>E#{bk#YI4iBM!>eN;k2RN{9D zDNQlSEpg`sv8lrNi){%kUTQ{rVp>O1dgr&9w^FjYQ?qZM&k`MIX~W%bpK8vas~;8pFlwR-+${q?N|!FFToZbRE|O~Th#+WyW?ao1G-=V1guzTQ8 zJoafoaxf@8{J+BZK*KjZKIT$<94Zu=9k4WQu~w@SzpJ)8k}#H0rl>UnFfPG>MUX&nuCb3v)8Eo zosamg8QUu}nigGdQpTP^;DG392RV(JqKWNZ>RbI3x<0+iZ#^M*eQiSm%!r1g z^FOhDi;ozLyiDI3&e&`gC{e=R_Vgvr*eYxk5&uJC>o(X#Ej)NW5c~8-s(y2{?_=6b zwecZZezzJ0SHMJw*4|z)RJc^oJ@W2uQ!jLz`F?#|@>C8~a1K7svYCKxm{^7&o#s32 zwuq>zNcqGc^Ohhl?jJX|Pgd=2T!&Wk_){)Xh4mZuGio*W6Titp?~Dtvt-t!946PhD zuLPftkR$P=S`A3sTrB4hhUhUvZD&8W*7x97nhGe1X^pj8uxil*_emj)p(nx;d?Q|+Ltr6r7O>LS>1B#t zjp^QBOr+gsm+HfaNO~Pi0@gTw8V&?d>c~YUP{%$*kUzGx*;;~05fL~rxwHvo z9p7$n#^y_W&?74KfYF#=owrq`tC&ML2={wZX=A8vd=3duVn%^r(w`VShy|<)-ppu| zF!yp_aX~P`QuEH(2<(=!Q?~rqMG}xcX~I=^dB&Vkh^p9B)&gb5x*Y`{bcsom8yIAJ3Vj>XUNu|R z-{Ee#pV8TXVRqkhSjOwNt5;=f>md>AbH>o{(kzZ`uqP8-G>}83FXAOdae?ci7YiU{ zPlAu?@Ltt93_f~!@Nci#prJ-WC^FMFg_dBZa{OcZS#wRlx<$N8qp)gz%=LP7Zi2AO zD4!Lw!&L=WVulF&ThN?k?qB3pphZn~zfs6t%`o$HL}YHXzAy0u2r4FX$9R-1h!DCW zMxAWtk){{O!hq+BP^vI|eRBK;88E-LXNq$^P9%XCnY#WTa7q-vaXIl#82I3wv7qtM zpCYpAsy^V2475V`(E7^S7cGjB(V-km$&ns*ks@6fxz{C8%!3!Bc{qlSl@#R;FVUKh zK1CEs(d%V4RlRHknKF*KDlfC5x1r9;#XE-_PUYSYX#GgL&=PF3OZOW49`7zFlibHf0-Nhww%q0FVCxe0ZDG literal 0 HcmV?d00001 diff --git a/www/agc/images/vdc_LB_STstartrecording_altx2_OFF.gif b/www/agc/images/vdc_LB_STstartrecording_altx2_OFF.gif new file mode 100644 index 0000000000000000000000000000000000000000..c8b960c1490019400791e790c92bae0ed8bb73cf GIT binary patch literal 1857 zcmd_p30D$$0s!zohX{xWc%OmyL5h`y$4k5tG!#O}aauV}IY_7tJ_D4dgZgB6#~P_#X%a z0);|hFc=&TH!?CZHa12gkth@jjYgZ8n3$THVzF2=Gcz0xhsWay1cJG_xrK#=rKP2n zm6f%%wT+F9t*xz{ot?eCy`!U}lamvXNFTU$K&z& z{Hm&|>gsBNKu}XtQ(IeGS65eGUw`-R-Fx@$H8eCdHa0djH8nRki$tQ<*4F#?@3*zJ zwYRs6#o~^Rj)xB)N+c4gRNB?m)!p4KlgWB|dU|_%`}+D63Ppc^|KrDxpFDXoFfcGU zI5;#kG%_+WIyyQwHa0#!{`Be7iHV8H$;qjysoB}txw$!&N~Kn-=jZ1&8qLDO!s6oM z($bPvt6g4RURhaLU0q#UTYLWe`TF|$#>U3x=H}McmQJU8@#2MEuYdXS<@WaWt5>fK z2E)$I&hGB+>({Rj{tuA$@ezet+~TZE;>Z1L#|P0YDVsJR6}lIE#BwU z;w`-U!r!PKI*n>LXR_lYA7K=P`(`RRygAJ^=n~dC2@}ly_~_fd$j-JifH6a9Mv<6C zP@t_cuz3BG_0;_INSm(VS+yuN{{z4<<7Ya`k`0nWmPl9a0IWY{ByUGIBfpkg0kbU! zb|qJH*=m5;mhPkj7&Zh>_>M1GR3yj|bNMY{_+W&>j}td*%~j zBGj{8tc@bKz@;>3LQAI_AKK-tf~V_cp5Tf&OD4Jy^zLw8gM|220lm$Tg_%EUd&5>_ zjt|z=j-!5>!soclE~gMg2w0V-N$Co$&OkbI1E4B$zAMGHbgUFiu${v_xuaK-lnjXd zwDSkDQzeVJ;_7>2XEjk?0s{pKP2FG|?u$fQymQz>$t%J^F z%$P|jktlQyWg+q_MHQ(Mf~eg~UQJD=#vTF+NnUm3pR@^JoG#(h2A9%4y&wMN!zY&T zGfsKg`&k-^7(%B2sO5lRntZyg@^(ba50{^RH1V(A|HG+wY5!AfBlh4=tM3yIK4Z5U z4)#M;O9uy^@1THjiLj%~*#dc50<~8DfC$>-;p!!D5BdZ;g~Ai%!^U=WxYoQ3joZzP@{&2Ey1cHq7gyUbYjUJ{ zNhd?4oE=&0@-`bbMMt^lbQQVCMY`)QPH}gC#eIHy{(*-X66C#yUk0Fn`AGl(0VV(d z1pwH;0fretKyWa~6at5tAhtlwkWdH$hTIB+n!&fC;HF3f3T1{yBhAgXT3DbgEznjN zl$Di*wT-#8wG{?yiNRTI$5?OQX^q{5!P#MV+2RQHI9rDuc7&aFL_EP6@9ctiA=FplBZRKos*}ba2dpkl0vOd|cR}`0#`XE{7W#k;q9(;vPO4k(wNt8XF&z z9(_FHKw9R(^sJZ+{-+7qv6+IntdoZXDTkAD`6oY5%=wC+mzVtIsl$1BN5o$r%`Z4w zC`v0TIxZEbOQmUN&ZNs^8O3L_O3DOf=T4j}KUscC_;pQAW#t!D7xHQfB>5Llef#a{ zT8Xr<;nbzeLWLr~zPLnot?+V-v`KmPMrCzHTj@%UO| z(+!{jh6`@3>ld3^IL8`V6*>uO7bDw1svneLJdctL%?X#Ndd#e|IJIH8+>y51GoW=F z!eIz=H>=Gd>2{5GHnQ=`epEjl1_VwQe1>mL0E^MGjub6HTpx=|tz#qzo1?#n$5NkZ zgf=phL@PE3t`tRE8&;BN$ArSGRa`P#p{Fb3`_J@TuQ;x12Je1Tr0QI%>HzzJgc*48 zR-tbma?Wm6P9|p828zL8No}g(R=%*%Nwh;ug6A&EAxqO;MhP0xuMGNBUwZYpQ=RUF zDgY9ScXMY{-6R( z5?%!ND2kz)b5{A(5>itfDBv9>(G22{$W8)VdHSPA=tdyhA2TRgmr53!Nli^y2_?I* z6gK;OEy)^0+5mTo4z+CMQU_Q?RcVl^r`QaJN-n1Zc9HD!5j>|v0YtE8mdq>3mD{@& zo7R!t>xp9&Z$QB!qUO+}Sd@Vu1QG{4D}buzM51jbX4xjNsMmCqaJ^pR>a$X2ubOu4B|6Nb@w581 z=NEI9*XHXaZhtQ{R;K;^qAC3&>8_;jvY?ol0k`#+s>!tVCH1^=eYyMX^7^axD1IOv G@c9QBTrRHw literal 0 HcmV?d00001 diff --git a/www/agc/images/vdc_LB_STstoprecording_OFF.gif b/www/agc/images/vdc_LB_STstoprecording_OFF.gif new file mode 100644 index 0000000000000000000000000000000000000000..cc42496df2cfc9bfffe1f9d4ee0259c9b4da3a3e GIT binary patch literal 1692 zcmd_pi$Bu|008jc@3+x5kG6TOk!>2rJm&pOo9E1ED38Q3Lx_Z=Qdv{R#Rr!Ub<}dk z@|ba9C)~VWDUvtkkr@Kp>Gw6bhxHqN1jzrmn7zMx!wp3>J&k(9qD-)YQ__($?12(b2)-aC`Rb z!Q=7z`uYR{fk-5hNThxH_L0eCLqkI&BO_yDV-ph-DwS$xW@c_~Zed|zX=zEL(X6bj ztgWqWY;0_8ZSCyr?CtFx92^`S9i5z508wD zjEaila=Edwu{<6xE-o%UK0YBKAu%yADJdyAIr;eU<0&aAX=!OEPo7LqPtVB6$jr>l z%F4>l&OUSI%-OSN&z(D$laq7){P_zPE?m5Lkgww2>m?G&ojZ3L8X6iK z8=IP%nwy)YQfW&|i%ceKZEbC9Yiny?uRs{r&v| z0|P@tL&L+vBO@bYV`Jmv;}a7T_wV1IoSb~{;K9R(52vQ4rl+SLJ$f`VGxPZIi%?mDSbNr%#`*t*x!EuWxK@Y;JCT{r@5DU_8>}Vlv}+ z#M6nH$A~_@{v3ex5e}k&uYlRN9^aw>h#epjsmGLw`UD6K)1#xZ+XMM%f;7F-v}Wjg zoK2D$LK3ZOUWbcs2uk>A><5aS5#B?FEhLC>AqE&SZ~RBc40ZCBu}YrXm?_6V^|Ana9~3LYG*6Q7e&K^8BNF_T-yyTg~HpNh!%2UiJ>jg zLs9^`sBe6IrNb{*^Qug}#1;e$!2r6NC6IDJYhfvjz_#CrHm3&rA#JCDE$MZt1N*s4_$IEpxCR-u%Dus zy)Qu#R7U$)8hUI41Ux~0$xEpu$G{!iq{)K;u)A-(*m-L3H40Q@y&lsAq6H@uTZ)hn zhy*B%zk+lzHKZ7~7lL?0Az!K%}h9GVj1JG-B<%5Pd zaul9arGj*?U7?F~G+)XNH>?V0(DDqWk*7cj8A~?0u9R44R3BF4e3Y`&r2jXc^dzxx z_Dtz7H7xADG_Ef)LiP@UMv-Nnlsdh250k6RH7|Fg;;`FPWmMVPr5SvtmT3S$^XQNs zt&CyJMs2TmtX}Y|DWD9$2*ES6=OJKkX=ObG`=8g_e=2raett8kbK>*c(Z6;eRS*PR{sn^fN5cRB literal 0 HcmV?d00001 diff --git a/www/agc/images/vdc_LB_STstoprecording_alt.gif b/www/agc/images/vdc_LB_STstoprecording_alt.gif new file mode 100644 index 0000000000000000000000000000000000000000..9ba01468b5b04f1e57884963809b374a340056a3 GIT binary patch literal 1583 zcmc)JjXTo`0KoCzmSt=h%e=n~V`heVIj`9p^RhBVW;J;YV`H1QVwri_#>h)0J=Bz5 zcUveXW0A9`l00;oU07we} zLqHIymbMNA3e(nwLt%Ql5CjZv0NZK^hZ^a@jJE0^4fK%O`rC92jCBzxxFJdpZmO?m zW`M9TG_ph@to4z0NMn0rlmiNdL76(4qMVJ*v1TSXl&K5K0%u|AW^PTivLRZTds*9h zTBE&eEPZV4ebCl^c4$8V>r9*boY<&caQS$U=lr-YIn-nz3JU4X+I=Mx{5O|rRMZz z@%qwpe#+oq$rSWwWe)Ok2Y6Y(WXt+W@_x?dUCR*;=44;z=MH7^hXi?=EP*Chbc0u@ z5sGhSORr0Wzlub|;(}p*;fO%4sTPh4t8U5mj|oK+q66b1@uaw9LR>nTUwpr4|8%ix zLMi#J^x*H3x@m=MuDJ5i0m(v1)#H+~C#CX*Qt6^Z@kF9rJSh94tno=x#CYJ)%Aat*DlND?_{dC3dQ@1);EV5-c>07s;v1?Rr|48xl*TEk=Ly% z>erMFpKF@dRn1@PPJV7a{C9op*CR(Z4mEGKv~9GsZyr0faq`^8+3pSXKmRNArXf|7 zo}8baW?Ph%pJ_`E-@ydX>slaP;2!`F{O8*!0CW@R(zy`Yqt;YFk+?mhJsmgY2>S>x zEPt*q>pn3;e75)Wh-zYcjb-?y&fCpcR(Gr!Kfx~Rp4xSHwVcu0>MMSBYYEdZb&^z} zYZcLV{@&>@Iqv{c?1(oGRTxX+z{;6U_GRAVu~nxY+P>q2c^2soaZh~9>-$x#mY(zs zQyS4+EdZff_su@G0GzrU48dV{%f$#47?K3P(f?VnkX~Z*ihb*<+jD@s!bz;YO_za; zp+#0-y)R6p$N65p|6}JQ!y6}Pn|1wLw!SLnQYoYvXiwdk#z(w2FJ|;(_ z$7pc4%1i8w|gg9*KD%wghLOCbpqqeW#PLoB}|n-5}ALja#aWpg?7O{dyHk5k-w zP91Zer(Ty#J*BDLwH6iUtETc_5%aLjQR1NnB8#936g|M4#IxuiDG)ZX1%$Z4-Pw-F zu*5R3CID>e41$|?C$xlHIInqV;;~JO)1lL~+@J9MKzGq`tVwM0j63;)6eb;48&ji4$%fduOx3G$EPMWRWtvHMU7d-I x=dV6sXIxyJ-9rr;MwUrGR2rqV@Ym)t&s|)5m~-Xr+I-%K>y#1Wy6H`0hB>b}(^jvS~`w9J+gK~Wt?>I{-$NmVt{&7c^e zan#Xb>*!89gOn0ef>5R12JP&w)tS=TZTHaK{<+^_e;?tQc^E9Zmv>SnwpxHmX@BLo{^D}nVEU{^5yL8?3|pO+}zx}ygV+Ko1dRwSXfw8R8(ACTvAfP zMU z8X6iN9v&GP866!R8yg!RAAj`d(c{ODCnqPTrl#a_`SkSk%*@Qwr%&hR<`fFW{QUg0 zXU`TE78Vy5l}hE(($ezs^2*AJN~Ky|U0qvSd;a|S`uh5d7cVw8Ha0gmU%q_#>eZ{) zuV1Ux>aDGil5jHS4C5fBDfeO;Ommmh~bOb>7jDVqmF97B19$!ZR zkVgOuWyTzoPF5fd>@Lg>w#%zAmQ}f*Y&)i}<6Sc-jos2F+ZMck@pkH+xmz~w=d_XOij_2UR!-AJ5t6*Bu*V`1&jVL^x73_1~>4ySa-Wn z6rRJp8ZeAdS!gCnQ@@4t)2NXrfE(P(w=dyBs3p=lZ^uS$S*Pqf$ z(Sj0WqI!j;)SZwa^!9>wG{`ia2O>Knze*dGAB5d{KO3n@y3IN&1rrlJC-J~KJ_ts= zN%aHH@+>a;d)WE_(R+0n^4d}yFd;CbDNx_B&|bW=)nKMD_laiB-ader1<@u65}s3~ z&9T2{;&cjP1!IuGAFKATb+e#uB}j;C#V(VG76+=8*4MD zVTh19hv*wqK$aH0c6loX=f?h#dg690rp8VzX4S^VJlrHDE*yTNRsI(p-N4gyGhQ<{+vR$46bK z1WaYNz5O9GYwYdl#d9r8skJ$*mXB<@vK_q(89{`%0Zr;`@WfUZvfff#WkiLKm)6*00062B>)5l zl$1eW6(waTSVdJCs;;7@0ab^oDZ|w@G}R#p4X74O6{&edTUGN*HMoujLIKxP2G1Jkt&_!A5>DuV%TkE6j^z`lZ46rC8yrD7P z5ancqb~Ms=HpVy^8xYW@1dNfZ3C7jX#MQ{e%^2fucFY59=7}-&F|+dir(?e6mOeJt zKIZ0rmKOe2HY77_fVCCb#+GbuN3pOEw8REk*@W0&gB{!`ZniXAhY*|{-3~{?JJRgz zL+$Ou?6C|iE*$4g_i|)9I-PWKW;q9(@OO)HCB`_r#1cGXJ>5^adL+1cCc6JC$=xT> z`>SLR&vaLxw68oeynNHWj%RrLW%_t$d-`ShdU1XIvyTVnll%(E5n0UW+{mDk0RJ;2 zP98htEQMSa7+1idmjzKP0)ho0Gy#P!q=Z%l(nX~CUE^~A>Bh>Gv!lwL1L`YtY69-sDoV)|fG#!zzkKylVjsVP6FW#3B6R3xP+(j)nCCIMOB4A@1Hqvi#cg1(%%lg$a3A z$oX$}fA~xu=ziEilKHP_Cni1WqIFPS4h^hLUT4ZvJXteqv%Q?rdvA)q{`NO{=tMhv za<-e*KL7hY*xsyuJ8?GG$TuhXKhM9-JloG~Aa-GqRJBzNMaw(B{bLT{l5H4LOAVwE z57o+vXhlFYB;Cjp?_b=lzwJ!OiXlC3kx&!s_1s^XqF_pvOX$j^nP#k^9_PhI%l9o4 z4VbQ1)Zj1Z?x}k{T4-_d1&$JPXl#SoiE!@Tyk{%J1WSf!Pve`xD!p;H2Em;Yvxyr-?=qaC?Rk z07Q*H@dNT+54I^89>5it4>$n;U6`{V0W^=R&CZ@rI51n-!XHu$XxnAjVlndFFz)9p z8bp9gpYsypZon0m1Swo$gTJYzfLcQwt`_5^S_(BBBx}XsLlc~5?S^+|IO7cZsTR=V z%hN}VmVDH}yn<1I^58LFr7vkkj%*;Jg>X^;0ryF$U~nBO=ze^{^LA;2o(%u*BGkM( zWNA6Mb6PPw7vlbEX_Ro#ZtGA*%tiA8P++g+XG%4QjBR~O?` zcpXy2{2zk*;!lgV;DxLdKuo_bV?CqMM{tTOfRK38p^OJ&k>aG<6sBo4IM-_kW@FL4 zc7tdYdH!WH`%K}p+aJ{)VJtzNb>>0o;676NeluRy&zLA|GFDGprdrCAcFC6fwq-G~ zQg`e3SUqbB53+Yg*Mw@?tovAGRn&u@Boxbi0luxqWfjdQ;UvH#=puJ4d|10$Ipz%m zhOje`SqAxo(d1w8g>9{N^Shy{1zQtvh4Fn4xk}NxA$w=0KmD;7xqZFIc;rq3f_LN+ zQ%)VT*4|{C(<7rh!tAVH41TsD!1aB?%2S6Q7%{j}}z4>K`mIuw4 zF($1<1V_aC5395KQgGZ`Ta3x*fv%mRjUNWTKJoTe_08f#z&)dv0pgTdf%I0At{ zB9R&z8fY{cgTY|2SR4+gsi~=@rG>}iwY9Yg1Okyr)X~w=)z#J0(<6~c8#iv$*Vi{N zFfcSUG%_+WHa0djHQlsn6PZjlGcz+cH@C2`pi-%pmXgwj^=I-vkefxF@f;b!w zm&^6=@bL8X^z!oJ@pybb-`m^U$H!;q&Yix#zPoqt-m_ktfddB)A3hut6B8R78y6QBA0MBP zkdT;|n3R;1oSdAJl5+g`@zm7Rw6wJJ^z@93j1wnLWM*cH#p0~2tnBP;sZ^Silarg9 zo0pfDpPye)P*7M{SX5MW>eQ*?;^NZM(z3F$^78VEii*n0%BrfW>gwvVXV2Eu)YR72 zUbt{UCX?0G)yd`Z`uh6ImoGOoG+e!UwXw0Wsj2Du_3O>e%`Gi03WcJzwNz5V_D0|Ns?Lqo&E!y_XjDwS$iJ3IU2$&6(I3kwVD{{v=gM300hQBqVS`PiYPXfn^+R{+euB4IeN4(Q)|e2)S!Yv3T(gs+fw zXJd4&LIxFey?F$4pBjGa#d{~Uh@!c{)=LAqCBx|^-b#vRKwf)Q$dJ;4bJ{9&xMqe( z9X-dkoK+3oIM`F`o{iFQA)M*`iCey(;u3?`58U7?`g*CYamU5#0N{O(S&lUm7{U!S z!vKnQ1z8rlGj6OHht!FlW+?)zh-iEvCOg1Jcq4ih#V+YalO++Wj+_l*wW$#v#Z-4K z9QKhU6UM7Q9h!jr}jN!co%aC2>gdCEVtPql@b=&_p1LvWY_C! zXK%(#H*GeADGWZ-l_ycu^Q4&Lq+QMSGg&OwA|&*8Sqri9?At{bh6jv`?P4bMtXuS) zgUf$wh5UdKo54pzFSA8}purIULjQ^7H(zQp;4gvL%2-#n9n2230m z1)y1|9>jszqj18N(hFa2%jq^IVc5D~bE%fucvyvxmb2m!2JwqZrym{}$pM>`f>s#y zycp!rk2KfAf}|S*Ue&IlU*5g~WvtznH8$-&_5;Asoku7d<6Sf$@fI1~Ru(Id` zu70aPM+(Qf`4w34R!Ryex?-Zab+N2VUWAx$Sm3yQV-rfaM%d<#Bh&f(vfs~OA=Ah6 z2Br~2Vg(8zRh11=;5p%#%_0Z*5Iv3(7kmy8@85-red{C0TsPEHixH%huxmO$&b_5O z0RpeHDFt*V#RD;-vH$bFdZ;vnsiDHvzCdW6?_-Z?gLf=jj`HE;utoZ!qoy_E<7Z=| z9wK_n7}v5NNAY0lCtmyTb`}X7P0EI?P6ZdfQ;iGXd(bxcNqP+N!Z|dso*SNoBr8z& zb$||&^+HWjGYJfp-!(M}9}RU9N>>S(yXJNx7TJx@1aOi%Xr(X*vJ^ literal 0 HcmV?d00001 diff --git a/www/agc/manager_send.php b/www/agc/manager_send.php index 2d7e00ac2..fda51e09d 100644 --- a/www/agc/manager_send.php +++ b/www/agc/manager_send.php @@ -1,7 +1,7 @@ LICENSE: AGPLv2 +# Copyright (C) 2025 Matt Florell LICENSE: AGPLv2 # # This script is designed purely to insert records into the vicidial_manager table to signal Actions to an asterisk server # This script depends on the server_ip being sent and also needs to have a valid user/pass from the vicidial_users table @@ -158,10 +158,11 @@ # 240430-1046 - Allow for park/grab of xfer line through API # 240709-2010 - Changes to input variable filtering # 241122-1544 - Fix for DTMF issue #1525 +# 250831-0839 - Added MonitorStereo/StopMonitorStereo functions # -$version = '2.14-105'; -$build = '241122-1544'; +$version = '2.14-106'; +$build = '250831-0839'; $php_script = 'manager_send.php'; $mel=1; # Mysql Error Log enabled = 1 $mysql_log_count=161; @@ -285,7 +286,7 @@ ############################################# ##### START SYSTEM_SETTINGS LOOKUP ##### -$stmt = "SELECT use_non_latin,allow_sipsak_messages,enable_languages,language_method,meetme_enter_login_filename,meetme_enter_leave3way_filename,agent_debug_logging,allow_web_debug FROM system_settings;"; +$stmt = "SELECT use_non_latin,allow_sipsak_messages,enable_languages,language_method,meetme_enter_login_filename,meetme_enter_leave3way_filename,agent_debug_logging,allow_web_debug,stereo_recording,stereo_parallel_recording FROM system_settings;"; $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02001',$user,$server_ip,$session_name,$one_mysql_log);} #if ($DB) {echo "$stmt\n";} @@ -301,6 +302,8 @@ $meetme_enter_leave3way_filename = $row[5]; $SSagent_debug_logging = $row[6]; $SSallow_web_debug = $row[7]; + $SSstereo_recording = $row[8]; + $SSstereo_parallel_recording = $row[9]; } if ($SSallow_web_debug < 1) {$DB=0;} ##### END SETTINGS LOOKUP ##### @@ -2494,7 +2497,6 @@ } - ###################### # ACTION=Monitor or Stop Monitor - insert Monitor/StopMonitor Manager statement to start recording on a channel ###################### @@ -2598,7 +2600,7 @@ $stmt = "UPDATE recording_log set end_time='$NOW_TIME',end_epoch='$StarTtime',length_in_sec=$length_in_sec,length_in_min='$length_in_min' where filename='$filename' order by start_epoch desc;"; if ($DB) {echo "$stmt\n";} $rslt=mysql_to_mysqli($stmt, $link); - if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02071',$user,$server_ip,$session_name,$one_mysql_log);} + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02071',$user,$server_ip,$session_name,$one_mysql_log);} } } echo _QXZ("%1s command sent for Channel %2s on %3s",0,'',$ACTION,$channel,$server_ip)."\nFilename: $filename\nRecorDing_ID: $recording_id\n"; @@ -2608,10 +2610,6 @@ } - - - - ###################### # ACTION=MonitorConf or StopMonitorConf - insert Monitor/StopMonitor Manager statement to start recording on a conference ###################### @@ -2633,7 +2631,7 @@ if ($ACTION=="MonitorConf") { - $stmt="SELECT recording_id,filename FROM routing_initiated_recordings where user='$user' and processed='0' order by launch_time desc limit 1;"; + $stmt="SELECT recording_id,filename FROM routing_initiated_recordings where user='$user' and processed='0' and rir_type='' order by launch_time desc limit 1;"; $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02139',$user,$server_ip,$session_name,$one_mysql_log);} if ($DB) {echo "$stmt\n";} @@ -2818,6 +2816,11 @@ if ($DB) {echo "$stmt\n";} $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02079',$user,$server_ip,$session_name,$one_mysql_log);} + + $stmt = "UPDATE recording_live set end_time='$NOW_TIME',recording_status='FINISHED' where recording_id='$recording_id' and recording_status='STARTED';"; + if ($DB) {echo "$stmt\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} } # find and hang up all recordings going on in this conference # and extension = '$exten' @@ -2850,7 +2853,373 @@ } +###################### +# ACTION=MonitorStereo or StopMonitorStereo - insert Monitor/StopMonitor Manager statement to start recording on a customer channel +###################### +if ( ($ACTION=="MonitorStereo") || ($ACTION=="StopMonitorStereo") ) + { + $row=''; $rowx=''; + $channel_live=1; + $uniqueidSQL=''; + + if ( (($ACTION=="MonitorStereo") && ((strlen($exten)<3) or (strlen($channel)<4) or (strlen($filename)<8))) || (($ACTION=="StopMonitorStereo") && ((strlen($exten)<3) or (strlen($channel)<4) or (strlen($filename)<4))) ) + { + $channel_live=0; + echo _QXZ("Channel %1s is not valid or exten %2s is not valid or filename: %3s is not valid, %4s command not inserted",0,'',$channel,$exten,$filename,$ACTION)."\n"; + $stage .= " REC-Invalid $exten $filename $channel"; + } + else + { + $VDvicidial_id=''; + + if ($ACTION=="MonitorStereo") + { + $stmt="SELECT recording_id,filename FROM routing_initiated_recordings where user='$user' and processed='0' and rir_type='S' order by launch_time desc limit 1;"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02139',$user,$server_ip,$session_name,$one_mysql_log);} + if ($DB) {echo "$stmt\n";} + $rir_ct = mysqli_num_rows($rslt); + if ($rir_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $recording_id = $row[0]; + $filename = $row[1]; + + $stmt = "UPDATE routing_initiated_recordings SET processed='1' where recording_id='$recording_id';"; + if ($format=='debug') {echo "\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02140',$user,$server_ip,$session_name,$one_mysql_log);} + + $stage .= " RIR $recording_id"; + } + else + { + if ($FROMvdc=='YES') + { + ##### update vla recording record to blank + $stmt = "UPDATE vicidial_live_agents SET external_recording='' where user='$user';"; + if ($format=='debug') {echo "\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} + ##### get call type from vicidial_live_agents table + $VLA_inOUT='NONE'; + $stmt="SELECT comments FROM vicidial_live_agents where user='$user' order by last_update_time desc limit 1;"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02074',$user,$server_ip,$session_name,$one_mysql_log);} + if ($DB) {echo "$stmt\n";} + $VLA_inOUT_ct = mysqli_num_rows($rslt); + if ($VLA_inOUT_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $VLA_inOUT = $row[0]; + } + if ($VLA_inOUT == 'INBOUND') + { + $four_hours_ago = date("Y-m-d H:i:s", mktime(date("H")-4,date("i"),date("s"),date("m"),date("d"),date("Y"))); + + ##### look for the vicidial ID in the vicidial_closer_log table + $stmt="SELECT closecallid,campaign_id FROM vicidial_closer_log where lead_id='$lead_id' and user='$user' and call_date > \"$four_hours_ago\" order by closecallid desc limit 1;"; + } + else + { + ##### look for the vicidial ID in the vicidial_log table + $stmt="SELECT uniqueid,campaign_id FROM vicidial_log where uniqueid='$uniqueid' and lead_id='$lead_id';"; + } + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02075',$user,$server_ip,$session_name,$one_mysql_log);} + if ($DB) {echo "$stmt\n";} + $VM_mancall_ct = mysqli_num_rows($rslt); + if ($VM_mancall_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $VDvicidial_id = $row[0]; + $VDcampaign_id = $row[1]; + + $stmt = "UPDATE recording_log SET vicidial_id='$VDvicidial_id' where recording_id='$recording_id';"; + if ($format=='debug') {echo "\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02076',$user,$server_ip,$session_name,$one_mysql_log);} + } + + ##### gather stereo recording settings for this specific campaign/in-group + if ($VLA_inOUT == 'INBOUND') + { + $stmt="SELECT stereo_recording,stereo_parallel_recording,stereo_rec_filename,stereo_recording_agent FROM vicidial_inbound_groups where group_id='$VDcampaign_id';"; + } + else + { + $stmt="SELECT stereo_recording,stereo_parallel_recording,stereo_rec_filename,stereo_recording_agent FROM vicidial_campaigns where campaign_id='$VDcampaign_id';"; + } + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02075',$user,$server_ip,$session_name,$one_mysql_log);} + if ($DB) {echo "$stmt\n";} + $VM_mancall_ct = mysqli_num_rows($rslt); + if ($VM_mancall_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $stereo_recording = $row[0]; + $stereo_parallel_recording = $row[1]; + $stereo_rec_filename = $row[2]; + $stereo_recording_agent = $row[3]; + } + } + + if (preg_match("/CUSTOMER|BOTH/",$stereo_recording) ) + { + if ( ($SSstereo_parallel_recording > 0) and (!preg_match("/DISABLED/i",$stereo_parallel_recording)) ) + { + $stereo_exten = 'SPAC'; + if (preg_match("/BOTH_CHANNELS/",$stereo_recording) ) + {$stereo_exten='SPACBC';} + if (preg_match("/CUSTOMER_ONLY/",$stereo_recording) ) + {$stereo_exten='SPACCO';} + if (preg_match("/CUSTOMER_MUTE/",$stereo_recording) ) + {$stereo_exten='SPACCM';} + $stereo_ac = $stereo_exten.'-'.$stereo_recording_agent."\n"; + } + else + { + $stereo_exten = 'SAC'; + if (preg_match("/BOTH_CHANNELS/",$stereo_recording) ) + {$stereo_exten='SACBC';} + if (preg_match("/CUSTOMER_ONLY/",$stereo_recording) ) + {$stereo_exten='SACCO';} + if (preg_match("/CUSTOMER_MUTE/",$stereo_recording) ) + {$stereo_exten='SACCM';} + $stereo_ac = $stereo_exten.'-'.$stereo_recording_agent."\n"; + } + # if VENDORLEADCODE is used in the stereo recording filenames, look it up for this lead + if (preg_match("/VENDORLEADCODE/",$stereo_rec_filename)) + { + $stmt="SELECT vendor_lead_code FROM vicidial_list where lead_id='$lead_id';"; + $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";} + $VM_mancall_ct = mysqli_num_rows($rslt); + if ($VM_mancall_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $vendor_lead_code = $row[0]; + } + } + $recdate = date("Ymd-His"); + $tinydate = date("ymdHis"); + + $stereo_rec_filename = preg_replace("/CAMPAIGN/",$campaign,$stereo_rec_filename); + $stereo_rec_filename = preg_replace("/INGROUP/",$VDcampaign_id,$stereo_rec_filename); + $stereo_rec_filename = preg_replace("/CUSTPHONE/",$phone_number,$stereo_rec_filename); + $stereo_rec_filename = preg_replace("/FULLDATE/",$recdate,$stereo_rec_filename); + $stereo_rec_filename = preg_replace("/TINYDATE/",$tinydate,$stereo_rec_filename); + $stereo_rec_filename = preg_replace("/EPOCH/",$StarTtime,$stereo_rec_filename); + $stereo_rec_filename = preg_replace("/AGENT/",$user,$stereo_rec_filename); + $stereo_rec_filename = preg_replace("/VENDORLEADCODE/",$vendor_lead_code,$stereo_rec_filename); + $stereo_rec_filename = preg_replace("/LEADID/",$lead_id,$stereo_rec_filename); + $stereo_rec_filename = preg_replace("/CALLID/",$CalLCID,$stereo_rec_filename); + $stereo_rec_filename = preg_replace("/\"|\'/",'',$stereo_rec_filename); + + if (preg_match("/RECID/",$filename) ) + { + $stmt = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$server_ip','$stereo_exten','$NOW_TIME','$StarTtime','$stereo_rec_filename','$lead_id','$user','$VDvicidial_id')"; + if ($format=='debug') {echo "\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02133',$user,$server_ip,$session_name,$one_mysql_log);} + $RLaffected_rows = mysqli_affected_rows($link); + if ($RLaffected_rows > 0) + { + $recording_id = mysqli_insert_id($link); + } + + $stereo_rec_filename = preg_replace("/RECID/","$recording_id",$stereo_rec_filename); + + $stmt = "UPDATE recording_log SET filename='$stereo_rec_filename' where recording_id='$recording_id';"; + if ($format=='debug') {echo "\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02134',$user,$server_ip,$session_name,$one_mysql_log);} + } + else + { + $stmt = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$server_ip','$stereo_exten','$NOW_TIME','$StarTtime','$stereo_rec_filename','$lead_id','$user','$VDvicidial_id')"; + if ($format=='debug') {echo "\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02073',$user,$server_ip,$session_name,$one_mysql_log);} + $RLaffected_rows = mysqli_affected_rows($link); + if ($RLaffected_rows > 0) + { + $recording_id = mysqli_insert_id($link); + } + } + + if ( ($SSstereo_parallel_recording > 0) and (!preg_match("/DISABLED/i",$stereo_parallel_recording)) ) + { + $four_hours_ago = date("Y-m-d H:i:s", mktime(date("H")-4,date("i"),date("s"),date("m"),date("d"),date("Y"))); + + $parallel_recording_id=0; + # gather parallel_recording_id from recording_log_parallel + $stmt="SELECT parallel_recording_id FROM recording_log_parallel where lead_id='$lead_id' and user='$user' and channel='$channel' and start_time > \"$four_hours_ago\" order by parallel_recording_id desc limit 1;"; + $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";} + $PR_ct = mysqli_num_rows($rslt); + if ($PR_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $parallel_recording_id = $row[0]; + } + + # stereo_parallel_recording is enabled, only insert DB records, don't initiate recording + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,recording_status,parallel_recording_id) values('$recording_id','$server_ip','$NOW_TIME','0','$stereo_rec_filename','$lead_id','$VDcampaign_id STEREO_PARALLEL AGENT-CONTROLLED $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $VDvicidial_id|user: $user|channel: $channel|','STEREO START','$parallel_recording_id');"; + if ($format=='debug') {echo "\n";} + $rslt=mysql_to_mysqli($stmtA, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmtA,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL AGENT-CONTROLLED','$server_ip','$NOW_TIME','$channel','$stereo_rec_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED');"; + if ($format=='debug') {echo "\n";} + $rslt=mysql_to_mysqli($stmtD, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmtD,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} + } + else + { + ### start the stereo recording + $PATHmonitorT = '/var/spool/asterisk/monitorS'; + $stereo_recording_options = "r($PATHmonitorT/$stereo_rec_filename-out.wav)t($PATHmonitorT/$stereo_rec_filename-in.wav)"; + $vmgr_callerid = substr($stereo_rec_filename, 0, 17) . '...'; + $stmt="INSERT INTO vicidial_manager values('','','$NOW_TIME','NEW','N','$server_ip','','MixMonitor','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Options: $stereo_recording_options','','','','','','','');"; + if ($format=='debug') {echo "\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02135',$user,$server_ip,$session_name,$one_mysql_log);} + + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,recording_status) values('$recording_id','$server_ip','$NOW_TIME','0','$stereo_rec_filename','$lead_id','$VDcampaign_id STEREO AGENT-CONTROLLED $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $VDvicidial_id|user: $user|channel: $channel|','STEREO START');"; + if ($format=='debug') {echo "\n";} + $rslt=mysql_to_mysqli($stmtA, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmtA,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} + + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO AGENT-CONTROLLED','$server_ip','$NOW_TIME','$channel','$stereo_rec_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED');"; + if ($format=='debug') {echo "\n";} + $rslt=mysql_to_mysqli($stmtD, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmtD,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} + + if (preg_match("/CUSTOMER_ONLY/",$stereo_recording) ) + { + $vmgr_callerid = substr($stereo_rec_filename, 0, 16) . 'M...'; + $stmt="INSERT INTO vicidial_manager values('','','$NOW_TIME','NEW','N','$server_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: write','State: 1','','','','','','');"; + if ($format=='debug') {echo "\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} + } + if (preg_match("/CUSTOMER_MUTE/",$stereo_recording) ) + { + $vmgr_callerid = substr($stereo_rec_filename, 0, 16) . 'M...'; + $stmt="INSERT INTO vicidial_manager values('','','$NOW_TIME','NEW','N','$server_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: read','State: 1','','','','','','');"; + if ($format=='debug') {echo "\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} + } + } + $filename = $stereo_rec_filename; + } + $stage .= " AIR $recording_id $stereo_rec_filename"; + } + } + ##### BEGIN StopMonitorStereo steps ##### + else + { + $recording_type=''; + if ($FROMvdc=='YES') + { + ##### update vla recording record to blank + $stmt = "UPDATE vicidial_live_agents SET external_recording='' where user='$user';"; + if ($format=='debug') {echo "\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} + } + if ($uniqueid=='IN') + { + $four_hours_ago = date("Y-m-d H:i:s", mktime(date("H")-4,date("i"),date("s"),date("m"),date("d"),date("Y"))); + + ### find the value to put in the vicidial_id field if this was an inbound call + $stmt="SELECT closecallid from vicidial_closer_log where lead_id='$lead_id' and call_date > \"$four_hours_ago\" order by closecallid desc limit 1;"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02077',$user,$server_ip,$session_name,$one_mysql_log);} + $VAC_qm_ct = mysqli_num_rows($rslt); + if ($VAC_qm_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $uniqueidSQL = ",vicidial_id='$row[0]'"; + } + } + else + { + if (strlen($uniqueid) > 8) + {$uniqueidSQL = ",vicidial_id='$uniqueid'";} + } + + $rec_searchSQL = "filename='$filename'"; + if (preg_match("/^ID:/",$filename)) + { + $recording_id = $filename; + $recording_id = preg_replace("/^ID:/",'',$recording_id); + $rec_searchSQL = "recording_id='$recording_id'"; + } + + $stmt="SELECT recording_id,UNIX_TIMESTAMP(start_time),filename,recording_type FROM recording_live where channel='$channel' and user='$user' and recording_status='STARTED' and recording_type LIKE \"STEREO%\" and recording_type LIKE \"%AGENT-CONTROLLED%\" order by start_time desc;"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} + if ($DB) {echo "$stmt\n";} + $rec_count = mysqli_num_rows($rslt); + if ($rec_count>0) + { + $row=mysqli_fetch_row($rslt); + $recording_id = $row[0]; + $start_time = $row[1]; + $filename = $row[2]; + $recording_type = $row[3]; + $vmgr_callerid = substr($filename, 0, 17) . '...'; + $length_in_sec = ($StarTtime - $start_time); + $length_in_min = ($length_in_sec / 60); + $length_in_min = sprintf("%8.2f", $length_in_min); + + $stmt = "UPDATE recording_log set end_time='$NOW_TIME',end_epoch='$StarTtime',length_in_sec=$length_in_sec,length_in_min='$length_in_min' $uniqueidSQL where recording_id='$recording_id';"; + if ($DB) {echo "$stmt\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02079',$user,$server_ip,$session_name,$one_mysql_log);} + + $stmt = "UPDATE recording_log_stereo set end_time='$NOW_TIME',recording_status='FINISHED',length_in_sec=$length_in_sec where recording_id='$recording_id';"; + if ($DB) {echo "$stmt\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} + + $stmt = "UPDATE recording_live set end_time='$NOW_TIME',recording_status='FINISHED' where recording_id='$recording_id' and recording_status='STARTED';"; + if ($DB) {echo "$stmt\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} + + $stmt = "UPDATE routing_initiated_recordings set processed='1' where user='$user' and processed='0' and rir_type='S' order by launch_time desc limit 1;"; + if ($DB) {echo "$stmt\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} + } + + # if ($WeBRooTWritablE > 0) + # { + # $fp = fopen ("./vicidial_debug.txt", "a"); + # fwrite ($fp, "$NOW_TIME|STEREO_START|$user|$channel|$rec_count|$stmt|\n"); + # fclose($fp); + # } + + if (!preg_match("/PARALLEL/",$recording_type)) + { + # stop all stereo recordings on the customer channel + $stmt="INSERT INTO vicidial_manager values('','','$NOW_TIME','NEW','N','$server_ip','','StopMixMonitor','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','','','','','','','','');"; + if ($format=='debug') {echo "\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} + } + } + ##### END StopMonitorStereo steps ##### + echo _QXZ("%1s command sent for Channel %2s on %3s",0,'',$ACTION,$channel,$server_ip)."\nFilename: $filename\nRecorDing_ID: $recording_id\n RECORDING WILL LAST UP TO 60 MINUTES\n"; + } + } ###################### diff --git a/www/agc/vdc_db_query.php b/www/agc/vdc_db_query.php index b0bc5e9b0..848d1106e 100644 --- a/www/agc/vdc_db_query.php +++ b/www/agc/vdc_db_query.php @@ -560,10 +560,11 @@ # 250326-1937 - Fix for missing vicidial_inbound_group_agents entries # 250601-0843 - Fix for fronter/closer start/dispo URL variables # 250723-2002 - Fix for issue #1548 +# 250916-1918 - Added stereo recording features # -$version = '2.14-453'; -$build = '250723-2002'; +$version = '2.14-454'; +$build = '250916-1918'; $php_script = 'vdc_db_query.php'; $mel=1; # Mysql Error Log enabled = 1 $mysql_log_count=913; @@ -1089,7 +1090,7 @@ ############################################# ##### START SYSTEM_SETTINGS LOOKUP ##### -$stmt = "SELECT use_non_latin,timeclock_end_of_day,agentonly_callback_campaign_lock,alt_log_server_ip,alt_log_dbname,alt_log_login,alt_log_pass,tables_use_alt_log_db,qc_features_active,allow_emails,callback_time_24hour,enable_languages,language_method,agent_debug_logging,default_language,active_modules,allow_chats,default_phone_code,user_new_lead_limit,sip_event_logging,call_quota_lead_ranking,daily_call_count_limit,call_limit_24hour,allow_web_debug,abandon_check_queue,inbound_credits FROM system_settings;"; +$stmt = "SELECT use_non_latin,timeclock_end_of_day,agentonly_callback_campaign_lock,alt_log_server_ip,alt_log_dbname,alt_log_login,alt_log_pass,tables_use_alt_log_db,qc_features_active,allow_emails,callback_time_24hour,enable_languages,language_method,agent_debug_logging,default_language,active_modules,allow_chats,default_phone_code,user_new_lead_limit,sip_event_logging,call_quota_lead_ranking,daily_call_count_limit,call_limit_24hour,allow_web_debug,abandon_check_queue,inbound_credits,stereo_recording,stereo_parallel_recording FROM system_settings;"; $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00001',$user,$server_ip,$session_name,$one_mysql_log);} #if ($DB) {echo "$stmt\n";} @@ -1123,6 +1124,8 @@ $SSallow_web_debug = $row[23]; $SSabandon_check_queue = $row[24]; $SSinbound_credits = $row[25]; + $SSstereo_recording = $row[26]; + $SSstereo_parallel_recording = $row[27]; } if ($SSallow_web_debug < 1) {$DB=0; $format='text';} ##### END SETTINGS LOOKUP ##### @@ -5391,6 +5394,8 @@ $stage .= "|RIR"; } + # NOTE: Do NOT start stereo call recording yet, since the customer channel hasn't Answered and resolved yet + ### Skip logging and list overrides if dial in-group is used if (strlen($dial_ingroup) < 1) { @@ -7431,6 +7436,8 @@ $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00741',$user,$server_ip,$session_name,$one_mysql_log);} + # NOTE: Do NOT start stereo call recording yet, since the customer channel hasn't Answered and resolved yet + $stage .= "|RIR"; } @@ -8100,6 +8107,7 @@ if ($call_good > 0) { + $stereo_ac="\n"; if ($stage != "YES") { $wait_sec=0; @@ -8134,44 +8142,363 @@ if ( ($routing_initiated_recording == 'Y') and (preg_match("/^M/",$MDnextCID)) ) { - if (preg_match("/CUSTOMER/",$stereo_recording)) + $stmt="UPDATE recording_log set vicidial_id='$uniqueid' where lead_id='$lead_id' and vicidial_id='$MDnextCID';"; + if ($format=='debug') {echo "\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00742',$user,$server_ip,$session_name,$one_mysql_log);} + } + + if ( (preg_match("/CUSTOMER|BOTH/",$stereo_recording)) and (preg_match("/^M/",$MDnextCID)) and ($SSstereo_recording > 0) ) + { + $stmt="SELECT conf_engine FROM servers where server_ip='$server_ip';"; + $rslt=mysql_to_mysqli($stmt, $link); + $row=mysqli_fetch_row($rslt); + if ( $row[0] == 'CONFBRIDGE' ) { - $stmt="SELECT conf_engine FROM servers where server_ip='$server_ip';"; + $stmt="SELECT stereo_recording,stereo_parallel_recording,stereo_rec_filename,stereo_recording_agent,parallel_rec_co_filename,parallel_rec_cm_filename,parallel_rec_fr_filename FROM vicidial_campaigns where campaign_id='$campaign';"; $rslt=mysql_to_mysqli($stmt, $link); - $row=mysqli_fetch_row($rslt); - if ( $row[0] == 'CONFBRIDGE' ) + 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";} + $VM_mancall_ct = mysqli_num_rows($rslt); + if ($VM_mancall_ct > 0) { - if ( (strlen($recording_filename) < 1) or (strlen($recording_id) < 1) ) + $row=mysqli_fetch_row($rslt); + $stereo_recording = $row[0]; + $stereo_parallel_recording = $row[1]; + $stereo_rec_filename = $row[2]; + $stereo_recording_agent = $row[3]; + $parallel_rec_co_filename = $row[4]; + $parallel_rec_cm_filename = $row[5]; + $parallel_rec_fr_filename = $row[6]; + } + + if ( (preg_match("/CUSTOMER|BOTH/",$stereo_recording) ) and (strlen($stereo_rec_filename) > 5) ) + { + # if VENDORLEADCODE is used in any of the stereo recording filenames, look it up for this lead + if ( (preg_match("/VENDORLEADCODE/",$stereo_rec_filename)) or (preg_match("/VENDORLEADCODE/",$parallel_rec_co_filename)) or (preg_match("/VENDORLEADCODE/",$parallel_rec_cm_filename)) or (preg_match("/VENDORLEADCODE/",$parallel_rec_fr_filename)) ) { - $stmt = "SELECT recording_id,filename from recording_log where lead_id='$lead_id' and vicidial_id='$MDnextCID';"; + $stmt="SELECT vendor_lead_code FROM vicidial_list where lead_id='$lead_id';"; + $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";} + $VM_mancall_ct = mysqli_num_rows($rslt); + if ($VM_mancall_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $vendor_lead_code = $row[0]; + } + } + $recdate = date("Ymd-His"); + $tinydate = date("ymdHis"); + + $stereo_rec_filename = preg_replace("/CAMPAIGN/",$campaign,$stereo_rec_filename); + $stereo_rec_filename = preg_replace("/INGROUP/",$campaign,$stereo_rec_filename); + $stereo_rec_filename = preg_replace("/CUSTPHONE/",$phone_number,$stereo_rec_filename); + $stereo_rec_filename = preg_replace("/FULLDATE/",$recdate,$stereo_rec_filename); + $stereo_rec_filename = preg_replace("/TINYDATE/",$tinydate,$stereo_rec_filename); + $stereo_rec_filename = preg_replace("/EPOCH/",$StarTtime,$stereo_rec_filename); + $stereo_rec_filename = preg_replace("/AGENT/",$user,$stereo_rec_filename); + $stereo_rec_filename = preg_replace("/VENDORLEADCODE/",$vendor_lead_code,$stereo_rec_filename); + $stereo_rec_filename = preg_replace("/LEADID/",$lead_id,$stereo_rec_filename); + $stereo_rec_filename = preg_replace("/CALLID/",$MDnextCID,$stereo_rec_filename); + $stereo_rec_filename = preg_replace("/\"|\'/",'',$stereo_rec_filename); + + $PATHmonitorS = '/var/spool/asterisk/monitorS'; + $PATHmonitorP = '/var/spool/asterisk/monitorP'; + $PATHmonitorT = $PATHmonitorS; + + if ( ($SSstereo_parallel_recording > 0) && (preg_match("/CUSTOMER|FULL/",$stereo_parallel_recording)) ) + { + $PATHmonitorT = $PATHmonitorP; + $filename = "PL$stereo_rec_filename"; + + $stmt = "INSERT INTO recording_log_parallel (channel,server_ip,extension,start_time,length_in_sec,filename,lead_id,user,vicidial_id,recording_status) values('$channel','$server_ip','','$NOW_TIME','0','$filename','$lead_id','$user','$uniqueid','START');"; + if ($format=='debug') {echo "\n";} $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);} - $RL_ct = mysqli_num_rows($rslt); - if ($RL_ct > 0) + $PRLaffected_rows = mysqli_affected_rows($link); + if ($PRLaffected_rows > 0) { - $row=mysqli_fetch_row($rslt); - $recording_id = $row[0]; - $recording_filename = $row[1]; + $parallel_recording_id = mysqli_insert_id($link); + } + + $vmgr_callerid = substr($filename, 0, 17) . '...'; + $stereo_recording_options = "r($PATHmonitorT/$filename-out.wav)t($PATHmonitorT/$filename-in.wav)"; + $stmt="INSERT INTO vicidial_manager values('','','$NOW_TIME','NEW','N','$server_ip','','MixMonitor','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Options: $stereo_recording_options','','','','','','','');"; + if ($format=='debug') {echo "\n";} + $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 ((preg_match("/CUSTOMER-ONLY/",$stereo_parallel_recording))) + { + $temp_parallel_rec_co_filename = "CO".$stereo_rec_filename; + if (strlen($parallel_rec_co_filename) > 0) + { + $temp_parallel_rec_co_filename = $parallel_rec_co_filename; + $temp_parallel_rec_co_filename = preg_replace("/CAMPAIGN/",$campaign,$temp_parallel_rec_co_filename); + $temp_parallel_rec_co_filename = preg_replace("/INGROUP/",$campaign,$temp_parallel_rec_co_filename); + $temp_parallel_rec_co_filename = preg_replace("/CUSTPHONE/",$phone_number,$temp_parallel_rec_co_filename); + $temp_parallel_rec_co_filename = preg_replace("/FULLDATE/",$recdate,$temp_parallel_rec_co_filename); + $temp_parallel_rec_co_filename = preg_replace("/TINYDATE/",$tinydate,$temp_parallel_rec_co_filename); + $temp_parallel_rec_co_filename = preg_replace("/EPOCH/",$StarTtime,$temp_parallel_rec_co_filename); + $temp_parallel_rec_co_filename = preg_replace("/AGENT/",$user,$temp_parallel_rec_co_filename); + $temp_parallel_rec_co_filename = preg_replace("/VENDORLEADCODE/",$vendor_lead_code,$temp_parallel_rec_co_filename); + $temp_parallel_rec_co_filename = preg_replace("/LEADID/",$lead_id,$temp_parallel_rec_co_filename); + $temp_parallel_rec_co_filename = preg_replace("/CALLID/",$MDnextCID,$temp_parallel_rec_co_filename); + $temp_parallel_rec_co_filename = preg_replace("/\"|\'/",'',$temp_parallel_rec_co_filename); + } + + ### insert a record into the recording_log table + $stmt = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$server_ip','SPCO','$NOW_TIME','$StarTtime','$temp_parallel_rec_co_filename','$lead_id','$user','$uniqueid')"; + if ($format=='debug') {echo "\n";} + $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);} + $RLaffected_rows = mysqli_affected_rows($link); + if ($RLaffected_rows > 0) + { + $recording_id = mysqli_insert_id($link); + } + if (preg_match("/RECID/",$temp_parallel_rec_co_filename)) + { + $temp_parallel_rec_co_filename = preg_replace("/RECID/",$recording_id,$temp_parallel_rec_co_filename); + $stmt = "UPDATE recording_log SET filename='$temp_parallel_rec_co_filename' where recording_id='$recording_id';"; + if ($format=='debug') {echo "\n";} + $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);} + } + + ### insert record into recording_log_stereo table ### + $stmt = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$server_ip','$NOW_TIME','0','$temp_parallel_rec_co_filename','$lead_id','$campaign STEREO_PARALLEL CUSTOMER-ONLY $stereo_recording','vicidial_id: $uniqueid|user: $user|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + if ($format=='debug') {echo "\n";} + $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);} + + ### insert record into recording_live table ### + $stmt = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL CUSTOMER-ONLY','$server_ip','$NOW_TIME','$channel','$temp_parallel_rec_co_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED');"; + if ($format=='debug') {echo "\n";} + $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 ((preg_match("/CUSTOMER-MUTED/",$stereo_parallel_recording))) + { + $temp_parallel_rec_cm_filename = "CM".$stereo_rec_filename; + if (strlen($parallel_rec_cm_filename) > 0) + { + $temp_parallel_rec_cm_filename = $parallel_rec_cm_filename; + $temp_parallel_rec_cm_filename = preg_replace("/CAMPAIGN/",$campaign,$temp_parallel_rec_cm_filename); + $temp_parallel_rec_cm_filename = preg_replace("/INGROUP/",$campaign,$temp_parallel_rec_cm_filename); + $temp_parallel_rec_cm_filename = preg_replace("/CUSTPHONE/",$phone_number,$temp_parallel_rec_cm_filename); + $temp_parallel_rec_cm_filename = preg_replace("/FULLDATE/",$recdate,$temp_parallel_rec_cm_filename); + $temp_parallel_rec_cm_filename = preg_replace("/TINYDATE/",$tinydate,$temp_parallel_rec_cm_filename); + $temp_parallel_rec_cm_filename = preg_replace("/EPOCH/",$StarTtime,$temp_parallel_rec_cm_filename); + $temp_parallel_rec_cm_filename = preg_replace("/AGENT/",$user,$temp_parallel_rec_cm_filename); + $temp_parallel_rec_cm_filename = preg_replace("/VENDORLEADCODE/",$vendor_lead_code,$temp_parallel_rec_cm_filename); + $temp_parallel_rec_cm_filename = preg_replace("/LEADID/",$lead_id,$temp_parallel_rec_cm_filename); + $temp_parallel_rec_cm_filename = preg_replace("/CALLID/",$MDnextCID,$temp_parallel_rec_cm_filename); + $temp_parallel_rec_cm_filename = preg_replace("/\"|\'/",'',$temp_parallel_rec_cm_filename); + } + + ### insert a record into the recording_log table + $stmt = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$server_ip','SPCM','$NOW_TIME','$StarTtime','$temp_parallel_rec_cm_filename','$lead_id','$user','$uniqueid')"; + if ($format=='debug') {echo "\n";} + $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);} + $RLaffected_rows = mysqli_affected_rows($link); + if ($RLaffected_rows > 0) + { + $recording_id = mysqli_insert_id($link); + } + if (preg_match("/RECID/",$temp_parallel_rec_cm_filename)) + { + $temp_parallel_rec_cm_filename = preg_replace("/RECID/",$recording_id,$temp_parallel_rec_cm_filename); + $stmt = "UPDATE recording_log SET filename='$temp_parallel_rec_cm_filename' where recording_id='$recording_id';"; + if ($format=='debug') {echo "\n";} + $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);} + } + + ### insert record into recording_log_stereo table ### + $stmt = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$server_ip','$NOW_TIME','0','$temp_parallel_rec_cm_filename','$lead_id','$campaign STEREO_PARALLEL CUSTOMER-MUTED $stereo_recording','vicidial_id: $uniqueid|user: $user|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + if ($format=='debug') {echo "\n";} + $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);} + + ### insert record into recording_live table ### + $stmt = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL CUSTOMER-MUTED','$server_ip','$NOW_TIME','$channel','$temp_parallel_rec_cm_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED');"; + if ($format=='debug') {echo "\n";} + $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 ((preg_match("/FULL-RECORDING/",$stereo_parallel_recording))) + { + $temp_parallel_rec_fr_filename = "FR".$stereo_rec_filename; + if (strlen($parallel_rec_fr_filename) > 0) + { + $temp_parallel_rec_fr_filename = $parallel_rec_fr_filename; + $temp_parallel_rec_fr_filename = preg_replace("/CAMPAIGN/",$campaign,$temp_parallel_rec_fr_filename); + $temp_parallel_rec_fr_filename = preg_replace("/INGROUP/",$campaign,$temp_parallel_rec_fr_filename); + $temp_parallel_rec_fr_filename = preg_replace("/CUSTPHONE/",$phone_number,$temp_parallel_rec_fr_filename); + $temp_parallel_rec_fr_filename = preg_replace("/FULLDATE/",$recdate,$temp_parallel_rec_fr_filename); + $temp_parallel_rec_fr_filename = preg_replace("/TINYDATE/",$tinydate,$temp_parallel_rec_fr_filename); + $temp_parallel_rec_fr_filename = preg_replace("/EPOCH/",$StarTtime,$temp_parallel_rec_fr_filename); + $temp_parallel_rec_fr_filename = preg_replace("/AGENT/",$user,$temp_parallel_rec_fr_filename); + $temp_parallel_rec_fr_filename = preg_replace("/VENDORLEADCODE/",$vendor_lead_code,$temp_parallel_rec_fr_filename); + $temp_parallel_rec_fr_filename = preg_replace("/LEADID/",$lead_id,$temp_parallel_rec_fr_filename); + $temp_parallel_rec_fr_filename = preg_replace("/CALLID/",$MDnextCID,$temp_parallel_rec_fr_filename); + $temp_parallel_rec_fr_filename = preg_replace("/\"|\'/",'',$temp_parallel_rec_fr_filename); + } + + ### insert a record into the recording_log table + $stmt = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$server_ip','SPFR','$NOW_TIME','$StarTtime','$temp_parallel_rec_fr_filename','$lead_id','$user','$uniqueid')"; + if ($format=='debug') {echo "\n";} + $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);} + $RLaffected_rows = mysqli_affected_rows($link); + if ($RLaffected_rows > 0) + { + $recording_id = mysqli_insert_id($link); + } + if (preg_match("/RECID/",$temp_parallel_rec_fr_filename)) + { + $temp_parallel_rec_fr_filename = preg_replace("/RECID/",$recording_id,$temp_parallel_rec_fr_filename); + $stmt = "UPDATE recording_log SET filename='$temp_parallel_rec_fr_filename' where recording_id='$recording_id';"; + if ($format=='debug') {echo "\n";} + $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);} + } + + ### insert record into recording_log_stereo table ### + $stmt = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$server_ip','$NOW_TIME','0','$temp_parallel_rec_fr_filename','$lead_id','$campaign STEREO_PARALLEL FULL-RECORDING $stereo_recording','vicidial_id: $uniqueid|user: $user|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + if ($format=='debug') {echo "\n";} + $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);} + + ### insert record into recording_live table ### + $stmt = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL FULL-RECORDING','$server_ip','$NOW_TIME','$channel','$temp_parallel_rec_fr_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED');"; + if ($format=='debug') {echo "\n";} + $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);} + } + + # insert logs for agent-controlled stereo call recordings while parallel recordings are enabled + if ((preg_match("/ALLCALLS|ALLFORCE/",$stereo_recording_agent))) + { + $stereo_exten='SPAC'; + if (preg_match("/BOTH_CHANNELS/",$stereo_recording) ) + {$stereo_exten='SPACBC';} + if (preg_match("/CUSTOMER_ONLY/",$stereo_recording) ) + {$stereo_exten='SPACCO';} + if (preg_match("/CUSTOMER_MUTE/",$stereo_recording) ) + {$stereo_exten='SPACCM';} + $stereo_ac = $stereo_exten.'-'.$stereo_recording_agent."\n"; + $temp_parallel_rec_ag_filename = $stereo_rec_filename; + + ### insert a record into the recording_log table + $stmt = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$server_ip','$stereo_exten','$NOW_TIME','$StarTtime','$temp_parallel_rec_ag_filename','$lead_id','$user','$uniqueid')"; + if ($format=='debug') {echo "\n";} + $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);} + $RLaffected_rows = mysqli_affected_rows($link); + if ($RLaffected_rows > 0) + { + $recording_id = mysqli_insert_id($link); + } + if (preg_match("/RECID/",$temp_parallel_rec_fr_filename)) + { + $temp_parallel_rec_fr_filename = preg_replace("/RECID/",$recording_id,$temp_parallel_rec_fr_filename); + $stmt = "UPDATE recording_log SET filename='$temp_parallel_rec_ag_filename' where recording_id='$recording_id';"; + if ($format=='debug') {echo "\n";} + $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);} + } + + ### insert record into recording_log_stereo table ### + $stmt = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$server_ip','$NOW_TIME','0','$temp_parallel_rec_ag_filename','$lead_id','$campaign STEREO_PARALLEL AGENT-CONTROLLED $stereo_recording','vicidial_id: $uniqueid|user: $user|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + if ($format=='debug') {echo "\n";} + $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);} + + ### insert record into recording_live table ### + $stmt = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL AGENT-CONTROLLED','$server_ip','$NOW_TIME','$channel','$temp_parallel_rec_ag_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED');"; + if ($format=='debug') {echo "\n";} + $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 ((preg_match("/ONDEMAND/",$stereo_recording_agent))) + { + $stereo_ac='SOD-'.$stereo_recording_agent."\n"; } } - $tempMDnextCID = $MDnextCID; - $tempMDnextCID = preg_replace("/^../",'SR',$tempMDnextCID); - $stmt="INSERT INTO vicidial_manager values('','','$NOW_TIME','NEW','N','$server_ip','','MixMonitor','$tempMDnextCID','ActionID: $tempMDnextCID','Channel: $channel','options: r(../monitorS/$recording_filename-in.wav)t(../monitorS/$recording_filename-out.wav)','','','','','','','');"; - if ($format=='debug') {echo "\n";} - $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);} + else + { + if ((preg_match("/ALLCALLS|ALLFORCE/",$stereo_recording_agent))) + { + $stereo_ac='SAC-'.$stereo_recording_agent."\n"; + ## Start NON-parallel stereo call recording ## + # insert a record into the recording_log table + $stmt = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$server_ip','SAC','$NOW_TIME','$StarTtime','$stereo_rec_filename','$lead_id','$user','$uniqueid')"; + if ($format=='debug') {echo "\n";} + $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);} + $RLaffected_rows = mysqli_affected_rows($link); + if ($RLaffected_rows > 0) + { + $recording_id = mysqli_insert_id($link); + } + if (preg_match("/RECID/",$stereo_rec_filename)) + { + $stereo_rec_filename = preg_replace("/RECID/",$recording_id,$stereo_rec_filename); + $stmt = "UPDATE recording_log SET filename='$stereo_rec_filename' where recording_id='$recording_id';"; + if ($format=='debug') {echo "\n";} + $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);} + } - $stmt="INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log) values('$recording_id','$server_ip','$NOW_TIME','0','$recording_filename','$lead_id','$stereo_recording $campaign','start: $NOW_TIME|vicidial_id: $uniqueid|user: $user|channel: $channel|CID: $MDnextCID|');"; - if ($format=='debug') {echo "\n";} - $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);} + $vmgr_callerid = substr($stereo_rec_filename, 0, 17) . '...'; + $stereo_recording_options = "r($PATHmonitorT/$stereo_rec_filename-out.wav)t($PATHmonitorT/$stereo_rec_filename-in.wav)"; + $stmt="INSERT INTO vicidial_manager values('','','$NOW_TIME','NEW','N','$server_ip','','MixMonitor','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Options: $stereo_recording_options','','','','','','','');"; + if ($format=='debug') {echo "\n";} + $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);} + + ### insert record into recording_log_stereo table ### + $stmt = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$server_ip','$NOW_TIME','0','$stereo_rec_filename','$lead_id','$campaign STEREO AGENT-CONTROLLED $stereo_recording','vicidial_id: $uniqueid|user: $user|channel: $channel|','$parallel_recording_id','START');"; + if ($format=='debug') {echo "\n";} + $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);} + + ### insert record into recording_live table ### + $stmt = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO AGENT-CONTROLLED','$server_ip','$NOW_TIME','$channel','$stereo_rec_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED');"; + if ($format=='debug') {echo "\n";} + $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 (preg_match("/CUSTOMER_ONLY/",$stereo_recording) ) + { + $vmgr_callerid = substr($stereo_rec_filename, 0, 16) . 'M...'; + $stmt="INSERT INTO vicidial_manager values('','','$NOW_TIME','NEW','N','$server_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: write','State: 1','','','','','','');"; + if ($format=='debug') {echo "\n";} + $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 (preg_match("/CUSTOMER_MUTE/",$stereo_recording) ) + { + $vmgr_callerid = substr($stereo_rec_filename, 0, 16) . 'M...'; + $stmt="INSERT INTO vicidial_manager values('','','$NOW_TIME','NEW','N','$server_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: read','State: 1','','','','','','');"; + if ($format=='debug') {echo "\n";} + $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 ((preg_match("/ONDEMAND/",$stereo_recording_agent))) + { + $stereo_ac='SOD-'.$stereo_recording_agent."\n"; + } + } } } - $stmt="UPDATE recording_log set vicidial_id='$uniqueid' where lead_id='$lead_id' and vicidial_id='$MDnextCID';"; - if ($format=='debug') {echo "\n";} - $rslt=mysql_to_mysqli($stmt, $link); - if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00742',$user,$server_ip,$session_name,$one_mysql_log);} } if ($SSabandon_check_queue > 0) @@ -8338,7 +8665,7 @@ } ##### END SIP event logging, if enabled in the system ##### - echo "$call_output$sip_event_action_output"; + echo "$call_output$sip_event_action_output$stereo_ac"; $stage .= " $uniqueid $channel"; } @@ -8389,10 +8716,10 @@ { if ($WeBRooTWritablE > 0) { - $fp = fopen ("./vicidial_debug.txt", "w"); + # $fp = fopen ("./vicidial_debug.txt", "w"); # fwrite ($fp, "$NOW_TIME|VL_LOG_0|$uniqueid|$lead_id|$user|$list_id|$campaign|$start_epoch|$phone_number|$agent_log_id|\n"); - fwrite ($fp, "$NOW_TIME|VL_LOG_0|\n"); - fclose($fp); + # fwrite ($fp, "$NOW_TIME|VL_LOG_0|\n"); + # fclose($fp); } echo "LOG NOT ENTERED\n"; @@ -8526,10 +8853,10 @@ if ( (strlen($uniqueid)<1) and ($VLA_inOUT == 'INBOUND') ) { - $fp = fopen ("./vicidial_debug.txt", "w"); + # $fp = fopen ("./vicidial_debug.txt", "a"); # fwrite ($fp, "$NOW_TIME|INBND_LOG_0|$uniqueid|$lead_id|$user|$inOUT|$VLA_inOUT|$start_epoch|$phone_number|$agent_log_id|\n"); - fwrite ($fp, "$NOW_TIME|INBND_LOG_0|\n"); - fclose($fp); + # fwrite ($fp, "$NOW_TIME|INBND_LOG_0|\n"); + # fclose($fp); $uniqueid='6666.1'; } @@ -8602,10 +8929,10 @@ if ( ($length_in_sec < 1) and ($VLA_inOUT == 'INBOUND') ) { - $fp = fopen ("./vicidial_debug.txt", "w"); + # $fp = fopen ("./vicidial_debug.txt", "a"); # fwrite ($fp, "$NOW_TIME|INBND_LOG_1|$uniqueid|$lead_id|$user|$inOUT|$length_in_sec|$VDterm_reason|$VDvicidial_id|$start_epoch|\n"); - fwrite ($fp, "$NOW_TIME|INBND_LOG_1|\n"); - fclose($fp); + # fwrite ($fp, "$NOW_TIME|INBND_LOG_1|\n"); + # fclose($fp); ##### start epoch in the vicidial_log table, couldn't find one in vicidial_closer_log $stmt="SELECT start_epoch,term_reason,campaign_id,status FROM vicidial_log where uniqueid='$uniqueid' and lead_id='$lead_id' and called_count='$called_count' order by call_date desc limit 1;"; @@ -8664,10 +8991,10 @@ } else { - $fp = fopen ("./vicidial_debug.txt", "w"); + # $fp = fopen ("./vicidial_debug.txt", "a"); # fwrite ($fp, "$NOW_TIME|INBND_LOG_2|$uniqueid|$lead_id|$user|$inOUT|$length_in_sec|$VDterm_reason|$VDvicidial_id|$start_epoch|\n"); - fwrite ($fp, "$NOW_TIME|INBND_LOG_2|\n"); - fclose($fp); + # fwrite ($fp, "$NOW_TIME|INBND_LOG_2|\n"); + # fclose($fp); } } @@ -9648,7 +9975,7 @@ $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00095',$user,$server_ip,$session_name,$one_mysql_log);} if ($rslt) {$rec_list = mysqli_num_rows($rslt);} - while ($rec_list>$loop_count) + while ($rec_list>$loop_count) { $row=mysqli_fetch_row($rslt); if (preg_match("/Local\/$conf_silent_prefix$conf_exten\@/i",$row[0])) @@ -9679,7 +10006,7 @@ $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00548',$user,$server_ip,$session_name,$one_mysql_log);} if ($rslt) {$rec_list = mysqli_num_rows($rslt);} - while ($rec_list>$loop_count) + while ($rec_list>$loop_count) { $row=mysqli_fetch_row($rslt); if (preg_match("/Local\/$conf_silent_prefix$conf_exten\@/i",$row[0])) @@ -9704,6 +10031,73 @@ $loop_count++; } + ### if stereo_recording enabled, then halt recording on the customer channel and look for recording logs to update + if ($SSstereo_recording > 0) + { + if ($WeBRooTWritablE > 0) + { + # $fp = fopen ("./vicidial_debug.txt", "a"); + # fwrite ($fp, "$NOW_TIME|SR_LOG_0|$uniqueid|$lead_id|$user|$inOUT|$VLA_inOUT|$SSstereo_recording|$server_ip|$channel|\n"); + # fclose($fp); + } + + # stop stereo recording on customer channel + $stmt="INSERT INTO vicidial_manager values('','','$NOW_TIME','NEW','N','$server_ip','','StopMixMonitor','SH123467$StarTtime','ActionID: SH123467$StarTtime','Channel: $channel','','','','','','','','');"; + if ($format=='debug') {echo "\n";} + $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);} + + ### gather live recordings tied to this customer channel + $stmt="SELECT recording_id,filename,start_time,UNIX_TIMESTAMP(start_time) from recording_live where channel='$channel' and lead_id='$lead_id' and recording_status='STARTED' and user='$user' and recording_type LIKE \"STEREO%\" limit 10;"; + $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);} + $ST_rec_ct = mysqli_num_rows($rslt); + $st=0; + while ($ST_rec_ct > $st) + { + $row=mysqli_fetch_row($rslt); + $STrecording_id[$st] = $row[0]; + $STfilename[$st] = $row[1]; + $STstart_time[$st] = $row[2]; + $STstart_epoch[$st] = $row[3]; + $st++; + } + + $st=0; + while ($ST_rec_ct > $st) + { + $length_in_sec = ($StarTtime - $STstart_epoch[$st]); + $length_in_min = ($length_in_sec / 60); + $length_in_min = sprintf("%8.2f", $length_in_min); + + ### update record in recording_live table ### + $stmt = "UPDATE recording_live SET end_time=NOW(),recording_status='FINISHED END-CALL' where recording_id='$STrecording_id[$st]';"; + if ($format=='debug') {echo "\n";} + $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);} + + ### update record in recording_log table ### + $stmt = "UPDATE recording_log SET end_time=NOW(),end_epoch='$StarTtime',length_in_sec='$length_in_sec',length_in_min='$length_in_min' where recording_id='$STrecording_id[$st]';"; + if ($format=='debug') {echo "\n";} + $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);} + + ### update record in recording_log_stereo table ### + $stmt = "UPDATE recording_log_stereo SET end_time=NOW(),recording_status='FINISHED END-CALL',length_in_sec='$length_in_sec' where recording_id='$STrecording_id[$st]';"; + if ($format=='debug') {echo "\n";} + $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);} + + $st++; + } + if ($WeBRooTWritablE > 0) + { + # $fp = fopen ("./vicidial_debug.txt", "a"); + # fwrite ($fp, "$NOW_TIME|SR_LOG_1|$uniqueid|$lead_id|$user|$inOUT|$VLA_inOUT|$SSstereo_recording|$st|$STrecording_id[$st]|$STfilename[$st]|$stmt|\n"); + # fwrite ($fp, "$NOW_TIME|INBND_LOG_3|\n"); + # fclose($fp); + } + } ### if a conference call or 3way call was attempted, then hangup all channels except for the agentchannel if ( ( ($conf_dialed > 0) or ($hangup_all_non_reserved > 0) ) and ($leaving_threeway < 1) and ($blind_transfer < 1) ) @@ -9781,10 +10175,10 @@ if ($WeBRooTWritablE > 0) { - $fp = fopen ("./vicidial_debug.txt", "w"); + # $fp = fopen ("./vicidial_debug.txt", "w"); # fwrite ($fp, "$NOW_TIME|INBND_LOG_3|$uniqueid|$lead_id|$user|$inOUT|$VLA_inOUT|$length_in_sec|$VDterm_reason|$VDvicidial_id|$vicidial_id|$start_epoch|$recording_id|\n"); - fwrite ($fp, "$NOW_TIME|INBND_LOG_3|\n"); - fclose($fp); + # fwrite ($fp, "$NOW_TIME|INBND_LOG_3|\n"); + # fclose($fp); } } } @@ -9797,6 +10191,11 @@ $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00100',$user,$server_ip,$session_name,$one_mysql_log);} + $stmt = "UPDATE recording_live set end_time='$NOW_TIME',recording_status='FINISHED END-CALL' where filename='$filename[$loop_count]' and recording_status='STARTED';"; + if ($DB) {echo "$stmt\n";} + $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);} + echo "$recording_id|$length_in_min|"; # $fp = fopen ("./recording_debug_$NOW_DATE$txt", "a"); @@ -10208,7 +10607,7 @@ $CBcomments = trim("$row[3]"); } } - $stmt="SELECT owner_populate,user_group_script,custom_one,custom_two,custom_three,custom_four,custom_five,state_descriptions FROM vicidial_campaigns where campaign_id='$campaign';"; + $stmt="SELECT owner_populate,user_group_script,custom_one,custom_two,custom_three,custom_four,custom_five,state_descriptions,stereo_recording,stereo_recording_agent FROM vicidial_campaigns where campaign_id='$campaign';"; $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00444',$user,$server_ip,$session_name,$one_mysql_log);} if ($DB) {echo "$stmt\n";} @@ -10224,6 +10623,8 @@ $camp_custom_four = $row[5]; $camp_custom_five = $row[6]; $state_descriptions = $row[7]; + $stereo_recording = $row[8]; + $stereo_recording_agent = $row[9]; } $ownerSQL=''; if ( ($owner_populate=='ENABLED') and ( (strlen($owner) < 1) or ($owner=='NULL') ) ) @@ -10376,10 +10777,10 @@ } if ($WeBRooTWritablE > 0) { - $fp = fopen ("./vicidial_debug.txt", "w"); + # $fp = fopen ("./vicidial_debug.txt", "w"); # fwrite ($fp, "$NOW_TIME|INBND|$callerid|$user|$user_group|$list_id|$lead_id|$phone_number|$uniqueid|$VDADchannel_group|$call_type|$dialed_number|$dialed_label|$INclosecallid|$INxfercallid|\n"); - fwrite ($fp, "$NOW_TIME|INBND|\n"); - fclose($fp); + # fwrite ($fp, "$NOW_TIME|INBND|\n"); + # fclose($fp); } } @@ -10523,7 +10924,7 @@ } } - echo "$VDCL_group_web|$VDCL_group_name||||$VDCL_campaign_script|$VDCL_get_call_launch|$VDCL_xferconf_a_dtmf|$VDCL_xferconf_a_number|$VDCL_xferconf_b_dtmf|$VDCL_xferconf_b_number|$VDCL_default_xfer_group|X|X||||$VDCL_group_web_two|$VDCL_timer_action|$VDCL_timer_action_message|$VDCL_timer_action_seconds|$VDCL_xferconf_c_number|$VDCL_xferconf_d_number|$VDCL_xferconf_e_number||||$VDCL_timer_action_destination|||||||$VDCL_group_web_three|$VDCL_ingroup_script_color|||$VDCL_campaign_script_two|$VDCL_ingroup_script_color_two|\n|\n"; + echo "$VDCL_group_web|$VDCL_group_name||||$VDCL_campaign_script|$VDCL_get_call_launch|$VDCL_xferconf_a_dtmf|$VDCL_xferconf_a_number|$VDCL_xferconf_b_dtmf|$VDCL_xferconf_b_number|$VDCL_default_xfer_group|X|X||||$VDCL_group_web_two|$VDCL_timer_action|$VDCL_timer_action_message|$VDCL_timer_action_seconds|$VDCL_xferconf_c_number|$VDCL_xferconf_d_number|$VDCL_xferconf_e_number||||$VDCL_timer_action_destination|||||||$VDCL_group_web_three|$VDCL_ingroup_script_color|||$VDCL_campaign_script_two|$VDCL_ingroup_script_color_two|||$stereo_recording|$stereo_recording_agent|\n|\n"; if (preg_match('/X/',$dialed_label)) { @@ -10643,7 +11044,7 @@ $ig_custom_five=''; $ig_state_descriptions=''; - $stmt = "SELECT group_name,group_color,web_form_address,fronter_display,ingroup_script,get_call_launch,xferconf_a_dtmf,xferconf_a_number,xferconf_b_dtmf,xferconf_b_number,default_xfer_group,ingroup_recording_override,ingroup_rec_filename,default_group_alias,web_form_address_two,timer_action,timer_action_message,timer_action_seconds,start_call_url,dispo_call_url,xferconf_c_number,xferconf_d_number,xferconf_e_number,uniqueid_status_display,uniqueid_status_prefix,timer_action_destination,web_form_address_three,status_group_id,inbound_survey,ingroup_script_two,browser_alert_sound,browser_alert_volume,custom_one,custom_two,custom_three,custom_four,custom_five,state_descriptions from vicidial_inbound_groups where group_id='$VDADchannel_group';"; + $stmt = "SELECT group_name,group_color,web_form_address,fronter_display,ingroup_script,get_call_launch,xferconf_a_dtmf,xferconf_a_number,xferconf_b_dtmf,xferconf_b_number,default_xfer_group,ingroup_recording_override,ingroup_rec_filename,default_group_alias,web_form_address_two,timer_action,timer_action_message,timer_action_seconds,start_call_url,dispo_call_url,xferconf_c_number,xferconf_d_number,xferconf_e_number,uniqueid_status_display,uniqueid_status_prefix,timer_action_destination,web_form_address_three,status_group_id,inbound_survey,ingroup_script_two,browser_alert_sound,browser_alert_volume,custom_one,custom_two,custom_three,custom_four,custom_five,state_descriptions,stereo_recording,stereo_recording_agent from vicidial_inbound_groups where group_id='$VDADchannel_group';"; if ($DB) {echo "$stmt\n";} $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00119',$user,$server_ip,$session_name,$one_mysql_log);} @@ -10688,6 +11089,8 @@ $ig_custom_four = $row[35]; $ig_custom_five = $row[36]; $ig_state_descriptions = $row[37]; + $stereo_recording = $row[38]; + $stereo_recording_agent = $row[39]; $status_group_gather_data = status_group_gather($row[27],'INGROUP'); @@ -11041,8 +11444,8 @@ } ### if web form is set then send on to vicidial.php for override of WEB_FORM address - if ( (strlen($VDCL_group_web)>5) or (strlen($VDCL_group_name)>0) ) {echo "$VDCL_group_web|$VDCL_group_name|$VDCL_group_color|$VDCL_fronter_display|$VDADchannel_group|$VDCL_ingroup_script|$VDCL_get_call_launch|$VDCL_xferconf_a_dtmf|$VDCL_xferconf_a_number|$VDCL_xferconf_b_dtmf|$VDCL_xferconf_b_number|$VDCL_default_xfer_group|$VDCL_ingroup_recording_override|$VDCL_ingroup_rec_filename|$VDCL_default_group_alias|$VDCL_caller_id_number|$VDCL_group_web_vars|$VDCL_group_web_two|$VDCL_timer_action|$VDCL_timer_action_message|$VDCL_timer_action_seconds|$VDCL_xferconf_c_number|$VDCL_xferconf_d_number|$VDCL_xferconf_e_number|$VDCL_uniqueid_status_display|$custom_call_id|$VDCL_uniqueid_status_prefix|$VDCL_timer_action_destination|$DID_id|$DID_extension|$DID_pattern|$DID_description|$INclosecallid|$INxfercallid|$VDCL_group_web_three|$VDCL_ingroup_script_color|$VDCL_inbound_survey|$VDCL_survey_participate|$VDCL_ingroup_script_two|$VDCL_ingroup_script_color_two|$VDCL_browser_alert_sound|$VDCL_browser_alert_volume|\n";} - else {echo "X|$VDCL_group_name|$VDCL_group_color|$VDCL_fronter_display|$VDADchannel_group|$VDCL_ingroup_script|$VDCL_get_call_launch|$VDCL_xferconf_a_dtmf|$VDCL_xferconf_a_number|$VDCL_xferconf_b_dtmf|$VDCL_xferconf_b_number|$VDCL_default_xfer_group|$VDCL_ingroup_recording_override|$VDCL_ingroup_rec_filename|$VDCL_default_group_alias|$VDCL_caller_id_number|$VDCL_group_web_vars|$VDCL_group_web_two|$VDCL_timer_action|$VDCL_timer_action_message|$VDCL_timer_action_seconds|$VDCL_xferconf_c_number|$VDCL_xferconf_d_number|$VDCL_xferconf_e_number|$VDCL_uniqueid_status_display|$custom_call_id|$VDCL_uniqueid_status_prefix|$VDCL_timer_action_destination|$DID_id|$DID_extension|$DID_pattern|$DID_description|$INclosecallid|$INxfercallid|$VDCL_group_web_three|$VDCL_ingroup_script_color|$VDCL_inbound_survey|$VDCL_survey_participate|$VDCL_ingroup_script_two|$VDCL_ingroup_script_color_two|$VDCL_browser_alert_sound|$VDCL_browser_alert_volume|\n";} + if ( (strlen($VDCL_group_web)>5) or (strlen($VDCL_group_name)>0) ) {echo "$VDCL_group_web|$VDCL_group_name|$VDCL_group_color|$VDCL_fronter_display|$VDADchannel_group|$VDCL_ingroup_script|$VDCL_get_call_launch|$VDCL_xferconf_a_dtmf|$VDCL_xferconf_a_number|$VDCL_xferconf_b_dtmf|$VDCL_xferconf_b_number|$VDCL_default_xfer_group|$VDCL_ingroup_recording_override|$VDCL_ingroup_rec_filename|$VDCL_default_group_alias|$VDCL_caller_id_number|$VDCL_group_web_vars|$VDCL_group_web_two|$VDCL_timer_action|$VDCL_timer_action_message|$VDCL_timer_action_seconds|$VDCL_xferconf_c_number|$VDCL_xferconf_d_number|$VDCL_xferconf_e_number|$VDCL_uniqueid_status_display|$custom_call_id|$VDCL_uniqueid_status_prefix|$VDCL_timer_action_destination|$DID_id|$DID_extension|$DID_pattern|$DID_description|$INclosecallid|$INxfercallid|$VDCL_group_web_three|$VDCL_ingroup_script_color|$VDCL_inbound_survey|$VDCL_survey_participate|$VDCL_ingroup_script_two|$VDCL_ingroup_script_color_two|$VDCL_browser_alert_sound|$VDCL_browser_alert_volume|$stereo_recording|$stereo_recording_agent|\n";} + else {echo "X|$VDCL_group_name|$VDCL_group_color|$VDCL_fronter_display|$VDADchannel_group|$VDCL_ingroup_script|$VDCL_get_call_launch|$VDCL_xferconf_a_dtmf|$VDCL_xferconf_a_number|$VDCL_xferconf_b_dtmf|$VDCL_xferconf_b_number|$VDCL_default_xfer_group|$VDCL_ingroup_recording_override|$VDCL_ingroup_rec_filename|$VDCL_default_group_alias|$VDCL_caller_id_number|$VDCL_group_web_vars|$VDCL_group_web_two|$VDCL_timer_action|$VDCL_timer_action_message|$VDCL_timer_action_seconds|$VDCL_xferconf_c_number|$VDCL_xferconf_d_number|$VDCL_xferconf_e_number|$VDCL_uniqueid_status_display|$custom_call_id|$VDCL_uniqueid_status_prefix|$VDCL_timer_action_destination|$DID_id|$DID_extension|$DID_pattern|$DID_description|$INclosecallid|$INxfercallid|$VDCL_group_web_three|$VDCL_ingroup_script_color|$VDCL_inbound_survey|$VDCL_survey_participate|$VDCL_ingroup_script_two|$VDCL_ingroup_script_color_two|$VDCL_browser_alert_sound|$VDCL_browser_alert_volume|$stereo_recording|$stereo_recording_agent|\n";} if (strlen($fronter) < 2) {$fronter = $tsr;} $stmt = "SELECT full_name from vicidial_users where user='$fronter';"; @@ -13619,10 +14022,10 @@ } if ($WeBRooTWritablE > 0) { - $fp = fopen ("./vicidial_debug.txt", "w"); + # $fp = fopen ("./vicidial_debug.txt", "w"); # fwrite ($fp, "$NOW_TIME|INBND|$callerid|$user|$user_group|$list_id|$lead_id|$phone_number|$uniqueid|$VDADchannel_group|$call_type|$dialed_number|$dialed_label|$INclosecallid|$INxfercallid|\n"); - fwrite ($fp, "$NOW_TIME|INBND|\n"); - fclose($fp); + # fwrite ($fp, "$NOW_TIME|INBND|\n"); + # fclose($fp); } $stmt="INSERT INTO vicidial_sessions_recent SET lead_id='$lead_id',server_ip='$server_ip',call_date=NOW(),user='$user',campaign_id='$VDADchannel_group',conf_exten='$conf_exten',call_type='S';"; @@ -21051,10 +21454,10 @@ $row=mysqli_fetch_row($rslt); if ($WeBRooTWritablE > 0) { - $fp = fopen ("./vicidial_debug.txt", "w"); + # $fp = fopen ("./vicidial_debug.txt", "w"); # fwrite ($fp, "$NOW_TIME|GRAB_CALL |$stmtU|$VACaffected_rows|$stmtD|$row[0]|$row[1]|$row[2]|$row[3]|$row[4]|$row[5]|$row[6]|$row[7]|$row[8]|$row[9]|$row[10]|$row[11]|$row[12]|$row[13]|$row[14]|$row[15]|$row[16]|$row[17]|$row[18]|\n"); - fwrite ($fp, "$NOW_TIME|GRAB_CALL|\n"); - fclose($fp); + # fwrite ($fp, "$NOW_TIME|GRAB_CALL|\n"); + # fclose($fp); } } if ($SSagent_debug_logging > 0) {vicidial_ajax_log($NOW_TIME,$startMS,$link,$ACTION,$php_script,$user,$stage,$lead_id,$session_name,$stmt);} diff --git a/www/agc/vicidial.php b/www/agc/vicidial.php index fa93499b3..ea85c312d 100644 --- a/www/agc/vicidial.php +++ b/www/agc/vicidial.php @@ -748,10 +748,11 @@ # 250326-2032 - Added agent_hide_dial_fail system_setting # 250806-0859 - Added manual_dial_lead_id 'ONLY' option and user override setting # 250808-1322 - Added agent_man_dial_filter & agent_3way_dial_filter system settings +# 250916-2055 - Added stereo recording features # -$version = '2.14-714c'; -$build = '250808-1322'; +$version = '2.14-715c'; +$build = '250916-2055'; $php_script = 'vicidial.php'; $mel=1; # Mysql Error Log enabled = 1 $mysql_log_count=103; @@ -3154,7 +3155,7 @@ function login_submit() $HKstatusnames = substr("$HKstatusnames", 0, -1); ##### grab the campaign settings - $stmt="SELECT park_ext,park_file_name,web_form_address,allow_closers,auto_dial_level,dial_timeout,dial_prefix,campaign_cid,campaign_vdad_exten,campaign_rec_exten,campaign_recording,campaign_rec_filename,campaign_script,get_call_launch,am_message_exten,xferconf_a_dtmf,xferconf_a_number,xferconf_b_dtmf,xferconf_b_number,alt_number_dialing,scheduled_callbacks,wrapup_seconds,wrapup_message,closer_campaigns,use_internal_dnc,allcalls_delay,omit_phone_code,agent_pause_codes_active,no_hopper_leads_logins,campaign_allow_inbound,manual_dial_list_id,default_xfer_group,xfer_groups,disable_alter_custphone,display_queue_count,manual_dial_filter,agent_clipboard_copy,use_campaign_dnc,three_way_call_cid,dial_method,three_way_dial_prefix,web_form_target,vtiger_screen_login,agent_allow_group_alias,default_group_alias,quick_transfer_button,prepopulate_transfer_preset,view_calls_in_queue,view_calls_in_queue_launch,call_requeue_button,pause_after_each_call,no_hopper_dialing,agent_dial_owner_only,agent_display_dialable_leads,web_form_address_two,agent_select_territories,crm_popup_login,crm_login_address,timer_action,timer_action_message,timer_action_seconds,start_call_url,dispo_call_url,xferconf_c_number,xferconf_d_number,xferconf_e_number,use_custom_cid,scheduled_callbacks_alert,scheduled_callbacks_count,manual_dial_override,blind_monitor_warning,blind_monitor_message,blind_monitor_filename,timer_action_destination,enable_xfer_presets,hide_xfer_number_to_dial,manual_dial_prefix,customer_3way_hangup_logging,customer_3way_hangup_seconds,customer_3way_hangup_action,ivr_park_call,manual_preview_dial,api_manual_dial,manual_dial_call_time_check,my_callback_option,per_call_notes,agent_lead_search,agent_lead_search_method,queuemetrics_phone_environment,auto_pause_precall,auto_pause_precall_code,auto_resume_precall,manual_dial_cid,custom_3way_button_transfer,callback_days_limit,disable_dispo_screen,disable_dispo_status,screen_labels,status_display_fields,pllb_grouping,pllb_grouping_limit,in_group_dial,in_group_dial_select,pause_after_next_call,owner_populate,manual_dial_lead_id,dead_max,dispo_max,pause_max,dead_max_dispo,dispo_max_dispo,max_inbound_calls,manual_dial_search_checkbox,hide_call_log_info,timer_alt_seconds,wrapup_bypass,wrapup_after_hotkey,callback_active_limit,callback_active_limit_override,comments_all_tabs,comments_dispo_screen,comments_callback_screen,qc_comment_history,show_previous_callback,clear_script,manual_dial_search_filter,web_form_address_three,manual_dial_override_field,status_display_ingroup,customer_gone_seconds,agent_display_fields,manual_dial_timeout,manual_auto_next,manual_auto_show,allow_required_fields,dead_to_dispo,agent_xfer_validation,ready_max_logout,callback_display_days,three_way_record_stop,hangup_xfer_record_start,max_inbound_calls_outcome,manual_auto_next_options,agent_screen_time_display,pause_max_dispo,script_top_dispo,routing_initiated_recordings,dead_trigger_seconds,dead_trigger_action,dead_trigger_repeat,dead_trigger_filename,scheduled_callbacks_force_dial,callback_hours_block,callback_display_days,scheduled_callbacks_timezones_container,three_way_volume_buttons,manual_dial_validation,mute_recordings,leave_vm_no_dispo,leave_vm_message_group_id,campaign_script_two,browser_alert_sound,browser_alert_volume,three_way_record_stop_exception,pause_max_exceptions,transfer_button_launch,leave_3way_start_recording,leave_3way_start_recording_exception,calls_waiting_vl_one,calls_waiting_vl_two,in_man_dial_next_ready_seconds,in_man_dial_next_ready_seconds_override,transfer_no_dispo,local_call_time,pause_max_url,agent_hide_hangup,ig_xfer_list_sort,script_tab_frame_size,user_group_script,agent_hangup_route,agent_hangup_value,agent_hangup_ig_override,show_confetti,custom_one,custom_two,custom_three,custom_four,custom_five,allow_chats,dead_stop_recording,force_per_call_notes,state_descriptions,script_tab_height,leave_3way_stop_recording,manual_minimum_ring_seconds,manual_minimum_attempt_seconds,manual_minimum_answer_seconds,sip_event_logging,stereo_recording FROM vicidial_campaigns where campaign_id = '$VD_campaign';"; + $stmt="SELECT park_ext,park_file_name,web_form_address,allow_closers,auto_dial_level,dial_timeout,dial_prefix,campaign_cid,campaign_vdad_exten,campaign_rec_exten,campaign_recording,campaign_rec_filename,campaign_script,get_call_launch,am_message_exten,xferconf_a_dtmf,xferconf_a_number,xferconf_b_dtmf,xferconf_b_number,alt_number_dialing,scheduled_callbacks,wrapup_seconds,wrapup_message,closer_campaigns,use_internal_dnc,allcalls_delay,omit_phone_code,agent_pause_codes_active,no_hopper_leads_logins,campaign_allow_inbound,manual_dial_list_id,default_xfer_group,xfer_groups,disable_alter_custphone,display_queue_count,manual_dial_filter,agent_clipboard_copy,use_campaign_dnc,three_way_call_cid,dial_method,three_way_dial_prefix,web_form_target,vtiger_screen_login,agent_allow_group_alias,default_group_alias,quick_transfer_button,prepopulate_transfer_preset,view_calls_in_queue,view_calls_in_queue_launch,call_requeue_button,pause_after_each_call,no_hopper_dialing,agent_dial_owner_only,agent_display_dialable_leads,web_form_address_two,agent_select_territories,crm_popup_login,crm_login_address,timer_action,timer_action_message,timer_action_seconds,start_call_url,dispo_call_url,xferconf_c_number,xferconf_d_number,xferconf_e_number,use_custom_cid,scheduled_callbacks_alert,scheduled_callbacks_count,manual_dial_override,blind_monitor_warning,blind_monitor_message,blind_monitor_filename,timer_action_destination,enable_xfer_presets,hide_xfer_number_to_dial,manual_dial_prefix,customer_3way_hangup_logging,customer_3way_hangup_seconds,customer_3way_hangup_action,ivr_park_call,manual_preview_dial,api_manual_dial,manual_dial_call_time_check,my_callback_option,per_call_notes,agent_lead_search,agent_lead_search_method,queuemetrics_phone_environment,auto_pause_precall,auto_pause_precall_code,auto_resume_precall,manual_dial_cid,custom_3way_button_transfer,callback_days_limit,disable_dispo_screen,disable_dispo_status,screen_labels,status_display_fields,pllb_grouping,pllb_grouping_limit,in_group_dial,in_group_dial_select,pause_after_next_call,owner_populate,manual_dial_lead_id,dead_max,dispo_max,pause_max,dead_max_dispo,dispo_max_dispo,max_inbound_calls,manual_dial_search_checkbox,hide_call_log_info,timer_alt_seconds,wrapup_bypass,wrapup_after_hotkey,callback_active_limit,callback_active_limit_override,comments_all_tabs,comments_dispo_screen,comments_callback_screen,qc_comment_history,show_previous_callback,clear_script,manual_dial_search_filter,web_form_address_three,manual_dial_override_field,status_display_ingroup,customer_gone_seconds,agent_display_fields,manual_dial_timeout,manual_auto_next,manual_auto_show,allow_required_fields,dead_to_dispo,agent_xfer_validation,ready_max_logout,callback_display_days,three_way_record_stop,hangup_xfer_record_start,max_inbound_calls_outcome,manual_auto_next_options,agent_screen_time_display,pause_max_dispo,script_top_dispo,routing_initiated_recordings,dead_trigger_seconds,dead_trigger_action,dead_trigger_repeat,dead_trigger_filename,scheduled_callbacks_force_dial,callback_hours_block,callback_display_days,scheduled_callbacks_timezones_container,three_way_volume_buttons,manual_dial_validation,mute_recordings,leave_vm_no_dispo,leave_vm_message_group_id,campaign_script_two,browser_alert_sound,browser_alert_volume,three_way_record_stop_exception,pause_max_exceptions,transfer_button_launch,leave_3way_start_recording,leave_3way_start_recording_exception,calls_waiting_vl_one,calls_waiting_vl_two,in_man_dial_next_ready_seconds,in_man_dial_next_ready_seconds_override,transfer_no_dispo,local_call_time,pause_max_url,agent_hide_hangup,ig_xfer_list_sort,script_tab_frame_size,user_group_script,agent_hangup_route,agent_hangup_value,agent_hangup_ig_override,show_confetti,custom_one,custom_two,custom_three,custom_four,custom_five,allow_chats,dead_stop_recording,force_per_call_notes,state_descriptions,script_tab_height,leave_3way_stop_recording,manual_minimum_ring_seconds,manual_minimum_attempt_seconds,manual_minimum_answer_seconds,sip_event_logging,stereo_recording,stereo_recording_agent FROM vicidial_campaigns where campaign_id = '$VD_campaign';"; $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'01013',$VD_login,$server_ip,$session_name,$one_mysql_log);} if ($DB) {echo "$stmt\n";} @@ -3358,6 +3359,7 @@ function login_submit() $manual_minimum_answer_seconds =$row[196]; $CAMPsip_event_logging = $row[197]; $stereo_recording = $row[198]; + $stereo_recording_agent = $row[199]; if ( (!preg_match("/DISABLED/",$VU_manual_dial_lead_id)) and (strlen($VU_manual_dial_lead_id) > 0) ) { @@ -3365,7 +3367,7 @@ function login_submit() $manual_dial_lead_id = $VU_manual_dial_lead_id; } - if ($SSstereo_recording < 1) {$stereo_recording='DISABLED';} + if ($SSstereo_recording < 1) {$stereo_recording='DISABLED'; $stereo_recording_agent='NEVER';} if ( ($manual_minimum_ring_seconds > 0) and ($SSsip_event_logging < 1) ) { @@ -5691,6 +5693,10 @@ function login_submit() $start_recording_GIF_off = 'vdc_LB_startrecording_OFF.gif'; $stop_recording_GIF = 'vdc_LB_stoprecording.gif'; $stop_recording_GIF_off = 'vdc_LB_stoprecording_OFF.gif'; +$STstart_recording_GIF = 'vdc_LB_STstartrecording.gif'; +$STstart_recording_GIF_off = 'vdc_LB_STstartrecording_OFF.gif'; +$STstop_recording_GIF = 'vdc_LB_STstoprecording.gif'; +$STstop_recording_GIF_off = 'vdc_LB_STstoprecording_OFF.gif'; if (preg_match("/RECORDING/",$SSrecording_buttons)) { if (preg_match("/2xHEIGHT/",$SSrecording_buttons)) @@ -5699,6 +5705,10 @@ function login_submit() $start_recording_GIF_off = 'vdc_LB_startrecording_altx2_OFF.gif'; $stop_recording_GIF = 'vdc_LB_stoprecording_altx2.gif'; $stop_recording_GIF_off = 'vdc_LB_stoprecording_altx2_OFF.gif'; + $STstart_recording_GIF = 'vdc_LB_STstartrecording_altx2.gif'; + $STstart_recording_GIF_off = 'vdc_LB_STstartrecording_altx2_OFF.gif'; + $STstop_recording_GIF = 'vdc_LB_STstoprecording_altx2.gif'; + $STstop_recording_GIF_off = 'vdc_LB_STstoprecording_altx2_OFF.gif'; } else { @@ -5706,6 +5716,10 @@ function login_submit() $start_recording_GIF_off = 'vdc_LB_startrecording_alt_OFF.gif'; $stop_recording_GIF = 'vdc_LB_stoprecording_alt.gif'; $stop_recording_GIF_off = 'vdc_LB_stoprecording_alt_OFF.gif'; + $STstart_recording_GIF = 'vdc_LB_STstartrecording_alt.gif'; + $STstart_recording_GIF_off = 'vdc_LB_STstartrecording_alt_OFF.gif'; + $STstop_recording_GIF = 'vdc_LB_STstoprecording_alt.gif'; + $STstop_recording_GIF_off = 'vdc_LB_STstoprecording_alt_OFF.gif'; } } @@ -6261,6 +6275,12 @@ function login_submit() var campaign_rec_filename = ''; var LIVE_campaign_recording = ''; var LIVE_campaign_rec_filename = ''; + var STcampaign_recording = ''; + var STcampaign_rec_filename = ''; + var VDICstereo_recording = ''; + var VDICstereo_recording_agent = ''; + var LIVE_STcampaign_recording = ''; + var LIVE_STcampaign_rec_filename = ''; var LIVE_default_group_alias = ''; var LIVE_caller_id_number = ''; var LIVE_web_vars = ''; @@ -6488,6 +6508,8 @@ function login_submit() var external_igb_set_name=''; var recording_filename=''; var recording_id=''; + var STrecording_filename=''; + var STrecording_id=''; var delayed_script_load=''; var script_recording_delay=''; var VDRP_stage='PAUSED'; @@ -6656,6 +6678,7 @@ function login_submit() var mrglock_ig_select_ct=''; var agent_select_territories_skip_count=0; var last_recording_filename=''; + var STlast_recording_filename=''; var dead_max=''; var dead_max_dispo=''; var dead_to_dispo=''; @@ -6746,6 +6769,8 @@ function login_submit() var MD_dial_timed_out=0; var routing_initiated_recording=''; var stereo_recording=''; + var SSstereo_recording=; + var stereo_recording_agent=''; var dead_trigger_count=0; var dead_recording_triggered=0; var dead_trigger_first_ran=0; @@ -6803,6 +6828,7 @@ function login_submit() var user_pass_webform = ''; var phone_login_webform = ''; var recording_active=0; + var STrecording_active=0; var pause_max_url_trigger = ''; var agent_hide_hangup_ACTIVE = ''; var agent_datetime=''; @@ -6874,6 +6900,10 @@ function login_submit() image_LB_stoprecording.src="./images/"; var image_LB_startrecording = new Image(); image_LB_startrecording.src="./images/"; + var image_LB_STstoprecording = new Image(); + image_LB_STstoprecording.src="./images/"; + var image_LB_STstartrecording = new Image(); + image_LB_STstartrecording.src="./images/"; var image_LB_paused = new Image(); image_LB_paused.src="./images/"; var image_LB_active = new Image(); @@ -6898,6 +6928,10 @@ function login_submit() image_LB_stoprecording_OFF.src="./images/"; var image_LB_startrecording_OFF = new Image(); image_LB_startrecording_OFF.src="./images/"; + var image_LB_STstoprecording_OFF = new Image(); + image_LB_STstoprecording_OFF.src="./images/"; + var image_LB_STstartrecording_OFF = new Image(); + image_LB_STstartrecording_OFF.src="./images/"; var image_LB_senddtmf_OFF = new Image(); image_LB_senddtmf_OFF.src="./images/"; var image_LB_ivrgrabparkedcall = new Image(); @@ -8358,6 +8392,21 @@ function check_for_conf_calls(taskconfnum,taskforce) { conf_send_recording('StopMonitorConf', session_id, recording_filename,'1','','YES'); } + var regAPIrec = new RegExp("BEGIN","g"); + if (api_recording.match(regAPIrec)) + { + var APIrec_append = api_recording; + if (APIrec_append.length > 5) + {APIrec_append = APIrec_append.replace(regAPIrec, '');} + else + {APIrec_append='';} + + conf_send_stereo_recording('MonitorStereo', session_id,'','1', APIrec_append,'YES'); + } + if (api_recording=='END') + { + conf_send_stereo_recording('StopMonitorStereo', session_id, recording_filename,'1','','YES'); + } if (api_transferconf_function.length > 0) { if (api_transferconf_ID == api_transferconf_values_array[7]) @@ -8729,6 +8778,12 @@ function check_for_conf_calls(taskconfnum,taskforce) { parked_hangup='1'; } + if ( (SSstereo_recording > 0) && ( (VDICstereo_recording == 'BOTH_CHANNELS') || (VDICstereo_recording == 'CUSTOMER_ONLY') || (VDICstereo_recording == 'CUSTOMER_MUTE') ) ) + { + // call is dead set stereo recording button to disabled + var conf_rec_start_html = "\" border=\"0\" alt=\"Start Stereo Recording\" />"; + document.getElementById("StRecorDControl").innerHTML = conf_rec_start_html; + } } } if ( (CheckDEADcall > 0) && (VD_live_customer_call==1) && (VD_live_call_secondS > 5) && ((CalL_AutO_LauncH == 'CHAT')) && (currently_in_email_or_chat > 0) ) @@ -9172,6 +9227,117 @@ function conf_send_recording(taskconfrectype,taskconfrec,taskconffile,taskfromap } } + +// ################################################################################ +// Send MonitorStereo/StopMonitorStereo command for stereo_recording of conferences + function conf_send_stereo_recording(taskconfrectype,taskconfrec,taskconffile,taskfromapi,taskapiappend,CSRclick) + { + if (CSRclick=='YES') + {button_click_log = button_click_log + "" + SQLdate + "-----conf_send_stereo_recording---" + taskconfrectype + " " + taskconfrec + " " + taskconffile + " " + taskfromapi + " " + taskapiappend + "|";} + else + {button_click_log = button_click_log + "" + SQLdate + "-----conf_send_stereo_recordingAUTO---" + taskconfrectype + " " + taskconfrec + " " + taskconffile + " " + taskfromapi + " " + taskapiappend + " " + all_record + "|";} + if (inOUT == 'OUT') + { + tmp_vicidial_id = document.vicidial_form.uniqueid.value; + } + else + { + tmp_vicidial_id = 'IN'; + } + var xmlhttp=false; + /*@cc_on @*/ + /*@if (@_jscript_version >= 5) + // JScript gives us Conditional compilation, we can cope with old IE versions. + // and security blocked creation of the objects. + try { + xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); + } catch (e) { + try { + xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + } catch (E) { + xmlhttp = false; + } + } + @end @*/ + if (!xmlhttp && typeof XMLHttpRequest!='undefined') + { + xmlhttp = new XMLHttpRequest(); + } + if (xmlhttp) + { + if (taskconfrectype == 'MonitorStereo') + { + recording_active=1; + var REGrecCLEANvlc = new RegExp(" ","g"); + var recVendorLeadCode = document.vicidial_form.vendor_lead_code.value; + recVendorLeadCode = recVendorLeadCode.replace(REGrecCLEANvlc, ''); + var recLeadID = document.vicidial_form.lead_id.value; + var query_recording_exten = recording_exten; + var channelrec = "Local/" + conf_silent_prefix + '' + taskconfrec + "@" + ext_context; + var conf_rec_start_html = "\" border=\"0\" alt=\"Stop Stereo Recording\" />"; + + if (VDICstereo_recording_agent == 'ALLFORCE') + { + document.getElementById("StRecorDControl").innerHTML = "\" border=\"0\" alt=\"Stop Stereo Recording\" />"; + } + else + { + document.getElementById("StRecorDControl").innerHTML = conf_rec_start_html; + } + } + if (taskconfrectype == 'StopMonitorStereo') + { + recording_active=0; + filename = taskconffile; + var query_recording_exten = session_id; + var channelrec = "Local/" + conf_silent_prefix + '' + taskconfrec + "@" + ext_context; + var conf_rec_start_html = "\" border=\"0\" alt=\"Start Stereo Recording\" />"; + if (VDICstereo_recording_agent == 'ALLFORCE') + { + document.getElementById("StRecorDControl").innerHTML = "\" border=\"0\" alt=\"Start Stereo Recording\" />"; + } + else + { + document.getElementById("StRecorDControl").innerHTML = conf_rec_start_html; + } + } + confmonitor_query = "server_ip=" + server_ip + "&session_name=" + session_name + "&campaign=" + campaign + "&user=" + user + "&pass=" + pass + "&ACTION=" + taskconfrectype + "&format=text&channel=" + lastcustchannel + "&filename=NOfilenameNEEDED&exten=" + query_recording_exten + "&ext_context=" + ext_context + "&lead_id=" + document.vicidial_form.lead_id.value + "&CalLCID=" + LasTCID + "&phone_number=" + lead_dial_number + "&ext_priority=1&FROMvdc=YES&uniqueid=" + tmp_vicidial_id + "&FROMapi=" + taskfromapi; + xmlhttp.open('POST', 'manager_send.php'); + xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8'); + xmlhttp.send(confmonitor_query); + xmlhttp.onreadystatechange = function() + { + if (xmlhttp.readyState == 4 && xmlhttp.status == 200) + { + var RClookResponse = null; + // document.getElementById("busycallsdebug").innerHTML = confmonitor_query; + // alert(confmonitor_query); + // alert(xmlhttp.responseText); + RClookResponse = xmlhttp.responseText; + var RClookResponse_array=RClookResponse.split("\n"); + var RClookFILE = RClookResponse_array[1]; + var RClookID = RClookResponse_array[2]; + var RClookFILE_array = RClookFILE.split("Filename: "); + var RClookID_array = RClookID.split("RecorDing_ID: "); + + if (taskconfrectype == 'MonitorStereo') + { + var conf_rec_start_html = "\" border=\"0\" alt=\"Stop Stereo Recording\" />"; + if (VDICstereo_recording_agent == 'ALLFORCE') + { + document.getElementById("StRecorDControl").innerHTML = "\" border=\"0\" alt=\"Stop Stereo Recording\" />"; + } + else + { + document.getElementById("StRecorDControl").innerHTML = conf_rec_start_html; + } + } + } + } + delete xmlhttp; + } + } + // ################################################################################ // Send Redirect command for live call to Manager sends phone name where call is going to // Covers the following types: XFER, VMAIL, ENTRY, CONF, PARK, FROMPARK, XfeRLOCAL, XfeRINTERNAL, XfeRBLIND, VfeRVMAIL @@ -9821,6 +9987,7 @@ function DialLog(taskMDstage,nodeletevdac) { var conf_rec_start_html = "\" border=\"0\" alt=\"Start Recording\" />"; var conf_rec_mute_html = "\" border=\"0\" alt=\"Mute Recording Disabled\" />
"; + var STconf_rec_start_html = "\" border=\"0\" alt=\"Start Stereo Recording\" />"; if ( (LIVE_campaign_recording == 'NEVER') || (LIVE_campaign_recording == 'ALLFORCE') ) { document.getElementById("RecorDControl").innerHTML = "\" border=\"0\" alt=\"Start Recording\" />"; @@ -9832,6 +9999,8 @@ function DialLog(taskMDstage,nodeletevdac) document.getElementById("RecorDMute").innerHTML = conf_rec_mute_html; } + document.getElementById("StRecorDControl").innerHTML = "\" border=\"0\" alt=\"Start Stereo Recording\" />"; + MDlogRecorDings = MDlogResponse_array[3]; if (window.MDlogRecorDings) { @@ -11449,7 +11618,6 @@ function ManualDialCheckChanneL(taskCheckOR) debug_response = debug_response.replace(REGcommentsDBNL, "
"); // document.getElementById("debugbottomspan").innerHTML = "
|" + manDiaLlook_query + "|
\n" + debug_response; - MDlookResponse = xmlhttp.responseText; var MDlookResponse_array=MDlookResponse.split("\n"); var MDlookCID = MDlookResponse_array[0]; @@ -11508,6 +11676,7 @@ function ManualDialCheckChanneL(taskCheckOR) button_click_log = button_click_log + "" + SQLdate + "-----DiaLAlerT---Call-Rejected" + XDerrorDesc + "|"; agent_events('agent_alert', "Call Rejected: " + XDerrorDesc + ' ' + XDerrorDescSIP, aec); aec++; } + if ( (XDchannel.match(regMDL)) && (asterisk_version != '1.0.8') && (asterisk_version != '1.0.9') && (MD_ring_secondS < 10) ) { // bad grab of Local channel, try again @@ -11586,8 +11755,9 @@ function ManualDialCheckChanneL(taskCheckOR) else { custchannellive=1; - document.vicidial_form.uniqueid.value = MDlookResponse_array[0]; + document.vicidial_form.uniqueid.value = MDlookResponse_array[0]; document.getElementById("callchannel").innerHTML = MDlookResponse_array[1]; + var stereo_info = MDlookResponse_array[2]; lastcustchannel = MDlookResponse_array[1]; if( document.images ) { document.images['livecall'].src = image_livecall_ON.src;} document.vicidial_form.SecondS.value = 0; @@ -11608,6 +11778,32 @@ function ManualDialCheckChanneL(taskCheckOR) document.getElementById("MainStatuSSpan").innerHTML = " " + status_display_number + " " + status_display_content + "  "; + var regSRC = new RegExp("^SAC|^SPAC","ig"); + var regSRD = new RegExp("^SOD","ig"); + var regSRAF = new RegExp("ALLFORCE","ig"); + if (stereo_info.match(regSRC)) + { + // stereo recording was started + var conf_rec_start_html = "\" border=\"0\" alt=\"Stop Stereo Recording\" />"; + + if (stereo_info.match(regSRAF)) + { + // Agent-control is ALLFORCE, use disabled button + document.getElementById("StRecorDControl").innerHTML = "\" border=\"0\" alt=\"Stop Stereo Recording\" />"; + } + else + { + document.getElementById("StRecorDControl").innerHTML = conf_rec_start_html; + } + } + if (stereo_info.match(regSRD)) + { + // stereo recording not started, but set to ONDEMAND + var conf_rec_start_html = "\" border=\"0\" alt=\"Start Stereo Recording\" />"; + document.getElementById("StRecorDControl").innerHTML = conf_rec_start_html; + } + + document.getElementById("ParkControl").innerHTML ="\" border=\"0\" alt=\"Park Call\" />"; if ( (ivr_park_call=='ENABLED') || (ivr_park_call=='ENABLED_PARK_ONLY') ) { @@ -14100,6 +14296,8 @@ function check_for_auto_incoming() browser_alert_sound = VDIC_data_VDIG[40]; browser_alert_volume = VDIC_data_VDIG[41]; } + VDICstereo_recording = VDIC_data_VDIG[42]; + VDICstereo_recording_agent = VDIC_data_VDIG[43]; var VDIC_data_VDFR=check_VDIC_array[3].split("|"); if ( (VDIC_data_VDFR[1].length > 1) && (VDCL_fronter_display == 'Y') ) @@ -14460,6 +14658,30 @@ function check_for_auto_incoming() document.getElementById("MainStatuSSpan").innerHTML = " " + dial_display_number + " " + custom_call_id + " " + temp_status_display_ingroup + "  " + VDIC_fronter + " " + status_display_content; } + if ( (SSstereo_recording > 0) && ( (VDICstereo_recording == 'BOTH_CHANNELS') || (VDICstereo_recording == 'CUSTOMER_ONLY') || (VDICstereo_recording == 'CUSTOMER_MUTE') ) ) + { + if (VDICstereo_recording_agent == 'ALLCALLS') + { + // stereo recording was started, allow agent to stop it + document.getElementById("StRecorDControl").innerHTML = "\" border=\"0\" alt=\"Stop Stereo Recording\" />"; + } + if (VDICstereo_recording_agent == 'ALLFORCE') + { + // Agent-control is ALLFORCE, use disabled button + document.getElementById("StRecorDControl").innerHTML = "\" border=\"0\" alt=\"Stop Stereo Recording\" />"; + } + if (VDICstereo_recording_agent == 'ONDEMAND') + { + // stereo recording not started, but agent control set to ONDEMAND + document.getElementById("StRecorDControl").innerHTML = "\" border=\"0\" alt=\"Start Stereo Recording\" />"; + } + if (VDICstereo_recording_agent == 'NEVER') + { + // stereo recording not started, and agent control set to NEVER + document.getElementById("StRecorDControl").innerHTML = "\" border=\"0\" alt=\"Start Stereo Recording\" />"; + } + } + document.getElementById("ParkControl").innerHTML ="\" border=\"0\" alt=\"Park Call\" />"; if ( (ivr_park_call=='ENABLED') || (ivr_park_call=='ENABLED_PARK_ONLY') ) { @@ -21669,6 +21891,8 @@ function start_all_refresh() hideDiv('InvalidOpenerSpan'); hideDiv('OtherTabCommentsSpan'); hideDiv('AgentTimeDisplayBox'); + if ( (SSstereo_recording < 1) || (stereo_recording == 'DISABLED') ) + {hideDiv('StRecorDControl');} if (launch_scb_force_dial < 1) {hideDiv('SCForceDialBox');} else @@ -21759,6 +21983,9 @@ function start_all_refresh() var conf_rec_mute_html = "\" border=\"0\" alt=\"Mute Recording Disabled\" />
"; document.getElementById("RecorDMute").innerHTML = conf_rec_mute_html; } + + document.getElementById("StRecorDControl").innerHTML = "\" border=\"0\" alt=\"Start Stereo Recording\" />"; + if (INgroupCOUNT > 0) { if (VU_closer_default_blended == 1) @@ -23570,7 +23797,11 @@ function ShoWGenDerPulldown() " border="0" alt="Start Recording" />
- 0) + {echo "\"Start
";} + else + {echo "";} if (!preg_match("/NOGAP/",$SSrecording_buttons)) {echo "
\n";} if ($SSenable_first_webform > 0) diff --git a/www/vicidial/AST_timeonVDADall.php b/www/vicidial/AST_timeonVDADall.php index f57dcb43e..7d8513303 100644 --- a/www/vicidial/AST_timeonVDADall.php +++ b/www/vicidial/AST_timeonVDADall.php @@ -136,6 +136,7 @@ # 250103-0929 - Added enhanced_agent_monitoring code # 250130-1130 - Changed vicidial_daily_rt_monitor_log to vicidial_daily_rt_monitorING_log to match SQL file, also added sort clause to WHISPER # 250320-2307 - Added "3-WAYD" status for dead 3way call agent +# 250523-1730 - Added inbound calls counting capability # $version = '2.14-120'; @@ -258,6 +259,8 @@ elseif (isset($_POST["user_group_filter"])) {$user_group_filter=$_POST["user_group_filter"];} if (isset($_GET["ingroup_filter"])) {$ingroup_filter=$_GET["ingroup_filter"];} elseif (isset($_POST["ingroup_filter"])) {$ingroup_filter=$_POST["ingroup_filter"];} +if (isset($_GET["inbound_calls_filter"])) {$inbound_calls_filter=$_GET["inbound_calls_filter"];} + elseif (isset($_POST["inbound_calls_filter"])) {$inbound_calls_filter=$_POST["inbound_calls_filter"];} if (isset($_GET["droppedOFtotal"])) {$droppedOFtotal=$_GET["droppedOFtotal"];} elseif (isset($_POST["droppedOFtotal"])) {$droppedOFtotal=$_POST["droppedOFtotal"];} if (isset($_GET["report_display_type"])) {$report_display_type=$_GET["report_display_type"];} @@ -337,6 +340,7 @@ if (!is_array($groups)) {$groups=array();} if (!is_array($user_group_filter)) {$user_group_filter=array();} if (!is_array($ingroup_filter)) {$ingroup_filter=array();} +if (!is_array($inbound_calls_filter)) {$inbound_calls_filter=array();} if (!isset($usergroup)) {$usergroup='';} if (!isset($UGdisplay)) {$UGdisplay=0;} # 0=no, 1=yes if (!isset($UidORname)) {$UidORname=1;} # 0=id, 1=name @@ -761,6 +765,20 @@ function get_server_load($windows = false) $ingroup_SQL = preg_replace('/,$/i', '',$ingroup_SQL); #if ($DB > 0) {echo "INBOUND INPUT DEBUG: |$ingroup_ct|$ingroup_string|\n";} +$i=0; +$inbound_calls_string='|'; +$inbound_calls_ct = count($inbound_calls_filter); +while($i < $inbound_calls_ct) + { + $inbound_calls_filter[$i] = preg_replace('/[^-_0-9a-zA-Z]/', '', $inbound_calls_filter[$i]); + $inbound_calls_string .= "$inbound_calls_filter[$i]|"; + $inbound_calls_SQL .= "'$inbound_calls_filter[$i]',"; + $inbound_callsQS .= "&inbound_calls_filter[]=$inbound_calls_filter[$i]"; + + $i++; + } +$inbound_calls_SQL = preg_replace('/,$/i', '',$inbound_calls_SQL); + ### if no campaigns selected, display all if ( ($group_ct < 1) or (strlen($group_string) < 2) ) { @@ -785,6 +803,15 @@ function get_server_load($windows = false) $ingroupQS .= "&ingroup_filter[]=ALL-INGROUPS"; $ingroup_none=1; } +### if no inbound call counts selected, display all +$inbound_calls_none=0; +if ( ($inbound_calls_ct < 1) or (strlen($inbound_calls_string) < 2) ) + { + $inbound_calls_filter[0] = 'ALL-INGROUPS'; + $inbound_calls_string = '|ALL-INGROUPS|'; + $inbound_callsQS .= "&inbound_calls_filter[]=ALL-INGROUPS"; + $inbound_calls_none=1; + } if ( (preg_match('/\s\-\-NONE\-\-\s/',$group_string) ) or ($group_ct < 1) ) { @@ -846,6 +873,25 @@ function get_server_load($windows = false) $all_active_ingroups = 0; } +if ( (preg_match('/\s\-\-NONE\-\-\s/',$inbound_calls_string) ) or ($inbound_calls_ct < 1) ) + { + $all_active_inbound_call_groups = 0; + $inbound_calls_SQL = "''"; + } +elseif ( preg_match('/ALL\-INGROUPS/i',$inbound_calls_string) ) + { + if (preg_match('/\-\-\-ALL\-\-\-/', $LOGadmin_viewable_groups)) + { + $all_active_inbound_calls = 1; + } + else + { + $inbound_calls_SQL = "'$rawLOGadmin_viewable_groupsSQL'"; + $inbound_calls_SQLand = "and campaign_id IN($rawLOGadmin_viewable_groupsSQL)"; + $inbound_calls_SQLwhere = "where campaign_id IN($rawLOGadmin_viewable_groupsSQL)"; + } + } + $stmt="SELECT user_group from vicidial_user_groups $whereLOGadmin_viewable_groupsSQL order by user_group;"; $rslt=mysql_to_mysqli($stmt, $link); if (!isset($DB)) {$DB=0;} @@ -1480,7 +1526,7 @@ function hide_ingroup_info() \n"; - echo"\n"; + echo"\n"; echo "$report_name: $group\n"; $short_header=1; @@ -1538,9 +1584,9 @@ function hide_ingroup_info() echo "\n"; echo "   "; echo "\n"; - echo ""._QXZ("STOP")." | "; - echo ""._QXZ("SLOW")." | "; - echo ""._QXZ("GO").""; + echo ""._QXZ("STOP")." | "; + echo ""._QXZ("SLOW")." | "; + echo ""._QXZ("GO").""; if (preg_match('/ALL\-ACTIVE/i',$group_string)) { echo "       "._QXZ("MODIFY")." | \n"; @@ -2296,7 +2342,7 @@ function hide_ingroup_info() if ($adastats>1) { - $min_link='- min '; + $min_link='- min '; if ($RTajax > 0) {$min_link='';} @@ -2474,71 +2520,71 @@ function hide_ingroup_info() { if ($adastats<2) { - echo "+ "._QXZ("VIEW MORE").""; + echo "+ "._QXZ("VIEW MORE").""; } else { - echo "- "._QXZ("VIEW LESS").""; + echo "- "._QXZ("VIEW LESS").""; } } if ($UGdisplay>0) { - echo "       "._QXZ("HIDE USER GROUP").""; + echo "       "._QXZ("HIDE USER GROUP").""; } else { - echo "       "._QXZ("VIEW USER GROUP").""; + echo "       "._QXZ("VIEW USER GROUP").""; } if ($SERVdisplay>0) { - echo "       "._QXZ("HIDE SERVER INFO").""; + echo "       "._QXZ("HIDE SERVER INFO").""; } else { - echo "       "._QXZ("SHOW SERVER INFO").""; + echo "       "._QXZ("SHOW SERVER INFO").""; } if ($CALLSdisplay>0) { - echo "       "._QXZ("HIDE WAITING CALLS").""; + echo "       "._QXZ("HIDE WAITING CALLS").""; } else { - echo "       "._QXZ("SHOW WAITING CALLS").""; + echo "       "._QXZ("SHOW WAITING CALLS").""; } if ($ALLINGROUPstats>0) { - echo "       "._QXZ("HIDE IN-GROUP STATS").""; + echo "       "._QXZ("HIDE IN-GROUP STATS").""; } else { - echo "       "._QXZ("SHOW IN-GROUP STATS").""; + echo "       "._QXZ("SHOW IN-GROUP STATS").""; } if ($PHONEdisplay>0) { - echo "       "._QXZ("HIDE PHONES").""; + echo "       "._QXZ("HIDE PHONES").""; } else { - echo "       "._QXZ("SHOW PHONES").""; + echo "       "._QXZ("SHOW PHONES").""; } if ($CUSTPHONEdisplay>0) { - echo "       "._QXZ("HIDE CUSTPHONES").""; + echo "       "._QXZ("HIDE CUSTPHONES").""; } else { - echo "       "._QXZ("SHOW CUSTPHONES").""; + echo "       "._QXZ("SHOW CUSTPHONES").""; } if ($LOGuser_level>=9) { if ($CUSTINFOdisplay>0) { - echo "       "._QXZ("HIDE FULL CUST INFO").""; + echo "       "._QXZ("HIDE FULL CUST INFO").""; } else { - echo "       "._QXZ("SHOW FULL CUST INFO").""; + echo "       "._QXZ("SHOW FULL CUST INFO").""; } } } @@ -3100,12 +3146,12 @@ function hide_ingroup_info() $HDstation = "----------------+"; $HTstation = " "._QXZ("STATION", 14)." |"; $HDphone = "-------------------+"; - $HTphone = " "._QXZ("PHONE",11)." |"; + $HTphone = " "._QXZ("PHONE",11)." |"; if ($RTajax > 0) {$HTphone = " "._QXZ("PHONE",11)." |";} $HDuser = "------------------------+"; - $HTuser = " "._QXZ("USER",5)." "; + $HTuser = " "._QXZ("USER",5)." "; if ($RTajax > 0) {$HTuser = " "._QXZ("USER",5)." ";} if ($UidORname>0) @@ -3114,7 +3160,7 @@ function hide_ingroup_info() {$HTuser .= ""._QXZ("SHOW ID",8)." ";} else { - $HTuser .= ""._QXZ("SHOW ID",8)." "; + $HTuser .= ""._QXZ("SHOW ID",8)." "; } } else @@ -3123,13 +3169,13 @@ function hide_ingroup_info() {$HTuser .= ""._QXZ("SHOW NAME",9)."";} else { - $HTuser .= ""._QXZ("SHOW NAME",9).""; + $HTuser .= ""._QXZ("SHOW NAME",9).""; } } $HTuser .= " "._QXZ("INFO",6)." |"; $HDusergroup = "--------------+"; - $HTusergroup = " "._QXZ("USER GROUP",12)." |"; + $HTusergroup = " "._QXZ("USER GROUP",12)." |"; if ($RTajax > 0) {$HTusergroup = " "._QXZ("USER GROUP",12)." |";} $HDsessionid = "-----------+"; @@ -3153,15 +3199,17 @@ function hide_ingroup_info() $HDcall_server_ip = "-----------------+"; $HTcall_server_ip = " "._QXZ("CALL SERVER IP",15)." |"; $HDtime = "---------+"; - $HTtime = " MM:SS |"; + $HTtime = " MM:SS |"; if ($RTajax > 0) {$HTtime = " MM:SS |";} $HDcampaign = "------------+"; - $HTcampaign = " "._QXZ("CAMPAIGN",10)." |"; + $HTcampaign = " "._QXZ("CAMPAIGN",10)." |"; if ($RTajax > 0) {$HTcampaign = " "._QXZ("CAMPAIGN",10)." |";} $HDcalls = "-------+"; $HTcalls = " "._QXZ("CALLS",5)." |"; + $HDinbcalls = "-----------+"; + $HTinbcalls = " "._QXZ("INB CALLS",9)." |"; $HDpause = ''; $HTpause = ''; $HDigcall = "------+-------------------"; @@ -3222,12 +3270,12 @@ function hide_ingroup_info() $HDstation = ""; $HTstation = "  "._QXZ("STATION")." "; $HDphone = ""; - $HTphone = " "._QXZ("PHONE")." "; + $HTphone = " "._QXZ("PHONE")." "; if ($RTajax > 0) {$HTphone = " "._QXZ("PHONE")." ";} $HDuser = ""; - $HTuser = " "._QXZ("USER")." "; + $HTuser = " "._QXZ("USER")." "; if ($RTajax > 0) {$HTuser = "   "._QXZ("USER")." ";} if ($UidORname>0) @@ -3236,7 +3284,7 @@ function hide_ingroup_info() {$HTuser .= " "._QXZ("SHOW ID")." ";} else { - $HTuser .= " "._QXZ("SHOW ID")." "; + $HTuser .= " "._QXZ("SHOW ID")." "; } } else @@ -3245,13 +3293,13 @@ function hide_ingroup_info() {$HTuser .= " "._QXZ("SHOW NAME")." ";} else { - $HTuser .= "  "._QXZ("SHOW NAME")." "; + $HTuser .= "  "._QXZ("SHOW NAME")." "; } } $HTuser .= " "._QXZ("INFO",6)." "; $HDusergroup = ""; - $HTusergroup = " "._QXZ("USER GROUP")." "; + $HTusergroup = " "._QXZ("USER GROUP")." "; if ($RTajax > 0) {$HTusergroup = " "._QXZ("USER GROUP")." ";} $HDsessionid = ""; @@ -3275,15 +3323,17 @@ function hide_ingroup_info() $HDcall_server_ip = ""; $HTcall_server_ip = "  "._QXZ("CALL SERVER IP")." "; $HDtime = ""; - $HTtime = " MM:SS "; + $HTtime = " MM:SS "; if ($RTajax > 0) {$HTtime = " MM:SS ";} $HDcampaign = ""; - $HTcampaign = " "._QXZ("CAMPAIGN")." "; + $HTcampaign = " "._QXZ("CAMPAIGN")." "; if ($RTajax > 0) {$HTcampaign = " "._QXZ("CAMPAIGN",10)." ";} $HDcalls = ""; $HTcalls = "  "._QXZ("CALLS")." "; + $HDinbcalls = ""; + $HTinbcalls = "  "._QXZ("INB CALLS")." "; $HDpause = ''; $HTpause = ''; $HDigcall = ""; @@ -3382,13 +3432,13 @@ function hide_ingroup_info() if ($realtime_block_user_info > 0) { - $Aline = "$HDbegin$HDusergroup$HDsessionid$HDlisten$HDbarge$HDwhisper$HDmonitor$HDstatus$HDpause$HDcustphone$HDcustinfo$HDserver_ip$HDcall_server_ip$HDtime$HDcampaign$HDcalls$HDlatency$HDastcall$HDigcall$\n"; - $Bline = "$HTbegin$HTusergroup$HTsessionid$HDlisten$HTbarge$HTwhisper$HTmonitor$HTstatus$HTpause$HTcustphone$HTcustinfo$HTserver_ip$HTcall_server_ip$HTtime$HTcampaign$HTcalls$HTlatency$HTastcall$HTigcall\n"; + $Aline = "$HDbegin$HDusergroup$HDsessionid$HDlisten$HDbarge$HDwhisper$HDmonitor$HDstatus$HDpause$HDcustphone$HDcustinfo$HDserver_ip$HDcall_server_ip$HDtime$HDcampaign$HDcalls$HDinbcalls$HDlatency$HDastcall$HDigcall$\n"; + $Bline = "$HTbegin$HTusergroup$HTsessionid$HDlisten$HTbarge$HTwhisper$HTmonitor$HTstatus$HTpause$HTcustphone$HTcustinfo$HTserver_ip$HTcall_server_ip$HTtime$HTcampaign$HTcalls$HTinbcalls$HTlatency$HTastcall$HTigcall\n"; } else { - $Aline = "$HDbegin$HDstation$HDphone$HDuser$HDusergroup$HDsessionid$HDlisten$HDbarge$HDwhisper$HDmonitor$HDstatus$HDpause$HDcustphone$HDcustinfo$HDserver_ip$HDcall_server_ip$HDtime$HDcampaign$HDcalls$HDlatency$HDastcall$HDigcall\n"; - $Bline = "$HTbegin$HTstation$HTphone$HTuser$HTusergroup$HTsessionid$HTlisten$HTbarge$HTwhisper$HTmonitor$HTstatus$HTpause$HTcustphone$HTcustinfo$HTserver_ip$HTcall_server_ip$HTtime$HTcampaign$HTcalls$HTlatency$HTastcall$HTigcall\n"; + $Aline = "$HDbegin$HDstation$HDphone$HDuser$HDusergroup$HDsessionid$HDlisten$HDbarge$HDwhisper$HDmonitor$HDstatus$HDpause$HDcustphone$HDcustinfo$HDserver_ip$HDcall_server_ip$HDtime$HDcampaign$HDcalls$HDinbcalls$HDlatency$HDastcall$HDigcall\n"; + $Bline = "$HTbegin$HTstation$HTphone$HTuser$HTusergroup$HTsessionid$HTlisten$HTbarge$HTwhisper$HTmonitor$HTstatus$HTpause$HTcustphone$HTcustinfo$HTserver_ip$HTcall_server_ip$HTtime$HTcampaign$HTcalls$HTinbcalls$HTlatency$HTastcall$HTigcall\n"; } $Aecho .= "$Aline"; $Aecho .= "$Bline"; @@ -3491,7 +3541,6 @@ function hide_ingroup_info() # select * from live_channels where ######################## - $stmt="SELECT extension,vicidial_live_agents.user,conf_exten,vicidial_live_agents.status,vicidial_live_agents.server_ip,UNIX_TIMESTAMP(last_call_time),UNIX_TIMESTAMP(last_call_finish),call_server_ip,vicidial_live_agents.campaign_id,vicidial_users.user_group,vicidial_users.full_name,vicidial_live_agents.comments,vicidial_live_agents.calls_today,vicidial_live_agents.callerid,lead_id,UNIX_TIMESTAMP(last_state_change),on_hook_agent,ring_callerid,agent_log_id,vicidial_live_agents.closer_campaigns from vicidial_live_agents,vicidial_users where vicidial_live_agents.user=vicidial_users.user and vicidial_users.user_hide_realtime='0' $UgroupSQL $usergroupSQL $user_group_filter_SQL order by $orderSQL;"; $rslt=mysql_to_mysqli($stmt, $link); if ($DB) {echo "$stmt\n";} @@ -3501,6 +3550,16 @@ function hide_ingroup_info() $i=0; $va=0; $mc=0; + + # Get inbound call counts + $inbound_call_counts=array(); + $inb_call_stmt="select user, count(*) from vicidial_closer_log where call_date>=date(now()) ".($all_active_inbound_calls ? "" : "and campaign_id in ($inbound_calls_SQL)")." group by user"; + $inb_call_rslt=mysql_to_mysqli($inb_call_stmt, $link); + while ($inb_call_row=mysqli_fetch_row($inb_call_rslt)) + { + $inbound_call_counts["$inb_call_row[0]"]=$inb_call_row[1]; + } + while ($i < $talking_to_print) { $row=mysqli_fetch_row($rslt); @@ -3864,6 +3923,7 @@ function hide_ingroup_info() $campaign_id = sprintf("%-10s", $Acampaign_id[$i]); $comments= $Acomments[$i]; $calls_today = sprintf("%-5s", $Acalls_today[$i]); + $inb_calls_today = sprintf("%-9s", ($inbound_call_counts["$Auser[$i]"]+0)); $monitor_info = sprintf("%-15s", $Amonitors[$i]); $monitor_type = sprintf("%-8s", $Amonitor_types[$i]); @@ -4373,11 +4433,11 @@ function hide_ingroup_info() { if ($realtime_block_user_info > 0) { - $Aecho .= "|$UGD $G$sessionid$EG$L$R$Aring_note[$i]|$MO $G"._QXZ("$status",6)."$EG $CM $pausecode|$CP$CI$SVD$G$call_time_MS$EG | $G$campaign_id$EG | $G$calls_today$EG |$LATENCY$ASTCT$INGRP\n"; + $Aecho .= "|$UGD $G$sessionid$EG$L$R$Aring_note[$i]|$MO $G"._QXZ("$status",6)."$EG $CM $pausecode|$CP$CI$SVD$G$call_time_MS$EG | $G$campaign_id$EG | $G$calls_today$EG | $G$inb_calls_today$EG |$LATENCY$ASTCT$INGRP\n"; } if ($realtime_block_user_info < 1) { - $Aecho .= "| $G$extension$EG$Aring_note[$i]|$phoneD$G$user$EG + |$UGD $G$sessionid$EG$L$R |$MO $G"._QXZ("$status",6)."$EG $CM $pausecode|$CP$CI$SVD$G$call_time_MS$EG | $G$campaign_id$EG | $G$calls_today$EG |$LATENCY$ASTCT$INGRP\n"; + $Aecho .= "| $G$extension$EG$Aring_note[$i]|$phoneD$G$user$EG + |$UGD $G$sessionid$EG$L$R |$MO $G"._QXZ("$status",6)."$EG $CM $pausecode|$CP$CI$SVD$G$call_time_MS$EG | $G$campaign_id$EG | $G$calls_today$EG | $G$inb_calls_today$EG |$LATENCY$ASTCT$INGRP\n"; } } @@ -4571,11 +4631,11 @@ function hide_ingroup_info() { if ($realtime_block_user_info > 0) { - $Aecho .= "$UGD $G$sessionid$EG$L$R$Aring_note[$i]$MO $G"._QXZ("$status",6)."$EG$CM$pausecodeHTML$CP$CI$SVD$G$call_time_MS$EG $G$campaign_id$EG $G$calls_today$EG $LATENCY$ASTCT$INGRP\n"; + $Aecho .= "$UGD $G$sessionid$EG$L$R$Aring_note[$i]$MO $G"._QXZ("$status",6)."$EG$CM$pausecodeHTML$CP$CI$SVD$G$call_time_MS$EG $G$campaign_id$EG $G$calls_today$EG $G$inb_calls_today$EG $LATENCY$ASTCT$INGRP\n"; } if ($realtime_block_user_info < 1) { - $Aecho .= " $G$extension$EG$Aring_note[$i]$phoneD$G$user$EG $G+$EG $UGD $G$sessionid$EG$L$R $MO $G"._QXZ("$status",6)."$EG$CM$pausecodeHTML$CP$CI$SVD$G$call_time_MS$EG $G$campaign_id$EG $G$calls_today$EG $LATENCY$ASTCT$INGRP\n"; + $Aecho .= " $G$extension$EG$Aring_note[$i]$phoneD$G$user$EG $G+$EG $UGD $G$sessionid$EG$L$R $MO $G"._QXZ("$status",6)."$EG$CM$pausecodeHTML$CP$CI$SVD$G$call_time_MS$EG $G$campaign_id$EG $G$calls_today$EG $G$inb_calls_today$EG $LATENCY$ASTCT$INGRP\n"; } } } diff --git a/www/vicidial/admin.php b/www/vicidial/admin.php index 238d3431d..f4e92db32 100644 --- a/www/vicidial/admin.php +++ b/www/vicidial/admin.php @@ -131,7 +131,7 @@ $Vtables = 'NONE,log_noanswer,did_agent_log,contact_information'; -$APIfunctions = 'ALL_FUNCTIONS add_group_alias add_lead add_list add_phone add_phone_alias add_user agent_ingroup_info agent_stats_export agent_status audio_playback blind_monitor call_agent callid_info change_ingroups check_phone_number copy_user did_log_export external_add_lead external_dial external_hangup external_pause external_status in_group_status logout moh_list ingroup_list campaigns_list callmenu_list hopper_list hopper_bulk_insert call_dispo_report agent_campaigns park_call pause_code preview_dial_action ra_call_control recording recording_lookup send_dtmf server_refresh set_timer_action sounds_list st_get_agent_active_lead st_login_log transfer_conference update_fields update_lead batch_update_lead update_list list_info list_custom_fields update_log_entry update_phone update_phone_alias update_user user_group_status vm_list vm_message webphone_url webserver logged_in_agents update_campaign update_alt_url update_presets add_did copy_did update_did lead_field_info lead_all_info lead_callback_info phone_number_log switch_lead ccc_lead_info lead_status_search lead_search lead_dearchive call_status_stats calls_in_queue_count force_fronter_leave_3way force_fronter_audio_stop update_cid_group_entry add_dnc_phone delete_dnc_phone add_fpg_phone send_notification refresh_panel update_remote_agent user_details'; +$APIfunctions = 'ALL_FUNCTIONS add_group_alias add_lead add_list add_phone add_phone_alias add_user agent_ingroup_info agent_stats_export agent_status audio_playback blind_monitor call_agent callid_info change_ingroups check_phone_number copy_user did_log_export external_add_lead external_dial external_hangup external_pause external_status in_group_status logout moh_list ingroup_list campaigns_list callmenu_list hopper_list hopper_bulk_insert call_dispo_report agent_campaigns park_call pause_code preview_dial_action ra_call_control recording stereo_recording recording_lookup send_dtmf server_refresh set_timer_action sounds_list st_get_agent_active_lead st_login_log transfer_conference update_fields update_lead batch_update_lead update_list list_info list_custom_fields update_log_entry update_phone update_phone_alias update_user user_group_status vm_list vm_message webphone_url webserver logged_in_agents update_campaign update_alt_url update_presets add_did copy_did update_did lead_field_info lead_all_info lead_callback_info phone_number_log switch_lead ccc_lead_info lead_status_search lead_search lead_dearchive call_status_stats calls_in_queue_count force_fronter_leave_3way force_fronter_audio_stop update_cid_group_entry add_dnc_phone delete_dnc_phone add_fpg_phone send_notification refresh_panel update_remote_agent user_details'; $browser_alert_sounds_list = 'bark_dog,beep_double,beep_five,beep_up,bell_double,bell_school,bird,blaster1,blaster2,buzz1,buzz2,cash_register,chat_alert,click_single,click_double,click_quiet,close_encounter,confirmation,ding,droplet,droplet_double,elephant,email_alert,hold_tone,horn_bike,horn_car,horn_car_triple,horn_clown,horn_double,horn_train,meow_cat,scream_wilhelm,silence_quick,siren,slide_down,slide_up,swish,teleport1,teleport2,ticking_two,ticking_four,ticking_six,whip,whistle_up,whistle_two,whistle_three,whoosh,xylophone1,xylophone2,xylophone3,xylophone4,20Hz_tone'; @@ -2850,6 +2850,24 @@ elseif (isset($_POST["agent_man_dial_filter"])) {$agent_man_dial_filter=$_POST["agent_man_dial_filter"];} if (isset($_GET["agent_3way_dial_filter"])) {$agent_3way_dial_filter=$_GET["agent_3way_dial_filter"];} elseif (isset($_POST["agent_3way_dial_filter"])) {$agent_3way_dial_filter=$_POST["agent_3way_dial_filter"];} +if (isset($_GET["stereo_recording"])) {$stereo_recording=$_GET["stereo_recording"];} + elseif (isset($_POST["stereo_recording"])) {$stereo_recording=$_POST["stereo_recording"];} +if (isset($_GET["recording_dtmf_detection"])) {$recording_dtmf_detection=$_GET["recording_dtmf_detection"];} + elseif (isset($_POST["recording_dtmf_detection"])) {$recording_dtmf_detection=$_POST["recording_dtmf_detection"];} +if (isset($_GET["recording_dtmf_muting"])) {$recording_dtmf_muting=$_GET["recording_dtmf_muting"];} + elseif (isset($_POST["recording_dtmf_muting"])) {$recording_dtmf_muting=$_POST["recording_dtmf_muting"];} +if (isset($_GET["stereo_parallel_recording"])) {$stereo_parallel_recording=$_GET["stereo_parallel_recording"];} + elseif (isset($_POST["stereo_parallel_recording"])) {$stereo_parallel_recording=$_POST["stereo_parallel_recording"];} +if (isset($_GET["stereo_rec_filename"])) {$stereo_rec_filename=$_GET["stereo_rec_filename"];} + elseif (isset($_POST["stereo_rec_filename"])) {$stereo_rec_filename=$_POST["stereo_rec_filename"];} +if (isset($_GET["stereo_recording_agent"])) {$stereo_recording_agent=$_GET["stereo_recording_agent"];} + elseif (isset($_POST["stereo_recording_agent"])) {$stereo_recording_agent=$_POST["stereo_recording_agent"];} +if (isset($_GET["parallel_rec_co_filename"])) {$parallel_rec_co_filename=$_GET["parallel_rec_co_filename"];} + elseif (isset($_POST["parallel_rec_co_filename"])) {$parallel_rec_co_filename=$_POST["parallel_rec_co_filename"];} +if (isset($_GET["parallel_rec_cm_filename"])) {$parallel_rec_cm_filename=$_GET["parallel_rec_cm_filename"];} + elseif (isset($_POST["parallel_rec_cm_filename"])) {$parallel_rec_cm_filename=$_POST["parallel_rec_cm_filename"];} +if (isset($_GET["parallel_rec_fr_filename"])) {$parallel_rec_fr_filename=$_GET["parallel_rec_fr_filename"];} + elseif (isset($_POST["parallel_rec_fr_filename"])) {$parallel_rec_fr_filename=$_POST["parallel_rec_fr_filename"];} $DB=preg_replace("/[^0-9a-zA-Z]/","",$DB); @@ -2862,10 +2880,9 @@ $status = $dial_status; } - ############################################# ##### START SYSTEM_SETTINGS LOOKUP ##### -$stmt = "SELECT use_non_latin,enable_queuemetrics_logging,enable_vtiger_integration,qc_features_active,outbound_autodial_active,sounds_central_control_active,enable_second_webform,user_territories_active,custom_fields_enabled,admin_web_directory,webphone_url,first_login_trigger,hosted_settings,default_phone_registration_password,default_phone_login_password,default_server_password,test_campaign_calls,active_voicemail_server,voicemail_timezones,default_voicemail_timezone,default_local_gmt,campaign_cid_areacodes_enabled,pllb_grouping_limit,did_ra_extensions_enabled,expanded_list_stats,contacts_enabled,alt_log_server_ip,alt_log_dbname,alt_log_login,alt_log_pass,tables_use_alt_log_db,call_menu_qualify_enabled,admin_list_counts,allow_voicemail_greeting,svn_revision,allow_emails,level_8_disable_add,pass_key,pass_hash_enabled,disable_auto_dial,country_code_list_stats,frozen_server_call_clear,active_modules,allow_chats,enable_languages,language_method,meetme_enter_login_filename,meetme_enter_leave3way_filename,enable_did_entry_list_id,enable_third_webform,default_language,user_hide_realtime_enabled,log_recording_access,alt_ivr_logging,admin_row_click,admin_screen_colors,ofcom_uk_drop_calc,agent_screen_colors,script_remove_js,manual_auto_next,user_new_lead_limit,agent_xfer_park_3way,agent_soundboards,web_loader_phone_length,agent_script,enable_auto_reports,enable_pause_code_limits,enable_drop_lists,allow_ip_lists,system_ip_blacklist,hide_inactive_lists,allow_manage_active_lists,expired_lists_inactive,did_system_filter,enable_gdpr_download_deletion,mute_recordings,user_admin_redirect,list_status_modification_confirmation,sip_event_logging,call_quota_lead_ranking,enable_second_script,enable_first_webform,recording_buttons,opensips_cid_name,require_password_length,user_account_emails,outbound_cid_any,entries_per_page,browser_call_alerts,inbound_answer_config,enable_international_dncs,daily_call_count_limit,allow_shared_dial,agent_search_method,admin_home_url,qc_claim_limit,qc_expire_days,two_factor_auth_hours,two_factor_container,call_limit_24hour,allowed_sip_stacks,agent_hide_hangup,allow_web_debug,max_logged_in_agents,user_codes_admin,abandon_check_queue,agent_notifications,demographic_quotas,inbound_credits,weekday_resets,two_factor_auth_agent_hours,hopper_hold_inserts,coldstorage_server_ip,coldstorage_dbname,coldstorage_login,coldstorage_pass,coldstorage_port,enhanced_agent_monitoring FROM system_settings;"; +$stmt = "SELECT use_non_latin,enable_queuemetrics_logging,enable_vtiger_integration,qc_features_active,outbound_autodial_active,sounds_central_control_active,enable_second_webform,user_territories_active,custom_fields_enabled,admin_web_directory,webphone_url,first_login_trigger,hosted_settings,default_phone_registration_password,default_phone_login_password,default_server_password,test_campaign_calls,active_voicemail_server,voicemail_timezones,default_voicemail_timezone,default_local_gmt,campaign_cid_areacodes_enabled,pllb_grouping_limit,did_ra_extensions_enabled,expanded_list_stats,contacts_enabled,alt_log_server_ip,alt_log_dbname,alt_log_login,alt_log_pass,tables_use_alt_log_db,call_menu_qualify_enabled,admin_list_counts,allow_voicemail_greeting,svn_revision,allow_emails,level_8_disable_add,pass_key,pass_hash_enabled,disable_auto_dial,country_code_list_stats,frozen_server_call_clear,active_modules,allow_chats,enable_languages,language_method,meetme_enter_login_filename,meetme_enter_leave3way_filename,enable_did_entry_list_id,enable_third_webform,default_language,user_hide_realtime_enabled,log_recording_access,alt_ivr_logging,admin_row_click,admin_screen_colors,ofcom_uk_drop_calc,agent_screen_colors,script_remove_js,manual_auto_next,user_new_lead_limit,agent_xfer_park_3way,agent_soundboards,web_loader_phone_length,agent_script,enable_auto_reports,enable_pause_code_limits,enable_drop_lists,allow_ip_lists,system_ip_blacklist,hide_inactive_lists,allow_manage_active_lists,expired_lists_inactive,did_system_filter,enable_gdpr_download_deletion,mute_recordings,user_admin_redirect,list_status_modification_confirmation,sip_event_logging,call_quota_lead_ranking,enable_second_script,enable_first_webform,recording_buttons,opensips_cid_name,require_password_length,user_account_emails,outbound_cid_any,entries_per_page,browser_call_alerts,inbound_answer_config,enable_international_dncs,daily_call_count_limit,allow_shared_dial,agent_search_method,admin_home_url,qc_claim_limit,qc_expire_days,two_factor_auth_hours,two_factor_container,call_limit_24hour,allowed_sip_stacks,agent_hide_hangup,allow_web_debug,max_logged_in_agents,user_codes_admin,abandon_check_queue,agent_notifications,demographic_quotas,inbound_credits,weekday_resets,two_factor_auth_agent_hours,hopper_hold_inserts,coldstorage_server_ip,coldstorage_dbname,coldstorage_login,coldstorage_pass,coldstorage_port,enhanced_agent_monitoring,stereo_recording,recording_dtmf_detection,recording_dtmf_muting,stereo_parallel_recording FROM system_settings;"; $rslt=mysql_to_mysqli($stmt, $link); #if ($DB) {echo "$stmt\n";} $qm_conf_ct = mysqli_num_rows($rslt); @@ -2990,6 +3007,10 @@ $SScoldstorage_pass = $row[115]; $SScoldstorage_port = $row[116]; $SSenhanced_agent_monitoring = $row[117]; + $SSstereo_recording = $row[118]; + $SSrecording_dtmf_detection = $row[119]; + $SSrecording_dtmf_muting = $row[120]; + $SSstereo_parallel_recording = $row[121]; } if ($SSallow_web_debug < 1) {$DB=0;} ##### END SETTINGS LOOKUP ##### @@ -3391,6 +3412,8 @@ $manual_minimum_answer_seconds = preg_replace('/[^0-9]/','',$manual_minimum_answer_seconds); $enhanced_agent_monitoring = preg_replace('/[^0-9]/','',$enhanced_agent_monitoring); $agent_hide_dial_fail = preg_replace('/[^0-9]/','',$agent_hide_dial_fail); +$recording_dtmf_detection = preg_replace('/[^0-9]/','',$recording_dtmf_detection); +$recording_dtmf_muting = preg_replace('/[^0-9]/','',$recording_dtmf_muting); $user_new_lead_limit = preg_replace('/[^-0-9]/','',$user_new_lead_limit); $drop_call_seconds = preg_replace('/[^-0-9]/','',$drop_call_seconds); @@ -3624,6 +3647,9 @@ $holiday_method = preg_replace('/[^-_0-9a-zA-Z]/','',$holiday_method); $leave_3way_stop_recording = preg_replace('/[^-_0-9a-zA-Z]/','',$leave_3way_stop_recording); $manual_dial_lead_id = preg_replace('/[^-_0-9a-zA-Z]/','',$manual_dial_lead_id); +$stereo_recording = preg_replace('/[^-_0-9a-zA-Z]/','',$stereo_recording); +$stereo_parallel_recording = preg_replace('/[^-_0-9a-zA-Z]/','',$stereo_parallel_recording); +$stereo_recording_agent = preg_replace('/[^-_0-9a-zA-Z]/','',$stereo_recording_agent); if ($non_latin < 1) { @@ -4304,6 +4330,10 @@ $city_rule = preg_replace('/[^- \.\,\_0-9a-zA-Z]/','',$city_rule); $county_rule = preg_replace('/[^- \.\,\_0-9a-zA-Z]/','',$county_rule); $ac_rule = preg_replace('/[^- \.\,\_0-9a-zA-Z]/','',$ac_rule); + $stereo_rec_filename = preg_replace('/[^-\.\_0-9a-zA-Z]/','',$stereo_rec_filename); + $parallel_rec_co_filename = preg_replace('/[^-\.\_0-9a-zA-Z]/','',$parallel_rec_co_filename); + $parallel_rec_cm_filename = preg_replace('/[^-\.\_0-9a-zA-Z]/','',$parallel_rec_cm_filename); + $parallel_rec_fr_filename = preg_replace('/[^-\.\_0-9a-zA-Z]/','',$parallel_rec_fr_filename); ### ALPHA-NUMERIC and underscore and dash and slash and at and dot $call_out_number_group = preg_replace('/[^-\.\:\/\@\_0-9a-zA-Z]/','',$call_out_number_group); @@ -5046,6 +5076,10 @@ $city_rule = preg_replace('/[^- \.\,\_0-9\p{L}]/u','',$city_rule); $county_rule = preg_replace('/[^- \.\,\_0-9\p{L}]/u','',$county_rule); $ac_rule = preg_replace('/[^- \.\,\_0-9\p{L}]/u','',$ac_rule); + $stereo_rec_filename = preg_replace('/[^- \.\,\_0-9\p{L}]/u','',$stereo_rec_filename); + $parallel_rec_co_filename = preg_replace('/[^- \.\,\_0-9\p{L}]/u','',$parallel_rec_co_filename); + $parallel_rec_cm_filename = preg_replace('/[^- \.\,\_0-9\p{L}]/u','',$parallel_rec_cm_filename); + $parallel_rec_fr_filename = preg_replace('/[^- \.\,\_0-9\p{L}]/u','',$parallel_rec_fr_filename); ### ALPHA-NUMERIC and underscore and dash and slash and at and dot $call_out_number_group = preg_replace('/[^-\.\:\/\@\_0-9\p{L}]/u','',$call_out_number_group); @@ -6250,12 +6284,13 @@ # 250722-1546 - Added hopper_bulk_insert non-agent API function # 250806-0841 - Added manual_dial_lead_id user setting, and new 'ONLY' option for campaign setting # 250808-1120 - Added agent_man_dial_filter & agent_3way_dial_filter system settings -# +# 250822-2056 - Added system/campaign/ingroup settings for stereo_recording +# # 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-942a'; -$build = '250808-1120'; +$admin_version = '2.14-943a'; +$build = '250822-2056'; $STARTtime = date("U"); $SQLdate = date("Y-m-d H:i:s"); @@ -6276,6 +6311,7 @@ $add_copy_disabled=0; $camp_lead_order_random=1; $vm_view_messages_link=''; +$stereo_dev_mode=1; $month_old = mktime(0, 0, 0, date("m")-1, date("d"), date("Y")); $past_month_date = date("Y-m-d H:i:s",$month_old); @@ -12694,7 +12730,7 @@ function ajax_logout_now() $rslt=mysql_to_mysqli($stmtX, $link); } - $stmt="INSERT INTO vicidial_campaigns (campaign_name,campaign_id,active,dial_status_a,dial_status_b,dial_status_c,dial_status_d,dial_status_e,lead_order,park_ext,park_file_name,web_form_address,allow_closers,hopper_level,auto_dial_level,next_agent_call,local_call_time,voicemail_ext,dial_timeout,dial_prefix,campaign_cid,campaign_vdad_exten,campaign_rec_exten,campaign_recording,campaign_rec_filename,campaign_script,get_call_launch,am_message_exten,amd_send_to_vmx,xferconf_a_dtmf,xferconf_a_number,xferconf_b_dtmf,xferconf_b_number,alt_number_dialing,scheduled_callbacks,lead_filter_id,drop_call_seconds,drop_action,safe_harbor_exten,display_dialable_count,wrapup_seconds,wrapup_message,closer_campaigns,use_internal_dnc,allcalls_delay,omit_phone_code,dial_method,available_only_ratio_tally,adaptive_dropped_percentage,adaptive_maximum_level,adaptive_latest_server_time,adaptive_intensity,adaptive_dl_diff_target,concurrent_transfers,auto_alt_dial,auto_alt_dial_statuses,agent_pause_codes_active,campaign_description,campaign_changedate,campaign_stats_refresh,campaign_logindate,dial_statuses,disable_alter_custdata,no_hopper_leads_logins,list_order_mix,campaign_allow_inbound,manual_dial_list_id,default_xfer_group,queue_priority,drop_inbound_group,qc_enabled,qc_statuses,qc_lists,qc_web_form_address,qc_script,survey_first_audio_file,survey_dtmf_digits,survey_ni_digit,survey_opt_in_audio_file,survey_ni_audio_file,survey_method,survey_no_response_action,survey_ni_status,survey_response_digit_map,survey_xfer_exten,survey_camp_record_dir,disable_alter_custphone,display_queue_count,qc_get_record_launch,qc_show_recording,qc_shift_id,manual_dial_filter,agent_clipboard_copy,agent_extended_alt_dial,use_campaign_dnc,three_way_call_cid,three_way_dial_prefix,web_form_target,vtiger_search_category,vtiger_create_call_record,vtiger_create_lead_record,vtiger_screen_login,cpd_amd_action,agent_allow_group_alias,default_group_alias,vtiger_search_dead,vtiger_status_call,survey_third_digit,survey_fourth_digit,survey_third_audio_file,survey_fourth_audio_file,survey_third_status,survey_fourth_status,survey_third_exten,survey_fourth_exten,drop_lockout_time,quick_transfer_button,prepopulate_transfer_preset,drop_rate_group,view_calls_in_queue,view_calls_in_queue_launch,grab_calls_in_queue,call_requeue_button,pause_after_each_call,no_hopper_dialing,agent_dial_owner_only,agent_display_dialable_leads,web_form_address_two,waitforsilence_options,agent_select_territories,crm_popup_login,crm_login_address,timer_action,timer_action_message,timer_action_seconds,start_call_url,dispo_call_url,xferconf_c_number,xferconf_d_number,xferconf_e_number,use_custom_cid,scheduled_callbacks_alert,queuemetrics_callstatus_override,extension_appended_cidname,scheduled_callbacks_count,manual_dial_override,blind_monitor_warning,blind_monitor_message,blind_monitor_filename,inbound_queue_no_dial,timer_action_destination,enable_xfer_presets,hide_xfer_number_to_dial,manual_dial_prefix,customer_3way_hangup_logging,customer_3way_hangup_seconds,customer_3way_hangup_action,ivr_park_call,ivr_park_call_agi,manual_preview_dial,realtime_agent_time_stats,use_auto_hopper,auto_hopper_multi,auto_trim_hopper,api_manual_dial,manual_dial_call_time_check,display_leads_count,lead_order_randomize,lead_order_secondary,per_call_notes,my_callback_option,agent_lead_search,agent_lead_search_method,queuemetrics_phone_environment,auto_pause_precall,auto_resume_precall,auto_pause_precall_code,manual_dial_cid,post_phone_time_diff_alert,custom_3way_button_transfer,available_only_tally_threshold,available_only_tally_threshold_agents,dial_level_threshold,dial_level_threshold_agents,safe_harbor_audio,safe_harbor_menu_id,survey_menu_id,callback_days_limit,dl_diff_target_method,disable_dispo_screen,disable_dispo_status,screen_labels,status_display_fields,na_call_url,survey_recording,pllb_grouping,pllb_grouping_limit,call_count_limit,call_count_target,callback_hours_block,callback_list_calltime,user_group,hopper_vlc_dup_check,safe_harbor_audio_field,pause_after_next_call,owner_populate,use_other_campaign_dnc,allow_emails,allow_chats,amd_inbound_group,amd_callmenu,survey_wait_sec,manual_dial_lead_id,dead_max,dispo_max,pause_max,dead_max_dispo,dispo_max_dispo,max_inbound_calls,manual_dial_search_checkbox,hide_call_log_info,timer_alt_seconds,wrapup_bypass,wrapup_after_hotkey,callback_active_limit,callback_active_limit_override,comments_all_tabs,comments_dispo_screen,comments_callback_screen,qc_comment_history,show_previous_callback,clear_script,cpd_unknown_action,manual_dial_search_filter,web_form_address_three,manual_dial_override_field,status_display_ingroup,customer_gone_seconds,agent_display_fields,am_message_wildcards,manual_dial_timeout,routing_initiated_recordings,manual_dial_hopper_check,callback_useronly_move_minutes,ofcom_uk_drop_calc,manual_auto_next,manual_auto_show,allow_required_fields,dead_to_dispo,agent_xfer_validation,ready_max_logout,callback_display_days,three_way_record_stop,hangup_xfer_record_start,scheduled_callbacks_email_alert,max_inbound_calls_outcome,manual_auto_next_options,agent_screen_time_display,next_dial_my_callbacks,inbound_no_agents_no_dial_container,inbound_no_agents_no_dial_threshold,cid_group_id,pause_max_dispo,script_top_dispo,dead_trigger_seconds,dead_trigger_action,dead_trigger_repeat,dead_trigger_filename,dead_trigger_url,scheduled_callbacks_force_dial,scheduled_callbacks_auto_reschedule,scheduled_callbacks_timezones_container,three_way_volume_buttons,callback_dnc,manual_dial_validation,mute_recordings,auto_active_list_new,call_quota_lead_ranking,sip_event_logging,campaign_script_two,leave_vm_no_dispo,leave_vm_message_group_id,dial_timeout_lead_container,amd_type,vmm_daily_limit,opensips_cid_name,amd_agent_route_options,browser_alert_sound,browser_alert_volume,three_way_record_stop_exception,in_group_dial,pause_max_exceptions,hopper_drop_run_trigger,daily_call_count_limit,daily_limit_manual,transfer_button_launch,shared_dial_rank,agent_search_method,qc_scorecard_id,qc_statuses_id,clear_form,leave_3way_start_recording,leave_3way_start_recording_exception,calls_waiting_vl_one,calls_waiting_vl_two,calls_inqueue_count_one,calls_inqueue_count_two,in_man_dial_next_ready_seconds,in_man_dial_next_ready_seconds_override,transfer_no_dispo,call_limit_24hour_method,call_limit_24hour_scope,call_limit_24hour,call_limit_24hour_override,cid_group_id_two,incall_tally_threshold_seconds,auto_alt_threshold,pause_max_url,agent_hide_hangup,ig_xfer_list_sort,script_tab_frame_size,max_logged_in_agents,user_group_script,agent_hangup_route,agent_hangup_value,agent_hangup_ig_override,show_confetti,demographic_quotas,demographic_quotas_container,demographic_quotas_rerank,demographic_quotas_list_resets,custom_one,custom_two,custom_three,custom_four,custom_five,dead_stop_recording,manual_vm_status_updates,force_per_call_notes,agent_search_ingroup_list,hopper_hold_inserts,daily_phone_number_call_limit,state_descriptions,script_tab_height,call_log_days,leave_3way_stop_recording,manual_minimum_ring_seconds,manual_minimum_attempt_seconds,manual_minimum_answer_seconds,khomp_settings_container) SELECT \"$campaign_name\",\"$campaign_id\",\"N\",dial_status_a,dial_status_b,dial_status_c,dial_status_d,dial_status_e,lead_order,park_ext,park_file_name,web_form_address,allow_closers,hopper_level,auto_dial_level,next_agent_call,local_call_time,voicemail_ext,dial_timeout,dial_prefix,campaign_cid,campaign_vdad_exten,campaign_rec_exten,campaign_recording,campaign_rec_filename,campaign_script,get_call_launch,am_message_exten,amd_send_to_vmx,xferconf_a_dtmf,xferconf_a_number,xferconf_b_dtmf,xferconf_b_number,alt_number_dialing,scheduled_callbacks,lead_filter_id,drop_call_seconds,drop_action,safe_harbor_exten,display_dialable_count,wrapup_seconds,wrapup_message,closer_campaigns,use_internal_dnc,allcalls_delay,omit_phone_code,dial_method,available_only_ratio_tally,adaptive_dropped_percentage,adaptive_maximum_level,adaptive_latest_server_time,adaptive_intensity,adaptive_dl_diff_target,concurrent_transfers,auto_alt_dial,auto_alt_dial_statuses,agent_pause_codes_active,campaign_description,campaign_changedate,campaign_stats_refresh,campaign_logindate,dial_statuses,disable_alter_custdata,no_hopper_leads_logins,\"DISABLED\",campaign_allow_inbound,manual_dial_list_id,default_xfer_group,queue_priority,drop_inbound_group,qc_enabled,qc_statuses,qc_lists,qc_web_form_address,qc_script,survey_first_audio_file,survey_dtmf_digits,survey_ni_digit,survey_opt_in_audio_file,survey_ni_audio_file,survey_method,survey_no_response_action,survey_ni_status,survey_response_digit_map,survey_xfer_exten,survey_camp_record_dir,disable_alter_custphone,display_queue_count,qc_get_record_launch,qc_show_recording,qc_shift_id,manual_dial_filter,agent_clipboard_copy,agent_extended_alt_dial,use_campaign_dnc,three_way_call_cid,three_way_dial_prefix,web_form_target,vtiger_search_category,vtiger_create_call_record,vtiger_create_lead_record,vtiger_screen_login,cpd_amd_action,agent_allow_group_alias,default_group_alias,vtiger_search_dead,vtiger_status_call,survey_third_digit,survey_fourth_digit,survey_third_audio_file,survey_fourth_audio_file,survey_third_status,survey_fourth_status,survey_third_exten,survey_fourth_exten,drop_lockout_time,quick_transfer_button,prepopulate_transfer_preset,drop_rate_group,view_calls_in_queue,view_calls_in_queue_launch,grab_calls_in_queue,call_requeue_button,pause_after_each_call,no_hopper_dialing,agent_dial_owner_only,agent_display_dialable_leads,web_form_address_two,waitforsilence_options,agent_select_territories,crm_popup_login,crm_login_address,timer_action,timer_action_message,timer_action_seconds,start_call_url,dispo_call_url,xferconf_c_number,xferconf_d_number,xferconf_e_number,use_custom_cid,scheduled_callbacks_alert,queuemetrics_callstatus_override,extension_appended_cidname,scheduled_callbacks_count,manual_dial_override,blind_monitor_warning,blind_monitor_message,blind_monitor_filename,inbound_queue_no_dial,timer_action_destination,enable_xfer_presets,hide_xfer_number_to_dial,manual_dial_prefix,customer_3way_hangup_logging,customer_3way_hangup_seconds,customer_3way_hangup_action,ivr_park_call,ivr_park_call_agi,manual_preview_dial,realtime_agent_time_stats,use_auto_hopper,auto_hopper_multi,auto_trim_hopper,api_manual_dial,manual_dial_call_time_check,display_leads_count,lead_order_randomize,lead_order_secondary,per_call_notes,my_callback_option,agent_lead_search,agent_lead_search_method,queuemetrics_phone_environment,auto_pause_precall,auto_resume_precall,auto_pause_precall_code,manual_dial_cid,post_phone_time_diff_alert,custom_3way_button_transfer,available_only_tally_threshold,available_only_tally_threshold_agents,dial_level_threshold,dial_level_threshold_agents,safe_harbor_audio,safe_harbor_menu_id,survey_menu_id,callback_days_limit,dl_diff_target_method,disable_dispo_screen,disable_dispo_status,screen_labels,status_display_fields,na_call_url,survey_recording,pllb_grouping,pllb_grouping_limit,call_count_limit,call_count_target,callback_hours_block,callback_list_calltime,user_group,hopper_vlc_dup_check,safe_harbor_audio_field,pause_after_next_call,owner_populate,use_other_campaign_dnc,allow_emails,allow_chats,amd_inbound_group,amd_callmenu,survey_wait_sec,manual_dial_lead_id,dead_max,dispo_max,pause_max,dead_max_dispo,dispo_max_dispo,max_inbound_calls,manual_dial_search_checkbox,hide_call_log_info,timer_alt_seconds,wrapup_bypass,wrapup_after_hotkey,callback_active_limit,callback_active_limit_override,comments_all_tabs,comments_dispo_screen,comments_callback_screen,qc_comment_history,show_previous_callback,clear_script,cpd_unknown_action,manual_dial_search_filter,web_form_address_three,manual_dial_override_field,status_display_ingroup,customer_gone_seconds,agent_display_fields,am_message_wildcards,manual_dial_timeout,routing_initiated_recordings,manual_dial_hopper_check,callback_useronly_move_minutes,ofcom_uk_drop_calc,manual_auto_next,manual_auto_show,allow_required_fields,dead_to_dispo,agent_xfer_validation,ready_max_logout,callback_display_days,three_way_record_stop,hangup_xfer_record_start,scheduled_callbacks_email_alert,max_inbound_calls_outcome,manual_auto_next_options,agent_screen_time_display,next_dial_my_callbacks,inbound_no_agents_no_dial_container,inbound_no_agents_no_dial_threshold,cid_group_id,pause_max_dispo,script_top_dispo,dead_trigger_seconds,dead_trigger_action,dead_trigger_repeat,dead_trigger_filename,dead_trigger_url,scheduled_callbacks_force_dial,scheduled_callbacks_auto_reschedule,scheduled_callbacks_timezones_container,three_way_volume_buttons,callback_dnc,manual_dial_validation,mute_recordings,auto_active_list_new,call_quota_lead_ranking,sip_event_logging,campaign_script_two,leave_vm_no_dispo,leave_vm_message_group_id,dial_timeout_lead_container,amd_type,vmm_daily_limit,opensips_cid_name,amd_agent_route_options,browser_alert_sound,browser_alert_volume,three_way_record_stop_exception,in_group_dial,pause_max_exceptions,hopper_drop_run_trigger,daily_call_count_limit,daily_limit_manual,transfer_button_launch,shared_dial_rank,agent_search_method,qc_scorecard_id,qc_statuses_id,clear_form,leave_3way_start_recording,leave_3way_start_recording_exception,calls_waiting_vl_one,calls_waiting_vl_two,calls_inqueue_count_one,calls_inqueue_count_two,in_man_dial_next_ready_seconds,in_man_dial_next_ready_seconds_override,transfer_no_dispo,call_limit_24hour_method,call_limit_24hour_scope,call_limit_24hour,call_limit_24hour_override,cid_group_id_two,incall_tally_threshold_seconds,auto_alt_threshold,pause_max_url,agent_hide_hangup,ig_xfer_list_sort,script_tab_frame_size,max_logged_in_agents,user_group_script,agent_hangup_route,agent_hangup_value,agent_hangup_ig_override,show_confetti,demographic_quotas,demographic_quotas_container,demographic_quotas_rerank,demographic_quotas_list_resets,custom_one,custom_two,custom_three,custom_four,custom_five,dead_stop_recording,manual_vm_status_updates,force_per_call_notes,agent_search_ingroup_list,hopper_hold_inserts,daily_phone_number_call_limit,state_descriptions,script_tab_height,call_log_days,leave_3way_stop_recording,manual_minimum_ring_seconds,manual_minimum_attempt_seconds,manual_minimum_answer_seconds,khomp_settings_container from vicidial_campaigns where campaign_id='$source_campaign_id';"; + $stmt="INSERT INTO vicidial_campaigns (campaign_name,campaign_id,active,dial_status_a,dial_status_b,dial_status_c,dial_status_d,dial_status_e,lead_order,park_ext,park_file_name,web_form_address,allow_closers,hopper_level,auto_dial_level,next_agent_call,local_call_time,voicemail_ext,dial_timeout,dial_prefix,campaign_cid,campaign_vdad_exten,campaign_rec_exten,campaign_recording,campaign_rec_filename,campaign_script,get_call_launch,am_message_exten,amd_send_to_vmx,xferconf_a_dtmf,xferconf_a_number,xferconf_b_dtmf,xferconf_b_number,alt_number_dialing,scheduled_callbacks,lead_filter_id,drop_call_seconds,drop_action,safe_harbor_exten,display_dialable_count,wrapup_seconds,wrapup_message,closer_campaigns,use_internal_dnc,allcalls_delay,omit_phone_code,dial_method,available_only_ratio_tally,adaptive_dropped_percentage,adaptive_maximum_level,adaptive_latest_server_time,adaptive_intensity,adaptive_dl_diff_target,concurrent_transfers,auto_alt_dial,auto_alt_dial_statuses,agent_pause_codes_active,campaign_description,campaign_changedate,campaign_stats_refresh,campaign_logindate,dial_statuses,disable_alter_custdata,no_hopper_leads_logins,list_order_mix,campaign_allow_inbound,manual_dial_list_id,default_xfer_group,queue_priority,drop_inbound_group,qc_enabled,qc_statuses,qc_lists,qc_web_form_address,qc_script,survey_first_audio_file,survey_dtmf_digits,survey_ni_digit,survey_opt_in_audio_file,survey_ni_audio_file,survey_method,survey_no_response_action,survey_ni_status,survey_response_digit_map,survey_xfer_exten,survey_camp_record_dir,disable_alter_custphone,display_queue_count,qc_get_record_launch,qc_show_recording,qc_shift_id,manual_dial_filter,agent_clipboard_copy,agent_extended_alt_dial,use_campaign_dnc,three_way_call_cid,three_way_dial_prefix,web_form_target,vtiger_search_category,vtiger_create_call_record,vtiger_create_lead_record,vtiger_screen_login,cpd_amd_action,agent_allow_group_alias,default_group_alias,vtiger_search_dead,vtiger_status_call,survey_third_digit,survey_fourth_digit,survey_third_audio_file,survey_fourth_audio_file,survey_third_status,survey_fourth_status,survey_third_exten,survey_fourth_exten,drop_lockout_time,quick_transfer_button,prepopulate_transfer_preset,drop_rate_group,view_calls_in_queue,view_calls_in_queue_launch,grab_calls_in_queue,call_requeue_button,pause_after_each_call,no_hopper_dialing,agent_dial_owner_only,agent_display_dialable_leads,web_form_address_two,waitforsilence_options,agent_select_territories,crm_popup_login,crm_login_address,timer_action,timer_action_message,timer_action_seconds,start_call_url,dispo_call_url,xferconf_c_number,xferconf_d_number,xferconf_e_number,use_custom_cid,scheduled_callbacks_alert,queuemetrics_callstatus_override,extension_appended_cidname,scheduled_callbacks_count,manual_dial_override,blind_monitor_warning,blind_monitor_message,blind_monitor_filename,inbound_queue_no_dial,timer_action_destination,enable_xfer_presets,hide_xfer_number_to_dial,manual_dial_prefix,customer_3way_hangup_logging,customer_3way_hangup_seconds,customer_3way_hangup_action,ivr_park_call,ivr_park_call_agi,manual_preview_dial,realtime_agent_time_stats,use_auto_hopper,auto_hopper_multi,auto_trim_hopper,api_manual_dial,manual_dial_call_time_check,display_leads_count,lead_order_randomize,lead_order_secondary,per_call_notes,my_callback_option,agent_lead_search,agent_lead_search_method,queuemetrics_phone_environment,auto_pause_precall,auto_resume_precall,auto_pause_precall_code,manual_dial_cid,post_phone_time_diff_alert,custom_3way_button_transfer,available_only_tally_threshold,available_only_tally_threshold_agents,dial_level_threshold,dial_level_threshold_agents,safe_harbor_audio,safe_harbor_menu_id,survey_menu_id,callback_days_limit,dl_diff_target_method,disable_dispo_screen,disable_dispo_status,screen_labels,status_display_fields,na_call_url,survey_recording,pllb_grouping,pllb_grouping_limit,call_count_limit,call_count_target,callback_hours_block,callback_list_calltime,user_group,hopper_vlc_dup_check,safe_harbor_audio_field,pause_after_next_call,owner_populate,use_other_campaign_dnc,allow_emails,allow_chats,amd_inbound_group,amd_callmenu,survey_wait_sec,manual_dial_lead_id,dead_max,dispo_max,pause_max,dead_max_dispo,dispo_max_dispo,max_inbound_calls,manual_dial_search_checkbox,hide_call_log_info,timer_alt_seconds,wrapup_bypass,wrapup_after_hotkey,callback_active_limit,callback_active_limit_override,comments_all_tabs,comments_dispo_screen,comments_callback_screen,qc_comment_history,show_previous_callback,clear_script,cpd_unknown_action,manual_dial_search_filter,web_form_address_three,manual_dial_override_field,status_display_ingroup,customer_gone_seconds,agent_display_fields,am_message_wildcards,manual_dial_timeout,routing_initiated_recordings,manual_dial_hopper_check,callback_useronly_move_minutes,ofcom_uk_drop_calc,manual_auto_next,manual_auto_show,allow_required_fields,dead_to_dispo,agent_xfer_validation,ready_max_logout,callback_display_days,three_way_record_stop,hangup_xfer_record_start,scheduled_callbacks_email_alert,max_inbound_calls_outcome,manual_auto_next_options,agent_screen_time_display,next_dial_my_callbacks,inbound_no_agents_no_dial_container,inbound_no_agents_no_dial_threshold,cid_group_id,pause_max_dispo,script_top_dispo,dead_trigger_seconds,dead_trigger_action,dead_trigger_repeat,dead_trigger_filename,dead_trigger_url,scheduled_callbacks_force_dial,scheduled_callbacks_auto_reschedule,scheduled_callbacks_timezones_container,three_way_volume_buttons,callback_dnc,manual_dial_validation,mute_recordings,auto_active_list_new,call_quota_lead_ranking,sip_event_logging,campaign_script_two,leave_vm_no_dispo,leave_vm_message_group_id,dial_timeout_lead_container,amd_type,vmm_daily_limit,opensips_cid_name,amd_agent_route_options,browser_alert_sound,browser_alert_volume,three_way_record_stop_exception,in_group_dial,pause_max_exceptions,hopper_drop_run_trigger,daily_call_count_limit,daily_limit_manual,transfer_button_launch,shared_dial_rank,agent_search_method,qc_scorecard_id,qc_statuses_id,clear_form,leave_3way_start_recording,leave_3way_start_recording_exception,calls_waiting_vl_one,calls_waiting_vl_two,calls_inqueue_count_one,calls_inqueue_count_two,in_man_dial_next_ready_seconds,in_man_dial_next_ready_seconds_override,transfer_no_dispo,call_limit_24hour_method,call_limit_24hour_scope,call_limit_24hour,call_limit_24hour_override,cid_group_id_two,incall_tally_threshold_seconds,auto_alt_threshold,pause_max_url,agent_hide_hangup,ig_xfer_list_sort,script_tab_frame_size,max_logged_in_agents,user_group_script,agent_hangup_route,agent_hangup_value,agent_hangup_ig_override,show_confetti,demographic_quotas,demographic_quotas_container,demographic_quotas_rerank,demographic_quotas_list_resets,custom_one,custom_two,custom_three,custom_four,custom_five,dead_stop_recording,manual_vm_status_updates,force_per_call_notes,agent_search_ingroup_list,hopper_hold_inserts,daily_phone_number_call_limit,state_descriptions,script_tab_height,call_log_days,leave_3way_stop_recording,manual_minimum_ring_seconds,manual_minimum_attempt_seconds,manual_minimum_answer_seconds,khomp_settings_container,stereo_recording,stereo_rec_filename,stereo_parallel_recording,recording_dtmf_muting,stereo_recording_agent,parallel_rec_co_filename,parallel_rec_cm_filename,parallel_rec_fr_filename) SELECT \"$campaign_name\",\"$campaign_id\",\"N\",dial_status_a,dial_status_b,dial_status_c,dial_status_d,dial_status_e,lead_order,park_ext,park_file_name,web_form_address,allow_closers,hopper_level,auto_dial_level,next_agent_call,local_call_time,voicemail_ext,dial_timeout,dial_prefix,campaign_cid,campaign_vdad_exten,campaign_rec_exten,campaign_recording,campaign_rec_filename,campaign_script,get_call_launch,am_message_exten,amd_send_to_vmx,xferconf_a_dtmf,xferconf_a_number,xferconf_b_dtmf,xferconf_b_number,alt_number_dialing,scheduled_callbacks,lead_filter_id,drop_call_seconds,drop_action,safe_harbor_exten,display_dialable_count,wrapup_seconds,wrapup_message,closer_campaigns,use_internal_dnc,allcalls_delay,omit_phone_code,dial_method,available_only_ratio_tally,adaptive_dropped_percentage,adaptive_maximum_level,adaptive_latest_server_time,adaptive_intensity,adaptive_dl_diff_target,concurrent_transfers,auto_alt_dial,auto_alt_dial_statuses,agent_pause_codes_active,campaign_description,campaign_changedate,campaign_stats_refresh,campaign_logindate,dial_statuses,disable_alter_custdata,no_hopper_leads_logins,\"DISABLED\",campaign_allow_inbound,manual_dial_list_id,default_xfer_group,queue_priority,drop_inbound_group,qc_enabled,qc_statuses,qc_lists,qc_web_form_address,qc_script,survey_first_audio_file,survey_dtmf_digits,survey_ni_digit,survey_opt_in_audio_file,survey_ni_audio_file,survey_method,survey_no_response_action,survey_ni_status,survey_response_digit_map,survey_xfer_exten,survey_camp_record_dir,disable_alter_custphone,display_queue_count,qc_get_record_launch,qc_show_recording,qc_shift_id,manual_dial_filter,agent_clipboard_copy,agent_extended_alt_dial,use_campaign_dnc,three_way_call_cid,three_way_dial_prefix,web_form_target,vtiger_search_category,vtiger_create_call_record,vtiger_create_lead_record,vtiger_screen_login,cpd_amd_action,agent_allow_group_alias,default_group_alias,vtiger_search_dead,vtiger_status_call,survey_third_digit,survey_fourth_digit,survey_third_audio_file,survey_fourth_audio_file,survey_third_status,survey_fourth_status,survey_third_exten,survey_fourth_exten,drop_lockout_time,quick_transfer_button,prepopulate_transfer_preset,drop_rate_group,view_calls_in_queue,view_calls_in_queue_launch,grab_calls_in_queue,call_requeue_button,pause_after_each_call,no_hopper_dialing,agent_dial_owner_only,agent_display_dialable_leads,web_form_address_two,waitforsilence_options,agent_select_territories,crm_popup_login,crm_login_address,timer_action,timer_action_message,timer_action_seconds,start_call_url,dispo_call_url,xferconf_c_number,xferconf_d_number,xferconf_e_number,use_custom_cid,scheduled_callbacks_alert,queuemetrics_callstatus_override,extension_appended_cidname,scheduled_callbacks_count,manual_dial_override,blind_monitor_warning,blind_monitor_message,blind_monitor_filename,inbound_queue_no_dial,timer_action_destination,enable_xfer_presets,hide_xfer_number_to_dial,manual_dial_prefix,customer_3way_hangup_logging,customer_3way_hangup_seconds,customer_3way_hangup_action,ivr_park_call,ivr_park_call_agi,manual_preview_dial,realtime_agent_time_stats,use_auto_hopper,auto_hopper_multi,auto_trim_hopper,api_manual_dial,manual_dial_call_time_check,display_leads_count,lead_order_randomize,lead_order_secondary,per_call_notes,my_callback_option,agent_lead_search,agent_lead_search_method,queuemetrics_phone_environment,auto_pause_precall,auto_resume_precall,auto_pause_precall_code,manual_dial_cid,post_phone_time_diff_alert,custom_3way_button_transfer,available_only_tally_threshold,available_only_tally_threshold_agents,dial_level_threshold,dial_level_threshold_agents,safe_harbor_audio,safe_harbor_menu_id,survey_menu_id,callback_days_limit,dl_diff_target_method,disable_dispo_screen,disable_dispo_status,screen_labels,status_display_fields,na_call_url,survey_recording,pllb_grouping,pllb_grouping_limit,call_count_limit,call_count_target,callback_hours_block,callback_list_calltime,user_group,hopper_vlc_dup_check,safe_harbor_audio_field,pause_after_next_call,owner_populate,use_other_campaign_dnc,allow_emails,allow_chats,amd_inbound_group,amd_callmenu,survey_wait_sec,manual_dial_lead_id,dead_max,dispo_max,pause_max,dead_max_dispo,dispo_max_dispo,max_inbound_calls,manual_dial_search_checkbox,hide_call_log_info,timer_alt_seconds,wrapup_bypass,wrapup_after_hotkey,callback_active_limit,callback_active_limit_override,comments_all_tabs,comments_dispo_screen,comments_callback_screen,qc_comment_history,show_previous_callback,clear_script,cpd_unknown_action,manual_dial_search_filter,web_form_address_three,manual_dial_override_field,status_display_ingroup,customer_gone_seconds,agent_display_fields,am_message_wildcards,manual_dial_timeout,routing_initiated_recordings,manual_dial_hopper_check,callback_useronly_move_minutes,ofcom_uk_drop_calc,manual_auto_next,manual_auto_show,allow_required_fields,dead_to_dispo,agent_xfer_validation,ready_max_logout,callback_display_days,three_way_record_stop,hangup_xfer_record_start,scheduled_callbacks_email_alert,max_inbound_calls_outcome,manual_auto_next_options,agent_screen_time_display,next_dial_my_callbacks,inbound_no_agents_no_dial_container,inbound_no_agents_no_dial_threshold,cid_group_id,pause_max_dispo,script_top_dispo,dead_trigger_seconds,dead_trigger_action,dead_trigger_repeat,dead_trigger_filename,dead_trigger_url,scheduled_callbacks_force_dial,scheduled_callbacks_auto_reschedule,scheduled_callbacks_timezones_container,three_way_volume_buttons,callback_dnc,manual_dial_validation,mute_recordings,auto_active_list_new,call_quota_lead_ranking,sip_event_logging,campaign_script_two,leave_vm_no_dispo,leave_vm_message_group_id,dial_timeout_lead_container,amd_type,vmm_daily_limit,opensips_cid_name,amd_agent_route_options,browser_alert_sound,browser_alert_volume,three_way_record_stop_exception,in_group_dial,pause_max_exceptions,hopper_drop_run_trigger,daily_call_count_limit,daily_limit_manual,transfer_button_launch,shared_dial_rank,agent_search_method,qc_scorecard_id,qc_statuses_id,clear_form,leave_3way_start_recording,leave_3way_start_recording_exception,calls_waiting_vl_one,calls_waiting_vl_two,calls_inqueue_count_one,calls_inqueue_count_two,in_man_dial_next_ready_seconds,in_man_dial_next_ready_seconds_override,transfer_no_dispo,call_limit_24hour_method,call_limit_24hour_scope,call_limit_24hour,call_limit_24hour_override,cid_group_id_two,incall_tally_threshold_seconds,auto_alt_threshold,pause_max_url,agent_hide_hangup,ig_xfer_list_sort,script_tab_frame_size,max_logged_in_agents,user_group_script,agent_hangup_route,agent_hangup_value,agent_hangup_ig_override,show_confetti,demographic_quotas,demographic_quotas_container,demographic_quotas_rerank,demographic_quotas_list_resets,custom_one,custom_two,custom_three,custom_four,custom_five,dead_stop_recording,manual_vm_status_updates,force_per_call_notes,agent_search_ingroup_list,hopper_hold_inserts,daily_phone_number_call_limit,state_descriptions,script_tab_height,call_log_days,leave_3way_stop_recording,manual_minimum_ring_seconds,manual_minimum_attempt_seconds,manual_minimum_answer_seconds,khomp_settings_container,stereo_recording,stereo_rec_filename,stereo_parallel_recording,recording_dtmf_muting,stereo_recording_agent,parallel_rec_co_filename,parallel_rec_cm_filename,parallel_rec_fr_filename from vicidial_campaigns where campaign_id='$source_campaign_id';"; $rslt=mysql_to_mysqli($stmt, $link); $affected_rows = mysqli_affected_rows($link); @@ -13720,7 +13756,7 @@ function ajax_logout_now() if (strlen($group_color) > 7) {$group_color = substr($group_color,0,7);} while (strlen($group_color) < 7) {$group_color .= '0';} } - $stmt="INSERT INTO vicidial_inbound_groups (group_id,group_name,group_color,active,web_form_address,voicemail_ext,next_agent_call,fronter_display,ingroup_script,get_call_launch,xferconf_a_dtmf,xferconf_a_number,xferconf_b_dtmf,xferconf_b_number,drop_call_seconds,drop_action,drop_exten,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,default_xfer_group,queue_priority,drop_inbound_group,ingroup_recording_override,ingroup_rec_filename,afterhours_xfer_group,qc_enabled,qc_statuses,qc_shift_id,qc_get_record_launch,qc_show_recording,qc_web_form_address,qc_script,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,answer_sec_pct_rt_stat_one,answer_sec_pct_rt_stat_two,default_group_alias,no_agent_no_queue,no_agent_action,no_agent_action_value,web_form_address_two,timer_action,timer_action_message,timer_action_seconds,start_call_url,dispo_call_url,xferconf_c_number,xferconf_d_number,xferconf_e_number,ignore_list_script_override,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,timer_action_destination,calculate_estimated_hold_seconds,add_lead_url,eht_minimum_prompt_filename,eht_minimum_prompt_no_block,eht_minimum_prompt_seconds,on_hook_ring_time,na_call_url,on_hook_cid,action_xfer_cid,drop_callmenu,after_hours_callmenu,user_group,max_calls_method,max_calls_count,max_calls_action,dial_ingroup_cid,group_handling,web_form_address_three,populate_lead_ingroup,drop_lead_reset,after_hours_lead_reset,nanq_lead_reset,wait_time_lead_reset,hold_time_lead_reset,status_group_id,routing_initiated_recordings,on_hook_cid_number,customer_chat_screen_colors,customer_chat_survey_link,customer_chat_survey_text,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,inbound_survey_question_filename,inbound_survey_callmenu,icbq_expiration_hours,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,icbq_call_time_id,add_lead_timezone,icbq_dial_filter,populate_lead_source,populate_lead_vendor,park_file_name,waiting_call_url_on,waiting_call_url_off,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,ingroup_script_two,browser_alert_sound,browser_alert_volume,answer_signal,no_agent_delay,agent_search_method,qc_scorecard_id,qc_statuses_id,populate_lead_comments,drop_call_seconds_override,populate_lead_owner,in_queue_nanque,in_queue_nanque_exceptions,custom_one,custom_two,custom_three,custom_four,custom_five,second_alert_trigger,second_alert_trigger_seconds,second_alert_filename,second_alert_delay,second_alert_container,second_alert_only,third_alert_trigger,third_alert_trigger_seconds,third_alert_filename,third_alert_delay,third_alert_container,third_alert_only,agent_search_list,state_descriptions) SELECT \"$group_id\",\"$group_name\",group_color,\"N\",web_form_address,voicemail_ext,next_agent_call,fronter_display,ingroup_script,get_call_launch,xferconf_a_dtmf,xferconf_a_number,xferconf_b_dtmf,xferconf_b_number,drop_call_seconds,drop_action,drop_exten,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,default_xfer_group,queue_priority,drop_inbound_group,ingroup_recording_override,ingroup_rec_filename,afterhours_xfer_group,qc_enabled,qc_statuses,qc_shift_id,qc_get_record_launch,qc_show_recording,qc_web_form_address,qc_script,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,answer_sec_pct_rt_stat_one,answer_sec_pct_rt_stat_two,default_group_alias,no_agent_no_queue,no_agent_action,no_agent_action_value,web_form_address_two,timer_action,timer_action_message,timer_action_seconds,start_call_url,dispo_call_url,xferconf_c_number,xferconf_d_number,xferconf_e_number,ignore_list_script_override,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,timer_action_destination,calculate_estimated_hold_seconds,add_lead_url,eht_minimum_prompt_filename,eht_minimum_prompt_no_block,eht_minimum_prompt_seconds,on_hook_ring_time,na_call_url,on_hook_cid,action_xfer_cid,drop_callmenu,after_hours_callmenu,user_group,max_calls_method,max_calls_count,max_calls_action,dial_ingroup_cid,group_handling,web_form_address_three,populate_lead_ingroup,drop_lead_reset,after_hours_lead_reset,nanq_lead_reset,wait_time_lead_reset,hold_time_lead_reset,status_group_id,routing_initiated_recordings,on_hook_cid_number,customer_chat_screen_colors,customer_chat_survey_link,customer_chat_survey_text,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,inbound_survey_question_filename,inbound_survey_callmenu,icbq_expiration_hours,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,icbq_call_time_id,add_lead_timezone,icbq_dial_filter,populate_lead_source,populate_lead_vendor,park_file_name,waiting_call_url_on,waiting_call_url_off,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,ingroup_script_two,browser_alert_sound,browser_alert_volume,answer_signal,no_agent_delay,agent_search_method,qc_scorecard_id,qc_statuses_id,populate_lead_comments,drop_call_seconds_override,populate_lead_owner,in_queue_nanque,in_queue_nanque_exceptions,custom_one,custom_two,custom_three,custom_four,custom_five,second_alert_trigger,second_alert_trigger_seconds,second_alert_filename,second_alert_delay,second_alert_container,second_alert_only,third_alert_trigger,third_alert_trigger_seconds,third_alert_filename,third_alert_delay,third_alert_container,third_alert_only,agent_search_list,state_descriptions from vicidial_inbound_groups where group_id=\"$source_group_id\";"; + $stmt="INSERT INTO vicidial_inbound_groups (group_id,group_name,group_color,active,web_form_address,voicemail_ext,next_agent_call,fronter_display,ingroup_script,get_call_launch,xferconf_a_dtmf,xferconf_a_number,xferconf_b_dtmf,xferconf_b_number,drop_call_seconds,drop_action,drop_exten,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,default_xfer_group,queue_priority,drop_inbound_group,ingroup_recording_override,ingroup_rec_filename,afterhours_xfer_group,qc_enabled,qc_statuses,qc_shift_id,qc_get_record_launch,qc_show_recording,qc_web_form_address,qc_script,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,answer_sec_pct_rt_stat_one,answer_sec_pct_rt_stat_two,default_group_alias,no_agent_no_queue,no_agent_action,no_agent_action_value,web_form_address_two,timer_action,timer_action_message,timer_action_seconds,start_call_url,dispo_call_url,xferconf_c_number,xferconf_d_number,xferconf_e_number,ignore_list_script_override,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,timer_action_destination,calculate_estimated_hold_seconds,add_lead_url,eht_minimum_prompt_filename,eht_minimum_prompt_no_block,eht_minimum_prompt_seconds,on_hook_ring_time,na_call_url,on_hook_cid,action_xfer_cid,drop_callmenu,after_hours_callmenu,user_group,max_calls_method,max_calls_count,max_calls_action,dial_ingroup_cid,group_handling,web_form_address_three,populate_lead_ingroup,drop_lead_reset,after_hours_lead_reset,nanq_lead_reset,wait_time_lead_reset,hold_time_lead_reset,status_group_id,routing_initiated_recordings,on_hook_cid_number,customer_chat_screen_colors,customer_chat_survey_link,customer_chat_survey_text,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,inbound_survey_question_filename,inbound_survey_callmenu,icbq_expiration_hours,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,icbq_call_time_id,add_lead_timezone,icbq_dial_filter,populate_lead_source,populate_lead_vendor,park_file_name,waiting_call_url_on,waiting_call_url_off,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,ingroup_script_two,browser_alert_sound,browser_alert_volume,answer_signal,no_agent_delay,agent_search_method,qc_scorecard_id,qc_statuses_id,populate_lead_comments,drop_call_seconds_override,populate_lead_owner,in_queue_nanque,in_queue_nanque_exceptions,custom_one,custom_two,custom_three,custom_four,custom_five,second_alert_trigger,second_alert_trigger_seconds,second_alert_filename,second_alert_delay,second_alert_container,second_alert_only,third_alert_trigger,third_alert_trigger_seconds,third_alert_filename,third_alert_delay,third_alert_container,third_alert_only,agent_search_list,state_descriptions,stereo_recording,stereo_rec_filename,stereo_parallel_recording,recording_dtmf_muting,stereo_recording_agent,parallel_rec_co_filename,parallel_rec_cm_filename,parallel_rec_fr_filename) SELECT \"$group_id\",\"$group_name\",group_color,\"N\",web_form_address,voicemail_ext,next_agent_call,fronter_display,ingroup_script,get_call_launch,xferconf_a_dtmf,xferconf_a_number,xferconf_b_dtmf,xferconf_b_number,drop_call_seconds,drop_action,drop_exten,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,default_xfer_group,queue_priority,drop_inbound_group,ingroup_recording_override,ingroup_rec_filename,afterhours_xfer_group,qc_enabled,qc_statuses,qc_shift_id,qc_get_record_launch,qc_show_recording,qc_web_form_address,qc_script,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,answer_sec_pct_rt_stat_one,answer_sec_pct_rt_stat_two,default_group_alias,no_agent_no_queue,no_agent_action,no_agent_action_value,web_form_address_two,timer_action,timer_action_message,timer_action_seconds,start_call_url,dispo_call_url,xferconf_c_number,xferconf_d_number,xferconf_e_number,ignore_list_script_override,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,timer_action_destination,calculate_estimated_hold_seconds,add_lead_url,eht_minimum_prompt_filename,eht_minimum_prompt_no_block,eht_minimum_prompt_seconds,on_hook_ring_time,na_call_url,on_hook_cid,action_xfer_cid,drop_callmenu,after_hours_callmenu,user_group,max_calls_method,max_calls_count,max_calls_action,dial_ingroup_cid,group_handling,web_form_address_three,populate_lead_ingroup,drop_lead_reset,after_hours_lead_reset,nanq_lead_reset,wait_time_lead_reset,hold_time_lead_reset,status_group_id,routing_initiated_recordings,on_hook_cid_number,customer_chat_screen_colors,customer_chat_survey_link,customer_chat_survey_text,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,inbound_survey_question_filename,inbound_survey_callmenu,icbq_expiration_hours,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,icbq_call_time_id,add_lead_timezone,icbq_dial_filter,populate_lead_source,populate_lead_vendor,park_file_name,waiting_call_url_on,waiting_call_url_off,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,ingroup_script_two,browser_alert_sound,browser_alert_volume,answer_signal,no_agent_delay,agent_search_method,qc_scorecard_id,qc_statuses_id,populate_lead_comments,drop_call_seconds_override,populate_lead_owner,in_queue_nanque,in_queue_nanque_exceptions,custom_one,custom_two,custom_three,custom_four,custom_five,second_alert_trigger,second_alert_trigger_seconds,second_alert_filename,second_alert_delay,second_alert_container,second_alert_only,third_alert_trigger,third_alert_trigger_seconds,third_alert_filename,third_alert_delay,third_alert_container,third_alert_only,agent_search_list,state_descriptions,stereo_recording,stereo_rec_filename,stereo_parallel_recording,recording_dtmf_muting,stereo_recording_agent,parallel_rec_co_filename,parallel_rec_cm_filename,parallel_rec_fr_filename from vicidial_inbound_groups where group_id=\"$source_group_id\";"; $rslt=mysql_to_mysqli($stmt, $link); $affected_rows = mysqli_affected_rows($link); @@ -17348,6 +17384,27 @@ function ajax_logout_now() } else { + if ($campaign_rec_filename == $stereo_rec_filename) + { + $stereo_rec_filename = "X".$stereo_rec_filename; + echo "
"._QXZ("Stereo Recording Filename identical to Recording Filename, so it has been appended ").": $stereo_rec_filename ($campaign_rec_filename)\n"; + } + if ( (strlen($parallel_rec_co_filename) > 0) and ( ($campaign_rec_filename == $parallel_rec_co_filename) or ($stereo_rec_filename == $parallel_rec_co_filename) or ($parallel_rec_cm_filename == $parallel_rec_co_filename) or ($parallel_rec_fr_filename == $parallel_rec_co_filename) ) ) + { + $parallel_rec_co_filename = "CO".$parallel_rec_co_filename; + echo "
"._QXZ("Parallel Customer-Only Recording Filename identical to another Recording Filename, so it has been appended ").": $parallel_rec_co_filename\n"; + } + if ( (strlen($parallel_rec_cm_filename) > 0) and ( ($campaign_rec_filename == $parallel_rec_cm_filename) or ($stereo_rec_filename == $parallel_rec_cm_filename) or ($parallel_rec_co_filename == $parallel_rec_cm_filename) or ($parallel_rec_fr_filename == $parallel_rec_cm_filename) ) ) + { + $parallel_rec_cm_filename = "CM".$parallel_rec_cm_filename; + echo "
"._QXZ("Parallel Customer-Muted Recording Filename identical to another Recording Filename, so it has been appended ").": $parallel_rec_cm_filename\n"; + } + if ( (strlen($parallel_rec_fr_filename) > 0) and ( ($campaign_rec_filename == $parallel_rec_fr_filename) or ($stereo_rec_filename == $parallel_rec_fr_filename) or ($parallel_rec_co_filename == $parallel_rec_fr_filename) or ($parallel_rec_cm_filename == $parallel_rec_fr_filename) ) ) + { + $parallel_rec_fr_filename = "FR".$parallel_rec_fr_filename; + echo "
"._QXZ("Parallel Full-Recording Recording Filename identical to another Recording Filename, so it has been appended ").": $parallel_rec_fr_filename\n"; + } + echo "
"._QXZ("CAMPAIGN MODIFIED").": $campaign_id\n"; if ( ($dial_method == 'MANUAL') or ($dial_method == 'INBOUND_MAN') ) @@ -17486,7 +17543,7 @@ function ajax_logout_now() if ($LOGmodify_dial_prefix > 0) {$prefixSQL = ",dial_prefix='$dial_prefix',manual_dial_prefix='$manual_dial_prefix',three_way_dial_prefix='$three_way_dial_prefix'";} - $stmtA="UPDATE vicidial_campaigns set campaign_name='$campaign_name',active='$active',dial_status_a='$dial_status_a',dial_status_b='$dial_status_b',dial_status_c='$dial_status_c',dial_status_d='$dial_status_d',dial_status_e='$dial_status_e',lead_order='$lead_order',allow_closers='$allow_closers',hopper_level='$hopper_level', auto_trim_hopper='$auto_trim_hopper', use_auto_hopper='$use_auto_hopper', auto_hopper_multi='$auto_hopper_multi', $adlSQL next_agent_call='$next_agent_call', local_call_time='$local_call_time', voicemail_ext='$voicemail_ext', dial_timeout='$dial_timeout', campaign_cid='$campaign_cid', campaign_vdad_exten='$campaign_vdad_exten', web_form_address='" . mysqli_real_escape_string($link, $web_form_address) . "', park_ext='$park_ext', park_file_name='$park_file_name', campaign_rec_exten='$campaign_rec_exten', campaign_recording='$campaign_recording', campaign_rec_filename='$campaign_rec_filename', campaign_script='$script_id', get_call_launch='$get_call_launch', am_message_exten='$am_message_exten', amd_send_to_vmx='$amd_send_to_vmx', xferconf_a_dtmf='$xferconf_a_dtmf',xferconf_a_number='$xferconf_a_number',xferconf_b_dtmf='$xferconf_b_dtmf',xferconf_b_number='$xferconf_b_number',lead_filter_id='$lead_filter_id',alt_number_dialing='$alt_number_dialing',scheduled_callbacks='$scheduled_callbacks',drop_action='$drop_action',drop_call_seconds='$drop_call_seconds',safe_harbor_exten='$safe_harbor_exten',wrapup_seconds='$wrapup_seconds',wrapup_message='$wrapup_message',closer_campaigns=$closer_campaignsSQL,use_internal_dnc='$use_internal_dnc',allcalls_delay='$allcalls_delay',omit_phone_code='$omit_phone_code',dial_method='$dial_method',available_only_ratio_tally='$available_only_ratio_tally',adaptive_dropped_percentage='$adaptive_dropped_percentage',adaptive_maximum_level='$adaptive_maximum_level',adaptive_latest_server_time='$adaptive_latest_server_time',adaptive_intensity='$adaptive_intensity',adaptive_dl_diff_target='$adaptive_dl_diff_target',concurrent_transfers='$concurrent_transfers',auto_alt_dial='$auto_alt_dial',agent_pause_codes_active='$agent_pause_codes_active',campaign_description='$campaign_description',campaign_changedate='$SQLdate',campaign_stats_refresh='$campaign_stats_refresh',disable_alter_custdata='$disable_alter_custdata',no_hopper_leads_logins='$no_hopper_leads_logins',list_order_mix='$list_order_mix',campaign_allow_inbound='$campaign_allow_inbound',manual_dial_list_id='$manual_dial_list_id',default_xfer_group='$default_xfer_group',xfer_groups='$XFERgroups_value',queue_priority='$queue_priority',drop_inbound_group='$drop_inbound_group',disable_alter_custphone='$disable_alter_custphone',display_queue_count='$display_queue_count',manual_dial_filter='$manual_dial_filter',agent_clipboard_copy='$agent_clipboard_copy',agent_extended_alt_dial='$agent_extended_alt_dial',use_campaign_dnc='$use_campaign_dnc',three_way_call_cid='$three_way_call_cid',web_form_target='$web_form_target',vtiger_search_category='$vtiger_search_category',vtiger_create_call_record='$vtiger_create_call_record',vtiger_create_lead_record='$vtiger_create_lead_record',vtiger_screen_login='$vtiger_screen_login',cpd_amd_action='$cpd_amd_action',agent_allow_group_alias='$agent_allow_group_alias',default_group_alias='$default_group_alias',vtiger_search_dead='$vtiger_search_dead',vtiger_status_call='$vtiger_status_call',drop_lockout_time='$drop_lockout_time',quick_transfer_button='$quick_transfer_button',prepopulate_transfer_preset='$prepopulate_transfer_preset',drop_rate_group='$drop_rate_group',view_calls_in_queue='$view_calls_in_queue',view_calls_in_queue_launch='$view_calls_in_queue_launch',grab_calls_in_queue='$grab_calls_in_queue',call_requeue_button='$call_requeue_button',pause_after_each_call='$pause_after_each_call',no_hopper_dialing='$no_hopper_dialing',agent_dial_owner_only='$agent_dial_owner_only',agent_display_dialable_leads='$agent_display_dialable_leads',web_form_address_two='" . mysqli_real_escape_string($link, $web_form_address_two) . "',waitforsilence_options='$waitforsilence_options',agent_select_territories='$agent_select_territories',crm_popup_login='$crm_popup_login',crm_login_address='" . mysqli_real_escape_string($link, $crm_login_address) . "',timer_action='$timer_action',timer_action_message='$timer_action_message',timer_action_seconds='$timer_action_seconds',start_call_url='" . mysqli_real_escape_string($link, $start_call_url) . "',dispo_call_url='" . mysqli_real_escape_string($link, $dispo_call_url) . "',xferconf_c_number='$xferconf_c_number',xferconf_d_number='$xferconf_d_number',xferconf_e_number='$xferconf_e_number',use_custom_cid='$use_custom_cid',scheduled_callbacks_alert='$scheduled_callbacks_alert',queuemetrics_callstatus_override='$queuemetrics_callstatus',extension_appended_cidname='$extension_appended_cidname',scheduled_callbacks_count='$scheduled_callbacks_count',manual_dial_override='$manual_dial_override',blind_monitor_warning='$blind_monitor_warning',blind_monitor_message='" . mysqli_real_escape_string($link, $blind_monitor_message) . "',blind_monitor_filename='$blind_monitor_filename',inbound_queue_no_dial='$inbound_queue_no_dial',timer_action_destination='$timer_action_destination',enable_xfer_presets='$enable_xfer_presets',hide_xfer_number_to_dial='$hide_xfer_number_to_dial',customer_3way_hangup_logging='$customer_3way_hangup_logging',customer_3way_hangup_seconds='$customer_3way_hangup_seconds',customer_3way_hangup_action='$customer_3way_hangup_action',ivr_park_call='$ivr_park_call',ivr_park_call_agi='$ivr_park_call_agi',manual_preview_dial='$manual_preview_dial',realtime_agent_time_stats='$realtime_agent_time_stats',api_manual_dial='$api_manual_dial',manual_dial_call_time_check='$manual_dial_call_time_check',lead_order_randomize='$lead_order_randomize',lead_order_secondary='$lead_order_secondary',per_call_notes='$per_call_notes',my_callback_option='$my_callback_option',agent_lead_search='$agent_lead_search',agent_lead_search_method='$agent_lead_search_method',queuemetrics_phone_environment='$queuemetrics_phone_environment',auto_pause_precall='$auto_pause_precall',auto_resume_precall='$auto_resume_precall',auto_pause_precall_code='$auto_pause_precall_code',manual_dial_cid='$manual_dial_cid',post_phone_time_diff_alert='$post_phone_time_diff_alert',custom_3way_button_transfer='$custom_3way_button_transfer',available_only_tally_threshold='$available_only_tally_threshold',available_only_tally_threshold_agents='$available_only_tally_threshold_agents',dial_level_threshold='$dial_level_threshold',dial_level_threshold_agents='$dial_level_threshold_agents',safe_harbor_audio='$safe_harbor_audio',safe_harbor_menu_id='$safe_harbor_menu_id',callback_days_limit='$callback_days_limit',dl_diff_target_method='$dl_diff_target_method',disable_dispo_screen='$disable_dispo_screen',disable_dispo_status='$disable_dispo_status',screen_labels='$screen_labels',status_display_fields='$status_display_fields',na_call_url='" . mysqli_real_escape_string($link, $na_call_url) . "',pllb_grouping='$pllb_grouping',pllb_grouping_limit='$pllb_grouping_limit',call_count_limit='$call_count_limit',call_count_target='$call_count_target',callback_hours_block='$callback_hours_block',callback_list_calltime='$callback_list_calltime',user_group='$user_group',hopper_vlc_dup_check='$hopper_vlc_dup_check',in_group_dial='$in_group_dial',in_group_dial_select='$in_group_dial_select',safe_harbor_audio_field='$safe_harbor_audio_field',pause_after_next_call='$pause_after_next_call',owner_populate='$owner_populate',use_other_campaign_dnc='$use_other_campaign_dnc',allow_emails='$allow_emails',allow_chats='$allow_chats',amd_inbound_group='$amd_inbound_group',amd_callmenu='$amd_callmenu',manual_dial_lead_id='$manual_dial_lead_id',dead_max='$dead_max',dispo_max='$dispo_max',pause_max='$pause_max',dead_max_dispo='$dead_max_dispo',dispo_max_dispo='$dispo_max_dispo',max_inbound_calls='$max_inbound_calls',manual_dial_search_checkbox='$manual_dial_search_checkbox',hide_call_log_info='$hide_call_log_info',timer_alt_seconds='$timer_alt_seconds',wrapup_bypass='$wrapup_bypass',wrapup_after_hotkey='$wrapup_after_hotkey',callback_active_limit='$callback_active_limit',callback_active_limit_override='$callback_active_limit_override',comments_all_tabs='$comments_all_tabs',comments_dispo_screen='$comments_dispo_screen',comments_callback_screen='$comments_callback_screen',qc_comment_history='$qc_comment_history',show_previous_callback='$show_previous_callback',clear_script='$clear_script',cpd_unknown_action='$cpd_unknown_action',manual_dial_search_filter='$manual_dial_search_filter',web_form_address_three='" . mysqli_real_escape_string($link, $web_form_address_three) . "',manual_dial_override_field='$manual_dial_override_field',status_display_ingroup='$status_display_ingroup',customer_gone_seconds='$customer_gone_seconds',agent_display_fields='$agent_display_fields',am_message_wildcards='$am_message_wildcards',manual_dial_timeout='$manual_dial_timeout',routing_initiated_recordings='$routing_initiated_recordings',manual_dial_hopper_check='$manual_dial_hopper_check',callback_useronly_move_minutes='$callback_useronly_move_minutes',ofcom_uk_drop_calc='$ofcom_uk_drop_calc',manual_auto_next='$manual_auto_next',manual_auto_show='$manual_auto_show',allow_required_fields='$allow_required_fields',dead_to_dispo='$dead_to_dispo',agent_xfer_validation='$agent_xfer_validation',ready_max_logout='$ready_max_logout',callback_display_days='$callback_display_days',three_way_record_stop='$three_way_record_stop',hangup_xfer_record_start='$hangup_xfer_record_start',scheduled_callbacks_email_alert='$scheduled_callbacks_email_alert',max_inbound_calls_outcome='$max_inbound_calls_outcome',manual_auto_next_options='$manual_auto_next_options',agent_screen_time_display='$agent_screen_time_display',next_dial_my_callbacks='$next_dial_my_callbacks',inbound_no_agents_no_dial_container='$inbound_no_agents_no_dial_container',inbound_no_agents_no_dial_threshold='$inbound_no_agents_no_dial_threshold',cid_group_id='$cid_group_id',pause_max_dispo='$pause_max_dispo',script_top_dispo='$script_top_dispo',dead_trigger_seconds='$dead_trigger_seconds',dead_trigger_action='$dead_trigger_action',dead_trigger_repeat='$dead_trigger_repeat',dead_trigger_filename='$dead_trigger_filename',dead_trigger_url='" . mysqli_real_escape_string($link, $dead_trigger_url) . "',scheduled_callbacks_force_dial='$scheduled_callbacks_force_dial',scheduled_callbacks_auto_reschedule='$scheduled_callbacks_auto_reschedule',scheduled_callbacks_timezones_container='$scheduled_callbacks_timezones_container',three_way_volume_buttons='$three_way_volume_buttons',callback_dnc='$callback_dnc',manual_dial_validation='$manual_dial_validation',mute_recordings='$mute_recordings',auto_active_list_new='$auto_active_list_new',call_quota_lead_ranking='$call_quota_lead_ranking',sip_event_logging='$sip_event_logging',campaign_script_two='$campaign_script_two',leave_vm_no_dispo='$leave_vm_no_dispo',leave_vm_message_group_id='$leave_vm_message_group_id',dial_timeout_lead_container='$dial_timeout_lead_container',amd_type='$amd_type',vmm_daily_limit='$vmm_daily_limit',opensips_cid_name='$opensips_cid_name',amd_agent_route_options='$amd_agent_route_options',browser_alert_sound='$browser_alert_sound',browser_alert_volume='$browser_alert_volume',three_way_record_stop_exception='$three_way_record_stop_exception',pause_max_exceptions='$pause_max_exceptions',daily_call_count_limit='$daily_call_count_limit',daily_limit_manual='$daily_limit_manual',transfer_button_launch='$transfer_button_launch',shared_dial_rank='$shared_dial_rank',agent_search_method='$agent_search_method',clear_form='$clear_form',leave_3way_start_recording='$leave_3way_start_recording',leave_3way_start_recording_exception='$leave_3way_start_recording_exception',calls_waiting_vl_one='$calls_waiting_vl_one',calls_waiting_vl_two='$calls_waiting_vl_two',calls_inqueue_count_one='$calls_inqueue_count_one',calls_inqueue_count_two='$calls_inqueue_count_two',in_man_dial_next_ready_seconds='$in_man_dial_next_ready_seconds',in_man_dial_next_ready_seconds_override='$in_man_dial_next_ready_seconds_override',transfer_no_dispo='$transfer_no_dispo',call_limit_24hour_method='$call_limit_24hour_method',call_limit_24hour_scope='$call_limit_24hour_scope',call_limit_24hour='$call_limit_24hour',call_limit_24hour_override='$call_limit_24hour_override',cid_group_id_two='$cid_group_id_two',incall_tally_threshold_seconds='$incall_tally_threshold_seconds',auto_alt_threshold='$auto_alt_threshold',pause_max_url='$pause_max_url',agent_hide_hangup='$agent_hide_hangup',ig_xfer_list_sort='$ig_xfer_list_sort',script_tab_frame_size='$script_tab_frame_size',max_logged_in_agents='$max_logged_in_agents',user_group_script='$user_group_script',agent_hangup_route='$agent_hangup_route',agent_hangup_value='$agent_hangup_value',agent_hangup_ig_override='$agent_hangup_ig_override',show_confetti='$show_confetti',demographic_quotas='$demographic_quotas',demographic_quotas_container='$demographic_quotas_container',demographic_quotas_rerank='$demographic_quotas_rerank',demographic_quotas_list_resets='$demographic_quotas_list_resets',custom_one='$custom_one',custom_two='$custom_two',custom_three='$custom_three',custom_four='$custom_four',custom_five='$custom_five',dead_stop_recording='$dead_stop_recording',manual_vm_status_updates='$manual_vm_status_updates',force_per_call_notes='$force_per_call_notes',agent_search_ingroup_list='$agent_search_ingroup_list',hopper_hold_inserts='$hopper_hold_inserts',daily_phone_number_call_limit='$daily_phone_number_call_limit',state_descriptions='$state_descriptions',script_tab_height='$script_tab_height',call_log_days='$call_log_days',leave_3way_stop_recording='$leave_3way_stop_recording',manual_minimum_ring_seconds='$manual_minimum_ring_seconds',manual_minimum_attempt_seconds='$manual_minimum_attempt_seconds',manual_minimum_answer_seconds='$manual_minimum_answer_seconds',khomp_settings_container='$khomp_settings_container' $prefixSQL $hdrtSQL where campaign_id='$campaign_id';"; + $stmtA="UPDATE vicidial_campaigns set campaign_name='$campaign_name',active='$active',dial_status_a='$dial_status_a',dial_status_b='$dial_status_b',dial_status_c='$dial_status_c',dial_status_d='$dial_status_d',dial_status_e='$dial_status_e',lead_order='$lead_order',allow_closers='$allow_closers',hopper_level='$hopper_level', auto_trim_hopper='$auto_trim_hopper', use_auto_hopper='$use_auto_hopper', auto_hopper_multi='$auto_hopper_multi', $adlSQL next_agent_call='$next_agent_call', local_call_time='$local_call_time', voicemail_ext='$voicemail_ext', dial_timeout='$dial_timeout', campaign_cid='$campaign_cid', campaign_vdad_exten='$campaign_vdad_exten', web_form_address='" . mysqli_real_escape_string($link, $web_form_address) . "', park_ext='$park_ext', park_file_name='$park_file_name', campaign_rec_exten='$campaign_rec_exten', campaign_recording='$campaign_recording', campaign_rec_filename='$campaign_rec_filename', campaign_script='$script_id', get_call_launch='$get_call_launch', am_message_exten='$am_message_exten', amd_send_to_vmx='$amd_send_to_vmx', xferconf_a_dtmf='$xferconf_a_dtmf',xferconf_a_number='$xferconf_a_number',xferconf_b_dtmf='$xferconf_b_dtmf',xferconf_b_number='$xferconf_b_number',lead_filter_id='$lead_filter_id',alt_number_dialing='$alt_number_dialing',scheduled_callbacks='$scheduled_callbacks',drop_action='$drop_action',drop_call_seconds='$drop_call_seconds',safe_harbor_exten='$safe_harbor_exten',wrapup_seconds='$wrapup_seconds',wrapup_message='$wrapup_message',closer_campaigns=$closer_campaignsSQL,use_internal_dnc='$use_internal_dnc',allcalls_delay='$allcalls_delay',omit_phone_code='$omit_phone_code',dial_method='$dial_method',available_only_ratio_tally='$available_only_ratio_tally',adaptive_dropped_percentage='$adaptive_dropped_percentage',adaptive_maximum_level='$adaptive_maximum_level',adaptive_latest_server_time='$adaptive_latest_server_time',adaptive_intensity='$adaptive_intensity',adaptive_dl_diff_target='$adaptive_dl_diff_target',concurrent_transfers='$concurrent_transfers',auto_alt_dial='$auto_alt_dial',agent_pause_codes_active='$agent_pause_codes_active',campaign_description='$campaign_description',campaign_changedate='$SQLdate',campaign_stats_refresh='$campaign_stats_refresh',disable_alter_custdata='$disable_alter_custdata',no_hopper_leads_logins='$no_hopper_leads_logins',list_order_mix='$list_order_mix',campaign_allow_inbound='$campaign_allow_inbound',manual_dial_list_id='$manual_dial_list_id',default_xfer_group='$default_xfer_group',xfer_groups='$XFERgroups_value',queue_priority='$queue_priority',drop_inbound_group='$drop_inbound_group',disable_alter_custphone='$disable_alter_custphone',display_queue_count='$display_queue_count',manual_dial_filter='$manual_dial_filter',agent_clipboard_copy='$agent_clipboard_copy',agent_extended_alt_dial='$agent_extended_alt_dial',use_campaign_dnc='$use_campaign_dnc',three_way_call_cid='$three_way_call_cid',web_form_target='$web_form_target',vtiger_search_category='$vtiger_search_category',vtiger_create_call_record='$vtiger_create_call_record',vtiger_create_lead_record='$vtiger_create_lead_record',vtiger_screen_login='$vtiger_screen_login',cpd_amd_action='$cpd_amd_action',agent_allow_group_alias='$agent_allow_group_alias',default_group_alias='$default_group_alias',vtiger_search_dead='$vtiger_search_dead',vtiger_status_call='$vtiger_status_call',drop_lockout_time='$drop_lockout_time',quick_transfer_button='$quick_transfer_button',prepopulate_transfer_preset='$prepopulate_transfer_preset',drop_rate_group='$drop_rate_group',view_calls_in_queue='$view_calls_in_queue',view_calls_in_queue_launch='$view_calls_in_queue_launch',grab_calls_in_queue='$grab_calls_in_queue',call_requeue_button='$call_requeue_button',pause_after_each_call='$pause_after_each_call',no_hopper_dialing='$no_hopper_dialing',agent_dial_owner_only='$agent_dial_owner_only',agent_display_dialable_leads='$agent_display_dialable_leads',web_form_address_two='" . mysqli_real_escape_string($link, $web_form_address_two) . "',waitforsilence_options='$waitforsilence_options',agent_select_territories='$agent_select_territories',crm_popup_login='$crm_popup_login',crm_login_address='" . mysqli_real_escape_string($link, $crm_login_address) . "',timer_action='$timer_action',timer_action_message='$timer_action_message',timer_action_seconds='$timer_action_seconds',start_call_url='" . mysqli_real_escape_string($link, $start_call_url) . "',dispo_call_url='" . mysqli_real_escape_string($link, $dispo_call_url) . "',xferconf_c_number='$xferconf_c_number',xferconf_d_number='$xferconf_d_number',xferconf_e_number='$xferconf_e_number',use_custom_cid='$use_custom_cid',scheduled_callbacks_alert='$scheduled_callbacks_alert',queuemetrics_callstatus_override='$queuemetrics_callstatus',extension_appended_cidname='$extension_appended_cidname',scheduled_callbacks_count='$scheduled_callbacks_count',manual_dial_override='$manual_dial_override',blind_monitor_warning='$blind_monitor_warning',blind_monitor_message='" . mysqli_real_escape_string($link, $blind_monitor_message) . "',blind_monitor_filename='$blind_monitor_filename',inbound_queue_no_dial='$inbound_queue_no_dial',timer_action_destination='$timer_action_destination',enable_xfer_presets='$enable_xfer_presets',hide_xfer_number_to_dial='$hide_xfer_number_to_dial',customer_3way_hangup_logging='$customer_3way_hangup_logging',customer_3way_hangup_seconds='$customer_3way_hangup_seconds',customer_3way_hangup_action='$customer_3way_hangup_action',ivr_park_call='$ivr_park_call',ivr_park_call_agi='$ivr_park_call_agi',manual_preview_dial='$manual_preview_dial',realtime_agent_time_stats='$realtime_agent_time_stats',api_manual_dial='$api_manual_dial',manual_dial_call_time_check='$manual_dial_call_time_check',lead_order_randomize='$lead_order_randomize',lead_order_secondary='$lead_order_secondary',per_call_notes='$per_call_notes',my_callback_option='$my_callback_option',agent_lead_search='$agent_lead_search',agent_lead_search_method='$agent_lead_search_method',queuemetrics_phone_environment='$queuemetrics_phone_environment',auto_pause_precall='$auto_pause_precall',auto_resume_precall='$auto_resume_precall',auto_pause_precall_code='$auto_pause_precall_code',manual_dial_cid='$manual_dial_cid',post_phone_time_diff_alert='$post_phone_time_diff_alert',custom_3way_button_transfer='$custom_3way_button_transfer',available_only_tally_threshold='$available_only_tally_threshold',available_only_tally_threshold_agents='$available_only_tally_threshold_agents',dial_level_threshold='$dial_level_threshold',dial_level_threshold_agents='$dial_level_threshold_agents',safe_harbor_audio='$safe_harbor_audio',safe_harbor_menu_id='$safe_harbor_menu_id',callback_days_limit='$callback_days_limit',dl_diff_target_method='$dl_diff_target_method',disable_dispo_screen='$disable_dispo_screen',disable_dispo_status='$disable_dispo_status',screen_labels='$screen_labels',status_display_fields='$status_display_fields',na_call_url='" . mysqli_real_escape_string($link, $na_call_url) . "',pllb_grouping='$pllb_grouping',pllb_grouping_limit='$pllb_grouping_limit',call_count_limit='$call_count_limit',call_count_target='$call_count_target',callback_hours_block='$callback_hours_block',callback_list_calltime='$callback_list_calltime',user_group='$user_group',hopper_vlc_dup_check='$hopper_vlc_dup_check',in_group_dial='$in_group_dial',in_group_dial_select='$in_group_dial_select',safe_harbor_audio_field='$safe_harbor_audio_field',pause_after_next_call='$pause_after_next_call',owner_populate='$owner_populate',use_other_campaign_dnc='$use_other_campaign_dnc',allow_emails='$allow_emails',allow_chats='$allow_chats',amd_inbound_group='$amd_inbound_group',amd_callmenu='$amd_callmenu',manual_dial_lead_id='$manual_dial_lead_id',dead_max='$dead_max',dispo_max='$dispo_max',pause_max='$pause_max',dead_max_dispo='$dead_max_dispo',dispo_max_dispo='$dispo_max_dispo',max_inbound_calls='$max_inbound_calls',manual_dial_search_checkbox='$manual_dial_search_checkbox',hide_call_log_info='$hide_call_log_info',timer_alt_seconds='$timer_alt_seconds',wrapup_bypass='$wrapup_bypass',wrapup_after_hotkey='$wrapup_after_hotkey',callback_active_limit='$callback_active_limit',callback_active_limit_override='$callback_active_limit_override',comments_all_tabs='$comments_all_tabs',comments_dispo_screen='$comments_dispo_screen',comments_callback_screen='$comments_callback_screen',qc_comment_history='$qc_comment_history',show_previous_callback='$show_previous_callback',clear_script='$clear_script',cpd_unknown_action='$cpd_unknown_action',manual_dial_search_filter='$manual_dial_search_filter',web_form_address_three='" . mysqli_real_escape_string($link, $web_form_address_three) . "',manual_dial_override_field='$manual_dial_override_field',status_display_ingroup='$status_display_ingroup',customer_gone_seconds='$customer_gone_seconds',agent_display_fields='$agent_display_fields',am_message_wildcards='$am_message_wildcards',manual_dial_timeout='$manual_dial_timeout',routing_initiated_recordings='$routing_initiated_recordings',manual_dial_hopper_check='$manual_dial_hopper_check',callback_useronly_move_minutes='$callback_useronly_move_minutes',ofcom_uk_drop_calc='$ofcom_uk_drop_calc',manual_auto_next='$manual_auto_next',manual_auto_show='$manual_auto_show',allow_required_fields='$allow_required_fields',dead_to_dispo='$dead_to_dispo',agent_xfer_validation='$agent_xfer_validation',ready_max_logout='$ready_max_logout',callback_display_days='$callback_display_days',three_way_record_stop='$three_way_record_stop',hangup_xfer_record_start='$hangup_xfer_record_start',scheduled_callbacks_email_alert='$scheduled_callbacks_email_alert',max_inbound_calls_outcome='$max_inbound_calls_outcome',manual_auto_next_options='$manual_auto_next_options',agent_screen_time_display='$agent_screen_time_display',next_dial_my_callbacks='$next_dial_my_callbacks',inbound_no_agents_no_dial_container='$inbound_no_agents_no_dial_container',inbound_no_agents_no_dial_threshold='$inbound_no_agents_no_dial_threshold',cid_group_id='$cid_group_id',pause_max_dispo='$pause_max_dispo',script_top_dispo='$script_top_dispo',dead_trigger_seconds='$dead_trigger_seconds',dead_trigger_action='$dead_trigger_action',dead_trigger_repeat='$dead_trigger_repeat',dead_trigger_filename='$dead_trigger_filename',dead_trigger_url='" . mysqli_real_escape_string($link, $dead_trigger_url) . "',scheduled_callbacks_force_dial='$scheduled_callbacks_force_dial',scheduled_callbacks_auto_reschedule='$scheduled_callbacks_auto_reschedule',scheduled_callbacks_timezones_container='$scheduled_callbacks_timezones_container',three_way_volume_buttons='$three_way_volume_buttons',callback_dnc='$callback_dnc',manual_dial_validation='$manual_dial_validation',mute_recordings='$mute_recordings',auto_active_list_new='$auto_active_list_new',call_quota_lead_ranking='$call_quota_lead_ranking',sip_event_logging='$sip_event_logging',campaign_script_two='$campaign_script_two',leave_vm_no_dispo='$leave_vm_no_dispo',leave_vm_message_group_id='$leave_vm_message_group_id',dial_timeout_lead_container='$dial_timeout_lead_container',amd_type='$amd_type',vmm_daily_limit='$vmm_daily_limit',opensips_cid_name='$opensips_cid_name',amd_agent_route_options='$amd_agent_route_options',browser_alert_sound='$browser_alert_sound',browser_alert_volume='$browser_alert_volume',three_way_record_stop_exception='$three_way_record_stop_exception',pause_max_exceptions='$pause_max_exceptions',daily_call_count_limit='$daily_call_count_limit',daily_limit_manual='$daily_limit_manual',transfer_button_launch='$transfer_button_launch',shared_dial_rank='$shared_dial_rank',agent_search_method='$agent_search_method',clear_form='$clear_form',leave_3way_start_recording='$leave_3way_start_recording',leave_3way_start_recording_exception='$leave_3way_start_recording_exception',calls_waiting_vl_one='$calls_waiting_vl_one',calls_waiting_vl_two='$calls_waiting_vl_two',calls_inqueue_count_one='$calls_inqueue_count_one',calls_inqueue_count_two='$calls_inqueue_count_two',in_man_dial_next_ready_seconds='$in_man_dial_next_ready_seconds',in_man_dial_next_ready_seconds_override='$in_man_dial_next_ready_seconds_override',transfer_no_dispo='$transfer_no_dispo',call_limit_24hour_method='$call_limit_24hour_method',call_limit_24hour_scope='$call_limit_24hour_scope',call_limit_24hour='$call_limit_24hour',call_limit_24hour_override='$call_limit_24hour_override',cid_group_id_two='$cid_group_id_two',incall_tally_threshold_seconds='$incall_tally_threshold_seconds',auto_alt_threshold='$auto_alt_threshold',pause_max_url='$pause_max_url',agent_hide_hangup='$agent_hide_hangup',ig_xfer_list_sort='$ig_xfer_list_sort',script_tab_frame_size='$script_tab_frame_size',max_logged_in_agents='$max_logged_in_agents',user_group_script='$user_group_script',agent_hangup_route='$agent_hangup_route',agent_hangup_value='$agent_hangup_value',agent_hangup_ig_override='$agent_hangup_ig_override',show_confetti='$show_confetti',demographic_quotas='$demographic_quotas',demographic_quotas_container='$demographic_quotas_container',demographic_quotas_rerank='$demographic_quotas_rerank',demographic_quotas_list_resets='$demographic_quotas_list_resets',custom_one='$custom_one',custom_two='$custom_two',custom_three='$custom_three',custom_four='$custom_four',custom_five='$custom_five',dead_stop_recording='$dead_stop_recording',manual_vm_status_updates='$manual_vm_status_updates',force_per_call_notes='$force_per_call_notes',agent_search_ingroup_list='$agent_search_ingroup_list',hopper_hold_inserts='$hopper_hold_inserts',daily_phone_number_call_limit='$daily_phone_number_call_limit',state_descriptions='$state_descriptions',script_tab_height='$script_tab_height',call_log_days='$call_log_days',leave_3way_stop_recording='$leave_3way_stop_recording',manual_minimum_ring_seconds='$manual_minimum_ring_seconds',manual_minimum_attempt_seconds='$manual_minimum_attempt_seconds',manual_minimum_answer_seconds='$manual_minimum_answer_seconds',khomp_settings_container='$khomp_settings_container',stereo_recording='$stereo_recording',stereo_rec_filename='$stereo_rec_filename',stereo_parallel_recording='$stereo_parallel_recording',recording_dtmf_muting='$recording_dtmf_muting',stereo_recording_agent='$stereo_recording_agent',parallel_rec_co_filename='$parallel_rec_co_filename',parallel_rec_cm_filename='$parallel_rec_cm_filename',parallel_rec_fr_filename='$parallel_rec_fr_filename' $prefixSQL $hdrtSQL where campaign_id='$campaign_id';"; if ($DB) {echo "|$stmt|\n";} $rslt=mysql_to_mysqli($stmtA, $link); @@ -18717,10 +18774,30 @@ function ajax_logout_now() { $areacode_filter_action_value = preg_replace('/[^-\/\|\_\#\*\,\.\_0-9\p{L}]/u','',$areacode_filter_action_value); } + if ($ingroup_rec_filename == $stereo_rec_filename) + { + $stereo_rec_filename = "X".$stereo_rec_filename; + echo "
"._QXZ("Stereo Recording Filename identical to Recording Filename, so it has been appended ").": $stereo_rec_filename ($ingroup_rec_filename)\n"; + } + if ( (strlen($parallel_rec_co_filename) > 0) and ( ($ingroup_rec_filename == $parallel_rec_co_filename) or ($stereo_rec_filename == $parallel_rec_co_filename) or ($parallel_rec_cm_filename == $parallel_rec_co_filename) or ($parallel_rec_fr_filename == $parallel_rec_co_filename) ) ) + { + $parallel_rec_co_filename = "CO".$parallel_rec_co_filename; + echo "
"._QXZ("Parallel Customer-Only Recording Filename identical to another Recording Filename, so it has been appended ").": $parallel_rec_co_filename\n"; + } + if ( (strlen($parallel_rec_cm_filename) > 0) and ( ($ingroup_rec_filename == $parallel_rec_cm_filename) or ($stereo_rec_filename == $parallel_rec_cm_filename) or ($parallel_rec_co_filename == $parallel_rec_cm_filename) or ($parallel_rec_fr_filename == $parallel_rec_cm_filename) ) ) + { + $parallel_rec_cm_filename = "CM".$parallel_rec_cm_filename; + echo "
"._QXZ("Parallel Customer-Muted Recording Filename identical to another Recording Filename, so it has been appended ").": $parallel_rec_cm_filename\n"; + } + if ( (strlen($parallel_rec_fr_filename) > 0) and ( ($ingroup_rec_filename == $parallel_rec_fr_filename) or ($stereo_rec_filename == $parallel_rec_fr_filename) or ($parallel_rec_co_filename == $parallel_rec_fr_filename) or ($parallel_rec_cm_filename == $parallel_rec_fr_filename) ) ) + { + $parallel_rec_fr_filename = "FR".$parallel_rec_fr_filename; + echo "
"._QXZ("Parallel Full-Recording Recording Filename identical to another Recording Filename, so it has been appended ").": $parallel_rec_fr_filename\n"; + } echo "
"._QXZ("GROUP MODIFIED ").": $group_id\n"; - $stmt="UPDATE vicidial_inbound_groups set group_name='$group_name', group_color='$group_color', active='$active', web_form_address='" . mysqli_real_escape_string($link, $web_form_address) . "', voicemail_ext='$voicemail_ext', next_agent_call='$next_agent_call', fronter_display='$fronter_display', ingroup_script='$script_id', get_call_launch='$get_call_launch', group_handling='$group_handling', xferconf_a_dtmf='$xferconf_a_dtmf',xferconf_a_number='$xferconf_a_number', xferconf_b_dtmf='$xferconf_b_dtmf',xferconf_b_number='$xferconf_b_number',drop_action='$drop_action',drop_call_seconds='$drop_call_seconds',drop_exten='$drop_exten',call_time_id='$call_time_id',after_hours_action='$after_hours_action',after_hours_message_filename='$after_hours_message_filename',after_hours_exten='$after_hours_exten',after_hours_voicemail='$after_hours_voicemail',welcome_message_filename='$welcome_message_filename',moh_context='$moh_context',onhold_prompt_filename='$onhold_prompt_filename',prompt_interval='$prompt_interval',agent_alert_exten='$agent_alert_exten',agent_alert_delay='$agent_alert_delay',default_xfer_group='$default_xfer_group',queue_priority='$queue_priority',drop_inbound_group='$drop_inbound_group',ingroup_recording_override='$ingroup_recording_override',ingroup_rec_filename='$ingroup_rec_filename',afterhours_xfer_group='$afterhours_xfer_group',qc_enabled='$qc_enabled',qc_statuses='$QC_statuses',qc_shift_id='$qc_shift_id',qc_get_record_launch='$qc_get_record_launch',qc_show_recording='$qc_show_recording',qc_web_form_address='" . mysqli_real_escape_string($link, $qc_web_form_address) . "',qc_scorecard_id='$qc_scorecard_id',qc_script='$qc_script',play_place_in_line='$play_place_in_line',play_estimate_hold_time='$play_estimate_hold_time',hold_time_option='$hold_time_option',hold_time_option_seconds='$hold_time_option_seconds',hold_time_option_exten='$hold_time_option_exten',hold_time_option_voicemail='$hold_time_option_voicemail',hold_time_option_xfer_group='$hold_time_option_xfer_group',hold_time_option_callback_filename='$hold_time_option_callback_filename',hold_time_option_callback_list_id='$hold_time_option_callback_list_id',hold_recall_xfer_group='$hold_recall_xfer_group',no_delay_call_route='$no_delay_call_route',play_welcome_message='$play_welcome_message',answer_sec_pct_rt_stat_one='$answer_sec_pct_rt_stat_one',answer_sec_pct_rt_stat_two='$answer_sec_pct_rt_stat_two',default_group_alias='$default_group_alias',no_agent_no_queue='$no_agent_no_queue',no_agent_action='$no_agent_action',no_agent_action_value='$no_agent_action_value',web_form_address_two='" . mysqli_real_escape_string($link, $web_form_address_two) . "',timer_action='$timer_action',timer_action_message='$timer_action_message',timer_action_seconds='$timer_action_seconds',start_call_url='" . mysqli_real_escape_string($link, $start_call_url) . "',dispo_call_url='" . mysqli_real_escape_string($link, $dispo_call_url) . "',xferconf_c_number='$xferconf_c_number',xferconf_d_number='$xferconf_d_number',xferconf_e_number='$xferconf_e_number',ignore_list_script_override='$ignore_list_script_override',extension_appended_cidname='$extension_appended_cidname',uniqueid_status_display='$uniqueid_status_display',uniqueid_status_prefix='$uniqueid_status_prefix',hold_time_option_minimum='$hold_time_option_minimum',hold_time_option_press_filename='$hold_time_option_press_filename',hold_time_option_callmenu='$hold_time_option_callmenu',onhold_prompt_no_block='$onhold_prompt_no_block',onhold_prompt_seconds='$onhold_prompt_seconds',hold_time_option_no_block='$hold_time_option_no_block',hold_time_option_prompt_seconds='$hold_time_option_prompt_seconds',hold_time_second_option='$hold_time_second_option',hold_time_third_option='$hold_time_third_option',wait_hold_option_priority='$wait_hold_option_priority',wait_time_option='$wait_time_option',wait_time_second_option='$wait_time_second_option',wait_time_third_option='$wait_time_third_option',wait_time_option_seconds='$wait_time_option_seconds',wait_time_option_exten='$wait_time_option_exten',wait_time_option_voicemail='$wait_time_option_voicemail',wait_time_option_xfer_group='$wait_time_option_xfer_group',wait_time_option_callmenu='$wait_time_option_callmenu',wait_time_option_callback_filename='$wait_time_option_callback_filename',wait_time_option_callback_list_id='$wait_time_option_callback_list_id',wait_time_option_press_filename='$wait_time_option_press_filename',wait_time_option_no_block='$wait_time_option_no_block',wait_time_option_prompt_seconds='$wait_time_option_prompt_seconds',timer_action_destination='$timer_action_destination',calculate_estimated_hold_seconds='$calculate_estimated_hold_seconds',add_lead_url='" . mysqli_real_escape_string($link, $add_lead_url) . "',eht_minimum_prompt_filename='$eht_minimum_prompt_filename',eht_minimum_prompt_no_block='$eht_minimum_prompt_no_block',eht_minimum_prompt_seconds='$eht_minimum_prompt_seconds',on_hook_ring_time='$on_hook_ring_time',na_call_url='" . mysqli_real_escape_string($link, $na_call_url) . "',on_hook_cid='$on_hook_cid',action_xfer_cid='$action_xfer_cid',drop_callmenu='$drop_callmenu',after_hours_callmenu='$after_hours_callmenu',user_group='$user_group',max_calls_method='$max_calls_method',max_calls_count='$max_calls_count',max_calls_action='$max_calls_action',dial_ingroup_cid='$dial_ingroup_cid',web_form_address_three='" . mysqli_real_escape_string($link, $web_form_address_three) . "',populate_lead_ingroup='$populate_lead_ingroup',drop_lead_reset='$drop_lead_reset',after_hours_lead_reset='$after_hours_lead_reset',nanq_lead_reset='$nanq_lead_reset',wait_time_lead_reset='$wait_time_lead_reset',hold_time_lead_reset='$hold_time_lead_reset',status_group_id='$status_group_id',routing_initiated_recordings='$routing_initiated_recordings',on_hook_cid_number='$on_hook_cid_number',customer_chat_screen_colors='$customer_chat_screen_colors',customer_chat_survey_link='" . mysqli_real_escape_string($link, $customer_chat_survey_link) . "',customer_chat_survey_text='$customer_chat_survey_text',populate_lead_province='$populate_lead_province',areacode_filter='$areacode_filter',areacode_filter_seconds='$areacode_filter_seconds',areacode_filter_action='$areacode_filter_action',areacode_filter_action_value='$areacode_filter_action_value',populate_state_areacode='$populate_state_areacode',inbound_survey='$inbound_survey',inbound_survey_filename='$inbound_survey_filename',inbound_survey_accept_digit='$inbound_survey_accept_digit',inbound_survey_question_filename='$inbound_survey_question_filename',inbound_survey_callmenu='$inbound_survey_callmenu',icbq_expiration_hours='$icbq_expiration_hours',closing_time_action='$closing_time_action',closing_time_now_trigger='$closing_time_now_trigger',closing_time_filename='$closing_time_filename',closing_time_end_filename='$closing_time_end_filename',closing_time_lead_reset='$closing_time_lead_reset',closing_time_option_exten='$closing_time_option_exten',closing_time_option_callmenu='$closing_time_option_callmenu',closing_time_option_voicemail='$closing_time_option_voicemail',closing_time_option_xfer_group='$closing_time_option_xfer_group',closing_time_option_callback_list_id='$closing_time_option_callback_list_id',icbq_call_time_id='$icbq_call_time_id',add_lead_timezone='$add_lead_timezone',icbq_dial_filter='$icbq_dial_filter',populate_lead_source='$populate_lead_source',populate_lead_vendor='$populate_lead_vendor',park_file_name='$park_file_name',waiting_call_url_on='" . mysqli_real_escape_string($link, $waiting_call_url_on) . "',waiting_call_url_off='" . mysqli_real_escape_string($link, $waiting_call_url_off) . "',enter_ingroup_url='" . mysqli_real_escape_string($link, $enter_ingroup_url) . "',cid_cb_confirm_number='$cid_cb_confirm_number',cid_cb_invalid_filter_phone_group='$cid_cb_invalid_filter_phone_group',cid_cb_valid_length='$cid_cb_valid_length',cid_cb_valid_filename='$cid_cb_valid_filename',cid_cb_confirmed_filename='$cid_cb_confirmed_filename',cid_cb_enter_filename='$cid_cb_enter_filename',cid_cb_you_entered_filename='$cid_cb_you_entered_filename',cid_cb_press_to_confirm_filename='$cid_cb_press_to_confirm_filename',cid_cb_invalid_filename='$cid_cb_invalid_filename',cid_cb_reenter_filename='$cid_cb_reenter_filename',cid_cb_error_filename='$cid_cb_error_filename',place_in_line_caller_number_filename='$place_in_line_caller_number_filename',place_in_line_you_next_filename='$place_in_line_you_next_filename', ingroup_script_two='$ingroup_script_two',browser_alert_sound='$browser_alert_sound',browser_alert_volume='$browser_alert_volume',answer_signal='$answer_signal',qc_statuses_id='$qc_statuses_id',no_agent_delay='$no_agent_delay',agent_search_method='$agent_search_method',populate_lead_comments='$populate_lead_comments',drop_call_seconds_override='$drop_call_seconds_override',populate_lead_owner='$populate_lead_owner',in_queue_nanque='$in_queue_nanque',in_queue_nanque_exceptions='$in_queue_nanque_exceptions',custom_one='$custom_one',custom_two='$custom_two',custom_three='$custom_three',custom_four='$custom_four',custom_five='$custom_five',second_alert_trigger='$second_alert_trigger',second_alert_trigger_seconds='$second_alert_trigger_seconds',second_alert_filename='$second_alert_filename',second_alert_delay='$second_alert_delay',second_alert_container='$second_alert_container',second_alert_only='$second_alert_only',third_alert_trigger='$third_alert_trigger',third_alert_trigger_seconds='$third_alert_trigger_seconds',third_alert_filename='$third_alert_filename',third_alert_delay='$third_alert_delay',third_alert_container='$third_alert_container',third_alert_only='$third_alert_only',agent_search_list='$agent_search_list',state_descriptions='$state_descriptions' where group_id='$group_id';"; + $stmt="UPDATE vicidial_inbound_groups set group_name='$group_name', group_color='$group_color', active='$active', web_form_address='" . mysqli_real_escape_string($link, $web_form_address) . "', voicemail_ext='$voicemail_ext', next_agent_call='$next_agent_call', fronter_display='$fronter_display', ingroup_script='$script_id', get_call_launch='$get_call_launch', group_handling='$group_handling', xferconf_a_dtmf='$xferconf_a_dtmf',xferconf_a_number='$xferconf_a_number', xferconf_b_dtmf='$xferconf_b_dtmf',xferconf_b_number='$xferconf_b_number',drop_action='$drop_action',drop_call_seconds='$drop_call_seconds',drop_exten='$drop_exten',call_time_id='$call_time_id',after_hours_action='$after_hours_action',after_hours_message_filename='$after_hours_message_filename',after_hours_exten='$after_hours_exten',after_hours_voicemail='$after_hours_voicemail',welcome_message_filename='$welcome_message_filename',moh_context='$moh_context',onhold_prompt_filename='$onhold_prompt_filename',prompt_interval='$prompt_interval',agent_alert_exten='$agent_alert_exten',agent_alert_delay='$agent_alert_delay',default_xfer_group='$default_xfer_group',queue_priority='$queue_priority',drop_inbound_group='$drop_inbound_group',ingroup_recording_override='$ingroup_recording_override',ingroup_rec_filename='$ingroup_rec_filename',afterhours_xfer_group='$afterhours_xfer_group',qc_enabled='$qc_enabled',qc_statuses='$QC_statuses',qc_shift_id='$qc_shift_id',qc_get_record_launch='$qc_get_record_launch',qc_show_recording='$qc_show_recording',qc_web_form_address='" . mysqli_real_escape_string($link, $qc_web_form_address) . "',qc_scorecard_id='$qc_scorecard_id',qc_script='$qc_script',play_place_in_line='$play_place_in_line',play_estimate_hold_time='$play_estimate_hold_time',hold_time_option='$hold_time_option',hold_time_option_seconds='$hold_time_option_seconds',hold_time_option_exten='$hold_time_option_exten',hold_time_option_voicemail='$hold_time_option_voicemail',hold_time_option_xfer_group='$hold_time_option_xfer_group',hold_time_option_callback_filename='$hold_time_option_callback_filename',hold_time_option_callback_list_id='$hold_time_option_callback_list_id',hold_recall_xfer_group='$hold_recall_xfer_group',no_delay_call_route='$no_delay_call_route',play_welcome_message='$play_welcome_message',answer_sec_pct_rt_stat_one='$answer_sec_pct_rt_stat_one',answer_sec_pct_rt_stat_two='$answer_sec_pct_rt_stat_two',default_group_alias='$default_group_alias',no_agent_no_queue='$no_agent_no_queue',no_agent_action='$no_agent_action',no_agent_action_value='$no_agent_action_value',web_form_address_two='" . mysqli_real_escape_string($link, $web_form_address_two) . "',timer_action='$timer_action',timer_action_message='$timer_action_message',timer_action_seconds='$timer_action_seconds',start_call_url='" . mysqli_real_escape_string($link, $start_call_url) . "',dispo_call_url='" . mysqli_real_escape_string($link, $dispo_call_url) . "',xferconf_c_number='$xferconf_c_number',xferconf_d_number='$xferconf_d_number',xferconf_e_number='$xferconf_e_number',ignore_list_script_override='$ignore_list_script_override',extension_appended_cidname='$extension_appended_cidname',uniqueid_status_display='$uniqueid_status_display',uniqueid_status_prefix='$uniqueid_status_prefix',hold_time_option_minimum='$hold_time_option_minimum',hold_time_option_press_filename='$hold_time_option_press_filename',hold_time_option_callmenu='$hold_time_option_callmenu',onhold_prompt_no_block='$onhold_prompt_no_block',onhold_prompt_seconds='$onhold_prompt_seconds',hold_time_option_no_block='$hold_time_option_no_block',hold_time_option_prompt_seconds='$hold_time_option_prompt_seconds',hold_time_second_option='$hold_time_second_option',hold_time_third_option='$hold_time_third_option',wait_hold_option_priority='$wait_hold_option_priority',wait_time_option='$wait_time_option',wait_time_second_option='$wait_time_second_option',wait_time_third_option='$wait_time_third_option',wait_time_option_seconds='$wait_time_option_seconds',wait_time_option_exten='$wait_time_option_exten',wait_time_option_voicemail='$wait_time_option_voicemail',wait_time_option_xfer_group='$wait_time_option_xfer_group',wait_time_option_callmenu='$wait_time_option_callmenu',wait_time_option_callback_filename='$wait_time_option_callback_filename',wait_time_option_callback_list_id='$wait_time_option_callback_list_id',wait_time_option_press_filename='$wait_time_option_press_filename',wait_time_option_no_block='$wait_time_option_no_block',wait_time_option_prompt_seconds='$wait_time_option_prompt_seconds',timer_action_destination='$timer_action_destination',calculate_estimated_hold_seconds='$calculate_estimated_hold_seconds',add_lead_url='" . mysqli_real_escape_string($link, $add_lead_url) . "',eht_minimum_prompt_filename='$eht_minimum_prompt_filename',eht_minimum_prompt_no_block='$eht_minimum_prompt_no_block',eht_minimum_prompt_seconds='$eht_minimum_prompt_seconds',on_hook_ring_time='$on_hook_ring_time',na_call_url='" . mysqli_real_escape_string($link, $na_call_url) . "',on_hook_cid='$on_hook_cid',action_xfer_cid='$action_xfer_cid',drop_callmenu='$drop_callmenu',after_hours_callmenu='$after_hours_callmenu',user_group='$user_group',max_calls_method='$max_calls_method',max_calls_count='$max_calls_count',max_calls_action='$max_calls_action',dial_ingroup_cid='$dial_ingroup_cid',web_form_address_three='" . mysqli_real_escape_string($link, $web_form_address_three) . "',populate_lead_ingroup='$populate_lead_ingroup',drop_lead_reset='$drop_lead_reset',after_hours_lead_reset='$after_hours_lead_reset',nanq_lead_reset='$nanq_lead_reset',wait_time_lead_reset='$wait_time_lead_reset',hold_time_lead_reset='$hold_time_lead_reset',status_group_id='$status_group_id',routing_initiated_recordings='$routing_initiated_recordings',on_hook_cid_number='$on_hook_cid_number',customer_chat_screen_colors='$customer_chat_screen_colors',customer_chat_survey_link='" . mysqli_real_escape_string($link, $customer_chat_survey_link) . "',customer_chat_survey_text='$customer_chat_survey_text',populate_lead_province='$populate_lead_province',areacode_filter='$areacode_filter',areacode_filter_seconds='$areacode_filter_seconds',areacode_filter_action='$areacode_filter_action',areacode_filter_action_value='$areacode_filter_action_value',populate_state_areacode='$populate_state_areacode',inbound_survey='$inbound_survey',inbound_survey_filename='$inbound_survey_filename',inbound_survey_accept_digit='$inbound_survey_accept_digit',inbound_survey_question_filename='$inbound_survey_question_filename',inbound_survey_callmenu='$inbound_survey_callmenu',icbq_expiration_hours='$icbq_expiration_hours',closing_time_action='$closing_time_action',closing_time_now_trigger='$closing_time_now_trigger',closing_time_filename='$closing_time_filename',closing_time_end_filename='$closing_time_end_filename',closing_time_lead_reset='$closing_time_lead_reset',closing_time_option_exten='$closing_time_option_exten',closing_time_option_callmenu='$closing_time_option_callmenu',closing_time_option_voicemail='$closing_time_option_voicemail',closing_time_option_xfer_group='$closing_time_option_xfer_group',closing_time_option_callback_list_id='$closing_time_option_callback_list_id',icbq_call_time_id='$icbq_call_time_id',add_lead_timezone='$add_lead_timezone',icbq_dial_filter='$icbq_dial_filter',populate_lead_source='$populate_lead_source',populate_lead_vendor='$populate_lead_vendor',park_file_name='$park_file_name',waiting_call_url_on='" . mysqli_real_escape_string($link, $waiting_call_url_on) . "',waiting_call_url_off='" . mysqli_real_escape_string($link, $waiting_call_url_off) . "',enter_ingroup_url='" . mysqli_real_escape_string($link, $enter_ingroup_url) . "',cid_cb_confirm_number='$cid_cb_confirm_number',cid_cb_invalid_filter_phone_group='$cid_cb_invalid_filter_phone_group',cid_cb_valid_length='$cid_cb_valid_length',cid_cb_valid_filename='$cid_cb_valid_filename',cid_cb_confirmed_filename='$cid_cb_confirmed_filename',cid_cb_enter_filename='$cid_cb_enter_filename',cid_cb_you_entered_filename='$cid_cb_you_entered_filename',cid_cb_press_to_confirm_filename='$cid_cb_press_to_confirm_filename',cid_cb_invalid_filename='$cid_cb_invalid_filename',cid_cb_reenter_filename='$cid_cb_reenter_filename',cid_cb_error_filename='$cid_cb_error_filename',place_in_line_caller_number_filename='$place_in_line_caller_number_filename',place_in_line_you_next_filename='$place_in_line_you_next_filename', ingroup_script_two='$ingroup_script_two',browser_alert_sound='$browser_alert_sound',browser_alert_volume='$browser_alert_volume',answer_signal='$answer_signal',qc_statuses_id='$qc_statuses_id',no_agent_delay='$no_agent_delay',agent_search_method='$agent_search_method',populate_lead_comments='$populate_lead_comments',drop_call_seconds_override='$drop_call_seconds_override',populate_lead_owner='$populate_lead_owner',in_queue_nanque='$in_queue_nanque',in_queue_nanque_exceptions='$in_queue_nanque_exceptions',custom_one='$custom_one',custom_two='$custom_two',custom_three='$custom_three',custom_four='$custom_four',custom_five='$custom_five',second_alert_trigger='$second_alert_trigger',second_alert_trigger_seconds='$second_alert_trigger_seconds',second_alert_filename='$second_alert_filename',second_alert_delay='$second_alert_delay',second_alert_container='$second_alert_container',second_alert_only='$second_alert_only',third_alert_trigger='$third_alert_trigger',third_alert_trigger_seconds='$third_alert_trigger_seconds',third_alert_filename='$third_alert_filename',third_alert_delay='$third_alert_delay',third_alert_container='$third_alert_container',third_alert_only='$third_alert_only',agent_search_list='$agent_search_list',state_descriptions='$state_descriptions',stereo_recording='$stereo_recording',stereo_rec_filename='$stereo_rec_filename',stereo_parallel_recording='$stereo_parallel_recording',recording_dtmf_muting='$recording_dtmf_muting',stereo_recording_agent='$stereo_recording_agent',parallel_rec_co_filename='$parallel_rec_co_filename',parallel_rec_cm_filename='$parallel_rec_cm_filename',parallel_rec_fr_filename='$parallel_rec_fr_filename' where group_id='$group_id';"; $rslt=mysql_to_mysqli($stmt, $link); switch($group_handling) @@ -21330,7 +21407,7 @@ function ajax_logout_now() $update_apinewlead_rows=mysqli_affected_rows($link); # update the system settings - $stmt="UPDATE system_settings set use_non_latin='$use_non_latin',webroot_writable='$webroot_writable',enable_queuemetrics_logging='$enable_queuemetrics_logging',queuemetrics_server_ip='$queuemetrics_server_ip',queuemetrics_dbname='$queuemetrics_dbname',queuemetrics_login='$queuemetrics_login',queuemetrics_pass='$queuemetrics_pass',queuemetrics_url='" . mysqli_real_escape_string($link, $queuemetrics_url) . "',queuemetrics_log_id='$queuemetrics_log_id',queuemetrics_eq_prepend='$queuemetrics_eq_prepend',vicidial_agent_disable='$vicidial_agent_disable',allow_sipsak_messages='$allow_sipsak_messages',admin_home_url='" . mysqli_real_escape_string($link, $admin_home_url) . "',enable_agc_xfer_log='$enable_agc_xfer_log',timeclock_end_of_day='$timeclock_end_of_day',vdc_header_date_format='$vdc_header_date_format',vdc_customer_date_format='$vdc_customer_date_format',vdc_header_phone_format='$vdc_header_phone_format',vdc_agent_api_active='$vdc_agent_api_active',enable_vtiger_integration='$enable_vtiger_integration',vtiger_server_ip='$vtiger_server_ip',vtiger_dbname='$vtiger_dbname',vtiger_login='$vtiger_login',vtiger_pass='$vtiger_pass',vtiger_url='" . mysqli_real_escape_string($link, $vtiger_url) . "',qc_features_active='$qc_features_active',outbound_autodial_active='$outbound_autodial_active',outbound_calls_per_second='$outbound_calls_per_second',enable_tts_integration='$enable_tts_integration',agentonly_callback_campaign_lock='$agentonly_callback_campaign_lock',sounds_central_control_active='$sounds_central_control_active',sounds_web_server='$sounds_web_server',sounds_web_directory='$sounds_web_directory',active_voicemail_server='$active_voicemail_server',auto_dial_limit='$auto_dial_limit',user_territories_active='$user_territories_active',allow_custom_dialplan='$allow_custom_dialplan',enable_second_webform='$enable_second_webform',default_webphone='$default_webphone',default_external_server_ip='$default_external_server_ip',webphone_url='" . mysqli_real_escape_string($link, $webphone_url) . "',enable_agc_dispo_log='$enable_agc_dispo_log',queuemetrics_loginout='$queuemetrics_loginout',callcard_enabled='$callcard_enabled',queuemetrics_callstatus='$queuemetrics_callstatus',default_codecs='$default_codecs',admin_web_directory='$admin_web_directory',label_title='$label_title',label_first_name='$label_first_name',label_middle_initial='$label_middle_initial',label_last_name='$label_last_name',label_address1='$label_address1',label_address2='$label_address2',label_address3='$label_address3',label_city='$label_city',label_state='$label_state',label_province='$label_province',label_postal_code='$label_postal_code',label_vendor_lead_code='$label_vendor_lead_code',label_gender='$label_gender',label_phone_number='$label_phone_number',label_phone_code='$label_phone_code',label_alt_phone='$label_alt_phone',label_security_phrase='$label_security_phrase',label_email='$label_email',label_comments='$label_comments',label_lead_id='$label_lead_id',label_list_id='$label_list_id',label_entry_date='$label_entry_date',label_gmt_offset_now='$label_gmt_offset_now',label_source_id='$label_source_id',label_called_since_last_reset='$label_called_since_last_reset',label_status='$label_status',label_user='$label_user',label_date_of_birth='$label_date_of_birth',label_country_code='$label_country_code',label_last_local_call_time='$label_last_local_call_time',label_called_count='$label_called_count',label_rank='$label_rank',label_owner='$label_owner',label_entry_list_id='$label_entry_list_id',custom_fields_enabled='$custom_fields_enabled',slave_db_server='$slave_db_server',reports_use_slave_db='$reports_use_slave_db'$custom_reports_slave_SQL,webphone_systemkey='$webphone_systemkey',first_login_trigger='$first_login_trigger',default_phone_registration_password='$default_phone_registration_password',default_phone_login_password='$default_phone_login_password',default_server_password='$default_server_password',admin_modify_refresh='$admin_modify_refresh',nocache_admin='$nocache_admin',generate_cross_server_exten='$generate_cross_server_exten',queuemetrics_addmember_enabled='$queuemetrics_addmember_enabled',queuemetrics_dispo_pause='$queuemetrics_dispo_pause',label_hide_field_logs='$label_hide_field_logs',queuemetrics_pe_phone_append='$queuemetrics_pe_phone_append',test_campaign_calls='$test_campaign_calls',agents_calls_reset='$agents_calls_reset',default_voicemail_timezone='$default_voicemail_timezone',default_local_gmt='$default_local_gmt',noanswer_log='$noanswer_log',alt_log_server_ip='$alt_log_server_ip',alt_log_dbname='$alt_log_dbname',alt_log_login='$alt_log_login',alt_log_pass='$alt_log_pass',tables_use_alt_log_db='$tables_use_alt_log_db',did_agent_log='$did_agent_log',campaign_cid_areacodes_enabled='$campaign_cid_areacodes_enabled',pllb_grouping_limit='$pllb_grouping_limit',did_ra_extensions_enabled='$did_ra_extensions_enabled',expanded_list_stats='$expanded_list_stats',contacts_enabled='$contacts_enabled',call_menu_qualify_enabled='$call_menu_qualify_enabled',admin_list_counts='$admin_list_counts',allow_voicemail_greeting='$allow_voicemail_greeting',queuemetrics_socket='$queuemetrics_socket',queuemetrics_socket_url='$queuemetrics_socket_url',enhanced_disconnect_logging='$enhanced_disconnect_logging',allow_emails='$allow_emails',level_8_disable_add='$level_8_disable_add',queuemetrics_record_hold='$queuemetrics_record_hold',country_code_list_stats='$country_code_list_stats',queuemetrics_pause_type='$queuemetrics_pause_type',frozen_server_call_clear='$frozen_server_call_clear',callback_time_24hour='$callback_time_24hour',enable_languages='$enable_languages',language_method='$language_method',meetme_enter_login_filename='$meetme_enter_login_filename',meetme_enter_leave3way_filename='$meetme_enter_leave3way_filename',enable_did_entry_list_id='$enable_did_entry_list_id',enable_third_webform='$enable_third_webform',allow_chats='$allow_chats',chat_url='" . mysqli_real_escape_string($link, $chat_url) . "',chat_timeout='$chat_timeout',agent_debug_logging='$agent_debug_logging',default_language='$default_language',agent_whisper_enabled='$agent_whisper_enabled',user_hide_realtime_enabled='$user_hide_realtime_enabled',usacan_phone_dialcode_fix='$usacan_phone_dialcode_fix',cache_carrier_stats_realtime='$cache_carrier_stats_realtime',log_recording_access='$log_recording_access',report_default_format='$report_default_format',alt_ivr_logging='$alt_ivr_logging',default_phone_code='$default_phone_code',admin_row_click='$admin_row_click',admin_screen_colors='$admin_screen_colors',ofcom_uk_drop_calc='$ofcom_uk_drop_calc',agent_screen_colors='$agent_screen_colors',script_remove_js='$script_remove_js',manual_auto_next='$manual_auto_next',user_new_lead_limit='$user_new_lead_limit',agent_xfer_park_3way='$agent_xfer_park_3way',agent_soundboards='$agent_soundboards',web_loader_phone_length='$web_loader_phone_length',agent_script='$agent_script',agent_chat_screen_colors='$agent_chat_screen_colors',enable_auto_reports='$enable_auto_reports',enable_pause_code_limits='$enable_pause_code_limits',enable_drop_lists='$enable_drop_lists',allow_ip_lists='$allow_ip_lists',system_ip_blacklist='$system_ip_blacklist',agent_push_events='$agent_push_events',agent_push_url='$agent_push_url',hide_inactive_lists='$hide_inactive_lists',allow_manage_active_lists='$allow_manage_active_lists',expired_lists_inactive='$expired_lists_inactive',did_system_filter='$did_system_filter',anyone_callback_inactive_lists='$anyone_callback_inactive_lists',enable_gdpr_download_deletion='$enable_gdpr_download_deletion',source_id_display='$source_id_display',agent_logout_link='$agent_logout_link',manual_dial_validation='$manual_dial_validation',mute_recordings='$mute_recordings',user_admin_redirect='$user_admin_redirect',list_status_modification_confirmation='$list_status_modification_confirmation',sip_event_logging='$sip_event_logging',call_quota_lead_ranking='$call_quota_lead_ranking',enable_second_script='$enable_second_script',enable_first_webform='$enable_first_webform',recording_buttons='$recording_buttons',opensips_cid_name='$opensips_cid_name',require_password_length='$require_password_length',user_account_emails='$user_account_emails',outbound_cid_any='$outbound_cid_any',entries_per_page='$entries_per_page',browser_call_alerts='$browser_call_alerts',queuemetrics_pausereason='$queuemetrics_pausereason',inbound_answer_config='$inbound_answer_config',enable_international_dncs='$enable_international_dncs',web_loader_phone_strip='$web_loader_phone_strip',manual_dial_phone_strip='$manual_dial_phone_strip',daily_call_count_limit='$daily_call_count_limit',allow_shared_dial='$allow_shared_dial',agent_search_method='$agent_search_method',phone_defaults_container='$phone_defaults_container',qc_claim_limit='$qc_claim_limit',qc_expire_days='$qc_expire_days',two_factor_auth_hours='$two_factor_auth_hours',two_factor_container='$two_factor_container',agent_hidden_sound='$agent_hidden_sound',agent_hidden_sound_volume='$agent_hidden_sound_volume',agent_hidden_sound_seconds='$agent_hidden_sound_seconds',agent_screen_timer='$agent_screen_timer',call_limit_24hour='$call_limit_24hour',allowed_sip_stacks='$allowed_sip_stacks',agent_hide_hangup='$agent_hide_hangup',allow_web_debug='$allow_web_debug',max_logged_in_agents='$max_logged_in_agents',user_codes_admin='$user_codes_admin',login_kickall='$login_kickall',abandon_check_queue='$abandon_check_queue',agent_notifications='$agent_notifications',demographic_quotas='$demographic_quotas',log_latency_gaps='$log_latency_gaps',inbound_credits='$inbound_credits',weekday_resets='$weekday_resets',two_factor_auth_agent_hours='$two_factor_auth_agent_hours',hopper_hold_inserts='$hopper_hold_inserts',coldstorage_server_ip='$coldstorage_server_ip',coldstorage_dbname='$coldstorage_dbname',coldstorage_login='$coldstorage_login',coldstorage_pass='$coldstorage_pass',coldstorage_port='$coldstorage_port',enhanced_agent_monitoring='$enhanced_agent_monitoring',agent_hide_dial_fail='$agent_hide_dial_fail',agent_man_dial_filter='$agent_man_dial_filter',agent_3way_dial_filter='$agent_3way_dial_filter'$custom_dialplanSQL;"; + $stmt="UPDATE system_settings set use_non_latin='$use_non_latin',webroot_writable='$webroot_writable',enable_queuemetrics_logging='$enable_queuemetrics_logging',queuemetrics_server_ip='$queuemetrics_server_ip',queuemetrics_dbname='$queuemetrics_dbname',queuemetrics_login='$queuemetrics_login',queuemetrics_pass='$queuemetrics_pass',queuemetrics_url='" . mysqli_real_escape_string($link, $queuemetrics_url) . "',queuemetrics_log_id='$queuemetrics_log_id',queuemetrics_eq_prepend='$queuemetrics_eq_prepend',vicidial_agent_disable='$vicidial_agent_disable',allow_sipsak_messages='$allow_sipsak_messages',admin_home_url='" . mysqli_real_escape_string($link, $admin_home_url) . "',enable_agc_xfer_log='$enable_agc_xfer_log',timeclock_end_of_day='$timeclock_end_of_day',vdc_header_date_format='$vdc_header_date_format',vdc_customer_date_format='$vdc_customer_date_format',vdc_header_phone_format='$vdc_header_phone_format',vdc_agent_api_active='$vdc_agent_api_active',enable_vtiger_integration='$enable_vtiger_integration',vtiger_server_ip='$vtiger_server_ip',vtiger_dbname='$vtiger_dbname',vtiger_login='$vtiger_login',vtiger_pass='$vtiger_pass',vtiger_url='" . mysqli_real_escape_string($link, $vtiger_url) . "',qc_features_active='$qc_features_active',outbound_autodial_active='$outbound_autodial_active',outbound_calls_per_second='$outbound_calls_per_second',enable_tts_integration='$enable_tts_integration',agentonly_callback_campaign_lock='$agentonly_callback_campaign_lock',sounds_central_control_active='$sounds_central_control_active',sounds_web_server='$sounds_web_server',sounds_web_directory='$sounds_web_directory',active_voicemail_server='$active_voicemail_server',auto_dial_limit='$auto_dial_limit',user_territories_active='$user_territories_active',allow_custom_dialplan='$allow_custom_dialplan',enable_second_webform='$enable_second_webform',default_webphone='$default_webphone',default_external_server_ip='$default_external_server_ip',webphone_url='" . mysqli_real_escape_string($link, $webphone_url) . "',enable_agc_dispo_log='$enable_agc_dispo_log',queuemetrics_loginout='$queuemetrics_loginout',callcard_enabled='$callcard_enabled',queuemetrics_callstatus='$queuemetrics_callstatus',default_codecs='$default_codecs',admin_web_directory='$admin_web_directory',label_title='$label_title',label_first_name='$label_first_name',label_middle_initial='$label_middle_initial',label_last_name='$label_last_name',label_address1='$label_address1',label_address2='$label_address2',label_address3='$label_address3',label_city='$label_city',label_state='$label_state',label_province='$label_province',label_postal_code='$label_postal_code',label_vendor_lead_code='$label_vendor_lead_code',label_gender='$label_gender',label_phone_number='$label_phone_number',label_phone_code='$label_phone_code',label_alt_phone='$label_alt_phone',label_security_phrase='$label_security_phrase',label_email='$label_email',label_comments='$label_comments',label_lead_id='$label_lead_id',label_list_id='$label_list_id',label_entry_date='$label_entry_date',label_gmt_offset_now='$label_gmt_offset_now',label_source_id='$label_source_id',label_called_since_last_reset='$label_called_since_last_reset',label_status='$label_status',label_user='$label_user',label_date_of_birth='$label_date_of_birth',label_country_code='$label_country_code',label_last_local_call_time='$label_last_local_call_time',label_called_count='$label_called_count',label_rank='$label_rank',label_owner='$label_owner',label_entry_list_id='$label_entry_list_id',custom_fields_enabled='$custom_fields_enabled',slave_db_server='$slave_db_server',reports_use_slave_db='$reports_use_slave_db'$custom_reports_slave_SQL,webphone_systemkey='$webphone_systemkey',first_login_trigger='$first_login_trigger',default_phone_registration_password='$default_phone_registration_password',default_phone_login_password='$default_phone_login_password',default_server_password='$default_server_password',admin_modify_refresh='$admin_modify_refresh',nocache_admin='$nocache_admin',generate_cross_server_exten='$generate_cross_server_exten',queuemetrics_addmember_enabled='$queuemetrics_addmember_enabled',queuemetrics_dispo_pause='$queuemetrics_dispo_pause',label_hide_field_logs='$label_hide_field_logs',queuemetrics_pe_phone_append='$queuemetrics_pe_phone_append',test_campaign_calls='$test_campaign_calls',agents_calls_reset='$agents_calls_reset',default_voicemail_timezone='$default_voicemail_timezone',default_local_gmt='$default_local_gmt',noanswer_log='$noanswer_log',alt_log_server_ip='$alt_log_server_ip',alt_log_dbname='$alt_log_dbname',alt_log_login='$alt_log_login',alt_log_pass='$alt_log_pass',tables_use_alt_log_db='$tables_use_alt_log_db',did_agent_log='$did_agent_log',campaign_cid_areacodes_enabled='$campaign_cid_areacodes_enabled',pllb_grouping_limit='$pllb_grouping_limit',did_ra_extensions_enabled='$did_ra_extensions_enabled',expanded_list_stats='$expanded_list_stats',contacts_enabled='$contacts_enabled',call_menu_qualify_enabled='$call_menu_qualify_enabled',admin_list_counts='$admin_list_counts',allow_voicemail_greeting='$allow_voicemail_greeting',queuemetrics_socket='$queuemetrics_socket',queuemetrics_socket_url='$queuemetrics_socket_url',enhanced_disconnect_logging='$enhanced_disconnect_logging',allow_emails='$allow_emails',level_8_disable_add='$level_8_disable_add',queuemetrics_record_hold='$queuemetrics_record_hold',country_code_list_stats='$country_code_list_stats',queuemetrics_pause_type='$queuemetrics_pause_type',frozen_server_call_clear='$frozen_server_call_clear',callback_time_24hour='$callback_time_24hour',enable_languages='$enable_languages',language_method='$language_method',meetme_enter_login_filename='$meetme_enter_login_filename',meetme_enter_leave3way_filename='$meetme_enter_leave3way_filename',enable_did_entry_list_id='$enable_did_entry_list_id',enable_third_webform='$enable_third_webform',allow_chats='$allow_chats',chat_url='" . mysqli_real_escape_string($link, $chat_url) . "',chat_timeout='$chat_timeout',agent_debug_logging='$agent_debug_logging',default_language='$default_language',agent_whisper_enabled='$agent_whisper_enabled',user_hide_realtime_enabled='$user_hide_realtime_enabled',usacan_phone_dialcode_fix='$usacan_phone_dialcode_fix',cache_carrier_stats_realtime='$cache_carrier_stats_realtime',log_recording_access='$log_recording_access',report_default_format='$report_default_format',alt_ivr_logging='$alt_ivr_logging',default_phone_code='$default_phone_code',admin_row_click='$admin_row_click',admin_screen_colors='$admin_screen_colors',ofcom_uk_drop_calc='$ofcom_uk_drop_calc',agent_screen_colors='$agent_screen_colors',script_remove_js='$script_remove_js',manual_auto_next='$manual_auto_next',user_new_lead_limit='$user_new_lead_limit',agent_xfer_park_3way='$agent_xfer_park_3way',agent_soundboards='$agent_soundboards',web_loader_phone_length='$web_loader_phone_length',agent_script='$agent_script',agent_chat_screen_colors='$agent_chat_screen_colors',enable_auto_reports='$enable_auto_reports',enable_pause_code_limits='$enable_pause_code_limits',enable_drop_lists='$enable_drop_lists',allow_ip_lists='$allow_ip_lists',system_ip_blacklist='$system_ip_blacklist',agent_push_events='$agent_push_events',agent_push_url='$agent_push_url',hide_inactive_lists='$hide_inactive_lists',allow_manage_active_lists='$allow_manage_active_lists',expired_lists_inactive='$expired_lists_inactive',did_system_filter='$did_system_filter',anyone_callback_inactive_lists='$anyone_callback_inactive_lists',enable_gdpr_download_deletion='$enable_gdpr_download_deletion',source_id_display='$source_id_display',agent_logout_link='$agent_logout_link',manual_dial_validation='$manual_dial_validation',mute_recordings='$mute_recordings',user_admin_redirect='$user_admin_redirect',list_status_modification_confirmation='$list_status_modification_confirmation',sip_event_logging='$sip_event_logging',call_quota_lead_ranking='$call_quota_lead_ranking',enable_second_script='$enable_second_script',enable_first_webform='$enable_first_webform',recording_buttons='$recording_buttons',opensips_cid_name='$opensips_cid_name',require_password_length='$require_password_length',user_account_emails='$user_account_emails',outbound_cid_any='$outbound_cid_any',entries_per_page='$entries_per_page',browser_call_alerts='$browser_call_alerts',queuemetrics_pausereason='$queuemetrics_pausereason',inbound_answer_config='$inbound_answer_config',enable_international_dncs='$enable_international_dncs',web_loader_phone_strip='$web_loader_phone_strip',manual_dial_phone_strip='$manual_dial_phone_strip',daily_call_count_limit='$daily_call_count_limit',allow_shared_dial='$allow_shared_dial',agent_search_method='$agent_search_method',phone_defaults_container='$phone_defaults_container',qc_claim_limit='$qc_claim_limit',qc_expire_days='$qc_expire_days',two_factor_auth_hours='$two_factor_auth_hours',two_factor_container='$two_factor_container',agent_hidden_sound='$agent_hidden_sound',agent_hidden_sound_volume='$agent_hidden_sound_volume',agent_hidden_sound_seconds='$agent_hidden_sound_seconds',agent_screen_timer='$agent_screen_timer',call_limit_24hour='$call_limit_24hour',allowed_sip_stacks='$allowed_sip_stacks',agent_hide_hangup='$agent_hide_hangup',allow_web_debug='$allow_web_debug',max_logged_in_agents='$max_logged_in_agents',user_codes_admin='$user_codes_admin',login_kickall='$login_kickall',abandon_check_queue='$abandon_check_queue',agent_notifications='$agent_notifications',demographic_quotas='$demographic_quotas',log_latency_gaps='$log_latency_gaps',inbound_credits='$inbound_credits',weekday_resets='$weekday_resets',two_factor_auth_agent_hours='$two_factor_auth_agent_hours',hopper_hold_inserts='$hopper_hold_inserts',coldstorage_server_ip='$coldstorage_server_ip',coldstorage_dbname='$coldstorage_dbname',coldstorage_login='$coldstorage_login',coldstorage_pass='$coldstorage_pass',coldstorage_port='$coldstorage_port',enhanced_agent_monitoring='$enhanced_agent_monitoring',agent_hide_dial_fail='$agent_hide_dial_fail',agent_man_dial_filter='$agent_man_dial_filter',agent_3way_dial_filter='$agent_3way_dial_filter',stereo_recording='$stereo_recording',recording_dtmf_detection='$recording_dtmf_detection',recording_dtmf_muting='$recording_dtmf_muting',stereo_parallel_recording='$stereo_parallel_recording'$custom_dialplanSQL;"; $rslt=mysql_to_mysqli($stmt, $link); $update_main_rows=mysqli_affected_rows($link); if ($DB) {echo "$update_main_rows|$stmt|\n";} @@ -26325,7 +26402,7 @@ function ajax_logout_now() $enable_vtiger_integration_LU = $row[0]; $vtiger_url_LU = $row[1]; - $stmt="SELECT campaign_id,campaign_name,active,dial_status_a,dial_status_b,dial_status_c,dial_status_d,dial_status_e,lead_order,park_ext,park_file_name,web_form_address,allow_closers,hopper_level,auto_dial_level,next_agent_call,local_call_time,voicemail_ext,dial_timeout,dial_prefix,campaign_cid,campaign_vdad_exten,campaign_rec_exten,campaign_recording,campaign_rec_filename,campaign_script,get_call_launch,am_message_exten,amd_send_to_vmx,xferconf_a_dtmf,xferconf_a_number,xferconf_b_dtmf,xferconf_b_number,alt_number_dialing,scheduled_callbacks,lead_filter_id,drop_call_seconds,drop_action,safe_harbor_exten,display_dialable_count,wrapup_seconds,wrapup_message,closer_campaigns,use_internal_dnc,allcalls_delay,omit_phone_code,dial_method,available_only_ratio_tally,adaptive_dropped_percentage,adaptive_maximum_level,adaptive_latest_server_time,adaptive_intensity,adaptive_dl_diff_target,concurrent_transfers,auto_alt_dial,auto_alt_dial_statuses,agent_pause_codes_active,campaign_description,campaign_changedate,campaign_stats_refresh,campaign_logindate,dial_statuses,disable_alter_custdata,no_hopper_leads_logins,list_order_mix,campaign_allow_inbound,manual_dial_list_id,default_xfer_group,xfer_groups,queue_priority,drop_inbound_group,qc_enabled,qc_statuses,qc_lists,qc_shift_id,qc_get_record_launch,qc_show_recording,qc_web_form_address,qc_script,survey_first_audio_file,survey_dtmf_digits,survey_ni_digit,survey_opt_in_audio_file,survey_ni_audio_file,survey_method,survey_no_response_action,survey_ni_status,survey_response_digit_map,survey_xfer_exten,survey_camp_record_dir,disable_alter_custphone,display_queue_count,manual_dial_filter,agent_clipboard_copy,agent_extended_alt_dial,use_campaign_dnc,three_way_call_cid,three_way_dial_prefix,web_form_target,vtiger_search_category,vtiger_create_call_record,vtiger_create_lead_record,vtiger_screen_login,cpd_amd_action,agent_allow_group_alias,default_group_alias,vtiger_search_dead,vtiger_status_call,survey_third_digit,survey_third_audio_file,survey_third_status,survey_third_exten,survey_fourth_digit,survey_fourth_audio_file,survey_fourth_status,survey_fourth_exten,drop_lockout_time,quick_transfer_button,prepopulate_transfer_preset,drop_rate_group,view_calls_in_queue,view_calls_in_queue_launch,grab_calls_in_queue,call_requeue_button,pause_after_each_call,no_hopper_dialing,agent_dial_owner_only,agent_display_dialable_leads,web_form_address_two,waitforsilence_options,agent_select_territories,campaign_calldate,crm_popup_login,crm_login_address,timer_action,timer_action_message,timer_action_seconds,start_call_url,dispo_call_url,xferconf_c_number,xferconf_d_number,xferconf_e_number,use_custom_cid,scheduled_callbacks_alert,queuemetrics_callstatus_override,extension_appended_cidname,scheduled_callbacks_count,manual_dial_override,blind_monitor_warning,blind_monitor_message,blind_monitor_filename,inbound_queue_no_dial,timer_action_destination,enable_xfer_presets,hide_xfer_number_to_dial,manual_dial_prefix,customer_3way_hangup_logging,customer_3way_hangup_seconds,customer_3way_hangup_action,ivr_park_call,ivr_park_call_agi,manual_preview_dial,realtime_agent_time_stats,use_auto_hopper,auto_hopper_multi,auto_trim_hopper,api_manual_dial,manual_dial_call_time_check,display_leads_count,lead_order_randomize,lead_order_secondary,per_call_notes,my_callback_option,agent_lead_search,agent_lead_search_method,queuemetrics_phone_environment,auto_pause_precall,auto_resume_precall,auto_pause_precall_code,manual_dial_cid,post_phone_time_diff_alert,custom_3way_button_transfer,available_only_tally_threshold,available_only_tally_threshold_agents,dial_level_threshold,dial_level_threshold_agents,safe_harbor_audio,safe_harbor_menu_id,survey_menu_id,callback_days_limit,dl_diff_target_method,disable_dispo_screen,disable_dispo_status,screen_labels,status_display_fields,na_call_url,survey_recording,pllb_grouping,pllb_grouping_limit,call_count_limit,call_count_target,callback_hours_block,callback_list_calltime,user_group,hopper_vlc_dup_check,in_group_dial,in_group_dial_select,safe_harbor_audio_field,pause_after_next_call,owner_populate,use_other_campaign_dnc,allow_emails,amd_inbound_group,amd_callmenu,survey_wait_sec,manual_dial_lead_id,dead_max,dispo_max,pause_max,dead_max_dispo,dispo_max_dispo,max_inbound_calls,manual_dial_search_checkbox,hide_call_log_info,timer_alt_seconds,wrapup_bypass,wrapup_after_hotkey,callback_active_limit,callback_active_limit_override,allow_chats,comments_all_tabs,comments_dispo_screen,comments_callback_screen,qc_comment_history,show_previous_callback,clear_script,cpd_unknown_action,manual_dial_search_filter,web_form_address_three,manual_dial_override_field,status_display_ingroup,customer_gone_seconds,agent_display_fields,am_message_wildcards,manual_dial_timeout,routing_initiated_recordings,manual_dial_hopper_check,callback_useronly_move_minutes,ofcom_uk_drop_calc,manual_auto_next,manual_auto_show,allow_required_fields,dead_to_dispo,agent_xfer_validation,ready_max_logout,callback_display_days,three_way_record_stop,hangup_xfer_record_start,scheduled_callbacks_email_alert,max_inbound_calls_outcome,manual_auto_next_options,agent_screen_time_display,next_dial_my_callbacks,inbound_no_agents_no_dial_container,inbound_no_agents_no_dial_threshold,cid_group_id,pause_max_dispo,script_top_dispo,dead_trigger_seconds,dead_trigger_action,dead_trigger_repeat,dead_trigger_filename,dead_trigger_url,scheduled_callbacks_force_dial,scheduled_callbacks_auto_reschedule,scheduled_callbacks_timezones_container,three_way_volume_buttons,callback_dnc,manual_dial_validation,mute_recordings,auto_active_list_new,call_quota_lead_ranking,call_quota_process_running,sip_event_logging,campaign_script_two,leave_vm_no_dispo,leave_vm_message_group_id,dial_timeout_lead_container,amd_type,vmm_daily_limit,opensips_cid_name,amd_agent_route_options,browser_alert_sound,browser_alert_volume,three_way_record_stop_exception,pause_max_exceptions,hopper_drop_run_trigger,daily_call_count_limit,daily_limit_manual,transfer_button_launch,shared_dial_rank,agent_search_method,qc_scorecard_id,qc_statuses_id,clear_form,leave_3way_start_recording,leave_3way_start_recording_exception,calls_waiting_vl_one,calls_waiting_vl_two,calls_inqueue_count_one,calls_inqueue_count_two,in_man_dial_next_ready_seconds,in_man_dial_next_ready_seconds_override,transfer_no_dispo,call_limit_24hour_method,call_limit_24hour_scope,call_limit_24hour,call_limit_24hour_override,cid_group_id_two,incall_tally_threshold_seconds,auto_alt_threshold,pause_max_url,agent_hide_hangup,ig_xfer_list_sort,script_tab_frame_size,max_logged_in_agents,user_group_script,agent_hangup_route,agent_hangup_value,agent_hangup_ig_override,show_confetti,demographic_quotas,demographic_quotas_container,demographic_quotas_rerank,demographic_quotas_list_resets,demographic_quotas_last_rerank,custom_one,custom_two,custom_three,custom_four,custom_five,dead_stop_recording,manual_vm_status_updates,force_per_call_notes,agent_search_ingroup_list,hopper_hold_inserts,daily_phone_number_call_limit,state_descriptions,script_tab_height,call_log_days,leave_3way_stop_recording,manual_minimum_ring_seconds,manual_minimum_attempt_seconds,manual_minimum_answer_seconds,khomp_settings_container from vicidial_campaigns where campaign_id='$campaign_id' $LOGallowed_campaignsSQL;"; + $stmt="SELECT campaign_id,campaign_name,active,dial_status_a,dial_status_b,dial_status_c,dial_status_d,dial_status_e,lead_order,park_ext,park_file_name,web_form_address,allow_closers,hopper_level,auto_dial_level,next_agent_call,local_call_time,voicemail_ext,dial_timeout,dial_prefix,campaign_cid,campaign_vdad_exten,campaign_rec_exten,campaign_recording,campaign_rec_filename,campaign_script,get_call_launch,am_message_exten,amd_send_to_vmx,xferconf_a_dtmf,xferconf_a_number,xferconf_b_dtmf,xferconf_b_number,alt_number_dialing,scheduled_callbacks,lead_filter_id,drop_call_seconds,drop_action,safe_harbor_exten,display_dialable_count,wrapup_seconds,wrapup_message,closer_campaigns,use_internal_dnc,allcalls_delay,omit_phone_code,dial_method,available_only_ratio_tally,adaptive_dropped_percentage,adaptive_maximum_level,adaptive_latest_server_time,adaptive_intensity,adaptive_dl_diff_target,concurrent_transfers,auto_alt_dial,auto_alt_dial_statuses,agent_pause_codes_active,campaign_description,campaign_changedate,campaign_stats_refresh,campaign_logindate,dial_statuses,disable_alter_custdata,no_hopper_leads_logins,list_order_mix,campaign_allow_inbound,manual_dial_list_id,default_xfer_group,xfer_groups,queue_priority,drop_inbound_group,qc_enabled,qc_statuses,qc_lists,qc_shift_id,qc_get_record_launch,qc_show_recording,qc_web_form_address,qc_script,survey_first_audio_file,survey_dtmf_digits,survey_ni_digit,survey_opt_in_audio_file,survey_ni_audio_file,survey_method,survey_no_response_action,survey_ni_status,survey_response_digit_map,survey_xfer_exten,survey_camp_record_dir,disable_alter_custphone,display_queue_count,manual_dial_filter,agent_clipboard_copy,agent_extended_alt_dial,use_campaign_dnc,three_way_call_cid,three_way_dial_prefix,web_form_target,vtiger_search_category,vtiger_create_call_record,vtiger_create_lead_record,vtiger_screen_login,cpd_amd_action,agent_allow_group_alias,default_group_alias,vtiger_search_dead,vtiger_status_call,survey_third_digit,survey_third_audio_file,survey_third_status,survey_third_exten,survey_fourth_digit,survey_fourth_audio_file,survey_fourth_status,survey_fourth_exten,drop_lockout_time,quick_transfer_button,prepopulate_transfer_preset,drop_rate_group,view_calls_in_queue,view_calls_in_queue_launch,grab_calls_in_queue,call_requeue_button,pause_after_each_call,no_hopper_dialing,agent_dial_owner_only,agent_display_dialable_leads,web_form_address_two,waitforsilence_options,agent_select_territories,campaign_calldate,crm_popup_login,crm_login_address,timer_action,timer_action_message,timer_action_seconds,start_call_url,dispo_call_url,xferconf_c_number,xferconf_d_number,xferconf_e_number,use_custom_cid,scheduled_callbacks_alert,queuemetrics_callstatus_override,extension_appended_cidname,scheduled_callbacks_count,manual_dial_override,blind_monitor_warning,blind_monitor_message,blind_monitor_filename,inbound_queue_no_dial,timer_action_destination,enable_xfer_presets,hide_xfer_number_to_dial,manual_dial_prefix,customer_3way_hangup_logging,customer_3way_hangup_seconds,customer_3way_hangup_action,ivr_park_call,ivr_park_call_agi,manual_preview_dial,realtime_agent_time_stats,use_auto_hopper,auto_hopper_multi,auto_trim_hopper,api_manual_dial,manual_dial_call_time_check,display_leads_count,lead_order_randomize,lead_order_secondary,per_call_notes,my_callback_option,agent_lead_search,agent_lead_search_method,queuemetrics_phone_environment,auto_pause_precall,auto_resume_precall,auto_pause_precall_code,manual_dial_cid,post_phone_time_diff_alert,custom_3way_button_transfer,available_only_tally_threshold,available_only_tally_threshold_agents,dial_level_threshold,dial_level_threshold_agents,safe_harbor_audio,safe_harbor_menu_id,survey_menu_id,callback_days_limit,dl_diff_target_method,disable_dispo_screen,disable_dispo_status,screen_labels,status_display_fields,na_call_url,survey_recording,pllb_grouping,pllb_grouping_limit,call_count_limit,call_count_target,callback_hours_block,callback_list_calltime,user_group,hopper_vlc_dup_check,in_group_dial,in_group_dial_select,safe_harbor_audio_field,pause_after_next_call,owner_populate,use_other_campaign_dnc,allow_emails,amd_inbound_group,amd_callmenu,survey_wait_sec,manual_dial_lead_id,dead_max,dispo_max,pause_max,dead_max_dispo,dispo_max_dispo,max_inbound_calls,manual_dial_search_checkbox,hide_call_log_info,timer_alt_seconds,wrapup_bypass,wrapup_after_hotkey,callback_active_limit,callback_active_limit_override,allow_chats,comments_all_tabs,comments_dispo_screen,comments_callback_screen,qc_comment_history,show_previous_callback,clear_script,cpd_unknown_action,manual_dial_search_filter,web_form_address_three,manual_dial_override_field,status_display_ingroup,customer_gone_seconds,agent_display_fields,am_message_wildcards,manual_dial_timeout,routing_initiated_recordings,manual_dial_hopper_check,callback_useronly_move_minutes,ofcom_uk_drop_calc,manual_auto_next,manual_auto_show,allow_required_fields,dead_to_dispo,agent_xfer_validation,ready_max_logout,callback_display_days,three_way_record_stop,hangup_xfer_record_start,scheduled_callbacks_email_alert,max_inbound_calls_outcome,manual_auto_next_options,agent_screen_time_display,next_dial_my_callbacks,inbound_no_agents_no_dial_container,inbound_no_agents_no_dial_threshold,cid_group_id,pause_max_dispo,script_top_dispo,dead_trigger_seconds,dead_trigger_action,dead_trigger_repeat,dead_trigger_filename,dead_trigger_url,scheduled_callbacks_force_dial,scheduled_callbacks_auto_reschedule,scheduled_callbacks_timezones_container,three_way_volume_buttons,callback_dnc,manual_dial_validation,mute_recordings,auto_active_list_new,call_quota_lead_ranking,call_quota_process_running,sip_event_logging,campaign_script_two,leave_vm_no_dispo,leave_vm_message_group_id,dial_timeout_lead_container,amd_type,vmm_daily_limit,opensips_cid_name,amd_agent_route_options,browser_alert_sound,browser_alert_volume,three_way_record_stop_exception,pause_max_exceptions,hopper_drop_run_trigger,daily_call_count_limit,daily_limit_manual,transfer_button_launch,shared_dial_rank,agent_search_method,qc_scorecard_id,qc_statuses_id,clear_form,leave_3way_start_recording,leave_3way_start_recording_exception,calls_waiting_vl_one,calls_waiting_vl_two,calls_inqueue_count_one,calls_inqueue_count_two,in_man_dial_next_ready_seconds,in_man_dial_next_ready_seconds_override,transfer_no_dispo,call_limit_24hour_method,call_limit_24hour_scope,call_limit_24hour,call_limit_24hour_override,cid_group_id_two,incall_tally_threshold_seconds,auto_alt_threshold,pause_max_url,agent_hide_hangup,ig_xfer_list_sort,script_tab_frame_size,max_logged_in_agents,user_group_script,agent_hangup_route,agent_hangup_value,agent_hangup_ig_override,show_confetti,demographic_quotas,demographic_quotas_container,demographic_quotas_rerank,demographic_quotas_list_resets,demographic_quotas_last_rerank,custom_one,custom_two,custom_three,custom_four,custom_five,dead_stop_recording,manual_vm_status_updates,force_per_call_notes,agent_search_ingroup_list,hopper_hold_inserts,daily_phone_number_call_limit,state_descriptions,script_tab_height,call_log_days,leave_3way_stop_recording,manual_minimum_ring_seconds,manual_minimum_attempt_seconds,manual_minimum_answer_seconds,khomp_settings_container,stereo_recording,stereo_rec_filename,stereo_parallel_recording,recording_dtmf_muting,stereo_recording_agent,parallel_rec_co_filename,parallel_rec_cm_filename,parallel_rec_fr_filename from vicidial_campaigns where campaign_id='$campaign_id' $LOGallowed_campaignsSQL;"; $rslt=mysql_to_mysqli($stmt, $link); $row=mysqli_fetch_row($rslt); $campaign_name = $row[1]; @@ -26682,6 +26759,14 @@ function ajax_logout_now() $manual_minimum_attempt_seconds = $row[352]; $manual_minimum_answer_seconds = $row[353]; $khomp_settings_container = $row[354]; + $stereo_recording = $row[355]; + $stereo_rec_filename = $row[356]; + $stereo_parallel_recording = $row[357]; + $recording_dtmf_muting = $row[358]; + $stereo_recording_agent = $row[359]; + $parallel_rec_co_filename = $row[360]; + $parallel_rec_cm_filename = $row[361]; + $parallel_rec_fr_filename = $row[362]; if (preg_match('/DISABLED/', $list_order_mix)) {$DEFlistDISABLE = ''; $DEFstatusDISABLED=0;} @@ -28062,6 +28147,41 @@ function ajax_logout_now() echo "\n"; } + if ( ($SSstereo_recording =='1') or ($SSstereo_recording =='2') or ($SSstereo_recording =='3') or ($SSstereo_recording =='4') or ($SSstereo_recording =='5') ) + { + echo ""._QXZ("Stereo Call Recordings").": $NWB#campaigns-stereo_recording$NWE\n"; + + echo ""._QXZ("Stereo Recording Agent Control").": $NWB#campaigns-stereo_recording_agent$NWE\n"; + + echo ""._QXZ("Stereo Rec Filename").": $NWB#campaigns-stereo_rec_filename$NWE\n"; + } + else + { + echo "\n"; + } + if ( ( ($SSstereo_recording =='1') or ($SSstereo_recording =='2') or ($SSstereo_recording =='3') or ($SSstereo_recording =='4') or ($SSstereo_recording =='5') ) and ($SSstereo_parallel_recording == '1') ) + { + echo ""._QXZ("Parallel Stereo Recordings").": $NWB#campaigns-stereo_parallel_recording$NWE\n"; + + echo ""._QXZ("Parallel Customer-Only Rec Filename").": $NWB#inbound_groups-parallel_rec_xx_filename$NWE\n"; + + echo ""._QXZ("Parallel Customer-Muted Rec Filename").": $NWB#inbound_groups-parallel_rec_xx_filename$NWE\n"; + + echo ""._QXZ("Parallel Full-Recording Rec Filename").": $NWB#inbound_groups-parallel_rec_xx_filename$NWE\n"; + } + else + { + echo "\n"; + } + if ( ( ($SSrecording_dtmf_muting =='1') or ($SSrecording_dtmf_muting =='2') or ($SSrecording_dtmf_muting =='3') ) and ($SSrecording_dtmf_detection == '1') ) + { + echo ""._QXZ("Recording DTMF Muting").": $NWB#campaigns-recording_dtmf_muting$NWE\n"; + } + else + { + echo "\n"; + } + echo ""._QXZ("Call Notes Per Call").": $NWB#campaigns-per_call_notes$NWE\n"; echo ""._QXZ("Per Call Notes Required").": $NWB#campaigns-force_per_call_notes$NWE\n"; @@ -33801,7 +33921,7 @@ function ajax_logout_now() echo "\n"; + if ( ($SSstereo_recording =='1') or ($SSstereo_recording =='2') or ($SSstereo_recording =='3') or ($SSstereo_recording =='4') or ($SSstereo_recording =='5') ) + { + echo "\n"; + + echo "\n"; + + echo "\n"; + } + else + { + echo "\n"; + } + if ( ( ($SSstereo_recording =='1') or ($SSstereo_recording =='2') or ($SSstereo_recording =='3') or ($SSstereo_recording =='4') or ($SSstereo_recording =='5') ) and ($SSstereo_parallel_recording == '1') ) + { + echo "\n"; + + echo "\n"; + + echo "\n"; + + echo "\n"; + } + else + { + echo "\n"; + } + if ( ( ($SSrecording_dtmf_muting =='1') or ($SSrecording_dtmf_muting =='2') or ($SSrecording_dtmf_muting =='3') ) and ($SSrecording_dtmf_detection == '1') ) + { + echo "\n"; + } + else + { + echo "\n"; + } + echo "\n"; echo "\n"; @@ -44183,7 +44346,7 @@ function ajax_logout_now() $ALLagent_count = $rowx[2]; } - $stmt="SELECT version,install_date,use_non_latin,webroot_writable,enable_queuemetrics_logging,queuemetrics_server_ip,queuemetrics_dbname,queuemetrics_login,queuemetrics_pass,queuemetrics_url,queuemetrics_log_id,queuemetrics_eq_prepend,vicidial_agent_disable,allow_sipsak_messages,admin_home_url,enable_agc_xfer_log,db_schema_version,auto_user_add_value,timeclock_end_of_day,timeclock_last_reset_date,vdc_header_date_format,vdc_customer_date_format,vdc_header_phone_format,vdc_agent_api_active,qc_last_pull_time,enable_vtiger_integration,vtiger_server_ip,vtiger_dbname,vtiger_login,vtiger_pass,vtiger_url,qc_features_active,outbound_autodial_active,outbound_calls_per_second,enable_tts_integration,agentonly_callback_campaign_lock,sounds_central_control_active,sounds_web_server,sounds_web_directory,active_voicemail_server,auto_dial_limit,user_territories_active,allow_custom_dialplan,db_schema_update_date,enable_second_webform,default_webphone,default_external_server_ip,webphone_url,enable_agc_dispo_log,custom_dialplan_entry,queuemetrics_loginout,callcard_enabled,queuemetrics_callstatus,default_codecs,admin_web_directory,label_title,label_first_name,label_middle_initial,label_last_name,label_address1,label_address2,label_address3,label_city,label_state,label_province,label_postal_code,label_vendor_lead_code,label_gender,label_phone_number,label_phone_code,label_alt_phone,label_security_phrase,label_email,label_comments,custom_fields_enabled,slave_db_server,reports_use_slave_db,webphone_systemkey,first_login_trigger,default_phone_registration_password,default_phone_login_password,default_server_password,admin_modify_refresh,nocache_admin,generate_cross_server_exten,queuemetrics_addmember_enabled,queuemetrics_dispo_pause,label_hide_field_logs,queuemetrics_pe_phone_append,test_campaign_calls,agents_calls_reset,default_voicemail_timezone,default_local_gmt,noanswer_log,alt_log_server_ip,alt_log_dbname,alt_log_login,alt_log_pass,tables_use_alt_log_db,did_agent_log,campaign_cid_areacodes_enabled,pllb_grouping_limit,did_ra_extensions_enabled,expanded_list_stats,contacts_enabled,call_menu_qualify_enabled,admin_list_counts,allow_voicemail_greeting,svn_revision,queuemetrics_socket,queuemetrics_socket_url,enhanced_disconnect_logging,allow_emails,level_8_disable_add,pass_hash_enabled,pass_key,pass_cost,disable_auto_dial,queuemetrics_record_hold,country_code_list_stats,reload_timestamp,queuemetrics_pause_type,frozen_server_call_clear,callback_time_24hour,allow_chats,chat_url,chat_timeout,enable_languages,language_method,meetme_enter_login_filename,meetme_enter_leave3way_filename,enable_did_entry_list_id,enable_third_webform,agent_debug_logging,default_language,agent_whisper_enabled,user_hide_realtime_enabled,usacan_phone_dialcode_fix,cache_carrier_stats_realtime,oldest_logs_date,log_recording_access,report_default_format,alt_ivr_logging,default_phone_code,admin_row_click,admin_screen_colors,ofcom_uk_drop_calc,agent_screen_colors,script_remove_js,manual_auto_next,user_new_lead_limit,agent_xfer_park_3way,rec_prompt_count,agent_soundboards,web_loader_phone_length,agent_script,agent_chat_screen_colors,enable_auto_reports,enable_pause_code_limits,enable_drop_lists,allow_ip_lists,system_ip_blacklist,agent_push_events,agent_push_url,hide_inactive_lists,allow_manage_active_lists,expired_lists_inactive,did_system_filter,anyone_callback_inactive_lists,enable_gdpr_download_deletion,source_id_display,agent_logout_link,manual_dial_validation,mute_recordings,user_admin_redirect,list_status_modification_confirmation,sip_event_logging,call_quota_lead_ranking,enable_second_script,enable_first_webform,recording_buttons,opensips_cid_name,require_password_length,user_account_emails,outbound_cid_any,entries_per_page,browser_call_alerts,queuemetrics_pausereason,inbound_answer_config,enable_international_dncs,web_loader_phone_strip,manual_dial_phone_strip,daily_call_count_limit,allow_shared_dial,agent_search_method,phone_defaults_container,qc_claim_limit,qc_expire_days,two_factor_auth_hours,two_factor_container,agent_hidden_sound,agent_hidden_sound_volume,agent_hidden_sound_seconds,agent_screen_timer,label_lead_id,label_list_id,label_entry_date,label_gmt_offset_now,label_source_id,label_called_since_last_reset,label_status,label_user,label_date_of_birth,label_country_code,label_last_local_call_time,label_called_count,label_rank,label_owner,label_entry_list_id,call_limit_24hour,allowed_sip_stacks,agent_hide_hangup,allow_web_debug,max_logged_in_agents,user_codes_admin,login_kickall,abandon_check_queue,agent_notifications,demographic_quotas,log_latency_gaps,inbound_credits,weekday_resets,two_factor_auth_agent_hours,highest_lead_id,hopper_hold_inserts,coldstorage_server_ip,coldstorage_dbname,coldstorage_login,coldstorage_pass,coldstorage_port,enhanced_agent_monitoring,agent_hide_dial_fail,agent_man_dial_filter,agent_3way_dial_filter from system_settings;"; + $stmt="SELECT version,install_date,use_non_latin,webroot_writable,enable_queuemetrics_logging,queuemetrics_server_ip,queuemetrics_dbname,queuemetrics_login,queuemetrics_pass,queuemetrics_url,queuemetrics_log_id,queuemetrics_eq_prepend,vicidial_agent_disable,allow_sipsak_messages,admin_home_url,enable_agc_xfer_log,db_schema_version,auto_user_add_value,timeclock_end_of_day,timeclock_last_reset_date,vdc_header_date_format,vdc_customer_date_format,vdc_header_phone_format,vdc_agent_api_active,qc_last_pull_time,enable_vtiger_integration,vtiger_server_ip,vtiger_dbname,vtiger_login,vtiger_pass,vtiger_url,qc_features_active,outbound_autodial_active,outbound_calls_per_second,enable_tts_integration,agentonly_callback_campaign_lock,sounds_central_control_active,sounds_web_server,sounds_web_directory,active_voicemail_server,auto_dial_limit,user_territories_active,allow_custom_dialplan,db_schema_update_date,enable_second_webform,default_webphone,default_external_server_ip,webphone_url,enable_agc_dispo_log,custom_dialplan_entry,queuemetrics_loginout,callcard_enabled,queuemetrics_callstatus,default_codecs,admin_web_directory,label_title,label_first_name,label_middle_initial,label_last_name,label_address1,label_address2,label_address3,label_city,label_state,label_province,label_postal_code,label_vendor_lead_code,label_gender,label_phone_number,label_phone_code,label_alt_phone,label_security_phrase,label_email,label_comments,custom_fields_enabled,slave_db_server,reports_use_slave_db,webphone_systemkey,first_login_trigger,default_phone_registration_password,default_phone_login_password,default_server_password,admin_modify_refresh,nocache_admin,generate_cross_server_exten,queuemetrics_addmember_enabled,queuemetrics_dispo_pause,label_hide_field_logs,queuemetrics_pe_phone_append,test_campaign_calls,agents_calls_reset,default_voicemail_timezone,default_local_gmt,noanswer_log,alt_log_server_ip,alt_log_dbname,alt_log_login,alt_log_pass,tables_use_alt_log_db,did_agent_log,campaign_cid_areacodes_enabled,pllb_grouping_limit,did_ra_extensions_enabled,expanded_list_stats,contacts_enabled,call_menu_qualify_enabled,admin_list_counts,allow_voicemail_greeting,svn_revision,queuemetrics_socket,queuemetrics_socket_url,enhanced_disconnect_logging,allow_emails,level_8_disable_add,pass_hash_enabled,pass_key,pass_cost,disable_auto_dial,queuemetrics_record_hold,country_code_list_stats,reload_timestamp,queuemetrics_pause_type,frozen_server_call_clear,callback_time_24hour,allow_chats,chat_url,chat_timeout,enable_languages,language_method,meetme_enter_login_filename,meetme_enter_leave3way_filename,enable_did_entry_list_id,enable_third_webform,agent_debug_logging,default_language,agent_whisper_enabled,user_hide_realtime_enabled,usacan_phone_dialcode_fix,cache_carrier_stats_realtime,oldest_logs_date,log_recording_access,report_default_format,alt_ivr_logging,default_phone_code,admin_row_click,admin_screen_colors,ofcom_uk_drop_calc,agent_screen_colors,script_remove_js,manual_auto_next,user_new_lead_limit,agent_xfer_park_3way,rec_prompt_count,agent_soundboards,web_loader_phone_length,agent_script,agent_chat_screen_colors,enable_auto_reports,enable_pause_code_limits,enable_drop_lists,allow_ip_lists,system_ip_blacklist,agent_push_events,agent_push_url,hide_inactive_lists,allow_manage_active_lists,expired_lists_inactive,did_system_filter,anyone_callback_inactive_lists,enable_gdpr_download_deletion,source_id_display,agent_logout_link,manual_dial_validation,mute_recordings,user_admin_redirect,list_status_modification_confirmation,sip_event_logging,call_quota_lead_ranking,enable_second_script,enable_first_webform,recording_buttons,opensips_cid_name,require_password_length,user_account_emails,outbound_cid_any,entries_per_page,browser_call_alerts,queuemetrics_pausereason,inbound_answer_config,enable_international_dncs,web_loader_phone_strip,manual_dial_phone_strip,daily_call_count_limit,allow_shared_dial,agent_search_method,phone_defaults_container,qc_claim_limit,qc_expire_days,two_factor_auth_hours,two_factor_container,agent_hidden_sound,agent_hidden_sound_volume,agent_hidden_sound_seconds,agent_screen_timer,label_lead_id,label_list_id,label_entry_date,label_gmt_offset_now,label_source_id,label_called_since_last_reset,label_status,label_user,label_date_of_birth,label_country_code,label_last_local_call_time,label_called_count,label_rank,label_owner,label_entry_list_id,call_limit_24hour,allowed_sip_stacks,agent_hide_hangup,allow_web_debug,max_logged_in_agents,user_codes_admin,login_kickall,abandon_check_queue,agent_notifications,demographic_quotas,log_latency_gaps,inbound_credits,weekday_resets,two_factor_auth_agent_hours,highest_lead_id,hopper_hold_inserts,coldstorage_server_ip,coldstorage_dbname,coldstorage_login,coldstorage_pass,coldstorage_port,enhanced_agent_monitoring,agent_hide_dial_fail,agent_man_dial_filter,agent_3way_dial_filter,stereo_recording,recording_dtmf_detection,recording_dtmf_muting,stereo_parallel_recording from system_settings;"; $rslt=mysql_to_mysqli($stmt, $link); $row=mysqli_fetch_row($rslt); $version = $row[0]; @@ -44430,6 +44593,10 @@ function ajax_logout_now() $agent_hide_dial_fail = $row[241]; $agent_man_dial_filter = $row[242]; $agent_3way_dial_filter = $row[243]; + $stereo_recording = $row[244]; + $recording_dtmf_detection = $row[245]; + $recording_dtmf_muting = $row[246]; + $stereo_parallel_recording = $row[247]; if ($pass_hash_enabled > 0) {$pass_hash_enabled = 'ENABLED';} else {$pass_hash_enabled = 'DISABLED';} @@ -45011,6 +45178,23 @@ function ajax_logout_now() echo "\n"; + if ($stereo_dev_mode > 0) + { + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + } + else + { + echo "\n"; + } + echo "\n"; echo "\n"; diff --git a/www/vicidial/admin_modify_lead.php b/www/vicidial/admin_modify_lead.php index 8208f4949..e04214dfc 100644 --- a/www/vicidial/admin_modify_lead.php +++ b/www/vicidial/admin_modify_lead.php @@ -120,6 +120,7 @@ # 240704-2329 - Added coldstorage log view option # 241002-0936 - Fix for displaying CID info on outbound calls that were blind transferred # 250129-0921 - Fix for closer call notes display, Issue #1534 +# 250913-0837 - Added Stereo Call Recording indicator # require("dbconnect_mysqli.php"); @@ -281,7 +282,7 @@ ############################################# ##### START SYSTEM_SETTINGS LOOKUP ##### -$stmt = "SELECT use_non_latin,custom_fields_enabled,webroot_writable,allow_emails,enable_languages,language_method,active_modules,log_recording_access,admin_screen_colors,enable_gdpr_download_deletion,source_id_display,mute_recordings,sip_event_logging,allow_web_debug,hopper_hold_inserts,coldstorage_server_ip,coldstorage_dbname,coldstorage_login,coldstorage_pass,coldstorage_port FROM system_settings;"; +$stmt = "SELECT use_non_latin,custom_fields_enabled,webroot_writable,allow_emails,enable_languages,language_method,active_modules,log_recording_access,admin_screen_colors,enable_gdpr_download_deletion,source_id_display,mute_recordings,sip_event_logging,allow_web_debug,hopper_hold_inserts,coldstorage_server_ip,coldstorage_dbname,coldstorage_login,coldstorage_pass,coldstorage_port,stereo_recording FROM system_settings;"; $rslt=mysql_to_mysqli($stmt, $link); #if ($DB) {echo "$stmt\n";} $qm_conf_ct = mysqli_num_rows($rslt); @@ -308,6 +309,7 @@ $SScoldstorage_login = $row[17]; $SScoldstorage_pass = $row[18]; $SScoldstorage_port = $row[19]; + $SSstereo_recording = $row[20]; } if ($SSallow_web_debug < 1) {$DB=0;} ##### END SETTINGS LOOKUP ##### @@ -4003,12 +4005,17 @@ function getMousePos(event) {mouseY=event.pageY;} $mute_column=''; if ($SSmute_recordings > 0) { - $mute_column = ""; + $mute_column = ""; + } + $stereo_column=''; + if ($SSstereo_recording > 0) + { + $stereo_column = ""; } echo ""._QXZ("RECORDINGS FOR THIS LEAD").":\n"; echo "
\n"; echo ""; - $stmt="SELECT group_id,group_name,group_color,active,web_form_address,voicemail_ext,next_agent_call,fronter_display,ingroup_script,get_call_launch,xferconf_a_dtmf,xferconf_a_number,xferconf_b_dtmf,xferconf_b_number,drop_call_seconds,drop_action,drop_exten,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,default_xfer_group,queue_priority,drop_inbound_group,ingroup_recording_override,ingroup_rec_filename,afterhours_xfer_group,qc_enabled,qc_statuses,qc_shift_id,qc_get_record_launch,qc_show_recording,qc_web_form_address,qc_script,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,answer_sec_pct_rt_stat_one,answer_sec_pct_rt_stat_two,default_group_alias,no_agent_no_queue,no_agent_action,no_agent_action_value,web_form_address_two,timer_action,timer_action_message,timer_action_seconds,start_call_url,dispo_call_url,xferconf_c_number,xferconf_d_number,xferconf_e_number,ignore_list_script_override,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,timer_action_destination,calculate_estimated_hold_seconds,add_lead_url,eht_minimum_prompt_filename,eht_minimum_prompt_no_block,eht_minimum_prompt_seconds,on_hook_ring_time,na_call_url,on_hook_cid,group_calldate,action_xfer_cid,drop_callmenu,after_hours_callmenu,user_group,max_calls_method,max_calls_count,max_calls_action,dial_ingroup_cid,group_handling,web_form_address_three,populate_lead_ingroup,drop_lead_reset,after_hours_lead_reset,nanq_lead_reset,wait_time_lead_reset,hold_time_lead_reset,status_group_id,routing_initiated_recordings,on_hook_cid_number,customer_chat_screen_colors,customer_chat_survey_link,customer_chat_survey_text,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,inbound_survey_question_filename,inbound_survey_callmenu,icbq_expiration_hours,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,icbq_call_time_id,add_lead_timezone,icbq_dial_filter,populate_lead_source,populate_lead_vendor,park_file_name,waiting_call_url_on,waiting_call_url_off,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,ingroup_script_two,browser_alert_sound,browser_alert_volume,answer_signal,no_agent_delay,agent_search_method,qc_scorecard_id,qc_statuses_id,populate_lead_comments,drop_call_seconds_override,populate_lead_owner,in_queue_nanque,in_queue_nanque_exceptions,custom_one,custom_two,custom_three,custom_four,custom_five,second_alert_trigger,second_alert_trigger_seconds,second_alert_filename,second_alert_delay,second_alert_container,second_alert_only,third_alert_trigger,third_alert_trigger_seconds,third_alert_filename,third_alert_delay,third_alert_container,third_alert_only,agent_search_list,state_descriptions from vicidial_inbound_groups where group_id='$group_id' $LOGadmin_viewable_groupsSQL;"; + $stmt="SELECT group_id,group_name,group_color,active,web_form_address,voicemail_ext,next_agent_call,fronter_display,ingroup_script,get_call_launch,xferconf_a_dtmf,xferconf_a_number,xferconf_b_dtmf,xferconf_b_number,drop_call_seconds,drop_action,drop_exten,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,default_xfer_group,queue_priority,drop_inbound_group,ingroup_recording_override,ingroup_rec_filename,afterhours_xfer_group,qc_enabled,qc_statuses,qc_shift_id,qc_get_record_launch,qc_show_recording,qc_web_form_address,qc_script,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,answer_sec_pct_rt_stat_one,answer_sec_pct_rt_stat_two,default_group_alias,no_agent_no_queue,no_agent_action,no_agent_action_value,web_form_address_two,timer_action,timer_action_message,timer_action_seconds,start_call_url,dispo_call_url,xferconf_c_number,xferconf_d_number,xferconf_e_number,ignore_list_script_override,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,timer_action_destination,calculate_estimated_hold_seconds,add_lead_url,eht_minimum_prompt_filename,eht_minimum_prompt_no_block,eht_minimum_prompt_seconds,on_hook_ring_time,na_call_url,on_hook_cid,group_calldate,action_xfer_cid,drop_callmenu,after_hours_callmenu,user_group,max_calls_method,max_calls_count,max_calls_action,dial_ingroup_cid,group_handling,web_form_address_three,populate_lead_ingroup,drop_lead_reset,after_hours_lead_reset,nanq_lead_reset,wait_time_lead_reset,hold_time_lead_reset,status_group_id,routing_initiated_recordings,on_hook_cid_number,customer_chat_screen_colors,customer_chat_survey_link,customer_chat_survey_text,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,inbound_survey_question_filename,inbound_survey_callmenu,icbq_expiration_hours,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,icbq_call_time_id,add_lead_timezone,icbq_dial_filter,populate_lead_source,populate_lead_vendor,park_file_name,waiting_call_url_on,waiting_call_url_off,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,ingroup_script_two,browser_alert_sound,browser_alert_volume,answer_signal,no_agent_delay,agent_search_method,qc_scorecard_id,qc_statuses_id,populate_lead_comments,drop_call_seconds_override,populate_lead_owner,in_queue_nanque,in_queue_nanque_exceptions,custom_one,custom_two,custom_three,custom_four,custom_five,second_alert_trigger,second_alert_trigger_seconds,second_alert_filename,second_alert_delay,second_alert_container,second_alert_only,third_alert_trigger,third_alert_trigger_seconds,third_alert_filename,third_alert_delay,third_alert_container,third_alert_only,agent_search_list,state_descriptions,stereo_recording,stereo_rec_filename,stereo_parallel_recording,recording_dtmf_muting,stereo_recording_agent,parallel_rec_co_filename,parallel_rec_cm_filename,parallel_rec_fr_filename from vicidial_inbound_groups where group_id='$group_id' $LOGadmin_viewable_groupsSQL;"; $rslt=mysql_to_mysqli($stmt, $link); $row=mysqli_fetch_row($rslt); @@ -34008,6 +34128,14 @@ function ajax_logout_now() $third_alert_only = $row[200]; $agent_search_list = $row[201]; $state_descriptions = $row[202]; + $stereo_recording = $row[203]; + $stereo_rec_filename = $row[204]; + $stereo_parallel_recording = $row[205]; + $recording_dtmf_muting = $row[206]; + $stereo_recording_agent = $row[207]; + $parallel_rec_co_filename = $row[208]; + $parallel_rec_cm_filename = $row[209]; + $parallel_rec_fr_filename = $row[210]; ##### get callmenu listings for dynamic pulldown $stmt="SELECT menu_id,menu_name from vicidial_call_menu $whereLOGadmin_viewable_groupsSQL order by menu_id;"; @@ -35061,6 +35189,41 @@ function ajax_logout_now() echo "
"._QXZ("Routing Initiated Recording").": $NWB#inbound_groups-routing_initiated_recordings$NWE
"._QXZ("Stereo Call Recordings").": $NWB#inbound_groups-stereo_recording$NWE
"._QXZ("Stereo Recording Agent Control").": $NWB#inbound_groups-stereo_recording_agent$NWE
"._QXZ("Stereo Rec Filename").": $NWB#inbound_groups-stereo_rec_filename$NWE
"._QXZ("Parallel Stereo Recordings").": $NWB#inbound_groups-stereo_parallel_recording$NWE
"._QXZ("Parallel Customer-Only Rec Filename").": $NWB#inbound_groups-parallel_rec_xx_filename$NWE
"._QXZ("Parallel Customer-Muted Rec Filename").": $NWB#inbound_groups-parallel_rec_xx_filename$NWE
"._QXZ("Parallel Full-Recording Rec Filename").": $NWB#inbound_groups-parallel_rec_xx_filename$NWE
"._QXZ("Recording DTMF Muting").": $NWB#inbound_groups-recording_dtmf_muting$NWE
"._QXZ("Stats Percent of Calls Answered Within X seconds")." 1: $NWB#inbound_groups-answer_sec_pct_rt_stat_one$NWE
"._QXZ("Stats Percent of Calls Answered Within X seconds")." 2: $NWB#inbound_groups-answer_sec_pct_rt_stat_one$NWE
"._QXZ("Allow Mute Recordings").": $NWB#settings-mute_recordings$NWE
"._QXZ("Allow Stereo Recordings").": $NWB#settings-stereo_recording$NWE
"._QXZ("Enable Stereo Parallel Recordings").": $NWB#settings-stereo_parallel_recording$NWE
"._QXZ("Allow Recording DTMF Detection").": $NWB#settings-recording_dtmf_detection$NWE
"._QXZ("Allow Recording DTMF Muting").": $NWB#settings-recording_dtmf_muting$NWE
\n"; + echo ""; + echo ""; + echo ""; + echo ""; + echo "
"._QXZ("First Login Trigger").": "._QXZ("$first_login_trigger")."   $NWB#settings-first_login_trigger$NWE
"._QXZ("User Password Minimum Length").": $NWB#settings-require_password_length$NWE
"._QXZ("MUTE").""._QXZ("MUTE")."   "._QXZ("STEREO")."
\n"; - echo "$mute_column\n"; + echo "$mute_column$stereo_column\n"; $stmt="SELECT recording_id,channel,server_ip,extension,start_time,start_epoch,end_time,end_epoch,length_in_sec,length_in_min,filename,location,lead_id,user,vicidial_id from recording_log where lead_id='" . mysqli_real_escape_string($link, $lead_id) . "' order by recording_id desc limit 500;"; $rslt=mysql_to_mysqli($stmt, $link); @@ -4024,7 +4031,8 @@ function getMousePos(event) {mouseY=event.pageY;} else {$bgcolor="bgcolor=\"#$SSstd_row1_background\"";} - $location = $row[11]; + $stereo_flag = $row[3]; + $location = $row[11]; if (strlen($location)>2) { @@ -4098,7 +4106,12 @@ function getMousePos(event) {mouseY=event.pageY;} if ($SSmute_recordings > 0) { if ($mute_events < 1) {$mute_events='';} - echo "\n"; + echo "\n"; + } + if ($SSstereo_recording > 0) + { + if (!preg_match("/^S/",$stereo_flag)) {$stereo_flag='';} + echo "\n"; } echo "$play_audio"; echo "\n"; diff --git a/www/vicidial/help_documentation.txt b/www/vicidial/help_documentation.txt index b9de10651..efc304816 100644 --- a/www/vicidial/help_documentation.txt +++ b/www/vicidial/help_documentation.txt @@ -1,4 +1,4 @@ -# version: 20250808112301 +# version: 20250917172301 users-user User ID 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-. users-pass Password This field is where you put the users password. Must be at least 2 characters in length, unless the User Password Minimum Length system setting is enabled, which will require a longer password. 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. users-force_change_password Force Change Password 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. @@ -269,6 +269,12 @@ campaigns-campaign_rec_filename Campaign Rec Filename This field allows you campaigns-allcalls_delay Recording Delay For ALLCALLS and ALLFORCE recording only. This setting will delay the starting of the recording on all calls for the number of seconds specified in this field. Default is 0. campaigns-routing_initiated_recordings Routing Initiated Recording This option, if enabled, allows you to have the call routing script for Outbound auto-dial 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 work with agent manual dialed calls only if the recording delay is also set to 0. Default is N for disabled. campaigns-mute_recordings Mute Recording Button This option, if enabled, will make the MUTE RECORDING button appear on the agent screen below the existing recording button. If a recording is muted, it will record silence or pause the recording until the MUTE RECORDING button is clicked a second time. You should not mute recordings for more than 15 minutes at a time. Default is N for disabled. +campaigns-stereo_recording Stereo Call Recordings If set to anything but DISABLED, this will allow additional stereo recordings with the customer on one side and the agent on the other for calls placed from this campaign. If set to CUSTOMER_ONLY, the agent side will be silent. If set to CUSTOMER_MUTE, the customer side will be silent. If set to BOTH_CHANNELS, then all audio will be included. Default is DISABLED. +campaigns-stereo_recording_agent Stereo Recording Agent Control If Stereo Call Recordings is enabled, this setting will define if the agent has control over the Stereo Call Recordings, and if so, how much control they have. NEVER will disable stereo recording on the client. ONDEMAND 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 is the default and will start recording on the client whenever a call is sent to an agent giving the agent no option to stop recording. Default is ALLFORCE. +campaigns-stereo_rec_filename Stereo Rec Filename If Stereo Call Recordings is enabled, this will be the recording filename of the Stereo call recordings. This cannot be set the same as the Campaign Rec Filename. This field is required to be populated for Stereo Call Recording to work for calls placed from this campaign. The dynamic fields that can be used are the same as can be used in the Campaign Rec Filename. Default is S_FULLDATE_CUSTPHONE. +campaigns-stereo_parallel_recording Parallel Stereo Recordings if enabled, then every call will be recorded in its entirety, from when the agent receives it until it leaves the agent session. The options include: CUSTOMER-ONLY, CUSTOMER-MUTED and FULL-RECORDING. If Stereo Recording Agent Control is also enabled, that can itself also result in multiple recordings on a single call. Default is DISABLED. +campaigns-parallel_rec_xx_filename Parallel Rec Filenames If Parallel Stereo Recordings are enabled, then these optional fields can be used to customize the call recording filenames for each type of Parallel Stereo Call Recording. If these fields are not populated, then the system will default to use the Stereo Rec Filename with a prefix at the beginning of each filename for the type of Parallel Stereo Call Recording that has been used: CO for Customer-Only, CM for Customer-Muted and FR for Full-Recording. Default is blank for all 3 of these fields. +campaigns-recording_dtmf_muting Recording DTMF Muting NOT FUNCTIONAL, STILL IN DEVELOPMENT. If enabled, and Allow Recording DTMF Detection is also enabled, call recordings will be muted for this number of seconds after the first DTMF signal is detected while recording is active. Default is 0 for disabled. campaigns-per_call_notes Call Notes Per Call Setting this option to ENABLED will allow agents to enter in notes for every call they handle in the agent interface. The notes entry field will appear below the Comments field in the agent interface. Also, if the Agent User Group is allowed to view Call Logs then the agent will be able to view past call notes for a lead at any time. Default is DISABLED. campaigns-force_per_call_notes Per Call Notes Required If enabled, the agent will have to enter text into the Call Notes field on their agent screen in order to Hangup the Customer phone call. The CHARACTERS options will also enable this feature, but they will require a minimum number of characters to be entered to allow hangup. Default is DISABLED. campaigns-comments_all_tabs Comments All Tabs Setting this option to ENABLED will display the Comments field on all tabs in the main agent screen. Default is DISABLED. @@ -663,6 +669,12 @@ inbound_groups-default_xfer_group Default Transfer Group This field is the inbound_groups-ingroup_recording_override In-Group Recording Override 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. inbound_groups-routing_initiated_recordings Routing Initiated Recording 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. inbound_groups-ingroup_rec_filename In-Group Recording Filename This field will override the Campaign Recording Filenaming Scheme unless it is set to NONE. The allowed variables are CAMPAIGN INGROUP CUSTPHONE FULLDATE TINYDATE EPOCH AGENT VENDORLEADCODE LEADID CALLID RECID. If your dialers have --POST recording processing enabled, you can also use POSTVLC POSTSP POSTARRD3 POSTSTATUS. These POST options will alter the recording file name after the call has been finished and will replace the post variable with the value from the default fields. The default is FULLDATE_AGENT and would look like this 20051020-103108_6666. Another example is CAMPAIGN_TINYDATE_CUSTPHONE which would look like this TESTCAMP_51020103108_3125551212. The resulting filename must be less than 90 characters in length. Default is NONE. +inbound_groups-stereo_recording Stereo Call Recordings If set to anything but DISABLED, this will allow additional stereo recordings with the customer on one side and the agent on the other for calls handled through this In-Group. If set to CUSTOMER_ONLY, the agent side will be silent. If set to CUSTOMER_MUTE, the customer side will be silent. If set to BOTH_CHANNELS, then all audio will be included. Default is DISABLED. NOTE: these Stereo Recording options do NOT default to inherit settings from whatever campaign the agent is logged into, which is how default mono call recording works. If you want calls handled through an In-Group to be Stereo Recorded, then that In-Group needs to have these settings enabled. +inbound_groups-stereo_recording_agent Stereo Recording Agent Control If Stereo Call Recordings is enabled, this setting will define if the agent has control over the Stereo Call Recordings for calls handled through this In-Group, and if so, how much control they have. NEVER will disable stereo recording on the client. ONDEMAND 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 is the default and will start recording on the client whenever a call is sent to an agent giving the agent no option to stop recording. Default is ALLFORCE. +inbound_groups-stereo_rec_filename Stereo Rec Filename If Stereo Call Recordings is enabled, this will be the recording filename of the Stereo call recordings for calls handled through this In-Group. This cannot be set the same as the Campaign Rec Filename. This field is required to be populated for Stereo Call Recording to work for calls handled through this In-Group. The dynamic fields that can be used are the same as can be used in the In-Group Recording Filename. Default is S_FULLDATE_CUSTPHONE. +inbound_groups-stereo_parallel_recording Parallel Stereo Recordings if enabled, then every call will be recorded in its entirety for calls handled through this In-Group, from when the agent receives it until it leaves the agent session. The options include: CUSTOMER-ONLY, CUSTOMER-MUTED and FULL-RECORDING. If Stereo Recording Agent Control is also enabled, that can itself also result in multiple recordings on a single call. Default is DISABLED. +inbound_groups-parallel_rec_xx_filename Parallel Rec Filenames If Parallel Stereo Recordings are enabled, then these optional fields can be used to customize the call recording filenames for each type of Parallel Stereo Call Recording. If these fields are not populated, then the system will default to use the Stereo Rec Filename with a prefix at the beginning of each filename for the type of Parallel Stereo Call Recording that has been used: CO for Customer-Only, CM for Customer-Muted and FR for Full-Recording. Default is blank for all 3 of these fields. +inbound_groups-recording_dtmf_muting Recording DTMF Muting NOT FUNCTIONAL, STILL IN DEVELOPMENT. If enabled, and Allow Recording DTMF Detection is also enabled, call recordings for calls handled through this In-Group will be muted for this number of seconds after the first DTMF signal is detected while recording is active. Default is 0 for disabled. inbound_groups-qc_enabled QC Enabled Setting this field to Y allows for the agent Quality Control features to work. Default is N. inbound_groups-qc_statuses QC Statuses This area is where you select which statuses of leads should be gone over by the QC system. Place a check next to the status that you want QC to review. inbound_groups-qc_statuses_id QC Statuses ID This area is where you select which "QC_TEMPLATE" settings container will be used to determine the call statuses that are eligible for QC evaluation in this ingroup. This will override both campaign and list "QC Statuses ID" settings. @@ -1235,6 +1247,10 @@ settings-agent_push_url Agent Push URL If Agent Push Events are enabled abo settings-log_recording_access Log Recording Access This option if enabled allows the logging of user access to call recordings. It also requires the User setting Access Recordings to be set to 1 to allow a user to access call recordings. Default is 0 for disabled. settings-recording_buttons Recording Buttons Type This option allows you to choose the appearance of the recording buttons on the agent screen. START_STOP will show a START RECORDING button if the call is not recording and a STOP RECORDING button when the call is recording. The RECORDING option will show a red NOT RECORDING button if the call is not recording and a green RECORDING button when the call is recording. If NOGAP is part of the option, then the space below the recording button will be removed. If 2xHEIGHT is part of the option, then the recording button will be double the height. Default is START_STOP. settings-mute_recordings Allow Mute Recordings This option if enabled allows you to enable the MUTE RECORDING button on the agent screen by campaign and-or user. This feature is only tested with systems running Asterisk 13. You should not mute recordings for more than 15 minutes at a time. Default is 0 for disabled. +settings-stereo_recording Allow Stereo Recordings If enabled, allows for additional call recordings in stereo, with the customer on one side and the agent on the other. Must also be enabled at the campaign level. Enabling this setting may require additional system resources if standard mono recordings are also still enabled. Default is 0 for disabled. +settings-stereo_parallel_recording Enable Stereo Parallel Recordings If enabled, and Allow Stereo Recordings is also enabled, allows for multiple parallel stereo call recordings for every call. Enabling this setting will require additional system resources, since every call will be recorded in its entirety, and post-call processing will be required to facilitate all of this settings features. Must also be enabled at the campaign level. Default is 0 for disabled. +settings-recording_dtmf_detection Allow Recording DTMF Detection NOT FUNCTIONAL, STILL IN DEVELOPMENT. If enabled, recordings will be flagged if any DTMF signals are detected during the recording duration. Default is 0 for disabled. +settings-recording_dtmf_muting Allow Recording DTMF Muting NOT FUNCTIONAL, STILL IN DEVELOPMENT. If enabled, and Allow Recording DTMF Detection is also enabled, call recordings will be muted for X seconds after the first DTMF signal is detected while recording is active. Must also be enabled at the campaign level. Default is 0 for disabled. settings-enable_auto_reports Enable Automated Reports This option if enabled allows you access to the Automated Reports section where you can set up reports to run at scheduled times and be delivered by email or FTP. Default is 0 for disabled. settings-first_login_trigger First Login Trigger This setting allows for the initial configuration of the server screen to be shown to the administrator when they first log into the system. settings-require_password_length User Password Minimum Length If set above 0, this setting will require that user passwords, phone and server passwords, and system settings default passwords be at least this minimum length of characters when those records settings are modified on the Modify pages. The most important factor in password security is the length of the password, and user passwords in this system can be up to 100 characters in length. Default is 0 for disabled. From 1092154f8c21695feeaba4864692a70ddb921a24 Mon Sep 17 00:00:00 2001 From: Mattf Date: Fri, 19 Sep 2025 18:03:14 +0000 Subject: [PATCH 02/12] fix for last commit git-svn-id: svn://svn.eflo.net/agc_2-X/trunk@3942 3d104415-ff17-0410-8863-d5cf3c621b8a --- extras/MySQL_AST_CREATE_tables.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extras/MySQL_AST_CREATE_tables.sql b/extras/MySQL_AST_CREATE_tables.sql index 212f2e17f..ea0bc1b52 100644 --- a/extras/MySQL_AST_CREATE_tables.sql +++ b/extras/MySQL_AST_CREATE_tables.sql @@ -1140,7 +1140,7 @@ stereo_rec_filename VARCHAR(50) default 'S_FULLDATE_CUSTPHONE', stereo_parallel_recording VARCHAR(50) default 'DISABLED', parallel_rec_co_filename VARCHAR(50) default '', parallel_rec_cm_filename VARCHAR(50) default '', -parallel_rec_fr_filename VARCHAR(50) default '' +parallel_rec_fr_filename VARCHAR(50) default '', recording_dtmf_muting SMALLINT(3) UNSIGNED default '0', stereo_recording_agent ENUM('NEVER','ONDEMAND','ALLCALLS','ALLFORCE') default 'ALLFORCE', ) ENGINE=MyISAM; @@ -1476,7 +1476,7 @@ stereo_rec_filename VARCHAR(50) default 'S_FULLDATE_CUSTPHONE', stereo_parallel_recording VARCHAR(50) default 'DISABLED', parallel_rec_co_filename VARCHAR(50) default '', parallel_rec_cm_filename VARCHAR(50) default '', -parallel_rec_fr_filename VARCHAR(50) default '' +parallel_rec_fr_filename VARCHAR(50) default '', recording_dtmf_muting SMALLINT(3) UNSIGNED default '0', stereo_recording_agent ENUM('NEVER','ONDEMAND','ALLCALLS','ALLFORCE','DISABLED') default 'ALLFORCE' ) ENGINE=MyISAM; From 245d3e22ede326415500ecdf4c368fc3594633e7 Mon Sep 17 00:00:00 2001 From: Mattf Date: Fri, 19 Sep 2025 18:34:52 +0000 Subject: [PATCH 03/12] more fixes for last commit git-svn-id: svn://svn.eflo.net/agc_2-X/trunk@3943 3d104415-ff17-0410-8863-d5cf3c621b8a --- docs/STEREO_CALL_RECORDINGS.txt | 2 +- extras/MySQL_AST_CREATE_tables.sql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/STEREO_CALL_RECORDINGS.txt b/docs/STEREO_CALL_RECORDINGS.txt index fc2556aa0..3934aa3ed 100644 --- a/docs/STEREO_CALL_RECORDINGS.txt +++ b/docs/STEREO_CALL_RECORDINGS.txt @@ -1,7 +1,7 @@ VICIDIAL STEREO CALL RECORDINGS Started: 2025-06-18 Updated: 2025-09-19 -TO USE THESE FEATURES, YOU WILL NEED TO HAVE ALL SERVERS IN YOUR CLUSTER USING SVN/TRUNK REVISION 3940(2025-09-19) CODE OR HIGHER!!! +TO USE THESE FEATURES, YOU WILL NEED TO HAVE ALL SERVERS IN YOUR CLUSTER USING SVN/TRUNK REVISION 3943(2025-09-19) CODE OR HIGHER!!! This project was designed to allow for additional stereo recording of phone calls at the agent and server levels directly on VICIdial Asterisk servers, with the customer always on one channel(the Right channel) and the agent and all other parties on the other channel(the Left channel). If you are looking for the VICI Gateway Recording Server documentation, please see the GATEWAY_RECORDING_SERVER.txt document. diff --git a/extras/MySQL_AST_CREATE_tables.sql b/extras/MySQL_AST_CREATE_tables.sql index ea0bc1b52..d949d7b45 100644 --- a/extras/MySQL_AST_CREATE_tables.sql +++ b/extras/MySQL_AST_CREATE_tables.sql @@ -1142,7 +1142,7 @@ parallel_rec_co_filename VARCHAR(50) default '', parallel_rec_cm_filename VARCHAR(50) default '', parallel_rec_fr_filename VARCHAR(50) default '', recording_dtmf_muting SMALLINT(3) UNSIGNED default '0', -stereo_recording_agent ENUM('NEVER','ONDEMAND','ALLCALLS','ALLFORCE') default 'ALLFORCE', +stereo_recording_agent ENUM('NEVER','ONDEMAND','ALLCALLS','ALLFORCE') default 'ALLFORCE' ) ENGINE=MyISAM; CREATE TABLE vicidial_lists ( From 25a8e1811797b4f3814bbaadf6eaa94c66a1e715 Mon Sep 17 00:00:00 2001 From: Mattf Date: Mon, 22 Sep 2025 20:41:42 +0000 Subject: [PATCH 04/12] small change to Non-Agent API logging: in_group_status git-svn-id: svn://svn.eflo.net/agc_2-X/trunk@3944 3d104415-ff17-0410-8863-d5cf3c621b8a --- www/vicidial/non_agent_api.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/vicidial/non_agent_api.php b/www/vicidial/non_agent_api.php index b8af34ecd..359755036 100644 --- a/www/vicidial/non_agent_api.php +++ b/www/vicidial/non_agent_api.php @@ -12978,7 +12978,7 @@ echo "$output"; $result = 'SUCCESS'; - $data = "$user|$in_groups|$stage"; + $data = "$user|$in_groups|$stage|$total_agents_waiting"; $result_reason = "in_group_status CALLS FOUND: $k"; api_log($link,$api_logging,$api_script,$user,$agent_user,$function,$value,$result,$result_reason,$source,$data); From ed0de5cbef53ca8943fb9e40c3ed1136a35cc5e8 Mon Sep 17 00:00:00 2001 From: Mattf Date: Thu, 25 Sep 2025 17:02:37 +0000 Subject: [PATCH 05/12] Added Talk Seconds URLs features to campaigns and in-groups Small fix for Stereo Call Recordings Added code for Monitor Deprecation after Asterisk 20 git-svn-id: svn://svn.eflo.net/agc_2-X/trunk@3945 3d104415-ff17-0410-8863-d5cf3c621b8a --- UPGRADE | 15 + agi/VD_amd.agi | 15 +- agi/agi-DID_route.agi | 13 +- agi/agi-IVR_recording_verification.agi | 13 +- agi/agi-NVA_recording.agi | 13 +- agi/agi-VDAD_ALL_inbound.agi | 23 +- agi/agi-VDAD_ALL_outbound.agi | 39 +- agi/agi-VDAD_RINGALL.agi | 13 +- bin/ADMIN_keepalive_ALL.pl | 27 +- docs/STEREO_CALL_RECORDINGS.txt | 4 +- extras/MySQL_AST_CREATE_tables.sql | 4 +- extras/upgrade_2.14.sql | 6 +- www/agc/manager_send.php | 34 +- www/agc/vdc_db_query.php | 777 ++++++++++++++++++++++--- www/agc/vicidial.php | 97 ++- www/vicidial/admin.php | 84 ++- www/vicidial/admin_url_multi.php | 32 +- www/vicidial/help_documentation.txt | 6 +- 18 files changed, 1075 insertions(+), 140 deletions(-) diff --git a/UPGRADE b/UPGRADE index d991a0a57..f8c259423 100644 --- a/UPGRADE +++ b/UPGRADE @@ -871,6 +871,21 @@ OTHER CHANGES: setting. This can send a URL request when new leads are added to the system through the "add_lead" Non-Agent API function. +249. Added agc/dispo_move_listSC.php script, allowing for multiple more complex + Dispo Move List functions after an agent dispositions a call. + +250. Added "hopper_bulk_insert" Non-Agent API function. + +251. Added Stereo Call Recording, allowing for additional call recordings with + the customer on one side(the Right channel) and the agent on the other + side(the Left channel), as well as optional parallel stereo call + recordings. For more information, read the doc: + STEREO_CALL_RECORDINGS.txt + +252. Added "Talk Seconds URLs" Campaign and In-Group features. Allows for URLs + to be sent out from the Agent Screen while the agent is talking to the + customer, based on the number of seconds they have been talking. + diff --git a/agi/VD_amd.agi b/agi/VD_amd.agi index 2ac7053d8..175ba8d0e 100644 --- a/agi/VD_amd.agi +++ b/agi/VD_amd.agi @@ -25,7 +25,7 @@ # exten => _91NXXNXXXXXX,n,Set(__AMDMINLEN=7) # NOTE: the above variable setting will ensure that this script has run for a minimum of 7 seconds before ending and hanging up # -# Copyright (C) 2024 Matt Florell LICENSE: AGPLv2 +# Copyright (C) 2025 Matt Florell LICENSE: AGPLv2 # # changes: # 60206-1434 - first build @@ -70,10 +70,11 @@ # 230412-1023 - Added Code to dispo NOAUDIODATA as ADAIR (Dead Air Auto) with Settings Container option, Issue #1459 # 230726-0932 - Added manual_vm_status_updates campaign option # 240906-2228 - Added AMD minimum length handling to increase short call durations +# 250924-2152 - Added code for deprecation of "Monitor" application after Asterisk 20 # $script = 'VD_amd.agi'; -$build = '230726-0932'; +$build = '250924-2152'; $A = 1; # set to 1 for AMD output messages mode $AMD_LOG = 3; # set to 1 for logfile and 2 forDB log, 3 for both @@ -713,7 +714,15 @@ else } else { - $AGI->exec("Monitor","wav,/var/spool/asterisk/monitor/MIX/$campaign_rec_filename"); + if ($ast_ver_str{major} > 20) + { + # Deprecation of "Monitor" application after Asterisk 20 + $AGI->exec("MixMonitor",",r($PATHmonitor/MIX/$campaign_rec_filename-in.wav)t($PATHmonitor/MIX/$campaign_rec_filename-out.wav)"); + } + else + { + $AGI->exec("Monitor","wav,/var/spool/asterisk/monitor/MIX/$campaign_rec_filename"); + } } ### insert record into recording_log table ### diff --git a/agi/agi-DID_route.agi b/agi/agi-DID_route.agi index 8363bcb38..fbfa72b7e 100644 --- a/agi/agi-DID_route.agi +++ b/agi/agi-DID_route.agi @@ -13,7 +13,7 @@ # ;inbound DID catch-all: #exten => _X.,1,AGI(agi-DID_route.agi) # -# Copyright (C) 2024 Matt Florell LICENSE: AGPLv2 +# Copyright (C) 2025 Matt Florell LICENSE: AGPLv2 # # changes: # 81007-0324 - First Build @@ -51,6 +51,7 @@ # 220507-0811 - Added pre_filter_recent_call function # 230124-1228 - Added logging of VICIrecGatewayID channel variable, and vicidial_did_gateway_log table # 241208-1748 - Changed DID filter_phone_group_id & pre_filter_phone_group_id to multi-selects +# 250924-2156 - Added code for deprecation of "Monitor" application after Asterisk 20 # @@ -879,7 +880,15 @@ if ($record_call =~ /Y/) } else { - $AGI->exec("Monitor","wav,/var/spool/asterisk/monitor/MIX/$filename"); + if ($ast_ver_str{major} > 20) + { + # Deprecation of "Monitor" application after Asterisk 20 + $AGI->exec("MixMonitor",",r($PATHmonitor/MIX/$filename-in.wav)t($PATHmonitor/MIX/$filename-out.wav)"); + } + else + { + $AGI->exec("Monitor","wav,/var/spool/asterisk/monitor/MIX/$filename"); + } } ### insert record into recording_log table ### diff --git a/agi/agi-IVR_recording_verification.agi b/agi/agi-IVR_recording_verification.agi index 5e707950a..eff0c54c1 100644 --- a/agi/agi-IVR_recording_verification.agi +++ b/agi/agi-IVR_recording_verification.agi @@ -42,7 +42,7 @@ #exten => _83002*.,5,Hangup # # -# Copyright (C) 2013 Matt Florell LICENSE: AGPLv2 +# Copyright (C) 2025 Matt Florell LICENSE: AGPLv2 # # CHANGELOG # 70912-1105 - First build, non-functional @@ -53,6 +53,7 @@ # 71120-1337 - added playing of recording ID at beginning of session # 120430-2214 - Converted call to Monitor app to be asterisk 1.8 compatible # 130108-1816 - Changes for Asterisk 1.8 compatibility +# 250924-2158 - Added code for deprecation of "Monitor" application after Asterisk 20 # &get_time_now; @@ -386,7 +387,15 @@ if ($record_call =~ /Y/) } else { - $AGI->exec("Monitor","wav,/var/spool/asterisk/monitor/MIX/$filename,m"); + if ($ast_ver_str{major} > 20) + { + # Deprecation of "Monitor" application after Asterisk 20 + $AGI->exec("MixMonitor",",r($PATHmonitor/MIX/$filename-in.wav)t($PATHmonitor/MIX/$filename-out.wav)"); + } + else + { + $AGI->exec("Monitor","wav,/var/spool/asterisk/monitor/MIX/$filename,m"); + } } ### insert record into recording_log table ### diff --git a/agi/agi-NVA_recording.agi b/agi/agi-NVA_recording.agi index ed8e387f1..49bc1a479 100644 --- a/agi/agi-NVA_recording.agi +++ b/agi/agi-NVA_recording.agi @@ -47,7 +47,7 @@ #exten => _X.,n,Goto(default,${EXTEN},1) #exten => _X.,n,Hangup # -# Copyright (C) 2015 Matt Florell LICENSE: AGPLv2 +# Copyright (C) 2025 Matt Florell LICENSE: AGPLv2 # # CHANGELOG # 91105-1402 - First build @@ -60,6 +60,7 @@ # 151211-0932 - Added phone search and phone NVA URL features # 151214-2148 - Added more variables to be used by nva url feature # 151220-1521 - Added phone NVA List ID option for not found phone numbers +# 250924-2137 - Added code for deprecation of "Monitor" application after Asterisk 20 # &get_time_now; @@ -404,7 +405,15 @@ if ($record_call =~ /Y/) } else { - $AGI->exec("Monitor","wav,/var/spool/asterisk/monitor/MIX/$filename"); + if ($ast_ver_str{major} > 20) + { + # Deprecation of "Monitor" application after Asterisk 20 + $AGI->exec("MixMonitor",",r(/var/spool/asterisk/monitor/MIX/$filename-in.wav)t(/var/spool/asterisk/monitor/MIX/$filename-out.wav)"); + } + else + { + $AGI->exec("Monitor","wav,/var/spool/asterisk/monitor/MIX/$filename"); + } } } diff --git a/agi/agi-VDAD_ALL_inbound.agi b/agi/agi-VDAD_ALL_inbound.agi index 1caa561e9..d07a2eb2e 100644 --- a/agi/agi-VDAD_ALL_inbound.agi +++ b/agi/agi-VDAD_ALL_inbound.agi @@ -265,7 +265,8 @@ # 240723-1632 - Small fix for ConfBridge # 240906-1032 - Added testing for stereo_recording in-group option *NOT PRODUCTION READY* # 250325-1724 - Fix for possible daily_limit issue -# 250825-1824 - Added stereo_recording code +# 250825-1824 - Added stereo_recording code +# 250924-2147 - Added code for deprecation of "Monitor" application after Asterisk 20 # $script = 'agi-VDAD_ALL_inbound.agi'; @@ -2691,7 +2692,15 @@ if ( ($CLchannel_group =~ /DID_INBOUND/) && (length($CLend_epoch) < 5) ) } else { - $AGI->exec("StopMonitor","wav,$PATHmonitor/MIX/$CLfilename"); + if ($ast_ver_str{major} > 20) + { + # Deprecation of "Monitor" application after Asterisk 20 + $AGI->exec("StopMixMonitor",""); + } + else + { + $AGI->exec("StopMonitor","wav,$PATHmonitor/MIX/$CLfilename"); + } } @@ -5034,7 +5043,15 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override } else { - $retval = $AGI->exec("Monitor","wav,$PATHmonitor/MIX/$campaign_rec_filename"); + if ($ast_ver_str{major} > 20) + { + # Deprecation of "Monitor" application after Asterisk 20 + $retval = $AGI->exec("MixMonitor",",r($PATHmonitor/MIX/$campaign_rec_filename-in.wav)t($PATHmonitor/MIX/$campaign_rec_filename-out.wav)"); + } + else + { + $retval = $AGI->exec("Monitor","wav,$PATHmonitor/MIX/$campaign_rec_filename"); + } } } diff --git a/agi/agi-VDAD_ALL_outbound.agi b/agi/agi-VDAD_ALL_outbound.agi index 1402190a4..b796786f3 100644 --- a/agi/agi-VDAD_ALL_outbound.agi +++ b/agi/agi-VDAD_ALL_outbound.agi @@ -133,6 +133,7 @@ # 241001-2222 - Fixes for Khomp call processing # 241020-1928 - Added khomp campaign settings options # 250827-1556 - Added stereo_recording code +# 250924-2150 - Added code for deprecation of "Monitor" application after Asterisk 20 # $script = 'agi-VDAD_ALL_outbound.agi'; @@ -1212,7 +1213,15 @@ if ($VDACaffected_rows > 0) } else { - $AGI->exec("Monitor","wav,$PATHmonitor/MIX/$campaign_rec_filename"); + if ($ast_ver_str{major} > 20) + { + # Deprecation of "Monitor" application after Asterisk 20 + $AGI->exec("MixMonitor",",r($PATHmonitor/MIX/$campaign_rec_filename-in.wav)t($PATHmonitor/MIX/$campaign_rec_filename-out.wav)"); + } + else + { + $AGI->exec("Monitor","wav,$PATHmonitor/MIX/$campaign_rec_filename"); + } } ### insert record into recording_log table ### @@ -3228,7 +3237,15 @@ while ($drop_timer <= $DROP_TIME) } else { - $retval = $AGI->exec("Monitor","wav,$PATHmonitor/MIX/$campaign_rec_filename"); + if ($ast_ver_str{major} > 20) + { + # Deprecation of "Monitor" application after Asterisk 20 + $retval = $AGI->exec("MixMonitor",",r($PATHmonitor/MIX/$campaign_rec_filename-in.wav)t($PATHmonitor/MIX/$campaign_rec_filename-out.wav)"); + } + else + { + $retval = $AGI->exec("Monitor","wav,$PATHmonitor/MIX/$campaign_rec_filename"); + } } } @@ -3938,7 +3955,7 @@ while ($drop_timer <= $DROP_TIME) $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - $stmtB = "INSERT INTO routing_initiated_recordings (recording_id,filename,launch_time,lead_id,vicidial_id,user,processed) values('$recording_id','$temp_parallel_rec_ag_filename','$now_date','$CIDlead_id','$uniqueid','$VDADuser','0')"; + $stmtB = "INSERT INTO routing_initiated_recordings (recording_id,filename,launch_time,lead_id,vicidial_id,user,processed,rir_type) values('$recording_id','$temp_parallel_rec_ag_filename','$now_date','$CIDlead_id','$uniqueid','$VDADuser','0','S')"; $affected_rowsB = $dbhA->do($stmtB); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rowsB; &mysql_error_logging; @@ -3987,7 +4004,7 @@ while ($drop_timer <= $DROP_TIME) $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - $stmtB = "INSERT INTO routing_initiated_recordings (recording_id,filename,launch_time,lead_id,vicidial_id,user,processed) values('$recording_id','$stereo_rec_filename','$now_date','$CIDlead_id','$uniqueid','$VDADuser','0')"; + $stmtB = "INSERT INTO routing_initiated_recordings (recording_id,filename,launch_time,lead_id,vicidial_id,user,processed,rir_type) values('$recording_id','$stereo_rec_filename','$now_date','$CIDlead_id','$uniqueid','$VDADuser','0','S')"; $affected_rowsB = $dbhA->do($stmtB); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rowsB; &mysql_error_logging; @@ -4642,7 +4659,15 @@ while ($drop_timer <= $DROP_TIME) } else { - $retval = $AGI->exec("Monitor","wav,$PATHmonitor/MIX/$campaign_rec_filename"); + if ($ast_ver_str{major} > 20) + { + # Deprecation of "Monitor" application after Asterisk 20 + $retval = $AGI->exec("MixMonitor",",r($PATHmonitor/MIX/$campaign_rec_filename-in.wav)t($PATHmonitor/MIX/$campaign_rec_filename-out.wav)"); + } + else + { + $retval = $AGI->exec("Monitor","wav,$PATHmonitor/MIX/$campaign_rec_filename"); + } } } @@ -5349,7 +5374,7 @@ while ($drop_timer <= $DROP_TIME) $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - $stmtB = "INSERT INTO routing_initiated_recordings (recording_id,filename,launch_time,lead_id,vicidial_id,user,processed) values('$recording_id','$temp_parallel_rec_ag_filename','$now_date','$CIDlead_id','$uniqueid','$VDADuser','0')"; + $stmtB = "INSERT INTO routing_initiated_recordings (recording_id,filename,launch_time,lead_id,vicidial_id,user,processed,rir_type) values('$recording_id','$temp_parallel_rec_ag_filename','$now_date','$CIDlead_id','$uniqueid','$VDADuser','0','S')"; $affected_rowsB = $dbhA->do($stmtB); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rowsB; &mysql_error_logging; @@ -5398,7 +5423,7 @@ while ($drop_timer <= $DROP_TIME) $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - $stmtB = "INSERT INTO routing_initiated_recordings (recording_id,filename,launch_time,lead_id,vicidial_id,user,processed) values('$recording_id','$stereo_rec_filename','$now_date','$CIDlead_id','$uniqueid','$VDADuser','0')"; + $stmtB = "INSERT INTO routing_initiated_recordings (recording_id,filename,launch_time,lead_id,vicidial_id,user,processed,rir_type) values('$recording_id','$stereo_rec_filename','$now_date','$CIDlead_id','$uniqueid','$VDADuser','0','S')"; $affected_rowsB = $dbhA->do($stmtB); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rowsB; &mysql_error_logging; diff --git a/agi/agi-VDAD_RINGALL.agi b/agi/agi-VDAD_RINGALL.agi index f5b7d145e..97301fb62 100644 --- a/agi/agi-VDAD_RINGALL.agi +++ b/agi/agi-VDAD_RINGALL.agi @@ -12,7 +12,7 @@ # exten => _8331*.,n,AGI(agi-VDAD_RINGALL.agi,${EXTEN}) # exten => _8331*.,n,Hangup # -# Copyright (C) 2024 Matt Florell LICENSE: AGPLv2 +# Copyright (C) 2025 Matt Florell LICENSE: AGPLv2 # # changes: # 110303-2325 - First build @@ -24,6 +24,7 @@ # 140421-1448 - Added code to halt ringing of other channels in ring_all NAC method # 240420-2241 - Added ConfBridge code # 240415-1702 - Fix for ConfBridge code +# 250924-2157 - Added code for deprecation of "Monitor" application after Asterisk 20 # $script = 'agi-VDAD_RINGALL.agi'; @@ -387,7 +388,15 @@ if ($NAGcount > 0) } else { - $AGI->exec("Monitor","wav,/var/spool/asterisk/monitor/MIX/$campaign_rec_filename"); + if ($ast_ver_str{major} > 20) + { + # Deprecation of "Monitor" application after Asterisk 20 + $AGI->exec("MixMonitor",",r($PATHmonitor/MIX/$campaign_rec_filename-in.wav)t($PATHmonitor/MIX/$campaign_rec_filename-out.wav)"); + } + else + { + $AGI->exec("Monitor","wav,/var/spool/asterisk/monitor/MIX/$campaign_rec_filename"); + } } ### insert record into recording_log table ### diff --git a/bin/ADMIN_keepalive_ALL.pl b/bin/ADMIN_keepalive_ALL.pl index 58044cf65..02c3e9853 100644 --- a/bin/ADMIN_keepalive_ALL.pl +++ b/bin/ADMIN_keepalive_ALL.pl @@ -174,9 +174,10 @@ # 240420-2209 - Added Conference Updater option # 250103-0932 - Added ConfBridge code and enhanced_agent_monitoring system setting code # 250914-1601 - Added pruning of recording_live table entries over 7 days old, deletion of parallel recording source files 3+ days +# 250924-2212 - Added code for deprecation of "Monitor" application after Asterisk 20 # -$build = '250914-1601'; +$build = '250924-2212'; $DB=0; # Debug flag $teodDB=0; # flag to log Timeclock End of Day processes to log file @@ -3402,7 +3403,17 @@ if ($asterisk_version =~ /^1.2/) {$Vext .= "exten => 8309,2,Monitor(wav,\${CALLERIDNAME})\n";} else - {$Vext .= "exten => 8309,2,Monitor(wav,\${CALLERID(name)})\n";} + { + if ($asterisk_version =~ /^2[1-9]|^3\d|^4\d/) + { + # Deprecation of "Monitor" application after Asterisk 20 + $Vext .= "exten => 8309,2,MixMonitor(,r($PATHmonitor/\${CALLERID(name)}-in.wav)t($PATHmonitor/\${CALLERID(name)}-out.wav))\n"; + } + else + { + $Vext .= "exten => 8309,2,Monitor(wav,\${CALLERID(name)})\n"; + } + } $Vext .= "exten => 8309,3,Wait($vicidial_recording_limit)\n"; $Vext .= "exten => 8309,4,Hangup()\n"; $Vext .= "; this is the GSM verison\n"; @@ -3410,7 +3421,17 @@ if ($asterisk_version =~ /^1.2/) {$Vext .= "exten => 8310,2,Monitor(gsm,\${CALLERIDNAME})\n";} else - {$Vext .= "exten => 8310,2,Monitor(gsm,\${CALLERID(name)})\n";} + { + if ($asterisk_version =~ /^2[1-9]|^3\d|^4\d/) + { + # Deprecation of "Monitor" application after Asterisk 20 + $Vext .= "exten => 8309,2,MixMonitor(,r($PATHmonitor/\${CALLERID(name)}-in.wav)t($PATHmonitor/\${CALLERID(name)}-out.wav))\n"; + } + else + { + $Vext .= "exten => 8310,2,Monitor(gsm,\${CALLERID(name)})\n"; + } + } $Vext .= "exten => 8310,3,Wait($vicidial_recording_limit)\n"; $Vext .= "exten => 8310,4,Hangup()\n"; diff --git a/docs/STEREO_CALL_RECORDINGS.txt b/docs/STEREO_CALL_RECORDINGS.txt index 3934aa3ed..15f840559 100644 --- a/docs/STEREO_CALL_RECORDINGS.txt +++ b/docs/STEREO_CALL_RECORDINGS.txt @@ -1,7 +1,7 @@ -VICIDIAL STEREO CALL RECORDINGS Started: 2025-06-18 Updated: 2025-09-19 +VICIDIAL STEREO CALL RECORDINGS Started: 2025-06-18 Updated: 2025-09-25 -TO USE THESE FEATURES, YOU WILL NEED TO HAVE ALL SERVERS IN YOUR CLUSTER USING SVN/TRUNK REVISION 3943(2025-09-19) CODE OR HIGHER!!! +TO USE THESE FEATURES, YOU WILL NEED TO HAVE ALL SERVERS IN YOUR CLUSTER USING SVN/TRUNK REVISION 3945(2025-09-25) CODE OR HIGHER!!! This project was designed to allow for additional stereo recording of phone calls at the agent and server levels directly on VICIdial Asterisk servers, with the customer always on one channel(the Right channel) and the agent and all other parties on the other channel(the Left channel). If you are looking for the VICI Gateway Recording Server documentation, please see the GATEWAY_RECORDING_SERVER.txt document. diff --git a/extras/MySQL_AST_CREATE_tables.sql b/extras/MySQL_AST_CREATE_tables.sql index d949d7b45..22bfb3025 100644 --- a/extras/MySQL_AST_CREATE_tables.sql +++ b/extras/MySQL_AST_CREATE_tables.sql @@ -3801,7 +3801,7 @@ url_id INT(9) UNSIGNED NOT NULL AUTO_INCREMENT, campaign_id VARCHAR(20) NOT NULL, entry_type ENUM('campaign','ingroup','list','system','') default '', active ENUM('Y','N') default 'N', -url_type ENUM('dispo','start','addlead','noagent','apinewlead','') default '', +url_type ENUM('dispo','start','addlead','noagent','apinewlead','talk','') default '', url_rank SMALLINT(5) default '1', url_statuses VARCHAR(1000) default '', url_description VARCHAR(255) default '', @@ -5853,4 +5853,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='1729',db_schema_update_date=NOW(),reload_timestamp=NOW(); +UPDATE system_settings SET db_schema_version='1730',db_schema_update_date=NOW(),reload_timestamp=NOW(); diff --git a/extras/upgrade_2.14.sql b/extras/upgrade_2.14.sql index ff395d574..14bcd2798 100644 --- a/extras/upgrade_2.14.sql +++ b/extras/upgrade_2.14.sql @@ -2873,7 +2873,7 @@ ALTER TABLE system_settings ADD agent_hide_dial_fail ENUM('0','1','2','3','4','5 UPDATE system_settings SET db_schema_version='1725',db_schema_update_date=NOW() where db_schema_version < 1725; ALTER TABLE vicidial_url_multi MODIFY entry_type ENUM('campaign','ingroup','list','system','') default ''; -ALTER TABLE vicidial_url_multi MODIFY url_type ENUM('dispo','start','addlead','noagent','apinewlead','') default ''; +ALTER TABLE vicidial_url_multi MODIFY url_type ENUM('dispo','start','addlead','noagent','apinewlead','talk','') default ''; UPDATE system_settings SET db_schema_version='1726',db_schema_update_date=NOW() where db_schema_version < 1726; @@ -3007,3 +3007,7 @@ CREATE TABLE recording_log_parallel_archive LIKE recording_log_parallel; CREATE TABLE recording_log_stereo_archive LIKE recording_log_stereo; UPDATE system_settings SET db_schema_version='1729',db_schema_update_date=NOW() where db_schema_version < 1729; + +ALTER TABLE vicidial_url_multi MODIFY url_type ENUM('dispo','start','addlead','noagent','apinewlead','talk','') default ''; + +UPDATE system_settings SET db_schema_version='1730',db_schema_update_date=NOW() where db_schema_version < 1730; diff --git a/www/agc/manager_send.php b/www/agc/manager_send.php index fda51e09d..1b748d9bb 100644 --- a/www/agc/manager_send.php +++ b/www/agc/manager_send.php @@ -165,7 +165,7 @@ $build = '250831-0839'; $php_script = 'manager_send.php'; $mel=1; # Mysql Error Log enabled = 1 -$mysql_log_count=161; +$mysql_log_count=177; $one_mysql_log=0; $SSagent_debug_logging=0; $startMS = microtime(); @@ -2820,7 +2820,7 @@ $stmt = "UPDATE recording_live set end_time='$NOW_TIME',recording_status='FINISHED' where recording_id='$recording_id' and recording_status='STARTED';"; if ($DB) {echo "$stmt\n";} $rslt=mysql_to_mysqli($stmt, $link); - if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02162',$user,$server_ip,$session_name,$one_mysql_log);} } # find and hang up all recordings going on in this conference # and extension = '$exten' @@ -2900,7 +2900,7 @@ $stmt = "UPDATE vicidial_live_agents SET external_recording='' where user='$user';"; if ($format=='debug') {echo "\n";} $rslt=mysql_to_mysqli($stmt, $link); - if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02163',$user,$server_ip,$session_name,$one_mysql_log);} ##### get call type from vicidial_live_agents table $VLA_inOUT='NONE'; @@ -2994,7 +2994,7 @@ { $stmt="SELECT vendor_lead_code FROM vicidial_list where lead_id='$lead_id';"; $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02164',$user,$server_ip,$session_name,$one_mysql_log);} if ($DB) {echo "$stmt\n";} $VM_mancall_ct = mysqli_num_rows($rslt); if ($VM_mancall_ct > 0) @@ -3058,7 +3058,7 @@ # gather parallel_recording_id from recording_log_parallel $stmt="SELECT parallel_recording_id FROM recording_log_parallel where lead_id='$lead_id' and user='$user' and channel='$channel' and start_time > \"$four_hours_ago\" order by parallel_recording_id desc limit 1;"; $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02165',$user,$server_ip,$session_name,$one_mysql_log);} if ($DB) {echo "$stmt\n";} $PR_ct = mysqli_num_rows($rslt); if ($PR_ct > 0) @@ -3071,12 +3071,12 @@ $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,recording_status,parallel_recording_id) values('$recording_id','$server_ip','$NOW_TIME','0','$stereo_rec_filename','$lead_id','$VDcampaign_id STEREO_PARALLEL AGENT-CONTROLLED $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $VDvicidial_id|user: $user|channel: $channel|','STEREO START','$parallel_recording_id');"; if ($format=='debug') {echo "\n";} $rslt=mysql_to_mysqli($stmtA, $link); - if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmtA,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmtA,'02166',$user,$server_ip,$session_name,$one_mysql_log);} $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL AGENT-CONTROLLED','$server_ip','$NOW_TIME','$channel','$stereo_rec_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED');"; if ($format=='debug') {echo "\n";} $rslt=mysql_to_mysqli($stmtD, $link); - if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmtD,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmtD,'02167',$user,$server_ip,$session_name,$one_mysql_log);} } else { @@ -3092,12 +3092,12 @@ $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,recording_status) values('$recording_id','$server_ip','$NOW_TIME','0','$stereo_rec_filename','$lead_id','$VDcampaign_id STEREO AGENT-CONTROLLED $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $VDvicidial_id|user: $user|channel: $channel|','STEREO START');"; if ($format=='debug') {echo "\n";} $rslt=mysql_to_mysqli($stmtA, $link); - if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmtA,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmtA,'02168',$user,$server_ip,$session_name,$one_mysql_log);} $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO AGENT-CONTROLLED','$server_ip','$NOW_TIME','$channel','$stereo_rec_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED');"; if ($format=='debug') {echo "\n";} $rslt=mysql_to_mysqli($stmtD, $link); - if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmtD,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmtD,'02169',$user,$server_ip,$session_name,$one_mysql_log);} if (preg_match("/CUSTOMER_ONLY/",$stereo_recording) ) { @@ -3105,7 +3105,7 @@ $stmt="INSERT INTO vicidial_manager values('','','$NOW_TIME','NEW','N','$server_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: write','State: 1','','','','','','');"; if ($format=='debug') {echo "\n";} $rslt=mysql_to_mysqli($stmt, $link); - if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02170',$user,$server_ip,$session_name,$one_mysql_log);} } if (preg_match("/CUSTOMER_MUTE/",$stereo_recording) ) { @@ -3113,7 +3113,7 @@ $stmt="INSERT INTO vicidial_manager values('','','$NOW_TIME','NEW','N','$server_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: read','State: 1','','','','','','');"; if ($format=='debug') {echo "\n";} $rslt=mysql_to_mysqli($stmt, $link); - if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02171',$user,$server_ip,$session_name,$one_mysql_log);} } } $filename = $stereo_rec_filename; @@ -3131,7 +3131,7 @@ $stmt = "UPDATE vicidial_live_agents SET external_recording='' where user='$user';"; if ($format=='debug') {echo "\n";} $rslt=mysql_to_mysqli($stmt, $link); - if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02172',$user,$server_ip,$session_name,$one_mysql_log);} } if ($uniqueid=='IN') { @@ -3164,7 +3164,7 @@ $stmt="SELECT recording_id,UNIX_TIMESTAMP(start_time),filename,recording_type FROM recording_live where channel='$channel' and user='$user' and recording_status='STARTED' and recording_type LIKE \"STEREO%\" and recording_type LIKE \"%AGENT-CONTROLLED%\" order by start_time desc;"; $rslt=mysql_to_mysqli($stmt, $link); - if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02173',$user,$server_ip,$session_name,$one_mysql_log);} if ($DB) {echo "$stmt\n";} $rec_count = mysqli_num_rows($rslt); if ($rec_count>0) @@ -3187,17 +3187,17 @@ $stmt = "UPDATE recording_log_stereo set end_time='$NOW_TIME',recording_status='FINISHED',length_in_sec=$length_in_sec where recording_id='$recording_id';"; if ($DB) {echo "$stmt\n";} $rslt=mysql_to_mysqli($stmt, $link); - if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02174',$user,$server_ip,$session_name,$one_mysql_log);} $stmt = "UPDATE recording_live set end_time='$NOW_TIME',recording_status='FINISHED' where recording_id='$recording_id' and recording_status='STARTED';"; if ($DB) {echo "$stmt\n";} $rslt=mysql_to_mysqli($stmt, $link); - if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02175',$user,$server_ip,$session_name,$one_mysql_log);} $stmt = "UPDATE routing_initiated_recordings set processed='1' where user='$user' and processed='0' and rir_type='S' order by launch_time desc limit 1;"; if ($DB) {echo "$stmt\n";} $rslt=mysql_to_mysqli($stmt, $link); - if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02176',$user,$server_ip,$session_name,$one_mysql_log);} } # if ($WeBRooTWritablE > 0) @@ -3213,7 +3213,7 @@ $stmt="INSERT INTO vicidial_manager values('','','$NOW_TIME','NEW','N','$server_ip','','StopMixMonitor','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','','','','','','','','');"; if ($format=='debug') {echo "\n";} $rslt=mysql_to_mysqli($stmt, $link); - if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02177',$user,$server_ip,$session_name,$one_mysql_log);} } } ##### END StopMonitorStereo steps ##### diff --git a/www/agc/vdc_db_query.php b/www/agc/vdc_db_query.php index 848d1106e..9ff366e18 100644 --- a/www/agc/vdc_db_query.php +++ b/www/agc/vdc_db_query.php @@ -561,13 +561,14 @@ # 250601-0843 - Fix for fronter/closer start/dispo URL variables # 250723-2002 - Fix for issue #1548 # 250916-1918 - Added stereo recording features +# 250923-1755 - Added talk_sec_url features # -$version = '2.14-454'; -$build = '250916-1918'; +$version = '2.14-455'; +$build = '250923-1755'; $php_script = 'vdc_db_query.php'; $mel=1; # Mysql Error Log enabled = 1 -$mysql_log_count=913; +$mysql_log_count=989; $one_mysql_log=0; $DB=0; $VD_login=0; @@ -779,6 +780,8 @@ elseif (isset($_POST["department"])) {$department=$_POST["department"];} if (isset($_GET["group_name"])) {$group_name=$_GET["group_name"];} elseif (isset($_POST["group_name"])) {$group_name=$_POST["group_name"];} +if (isset($_GET["group"])) {$group=$_GET["group"];} + elseif (isset($_POST["group"])) {$group=$_POST["group"];} if (isset($_GET["job_title"])) {$job_title=$_GET["job_title"];} elseif (isset($_POST["job_title"])) {$job_title=$_POST["job_title"];} if (isset($_GET["location"])) {$location=$_GET["location"];} @@ -1720,7 +1723,7 @@ # Gather list of In-Groups for this user that have hit the daily limit, so we can exclude them $stmt="SELECT group_id FROM vicidial_inbound_group_agents WHERE user='$user' and ( (daily_limit > -1) and (daily_limit <= calls_today) ) limit 1000;"; $rslt=mysql_to_mysqli($stmt, $link); - if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00XXX',$VD_login,$server_ip,$session_name,$one_mysql_log);} + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00914',$VD_login,$server_ip,$session_name,$one_mysql_log);} if ($DB) {echo "$stmt\n";} $VD_hit_limit_ingroups_ct = mysqli_num_rows($rslt); $VD_hit_limit_ingroups="'',"; @@ -1928,7 +1931,7 @@ $stmt="INSERT INTO vicidial_inbound_group_agents set user='$user',group_id='$in_groups[$k]';"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00915',$user,$server_ip,$session_name,$one_mysql_log);} # Set default values since settings didn't exist $group_weight = 0; @@ -4557,7 +4560,7 @@ $stmtPDC = "INSERT IGNORE INTO vicidial_phone_number_call_daily_counts SET phone_number='$agent_dialed_number',modify_date=NOW(),called_count='1' ON DUPLICATE KEY UPDATE modify_date=NOW(),called_count=(called_count + 1);"; if ($DB) {echo "$stmtPDC\n";} $rslt=mysql_to_mysqli($stmtPDC, $link); - if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmtPDC,'00XXX',$user,$server_ip,$session_name,$one_mysql_log);} + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmtPDC,'00916',$user,$server_ip,$session_name,$one_mysql_log);} if (!$CBleadIDset) { @@ -5576,7 +5579,7 @@ $stmt="SELECT url_rank,url_statuses,url_address,url_lists from vicidial_url_multi where campaign_id='$SUcampaign' and entry_type='$SUentry_type' and url_type='start' and active='Y' order by url_rank limit 1000;"; if ($DB) {echo "$stmt\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00917',$user,$server_ip,$session_name,$one_mysql_log);} $VUM_ct = mysqli_num_rows($rslt); $k=0; while ($VUM_ct > $k) @@ -6128,7 +6131,7 @@ $stmt="SELECT container_entry FROM vicidial_settings_containers WHERE container_id='$state_descriptions';"; if ($DB) {echo "$stmt\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00918',$user,$server_ip,$session_name,$one_mysql_log);} $SDE_ct = mysqli_num_rows($rslt); $state_debug .= "$SDE_ct|$stmt|\n"; if ($SDE_ct > 0) @@ -7605,7 +7608,7 @@ $stmt="SELECT url_rank,url_statuses,url_address,url_lists from vicidial_url_multi where campaign_id='$SUcampaign' and entry_type='$SUentry_type' and url_type='start' and active='Y' order by url_rank limit 1000;"; if ($DB) {echo "$stmt\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00919',$user,$server_ip,$session_name,$one_mysql_log);} $VUM_ct = mysqli_num_rows($rslt); $k=0; while ($VUM_ct > $k) @@ -8108,6 +8111,7 @@ if ($call_good > 0) { $stereo_ac="\n"; + $talk_sec_urls_sec=''; if ($stage != "YES") { $wait_sec=0; @@ -8148,6 +8152,23 @@ if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00742',$user,$server_ip,$session_name,$one_mysql_log);} } + # Gather active talk_sec_urls and their trigger times + $stmt="SELECT distinct(url_call_length) FROM vicidial_url_multi where campaign_id='$campaign' and entry_type='campaign' and url_type='talk' and active='Y' and url_call_length > 0 order by url_call_length limit 1000;"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00920',$user,$server_ip,$session_name,$one_mysql_log);} + if ($DB) {echo "$stmt\n";} + $camp_tsu_ct = mysqli_num_rows($rslt); + $tsu=0; + while ($camp_tsu_ct > $tsu) + { + $row=mysqli_fetch_row($rslt); + if ($tsu < 1) + {$talk_sec_urls_sec = 'TALKURLS-';} + $talk_sec_urls_sec .= $row[0]."-"; + $tsu++; + } + $talk_sec_urls_sec .= "\n"; + if ( (preg_match("/CUSTOMER|BOTH/",$stereo_recording)) and (preg_match("/^M/",$MDnextCID)) and ($SSstereo_recording > 0) ) { $stmt="SELECT conf_engine FROM servers where server_ip='$server_ip';"; @@ -8157,7 +8178,7 @@ { $stmt="SELECT stereo_recording,stereo_parallel_recording,stereo_rec_filename,stereo_recording_agent,parallel_rec_co_filename,parallel_rec_cm_filename,parallel_rec_fr_filename FROM vicidial_campaigns where campaign_id='$campaign';"; $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00921',$user,$server_ip,$session_name,$one_mysql_log);} if ($DB) {echo "$stmt\n";} $VM_mancall_ct = mysqli_num_rows($rslt); if ($VM_mancall_ct > 0) @@ -8179,7 +8200,7 @@ { $stmt="SELECT vendor_lead_code FROM vicidial_list where lead_id='$lead_id';"; $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00922',$user,$server_ip,$session_name,$one_mysql_log);} if ($DB) {echo "$stmt\n";} $VM_mancall_ct = mysqli_num_rows($rslt); if ($VM_mancall_ct > 0) @@ -8215,7 +8236,7 @@ $stmt = "INSERT INTO recording_log_parallel (channel,server_ip,extension,start_time,length_in_sec,filename,lead_id,user,vicidial_id,recording_status) values('$channel','$server_ip','','$NOW_TIME','0','$filename','$lead_id','$user','$uniqueid','START');"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00923',$user,$server_ip,$session_name,$one_mysql_log);} $PRLaffected_rows = mysqli_affected_rows($link); if ($PRLaffected_rows > 0) { @@ -8227,7 +8248,7 @@ $stmt="INSERT INTO vicidial_manager values('','','$NOW_TIME','NEW','N','$server_ip','','MixMonitor','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Options: $stereo_recording_options','','','','','','','');"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00924',$user,$server_ip,$session_name,$one_mysql_log);} if ((preg_match("/CUSTOMER-ONLY/",$stereo_parallel_recording))) { @@ -8252,7 +8273,7 @@ $stmt = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$server_ip','SPCO','$NOW_TIME','$StarTtime','$temp_parallel_rec_co_filename','$lead_id','$user','$uniqueid')"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00925',$user,$server_ip,$session_name,$one_mysql_log);} $RLaffected_rows = mysqli_affected_rows($link); if ($RLaffected_rows > 0) { @@ -8264,20 +8285,20 @@ $stmt = "UPDATE recording_log SET filename='$temp_parallel_rec_co_filename' where recording_id='$recording_id';"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00926',$user,$server_ip,$session_name,$one_mysql_log);} } ### insert record into recording_log_stereo table ### $stmt = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$server_ip','$NOW_TIME','0','$temp_parallel_rec_co_filename','$lead_id','$campaign STEREO_PARALLEL CUSTOMER-ONLY $stereo_recording','vicidial_id: $uniqueid|user: $user|channel: $channel|','$parallel_recording_id','PARALLEL START');"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00927',$user,$server_ip,$session_name,$one_mysql_log);} ### insert record into recording_live table ### $stmt = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL CUSTOMER-ONLY','$server_ip','$NOW_TIME','$channel','$temp_parallel_rec_co_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED');"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00928',$user,$server_ip,$session_name,$one_mysql_log);} } if ((preg_match("/CUSTOMER-MUTED/",$stereo_parallel_recording))) @@ -8303,7 +8324,7 @@ $stmt = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$server_ip','SPCM','$NOW_TIME','$StarTtime','$temp_parallel_rec_cm_filename','$lead_id','$user','$uniqueid')"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00929',$user,$server_ip,$session_name,$one_mysql_log);} $RLaffected_rows = mysqli_affected_rows($link); if ($RLaffected_rows > 0) { @@ -8315,20 +8336,20 @@ $stmt = "UPDATE recording_log SET filename='$temp_parallel_rec_cm_filename' where recording_id='$recording_id';"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00930',$user,$server_ip,$session_name,$one_mysql_log);} } ### insert record into recording_log_stereo table ### $stmt = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$server_ip','$NOW_TIME','0','$temp_parallel_rec_cm_filename','$lead_id','$campaign STEREO_PARALLEL CUSTOMER-MUTED $stereo_recording','vicidial_id: $uniqueid|user: $user|channel: $channel|','$parallel_recording_id','PARALLEL START');"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00931',$user,$server_ip,$session_name,$one_mysql_log);} ### insert record into recording_live table ### $stmt = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL CUSTOMER-MUTED','$server_ip','$NOW_TIME','$channel','$temp_parallel_rec_cm_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED');"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00932',$user,$server_ip,$session_name,$one_mysql_log);} } if ((preg_match("/FULL-RECORDING/",$stereo_parallel_recording))) @@ -8354,7 +8375,7 @@ $stmt = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$server_ip','SPFR','$NOW_TIME','$StarTtime','$temp_parallel_rec_fr_filename','$lead_id','$user','$uniqueid')"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00933',$user,$server_ip,$session_name,$one_mysql_log);} $RLaffected_rows = mysqli_affected_rows($link); if ($RLaffected_rows > 0) { @@ -8366,20 +8387,20 @@ $stmt = "UPDATE recording_log SET filename='$temp_parallel_rec_fr_filename' where recording_id='$recording_id';"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00934',$user,$server_ip,$session_name,$one_mysql_log);} } ### insert record into recording_log_stereo table ### $stmt = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$server_ip','$NOW_TIME','0','$temp_parallel_rec_fr_filename','$lead_id','$campaign STEREO_PARALLEL FULL-RECORDING $stereo_recording','vicidial_id: $uniqueid|user: $user|channel: $channel|','$parallel_recording_id','PARALLEL START');"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00935',$user,$server_ip,$session_name,$one_mysql_log);} ### insert record into recording_live table ### $stmt = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL FULL-RECORDING','$server_ip','$NOW_TIME','$channel','$temp_parallel_rec_fr_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED');"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00936',$user,$server_ip,$session_name,$one_mysql_log);} } # insert logs for agent-controlled stereo call recordings while parallel recordings are enabled @@ -8399,7 +8420,7 @@ $stmt = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$server_ip','$stereo_exten','$NOW_TIME','$StarTtime','$temp_parallel_rec_ag_filename','$lead_id','$user','$uniqueid')"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00937',$user,$server_ip,$session_name,$one_mysql_log);} $RLaffected_rows = mysqli_affected_rows($link); if ($RLaffected_rows > 0) { @@ -8411,20 +8432,20 @@ $stmt = "UPDATE recording_log SET filename='$temp_parallel_rec_ag_filename' where recording_id='$recording_id';"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00938',$user,$server_ip,$session_name,$one_mysql_log);} } ### insert record into recording_log_stereo table ### $stmt = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$server_ip','$NOW_TIME','0','$temp_parallel_rec_ag_filename','$lead_id','$campaign STEREO_PARALLEL AGENT-CONTROLLED $stereo_recording','vicidial_id: $uniqueid|user: $user|channel: $channel|','$parallel_recording_id','PARALLEL START');"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00939',$user,$server_ip,$session_name,$one_mysql_log);} ### insert record into recording_live table ### $stmt = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL AGENT-CONTROLLED','$server_ip','$NOW_TIME','$channel','$temp_parallel_rec_ag_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED');"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00940',$user,$server_ip,$session_name,$one_mysql_log);} } if ((preg_match("/ONDEMAND/",$stereo_recording_agent))) { @@ -8441,7 +8462,7 @@ $stmt = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$server_ip','SAC','$NOW_TIME','$StarTtime','$stereo_rec_filename','$lead_id','$user','$uniqueid')"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00941',$user,$server_ip,$session_name,$one_mysql_log);} $RLaffected_rows = mysqli_affected_rows($link); if ($RLaffected_rows > 0) { @@ -8453,7 +8474,7 @@ $stmt = "UPDATE recording_log SET filename='$stereo_rec_filename' where recording_id='$recording_id';"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00942',$user,$server_ip,$session_name,$one_mysql_log);} } $vmgr_callerid = substr($stereo_rec_filename, 0, 17) . '...'; @@ -8461,19 +8482,19 @@ $stmt="INSERT INTO vicidial_manager values('','','$NOW_TIME','NEW','N','$server_ip','','MixMonitor','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Options: $stereo_recording_options','','','','','','','');"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00943',$user,$server_ip,$session_name,$one_mysql_log);} ### insert record into recording_log_stereo table ### $stmt = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$server_ip','$NOW_TIME','0','$stereo_rec_filename','$lead_id','$campaign STEREO AGENT-CONTROLLED $stereo_recording','vicidial_id: $uniqueid|user: $user|channel: $channel|','$parallel_recording_id','START');"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00944',$user,$server_ip,$session_name,$one_mysql_log);} ### insert record into recording_live table ### $stmt = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO AGENT-CONTROLLED','$server_ip','$NOW_TIME','$channel','$stereo_rec_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED');"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00945',$user,$server_ip,$session_name,$one_mysql_log);} if (preg_match("/CUSTOMER_ONLY/",$stereo_recording) ) { @@ -8481,7 +8502,7 @@ $stmt="INSERT INTO vicidial_manager values('','','$NOW_TIME','NEW','N','$server_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: write','State: 1','','','','','','');"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00946',$user,$server_ip,$session_name,$one_mysql_log);} } if (preg_match("/CUSTOMER_MUTE/",$stereo_recording) ) { @@ -8489,7 +8510,7 @@ $stmt="INSERT INTO vicidial_manager values('','','$NOW_TIME','NEW','N','$server_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: read','State: 1','','','','','','');"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00947',$user,$server_ip,$session_name,$one_mysql_log);} } } if ((preg_match("/ONDEMAND/",$stereo_recording_agent))) @@ -8665,7 +8686,7 @@ } ##### END SIP event logging, if enabled in the system ##### - echo "$call_output$sip_event_action_output$stereo_ac"; + echo "$call_output$sip_event_action_output$stereo_ac$talk_sec_urls_sec"; $stage .= " $uniqueid $channel"; } @@ -8681,7 +8702,7 @@ $stmt = "SELECT count(*) from vicidial_sip_event_recent where ( (caller_code='$MDnextCID') and ( (first_180_date IS NOT NULL) or (first_183_date IS NOT NULL) ) );"; if ($DB) {echo "$stmt\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00948',$user,$server_ip,$session_name,$one_mysql_log);} $MMRS_ct = mysqli_num_rows($rslt); if ($MMRS_ct > 0) { @@ -10045,12 +10066,12 @@ $stmt="INSERT INTO vicidial_manager values('','','$NOW_TIME','NEW','N','$server_ip','','StopMixMonitor','SH123467$StarTtime','ActionID: SH123467$StarTtime','Channel: $channel','','','','','','','','');"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00949',$user,$server_ip,$session_name,$one_mysql_log);} ### gather live recordings tied to this customer channel $stmt="SELECT recording_id,filename,start_time,UNIX_TIMESTAMP(start_time) from recording_live where channel='$channel' and lead_id='$lead_id' and recording_status='STARTED' and user='$user' and recording_type LIKE \"STEREO%\" limit 10;"; $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00950',$user,$server_ip,$session_name,$one_mysql_log);} $ST_rec_ct = mysqli_num_rows($rslt); $st=0; while ($ST_rec_ct > $st) @@ -10074,19 +10095,19 @@ $stmt = "UPDATE recording_live SET end_time=NOW(),recording_status='FINISHED END-CALL' where recording_id='$STrecording_id[$st]';"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00951',$user,$server_ip,$session_name,$one_mysql_log);} ### update record in recording_log table ### $stmt = "UPDATE recording_log SET end_time=NOW(),end_epoch='$StarTtime',length_in_sec='$length_in_sec',length_in_min='$length_in_min' where recording_id='$STrecording_id[$st]';"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00952',$user,$server_ip,$session_name,$one_mysql_log);} ### update record in recording_log_stereo table ### $stmt = "UPDATE recording_log_stereo SET end_time=NOW(),recording_status='FINISHED END-CALL',length_in_sec='$length_in_sec' where recording_id='$STrecording_id[$st]';"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00953',$user,$server_ip,$session_name,$one_mysql_log);} $st++; } @@ -10194,7 +10215,7 @@ $stmt = "UPDATE recording_live set end_time='$NOW_TIME',recording_status='FINISHED END-CALL' where filename='$filename[$loop_count]' and recording_status='STARTED';"; if ($DB) {echo "$stmt\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00954',$user,$server_ip,$session_name,$one_mysql_log);} echo "$recording_id|$length_in_min|"; @@ -10633,6 +10654,23 @@ $owner=$user; } + # Gather active talk_sec_urls and their trigger times + $talk_sec_urls_secs = ''; + $stmt="SELECT distinct(url_call_length) FROM vicidial_url_multi where campaign_id='$campaign' and entry_type='campaign' and url_type='talk' and active='Y' and url_call_length > 0 order by url_call_length limit 1000;"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00955',$user,$server_ip,$session_name,$one_mysql_log);} + if ($DB) {echo "$stmt\n";} + $camp_tsu_ct = mysqli_num_rows($rslt); + $tsu=0; + while ($camp_tsu_ct > $tsu) + { + $row=mysqli_fetch_row($rslt); + if ($tsu < 1) + {$talk_sec_urls_secs .= "-";} + $talk_sec_urls_secs .= "$row[0]-"; + $tsu++; + } + ### update the lead status to INCALL $stmt = "UPDATE vicidial_list set status='INCALL', user='$user' $ownerSQL where lead_id='$lead_id';"; if ($DB) {echo "$stmt\n";} @@ -10924,7 +10962,7 @@ } } - echo "$VDCL_group_web|$VDCL_group_name||||$VDCL_campaign_script|$VDCL_get_call_launch|$VDCL_xferconf_a_dtmf|$VDCL_xferconf_a_number|$VDCL_xferconf_b_dtmf|$VDCL_xferconf_b_number|$VDCL_default_xfer_group|X|X||||$VDCL_group_web_two|$VDCL_timer_action|$VDCL_timer_action_message|$VDCL_timer_action_seconds|$VDCL_xferconf_c_number|$VDCL_xferconf_d_number|$VDCL_xferconf_e_number||||$VDCL_timer_action_destination|||||||$VDCL_group_web_three|$VDCL_ingroup_script_color|||$VDCL_campaign_script_two|$VDCL_ingroup_script_color_two|||$stereo_recording|$stereo_recording_agent|\n|\n"; + echo "$VDCL_group_web|$VDCL_group_name||||$VDCL_campaign_script|$VDCL_get_call_launch|$VDCL_xferconf_a_dtmf|$VDCL_xferconf_a_number|$VDCL_xferconf_b_dtmf|$VDCL_xferconf_b_number|$VDCL_default_xfer_group|X|X||||$VDCL_group_web_two|$VDCL_timer_action|$VDCL_timer_action_message|$VDCL_timer_action_seconds|$VDCL_xferconf_c_number|$VDCL_xferconf_d_number|$VDCL_xferconf_e_number||||$VDCL_timer_action_destination|||||||$VDCL_group_web_three|$VDCL_ingroup_script_color|||$VDCL_campaign_script_two|$VDCL_ingroup_script_color_two|||$stereo_recording|$stereo_recording_agent|$talk_sec_urls_secs|\n|\n"; if (preg_match('/X/',$dialed_label)) { @@ -10984,7 +11022,7 @@ $stmt = "SELECT user from vicidial_xfer_log where xfercallid='$INxfercallid' limit 1;"; if ($DB) {echo "$stmt\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00956',$user,$server_ip,$session_name,$one_mysql_log);} $VDCL_vxl_ct = mysqli_num_rows($rslt); if ($VDCL_vxl_ct > 0) { @@ -11094,6 +11132,39 @@ $status_group_gather_data = status_group_gather($row[27],'INGROUP'); + # Gather active talk_sec_urls and their trigger times + $IGtalk_sec_urls_secs = ''; + $stmt="SELECT distinct(url_call_length) FROM vicidial_url_multi where campaign_id='$VDADchannel_group' and entry_type='ingroup' and url_type='talk' and active='Y' and url_call_length > 0 order by url_call_length limit 1000;"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00957',$user,$server_ip,$session_name,$one_mysql_log);} + if ($DB) {echo "$stmt\n";} + $camp_tsu_ct = mysqli_num_rows($rslt); + $tsu=0; + while ($camp_tsu_ct > $tsu) + { + $row=mysqli_fetch_row($rslt); + if ($tsu < 1) + {$IGtalk_sec_urls_secs .= "-";} + $IGtalk_sec_urls_secs .= "$row[0]-"; + $tsu++; + } + # check if this In-Group has talk seconds urls set to -FORCEDISABLE- + $force_disable=0; + $stmt = "SELECT count(*) from vicidial_url_multi where campaign_id='$VDADchannel_group' and entry_type='ingroup' and url_type='talk' and active='N' and url_address LIKE \"%FORCEDISABLE%\";"; + $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";} + $fdtu_field_ct = mysqli_num_rows($rslt); + if ($fdtu_field_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $force_disable = $row[0]; + } + if (strlen($IGtalk_sec_urls_secs) > 0) + {$talk_sec_urls_secs = $IGtalk_sec_urls_secs;} + if ($force_disable > 0) + {$talk_sec_urls_secs = '';} + $stmt = "SELECT campaign_script,xferconf_a_dtmf,xferconf_a_number,xferconf_b_dtmf,xferconf_b_number,default_group_alias,timer_action,timer_action_message,timer_action_seconds,start_call_url,dispo_call_url,xferconf_c_number,xferconf_d_number,xferconf_e_number,timer_action_destination,default_xfer_group,campaign_script_two,browser_alert_sound,browser_alert_volume,custom_one,custom_two,custom_three,custom_four,custom_five from vicidial_campaigns where campaign_id='$campaign';"; if ($DB) {echo "$stmt\n";} $rslt=mysql_to_mysqli($stmt, $link); @@ -11444,8 +11515,8 @@ } ### if web form is set then send on to vicidial.php for override of WEB_FORM address - if ( (strlen($VDCL_group_web)>5) or (strlen($VDCL_group_name)>0) ) {echo "$VDCL_group_web|$VDCL_group_name|$VDCL_group_color|$VDCL_fronter_display|$VDADchannel_group|$VDCL_ingroup_script|$VDCL_get_call_launch|$VDCL_xferconf_a_dtmf|$VDCL_xferconf_a_number|$VDCL_xferconf_b_dtmf|$VDCL_xferconf_b_number|$VDCL_default_xfer_group|$VDCL_ingroup_recording_override|$VDCL_ingroup_rec_filename|$VDCL_default_group_alias|$VDCL_caller_id_number|$VDCL_group_web_vars|$VDCL_group_web_two|$VDCL_timer_action|$VDCL_timer_action_message|$VDCL_timer_action_seconds|$VDCL_xferconf_c_number|$VDCL_xferconf_d_number|$VDCL_xferconf_e_number|$VDCL_uniqueid_status_display|$custom_call_id|$VDCL_uniqueid_status_prefix|$VDCL_timer_action_destination|$DID_id|$DID_extension|$DID_pattern|$DID_description|$INclosecallid|$INxfercallid|$VDCL_group_web_three|$VDCL_ingroup_script_color|$VDCL_inbound_survey|$VDCL_survey_participate|$VDCL_ingroup_script_two|$VDCL_ingroup_script_color_two|$VDCL_browser_alert_sound|$VDCL_browser_alert_volume|$stereo_recording|$stereo_recording_agent|\n";} - else {echo "X|$VDCL_group_name|$VDCL_group_color|$VDCL_fronter_display|$VDADchannel_group|$VDCL_ingroup_script|$VDCL_get_call_launch|$VDCL_xferconf_a_dtmf|$VDCL_xferconf_a_number|$VDCL_xferconf_b_dtmf|$VDCL_xferconf_b_number|$VDCL_default_xfer_group|$VDCL_ingroup_recording_override|$VDCL_ingroup_rec_filename|$VDCL_default_group_alias|$VDCL_caller_id_number|$VDCL_group_web_vars|$VDCL_group_web_two|$VDCL_timer_action|$VDCL_timer_action_message|$VDCL_timer_action_seconds|$VDCL_xferconf_c_number|$VDCL_xferconf_d_number|$VDCL_xferconf_e_number|$VDCL_uniqueid_status_display|$custom_call_id|$VDCL_uniqueid_status_prefix|$VDCL_timer_action_destination|$DID_id|$DID_extension|$DID_pattern|$DID_description|$INclosecallid|$INxfercallid|$VDCL_group_web_three|$VDCL_ingroup_script_color|$VDCL_inbound_survey|$VDCL_survey_participate|$VDCL_ingroup_script_two|$VDCL_ingroup_script_color_two|$VDCL_browser_alert_sound|$VDCL_browser_alert_volume|$stereo_recording|$stereo_recording_agent|\n";} + if ( (strlen($VDCL_group_web)>5) or (strlen($VDCL_group_name)>0) ) {echo "$VDCL_group_web|$VDCL_group_name|$VDCL_group_color|$VDCL_fronter_display|$VDADchannel_group|$VDCL_ingroup_script|$VDCL_get_call_launch|$VDCL_xferconf_a_dtmf|$VDCL_xferconf_a_number|$VDCL_xferconf_b_dtmf|$VDCL_xferconf_b_number|$VDCL_default_xfer_group|$VDCL_ingroup_recording_override|$VDCL_ingroup_rec_filename|$VDCL_default_group_alias|$VDCL_caller_id_number|$VDCL_group_web_vars|$VDCL_group_web_two|$VDCL_timer_action|$VDCL_timer_action_message|$VDCL_timer_action_seconds|$VDCL_xferconf_c_number|$VDCL_xferconf_d_number|$VDCL_xferconf_e_number|$VDCL_uniqueid_status_display|$custom_call_id|$VDCL_uniqueid_status_prefix|$VDCL_timer_action_destination|$DID_id|$DID_extension|$DID_pattern|$DID_description|$INclosecallid|$INxfercallid|$VDCL_group_web_three|$VDCL_ingroup_script_color|$VDCL_inbound_survey|$VDCL_survey_participate|$VDCL_ingroup_script_two|$VDCL_ingroup_script_color_two|$VDCL_browser_alert_sound|$VDCL_browser_alert_volume|$stereo_recording|$stereo_recording_agent|$talk_sec_urls_secs|\n";} + else {echo "X|$VDCL_group_name|$VDCL_group_color|$VDCL_fronter_display|$VDADchannel_group|$VDCL_ingroup_script|$VDCL_get_call_launch|$VDCL_xferconf_a_dtmf|$VDCL_xferconf_a_number|$VDCL_xferconf_b_dtmf|$VDCL_xferconf_b_number|$VDCL_default_xfer_group|$VDCL_ingroup_recording_override|$VDCL_ingroup_rec_filename|$VDCL_default_group_alias|$VDCL_caller_id_number|$VDCL_group_web_vars|$VDCL_group_web_two|$VDCL_timer_action|$VDCL_timer_action_message|$VDCL_timer_action_seconds|$VDCL_xferconf_c_number|$VDCL_xferconf_d_number|$VDCL_xferconf_e_number|$VDCL_uniqueid_status_display|$custom_call_id|$VDCL_uniqueid_status_prefix|$VDCL_timer_action_destination|$DID_id|$DID_extension|$DID_pattern|$DID_description|$INclosecallid|$INxfercallid|$VDCL_group_web_three|$VDCL_ingroup_script_color|$VDCL_inbound_survey|$VDCL_survey_participate|$VDCL_ingroup_script_two|$VDCL_ingroup_script_color_two|$VDCL_browser_alert_sound|$VDCL_browser_alert_volume|$stereo_recording|$stereo_recording_agent|$talk_sec_urls_secs|\n";} if (strlen($fronter) < 2) {$fronter = $tsr;} $stmt = "SELECT full_name from vicidial_users where user='$fronter';"; @@ -11498,7 +11569,7 @@ $stmt="SELECT container_entry FROM vicidial_settings_containers WHERE container_id='$state_descriptions';"; if ($DB) {echo "$stmt\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00958',$user,$server_ip,$session_name,$one_mysql_log);} $SDE_ct = mysqli_num_rows($rslt); $state_debug .= "$NOW_TIME|$SDE_ct|$stmt|\n"; if ($SDE_ct > 0) @@ -11751,7 +11822,7 @@ $stmt="SELECT url_rank,url_statuses,url_address,url_lists from vicidial_url_multi where campaign_id='$SUcampaign' and entry_type='$SUentry_type' and url_type='start' and active='Y' order by url_rank limit 1000;"; if ($DB) {echo "$stmt\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00959',$user,$server_ip,$session_name,$one_mysql_log);} $VUM_ct = mysqli_num_rows($rslt); $k=0; while ($VUM_ct > $k) @@ -12245,7 +12316,7 @@ # Gather list of In-Groups for this user that have hit the daily limit, so we can exclude them $stmt="SELECT group_id FROM vicidial_inbound_group_agents WHERE user='$user' and ( (daily_limit > -1) and (daily_limit <= calls_today) ) limit 1000;"; $rslt=mysql_to_mysqli($stmt, $link); - if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00XXX',$VD_login,$server_ip,$session_name,$one_mysql_log);} + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00960',$VD_login,$server_ip,$session_name,$one_mysql_log);} if ($DB) {echo "$stmt\n";} $VD_hit_limit_ingroups_ct = mysqli_num_rows($rslt); $VD_hit_limit_ingroups="'',"; @@ -12617,7 +12688,7 @@ $stmt = "SELECT calls_today,daily_limit from vicidial_inbound_group_agents where group_id='$VDADchannel_group' and user='$user';"; if ($DB) {echo "$stmt\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00961',$user,$server_ip,$session_name,$one_mysql_log);} $VDIG_cidgwv_ct = mysqli_num_rows($rslt); if ($VDIG_cidgwv_ct > 0) { @@ -12632,7 +12703,7 @@ $stmt = "SELECT outbound_autodial,closer_campaigns FROM vicidial_live_agents where user='$user';"; if ($DB) {echo "$stmt\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00962',$user,$server_ip,$session_name,$one_mysql_log);} $VDIG_cidgwv_ct = mysqli_num_rows($rslt); if ($VDIG_cidgwv_ct > 0) { @@ -12663,21 +12734,21 @@ $stmtA = "UPDATE vicidial_live_agents set external_ingroups='$ADcloser_campaigns',external_blended='$outbound_autodial',external_igb_set_user='VDIC',manager_ingroup_set='SET' where user='$user';"; if ($DB) {echo "$stmtA\n";} $rslt=mysql_to_mysqli($stmtA, $link); - if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmtA,'00XXX',$user,$server_ip,$session_name,$one_mysql_log);} + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmtA,'00963',$user,$server_ip,$session_name,$one_mysql_log);} $vla_update = mysqli_affected_rows($link); ### delete the vicidial_live_inbound_agents record for this user/in-group $stmtB = "DELETE FROM vicidial_live_inbound_agents where user='$user' and group_id='$VDADchannel_group';"; if ($DB) {echo "$stmtB\n";} $rslt=mysql_to_mysqli($stmtB, $link); - if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmtB,'00XXX',$user,$server_ip,$session_name,$one_mysql_log);} + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmtB,'00964',$user,$server_ip,$session_name,$one_mysql_log);} $vlia_delete = mysqli_affected_rows($link); $SQL_log = "$stmtA|$stmtB"; $SQL_log = preg_replace("/'|%/",'',$SQL_log); $stmtC = "INSERT INTO vicidial_admin_log set event_date=NOW(), user='$user', ip_address='$VARserver_ip', event_section='USERS', event_type='MODIFY', record_id='$user', event_code='DAILY LIMIT MODIFY USER', event_sql='$SQL_log', event_notes='|$VDADchannel_group|$VDCL_daily_limit <= $VDCL_calls_today|$user|IC|$closer_campaigns|$outbound_autodial|$vla_update|$vlia_delete|';"; $rslt=mysql_to_mysqli($stmtC, $link); - if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmtC,'00XXX',$user,$server_ip,$session_name,$one_mysql_log);} + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmtC,'00965',$user,$server_ip,$session_name,$one_mysql_log);} $affected_rowsC = mysqli_affected_rows($link); if ($DB) {echo "-- DAILY LIMIT IN-GROUP CALLS TRIGGER: |$VDADchannel_group|$VDCL_daily_limit <= $VDCL_calls_today|$user|IC|$closer_campaigns|$outbound_autodial|$vla_update|$vlia_delete|";} } @@ -12754,7 +12825,7 @@ $stmt = "SELECT user from vicidial_xfer_log where xfercallid='$INxfercallid' limit 1;"; if ($DB) {echo "$stmt\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00966',$user,$server_ip,$session_name,$one_mysql_log);} $VDCL_vxl_ct = mysqli_num_rows($rslt); if ($VDCL_vxl_ct > 0) { @@ -12765,6 +12836,23 @@ } } + # Gather active talk_sec_urls and their trigger times for the campaign + $talk_sec_urls_secs = ''; + $stmt="SELECT distinct(url_call_length) FROM vicidial_url_multi where campaign_id='$campaign' and entry_type='campaign' and url_type='talk' and active='Y' and url_call_length > 0 order by url_call_length limit 1000;"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00955',$user,$server_ip,$session_name,$one_mysql_log);} + if ($DB) {echo "$stmt\n";} + $camp_tsu_ct = mysqli_num_rows($rslt); + $tsu=0; + while ($camp_tsu_ct > $tsu) + { + $row=mysqli_fetch_row($rslt); + if ($tsu < 1) + {$talk_sec_urls_secs .= "-";} + $talk_sec_urls_secs .= "$row[0]-"; + $tsu++; + } + $stmt = "SELECT count(*) from vicidial_log where lead_id='$lead_id' and uniqueid='$uniqueid';"; if ($DB) {echo "$stmt\n";} $rslt=mysql_to_mysqli($stmt, $link); @@ -12901,6 +12989,39 @@ } } + # Gather active talk_sec_urls and their trigger times + $IGtalk_sec_urls_secs = ''; + $stmt="SELECT distinct(url_call_length) FROM vicidial_url_multi where campaign_id='$VDADchannel_group' and entry_type='ingroup' and url_type='talk' and active='Y' and url_call_length > 0 order by url_call_length limit 1000;"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00957',$user,$server_ip,$session_name,$one_mysql_log);} + if ($DB) {echo "$stmt\n";} + $camp_tsu_ct = mysqli_num_rows($rslt); + $tsu=0; + while ($camp_tsu_ct > $tsu) + { + $row=mysqli_fetch_row($rslt); + if ($tsu < 1) + {$IGtalk_sec_urls_secs .= "-";} + $IGtalk_sec_urls_secs .= "$row[0]-"; + $tsu++; + } + # check if this In-Group has talk seconds urls set to -FORCEDISABLE- + $force_disable=0; + $stmt = "SELECT count(*) from vicidial_url_multi where campaign_id='$VDADchannel_group' and entry_type='ingroup' and url_type='talk' and active='N' and url_address LIKE \"%FORCEDISABLE%\";"; + $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";} + $fdtu_field_ct = mysqli_num_rows($rslt); + if ($fdtu_field_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $force_disable = $row[0]; + } + if (strlen($IGtalk_sec_urls_secs) > 0) + {$talk_sec_urls_secs = $IGtalk_sec_urls_secs;} + if ($force_disable > 0) + {$talk_sec_urls_secs = '';} + ### update the comments in vicidial_live_agents record $stmt = "UPDATE vicidial_live_agents set last_inbound_call_time='$NOW_TIME' where user='$user' and server_ip='$server_ip';"; if ($DB) {echo "$stmt\n";} @@ -13057,7 +13178,7 @@ $stmt="SELECT container_entry FROM vicidial_settings_containers WHERE container_id='$state_descriptions';"; if ($DB) {echo "$stmt\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00967',$user,$server_ip,$session_name,$one_mysql_log);} $SDE_ct = mysqli_num_rows($rslt); $state_debug .= "$SDE_ct|$stmt|\n"; if ($SDE_ct > 0) @@ -13134,8 +13255,8 @@ } ### if web form is set then send on to vicidial.php for override of WEB_FORM address - if ( (strlen($VDCL_group_web)>5) or (strlen($VDCL_group_name)>0) ) {echo "$VDCL_group_web|$VDCL_group_name|$VDCL_group_color|$VDCL_fronter_display|$VDADchannel_group|$VDCL_ingroup_script|$VDCL_get_call_launch|$VDCL_xferconf_a_dtmf|$VDCL_xferconf_a_number|$VDCL_xferconf_b_dtmf|$VDCL_xferconf_b_number|$VDCL_default_xfer_group|$VDCL_ingroup_recording_override|$VDCL_ingroup_rec_filename|$VDCL_default_group_alias|$VDCL_caller_id_number|$VDCL_group_web_vars|$VDCL_group_web_two|$VDCL_timer_action|$VDCL_timer_action_message|$VDCL_timer_action_seconds|$VDCL_xferconf_c_number|$VDCL_xferconf_d_number|$VDCL_xferconf_e_number|$VDCL_uniqueid_status_display|$custom_call_id|$VDCL_uniqueid_status_prefix|$VDCL_timer_action_destination|$DID_id|$DID_extension|$DID_pattern|$DID_description|$INclosecallid|$INxfercallid|$VDCL_group_web_three|$VDCL_ingroup_script_color|$VDCL_ingroup_script_two|$VDCL_ingroup_script_color_two|\n";} - else {echo "X|$VDCL_group_name|$VDCL_group_color|$VDCL_fronter_display|$VDADchannel_group|$VDCL_ingroup_script|$VDCL_get_call_launch|$VDCL_xferconf_a_dtmf|$VDCL_xferconf_a_number|$VDCL_xferconf_b_dtmf|$VDCL_xferconf_b_number|$VDCL_default_xfer_group|$VDCL_ingroup_recording_override|$VDCL_ingroup_rec_filename|$VDCL_default_group_alias|$VDCL_caller_id_number|$VDCL_group_web_vars|$VDCL_group_web_two|$VDCL_timer_action|$VDCL_timer_action_message|$VDCL_timer_action_seconds|$VDCL_xferconf_c_number|$VDCL_xferconf_d_number|$VDCL_xferconf_e_number|$VDCL_uniqueid_status_display|$custom_call_id|$VDCL_uniqueid_status_prefix|$VDCL_timer_action_destination|$DID_id|$DID_extension|$DID_pattern|$DID_description|$INclosecallid|$INxfercallid|$VDCL_group_web_three|$VDCL_ingroup_script_color|$VDCL_ingroup_script_two|$VDCL_ingroup_script_color_two|\n";} + if ( (strlen($VDCL_group_web)>5) or (strlen($VDCL_group_name)>0) ) {echo "$VDCL_group_web|$VDCL_group_name|$VDCL_group_color|$VDCL_fronter_display|$VDADchannel_group|$VDCL_ingroup_script|$VDCL_get_call_launch|$VDCL_xferconf_a_dtmf|$VDCL_xferconf_a_number|$VDCL_xferconf_b_dtmf|$VDCL_xferconf_b_number|$VDCL_default_xfer_group|$VDCL_ingroup_recording_override|$VDCL_ingroup_rec_filename|$VDCL_default_group_alias|$VDCL_caller_id_number|$VDCL_group_web_vars|$VDCL_group_web_two|$VDCL_timer_action|$VDCL_timer_action_message|$VDCL_timer_action_seconds|$VDCL_xferconf_c_number|$VDCL_xferconf_d_number|$VDCL_xferconf_e_number|$VDCL_uniqueid_status_display|$custom_call_id|$VDCL_uniqueid_status_prefix|$VDCL_timer_action_destination|$DID_id|$DID_extension|$DID_pattern|$DID_description|$INclosecallid|$INxfercallid|$VDCL_group_web_three|$VDCL_ingroup_script_color|$VDCL_ingroup_script_two|$VDCL_ingroup_script_color_two|$talk_sec_urls_secs|\n";} + else {echo "X|$VDCL_group_name|$VDCL_group_color|$VDCL_fronter_display|$VDADchannel_group|$VDCL_ingroup_script|$VDCL_get_call_launch|$VDCL_xferconf_a_dtmf|$VDCL_xferconf_a_number|$VDCL_xferconf_b_dtmf|$VDCL_xferconf_b_number|$VDCL_default_xfer_group|$VDCL_ingroup_recording_override|$VDCL_ingroup_rec_filename|$VDCL_default_group_alias|$VDCL_caller_id_number|$VDCL_group_web_vars|$VDCL_group_web_two|$VDCL_timer_action|$VDCL_timer_action_message|$VDCL_timer_action_seconds|$VDCL_xferconf_c_number|$VDCL_xferconf_d_number|$VDCL_xferconf_e_number|$VDCL_uniqueid_status_display|$custom_call_id|$VDCL_uniqueid_status_prefix|$VDCL_timer_action_destination|$DID_id|$DID_extension|$DID_pattern|$DID_description|$INclosecallid|$INxfercallid|$VDCL_group_web_three|$VDCL_ingroup_script_color|$VDCL_ingroup_script_two|$VDCL_ingroup_script_color_two|$talk_sec_urls_secs|\n";} $stmt = "SELECT full_name from vicidial_users where user='$tsr';"; if ($DB) {echo "$stmt\n";} @@ -13357,7 +13478,7 @@ $stmt="SELECT url_rank,url_statuses,url_address,url_lists from vicidial_url_multi where campaign_id='$SUcampaign' and entry_type='$SUentry_type' and url_type='start' and active='Y' order by url_rank limit 1000;"; if ($DB) {echo "$stmt\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00968',$user,$server_ip,$session_name,$one_mysql_log);} $VUM_ct = mysqli_num_rows($rslt); $k=0; while ($VUM_ct > $k) @@ -14353,7 +14474,7 @@ $stmt="SELECT container_entry FROM vicidial_settings_containers WHERE container_id='$state_descriptions';"; if ($DB) {echo "$stmt\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00969',$user,$server_ip,$session_name,$one_mysql_log);} $SDE_ct = mysqli_num_rows($rslt); $state_debug .= "$SDE_ct|$stmt|\n"; if ($SDE_ct > 0) @@ -16445,7 +16566,7 @@ $stmt = "SELECT user from vicidial_xfer_log where xfercallid='$INxfercallid' limit 1;"; if ($DB) {echo "$stmt\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00970',$user,$server_ip,$session_name,$one_mysql_log);} $VDCL_vxl_ct = mysqli_num_rows($rslt); if ($VDCL_vxl_ct > 0) { @@ -17497,6 +17618,522 @@ } +################################################################################ +### TALKsecURL - Talk Seconds URLs run +################################################################################ +if ($ACTION == 'TALKsecURL') + { + ############################################ + ### BEGIN Issue Talk Seconds URL if defined + ############################################ + $talk_sec_url_count=0; + $talk_sec_urlARY = array(); + $talk_sec_urlARY[0]=''; + $talk_urls=''; + $talk_time = $customer_sec; + $talk_time_ms=0; + $talk_time_min=0; + $force_disable=0; + + $talk_time_ms = ($customer_sec * 1000); + $talk_time_min = ceil($customer_sec / 60); + + $DUentry_type = 'campaign'; + $VDADchannel_group=$campaign; + if ($inOUT == 'IN') + { + $DUentry_type = 'ingroup'; + $VDADchannel_group=$group; + + # check if this In-Group has talk seconds urls set to -FORCEDISABLE- + $stmt = "SELECT count(*) from vicidial_url_multi where campaign_id='$VDADchannel_group' and entry_type='$DUentry_type' and url_type='talk' and active='N' and url_address LIKE \"%FORCEDISABLE%\";"; + $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";} + $fdtu_field_ct = mysqli_num_rows($rslt); + if ($fdtu_field_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $force_disable = $row[0]; + } + + if ($force_disable < 1) + { + # check for In-Group talk_sec_urls + $stmt="SELECT url_rank,url_statuses,url_address,url_lists,url_call_length from vicidial_url_multi where campaign_id='$VDADchannel_group' and entry_type='$DUentry_type' and url_type='talk' and active='Y' and url_call_length='$customer_sec' order by url_rank limit 1000;"; + if ($DB) {echo "$stmt\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00971',$user,$server_ip,$session_name,$one_mysql_log);} + $VUM_ct = mysqli_num_rows($rslt); + $k=0; + while ($VUM_ct > $k) + { + $row=mysqli_fetch_row($rslt); + $url_rank = $row[0]; + $url_statuses = " $row[1] "; + $url_address = $row[2]; + $url_lists = " $row[3] "; + $url_call_length = $row[4]; + + if ( (strlen($url_lists)<3) or ( (strlen($url_lists)>2) and (preg_match("/ $list_id /",$url_lists)) ) ) + { + $talk_sec_urlARY[$talk_sec_url_count] = $url_address; + $talk_sec_url_count++; + } + $k++; + } + } + } + + if ( ($talk_sec_url_count < 1) and ($force_disable < 1) ) + { + $DUentry_type = 'campaign'; + $VDADchannel_group=$campaign; + # check for Campaign talk_sec_urls + $stmt="SELECT url_rank,url_statuses,url_address,url_lists,url_call_length from vicidial_url_multi where campaign_id='$VDADchannel_group' and entry_type='$DUentry_type' and url_type='talk' and active='Y' and url_call_length='$customer_sec' order by url_rank limit 1000;"; + if ($DB) {echo "$stmt\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00971',$user,$server_ip,$session_name,$one_mysql_log);} + $VUM_ct = mysqli_num_rows($rslt); + $k=0; + while ($VUM_ct > $k) + { + $row=mysqli_fetch_row($rslt); + $url_rank = $row[0]; + $url_statuses = " $row[1] "; + $url_address = $row[2]; + $url_lists = " $row[3] "; + $url_call_length = $row[4]; + + if ( (strlen($url_lists)<3) or ( (strlen($url_lists)>2) and (preg_match("/ $list_id /",$url_lists)) ) ) + { + $talk_sec_urlARY[$talk_sec_url_count] = $url_address; + $talk_sec_url_count++; + } + $k++; + } + } + + ### loop through each Talk Seconds URL entry and process ### + $j=0; + while ($talk_sec_url_count > $j) + { + if ( (preg_match('/--A--user_custom_/i',$talk_sec_urlARY[$j])) or (preg_match('/--A--fullname/i',$talk_sec_urlARY[$j])) or (preg_match('/--A--user_group/i',$talk_sec_urlARY[$j])) ) + { + $stmt = "SELECT custom_one,custom_two,custom_three,custom_four,custom_five,full_name,user_group from vicidial_users where user='$user';"; + if ($DB) {echo "$stmt\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00972',$user,$server_ip,$session_name,$one_mysql_log);} + $VUC_ct = mysqli_num_rows($rslt); + if ($VUC_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $user_custom_one = urlencode(trim($row[0])); + $user_custom_two = urlencode(trim($row[1])); + $user_custom_three = urlencode(trim($row[2])); + $user_custom_four = urlencode(trim($row[3])); + $user_custom_five = urlencode(trim($row[4])); + $fullname = urlencode(trim($row[5])); + $user_group = urlencode(trim($row[6])); + } + } + + if (preg_match('/--A--dialed_|--A--term_reason--B--/i',$talk_sec_urlARY[$j])) + { + $dialed_number = $phone_number; + $dialed_label = 'NONE'; + $term_reason = 'NONE'; + + if ($inOUT=='OUT') + { + ### find the dialed number and label for this call + $stmt = "SELECT phone_number,alt_dial,term_reason from vicidial_log where uniqueid='$uniqueid';"; + if ($DB) {echo "$stmt\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00973',$user,$server_ip,$session_name,$one_mysql_log);} + $vl_dialed_ct = mysqli_num_rows($rslt); + if ($vl_dialed_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $dialed_number = $row[0]; + $dialed_label = $row[1]; + $term_reason = $row[2]; + } + } + } + + if (preg_match('/--A--did_/i',$talk_sec_urlARY[$j])) + { + $DID_id=''; + $DID_extension=''; + $DID_pattern=''; + $DID_description=''; + + $stmt = "SELECT did_id,extension from vicidial_did_log where uniqueid='$uniqueid' and caller_id_number='$phone_number' order by call_date desc limit 1;"; + if ($DB) {echo "$stmt\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00974',$user,$server_ip,$session_name,$one_mysql_log);} + $VDIDL_ct = mysqli_num_rows($rslt); + if ($VDIDL_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $DID_id = $row[0]; + $DID_extension = $row[1]; + + $stmt = "SELECT did_pattern,did_description,custom_one,custom_two,custom_three,custom_four,custom_five from vicidial_inbound_dids where did_id='$DID_id' limit 1;"; + if ($DB) {echo "$stmt\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00975',$user,$server_ip,$session_name,$one_mysql_log);} + $VDIDL_ct = mysqli_num_rows($rslt); + if ($VDIDL_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $DID_pattern = urlencode(trim($row[0])); + $DID_description = urlencode(trim($row[1])); + $DID_custom_one = urlencode(trim($row[2])); + $DID_custom_two= urlencode(trim($row[3])); + $DID_custom_three= urlencode(trim($row[4])); + $DID_custom_four= urlencode(trim($row[5])); + $DID_custom_five= urlencode(trim($row[6])); + } + } + } + + if ( (preg_match('/callid--B--/i',$talk_sec_urlARY[$j])) or (preg_match('/group--B--|--A--term_reason--B--/i',$talk_sec_urlARY[$j])) or (preg_match('/fronter--B--|closer--B--/i',$talk_sec_urlARY[$j])) ) + { + $INclosecallid=''; + $INxfercallid=''; + $VDADchannel_group=$campaign; + $stmt = "SELECT campaign_id,closecallid,xfercallid,term_reason from vicidial_closer_log where uniqueid='$uniqueid' and user='$user' order by closecallid desc limit 1;"; + if ($DB) {echo "$stmt\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00976',$user,$server_ip,$session_name,$one_mysql_log);} + $VDCL_mvac_ct = mysqli_num_rows($rslt); + if ($VDCL_mvac_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $VDADchannel_group = $row[0]; + $INclosecallid = $row[1]; + $INxfercallid = $row[2]; + $term_reason = $row[3]; + } + if ( (strlen($INxfercallid) > 0) and ($INxfercallid > 0) and (preg_match('/fronter--B--|closer--B--/i',$talk_sec_urlARY[$j])) ) + { + # check for fronter in vicidial_xfer_log + $stmt = "SELECT user from vicidial_xfer_log where xfercallid='$INxfercallid' limit 1;"; + if ($DB) {echo "$stmt\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00977',$user,$server_ip,$session_name,$one_mysql_log);} + $VDCL_vxl_ct = mysqli_num_rows($rslt); + if ($VDCL_vxl_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $fronter = $row[0]; + $closer = $user; + } + } + } + + ##### grab the data from vicidial_list for the lead_id + $stmt="SELECT lead_id,entry_date,modify_date,status,user,vendor_lead_code,source_id,list_id,gmt_offset_now,called_since_last_reset,phone_code,phone_number,title,first_name,middle_initial,last_name,address1,address2,address3,city,state,province,postal_code,country_code,gender,date_of_birth,alt_phone,email,security_phrase,comments,called_count,last_local_call_time,rank,owner,entry_list_id FROM vicidial_list where lead_id='$lead_id' LIMIT 1;"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00978',$user,$server_ip,$session_name,$one_mysql_log);} + if ($DB) {echo "$stmt\n";} + $list_lead_ct = mysqli_num_rows($rslt); + if ($list_lead_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $entry_date = urlencode(trim($row[1])); + $dispo = urlencode(trim($row[3])); + $tsr = urlencode(trim($row[4])); + $vendor_id = urlencode(trim($row[5])); + $vendor_lead_code = urlencode(trim($row[5])); + $source_id = urlencode(trim($row[6])); + $list_id = urlencode(trim($row[7])); + $gmt_offset_now = urlencode(trim($row[8])); + $phone_code = urlencode(trim($row[10])); + $phone_number = urlencode(trim($row[11])); + $title = urlencode(trim($row[12])); + $first_name = urlencode(trim($row[13])); + $middle_initial = urlencode(trim($row[14])); + $last_name = urlencode(trim($row[15])); + $address1 = urlencode(trim($row[16])); + $address2 = urlencode(trim($row[17])); + $address3 = urlencode(trim($row[18])); + $city = urlencode(trim($row[19])); + $state = urlencode(trim($row[20])); + $province = urlencode(trim($row[21])); + $postal_code = urlencode(trim($row[22])); + $country_code = urlencode(trim($row[23])); + $gender = urlencode(trim($row[24])); + $date_of_birth = urlencode(trim($row[25])); + $alt_phone = urlencode(trim($row[26])); + $email = urlencode(trim($row[27])); + $security_phrase = urlencode(trim($row[28])); + $comments = urlencode(trim($row[29])); + $called_count = urlencode(trim($row[30])); + $call_date = urlencode(trim($row[31])); + $rank = urlencode(trim($row[32])); + $owner = urlencode(trim($row[33])); + $entry_list_id = urlencode(trim($row[34])); + } + + if (preg_match('/list_name--B--|list_description--B--/i',$talk_sec_urlARY[$j])) + { + $stmt = "SELECT list_name,list_description from vicidial_lists where list_id='$list_id' limit 1;"; + if ($DB) {echo "$stmt\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00797',$user,$server_ip,$session_name,$one_mysql_log);} + $VL_ln_ct = mysqli_num_rows($rslt); + if ($VL_ln_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $list_name = urlencode(trim($row[0])); + $list_description = urlencode(trim($row[1])); + } + } + + $talk_sec_urlARY[$j] = preg_replace('/^VAR/','',$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--lead_id--B--/i',"$lead_id",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--vendor_id--B--/i',"$vendor_id",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--vendor_lead_code--B--/i',"$vendor_lead_code",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--list_id--B--/i',"$list_id",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--list_name--B--/i',"$list_name",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--list_description--B--/i',"$list_description",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--gmt_offset_now--B--/i',"$gmt_offset_now",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--phone_code--B--/i',"$phone_code",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--phone_number--B--/i',"$phone_number",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--title--B--/i',"$title",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--first_name--B--/i',"$first_name",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--middle_initial--B--/i',"$middle_initial",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--last_name--B--/i',"$last_name",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--address1--B--/i',"$address1",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--address2--B--/i',"$address2",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--address3--B--/i',"$address3",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--city--B--/i',"$city",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--state--B--/i',"$state",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--province--B--/i',"$province",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--postal_code--B--/i',"$postal_code",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--country_code--B--/i',"$country_code",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--gender--B--/i',"$gender",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--date_of_birth--B--/i',"$date_of_birth",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--alt_phone--B--/i',"$alt_phone",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--email--B--/i',"$email",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--security_phrase--B--/i',"$security_phrase",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--comments--B--/i',"$comments",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--user--B--/i',"$user",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--pass--B--/i',"$orig_pass",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--campaign--B--/i',"$campaign",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--phone_login--B--/i',"$phone_login",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--original_phone_login--B--/i',"$original_phone_login",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--phone_pass--B--/i',"$phone_pass",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--fronter--B--/i',"$fronter",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--closer--B--/i',"$closer",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--group--B--/i',"$VDADchannel_group",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--channel_group--B--/i',"$VDADchannel_group",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--SQLdate--B--/i',urlencode(trim($SQLdate)),$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--epoch--B--/i',"$epoch",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--uniqueid--B--/i',"$uniqueid",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--customer_zap_channel--B--/i',urlencode(trim($customer_zap_channel)),$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--customer_server_ip--B--/i',"$customer_server_ip",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--server_ip--B--/i',"$server_ip",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--SIPexten--B--/i',urlencode(trim($exten)),$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--session_id--B--/i',"$conf_exten",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--phone--B--/i',"$phone_number",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--parked_by--B--/i',"$parked_by",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--dispo--B--/i',"$dispo",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--dispo_name--B--/i',"$dispo_name",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--dialed_number--B--/i',"$dialed_number",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--dialed_label--B--/i',"$dialed_label",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--source_id--B--/i',"$source_id",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--rank--B--/i',"$rank",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--owner--B--/i',"$owner",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--camp_script--B--/i',"$camp_script",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--in_script--B--/i',"$in_script",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--fullname--B--/i',"$fullname",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--user_custom_one--B--/i',"$user_custom_one",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--user_custom_two--B--/i',"$user_custom_two",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--user_custom_three--B--/i',"$user_custom_three",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--user_custom_four--B--/i',"$user_custom_four",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--user_custom_five--B--/i',"$user_custom_five",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--camp_custom_one--B--/i',"$camp_custom_one",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--camp_custom_two--B--/i',"$camp_custom_two",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--camp_custom_three--B--/i',"$camp_custom_three",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--camp_custom_four--B--/i',"$camp_custom_four",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--camp_custom_five--B--/i',"$camp_custom_five",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--talk_time--B--/i',"$talk_time",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--talk_time_ms--B--/i',"$talk_time_ms",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--talk_time_min--B--/i',"$talk_time_min",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--agent_log_id--B--/i',"$CALL_agent_log_id",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--entry_list_id--B--/i',"$entry_list_id",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--did_id--B--/i',urlencode(trim($DID_id)),$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--did_extension--B--/i',urlencode(trim($DID_extension)),$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--did_pattern--B--/i',urlencode(trim($DID_pattern)),$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--did_description--B--/i',urlencode(trim($DID_description)),$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--closecallid--B--/i',urlencode(trim($INclosecallid)),$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--xfercallid--B--/i',urlencode(trim($INxfercallid)),$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--call_id--B--/i',urlencode(trim($MDnextCID)),$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--user_group--B--/i',urlencode(trim($user_group)),$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--call_notes--B--/i',"$url_call_notes",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--recording_id--B--/i',"$recording_id",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--recording_filename--B--/i',"$recording_filename",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--entry_date--B--/i',"$entry_date",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--did_custom_one--B--/i',urlencode(trim($DID_custom_one)),$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--did_custom_two--B--/i',urlencode(trim($DID_custom_two)),$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--did_custom_three--B--/i',urlencode(trim($DID_custom_three)),$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--did_custom_four--B--/i',urlencode(trim($DID_custom_four)),$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--did_custom_five--B--/i',urlencode(trim($DID_custom_five)),$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--ig_custom_one--B--/i',urlencode(trim($ig_custom_one)),$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--ig_custom_two--B--/i',urlencode(trim($ig_custom_two)),$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--ig_custom_three--B--/i',urlencode(trim($ig_custom_three)),$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--ig_custom_four--B--/i',urlencode(trim($ig_custom_four)),$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--ig_custom_five--B--/i',urlencode(trim($ig_custom_five)),$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--agent_email--B--/i',urlencode(trim($agent_email)),$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--callback_lead_status--B--/i',urlencode(trim($CallBackLeadStatus)),$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--callback_datetime--B--/i',urlencode(trim($CallBackDatETimE)),$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--called_count--B--/i',"$called_count",$talk_sec_urlARY[$j]); + $talk_sec_urlARY[$j] = preg_replace('/--A--term_reason--B--/i',"$term_reason",$talk_sec_urlARY[$j]); + + if (strlen($FORMcustom_field_names)>2) + { + $custom_field_names = preg_replace("/^\||\|$/",'',$FORMcustom_field_names); + $custom_field_names = preg_replace("/\|.*_DUPLICATE_.*\|/",'|',$custom_field_names); + $custom_field_names = preg_replace("/\|/",",",$custom_field_names); + $custom_field_names_ARY = explode(',',$custom_field_names); + $custom_field_names_ct = count($custom_field_names_ARY); + $custom_field_names_SQL = $custom_field_names; + + if (preg_match("/cf_encrypt/",$active_modules)) + { + $enc_fields=0; + $stmt = "SELECT count(*) from vicidial_lists_fields where field_encrypt='Y' and list_id='$entry_list_id';"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($DB) {echo "$stmt\n";} + $enc_field_ct = mysqli_num_rows($rslt); + if ($enc_field_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $enc_fields = $row[0]; + } + if ($enc_fields > 0) + { + $stmt = "SELECT field_label from vicidial_lists_fields where field_encrypt='Y' and list_id='$entry_list_id';"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($DB) {echo "$stmt\n";} + $enc_field_ct = mysqli_num_rows($rslt); + $r=0; + while ($enc_field_ct > $r) + { + $row=mysqli_fetch_row($rslt); + $encrypt_list .= "$row[0],"; + $r++; + } + $encrypt_list = ",$encrypt_list"; + } + } + + + ##### BEGIN grab the data from custom table for the lead_id + if ($entry_list_id > 0) + { + $stmt="SELECT $custom_field_names_SQL FROM custom_$entry_list_id where lead_id='$lead_id' LIMIT 1;"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00980',$user,$server_ip,$session_name,$one_mysql_log);} + if ($DB) {echo "$stmt\n";} + $list_lead_ct = mysqli_num_rows($rslt); + if ($list_lead_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $o=0; + while ($custom_field_names_ct > $o) + { + $field_name_id = $custom_field_names_ARY[$o]; + $field_name_tag = "--A--" . $field_name_id . "--B--"; + if ($enc_fields > 0) + { + $field_enc=''; $field_enc_all=''; + if ($DB) {echo "|$column_list|$encrypt_list|\n";} + if ( (preg_match("/,$field_name_id,/",$encrypt_list)) and (strlen($row[$o]) > 0) ) + { + exec("../agc/aes.pl --decrypt --text=$row[$o]", $field_enc); + $field_enc_ct = count($field_enc); + $k=0; + while ($field_enc_ct > $k) + { + $field_enc_all .= $field_enc[$k]; + $k++; + } + $field_enc_all = preg_replace("/CRYPT: |\n|\r|\t/",'',$field_enc_all); + $row[$o] = base64_decode($field_enc_all); + } + } + $form_field_value = urlencode(trim("$row[$o]")); + + $talk_sec_urlARY[$j] = preg_replace("/$field_name_tag/i","$form_field_value",$talk_sec_urlARY[$j]); + $o++; + } + } + } + } + + ### insert a new url log entry + $stmt = "INSERT INTO vicidial_url_log SET uniqueid='$uniqueid',url_date=NOW(),url_type='talk_sec',url='" . mysqli_real_escape_string($link, $talk_sec_urlARY[$j]) . "',url_response='';"; + if ($DB) {echo "$stmt\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00981',$user,$server_ip,$session_name,$one_mysql_log);} + $affected_rows = mysqli_affected_rows($link); + $url_id = mysqli_insert_id($link); + + $URLstart_sec = date("U"); + + ### send talk_sec_url ### + if ($DB > 0) {echo "$talk_sec_urlARY[$j]
\n";} + + $talk_urls .= "$url_id|"; + + $URLstart_sec = date("U"); + + $SCUfile = file("$talk_sec_urlARY[$j]"); + if ( !($SCUfile) ) + { + $error_array = error_get_last(); + $error_type = $error_array["type"]; + $error_message = $error_array["message"]; + $error_line = $error_array["line"]; + $error_file = $error_array["file"]; + } + + if ($DB > 0) {echo "$SCUfile[0]
\n";} + + ### update url log entry + $URLend_sec = date("U"); + $URLdiff_sec = ($URLend_sec - $URLstart_sec); + if ($SCUfile) + { + $SCUfile_contents = implode("", $SCUfile); + $SCUfile_contents = preg_replace('/;/','',$SCUfile_contents); + $SCUfile_contents = addslashes($SCUfile_contents); + } + else + { + $SCUfile_contents = "PHP ERROR: Type=$error_type - Message=$error_message - Line=$error_line - File=$error_file"; + } + $stmt = "UPDATE vicidial_url_log SET response_sec='$URLdiff_sec',url_response='$SCUfile_contents' where url_log_id='$url_id';"; + if ($DB) {echo "$stmt\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00982',$user,$server_ip,$session_name,$one_mysql_log);} + $affected_rows = mysqli_affected_rows($link); + + $j++; + } + echo "Talk Seconds URLs:\n$talk_urls\n"; + ############################################ + ### END Issue Talk Seconds URLs if defined + ############################################ + $stage .= "|$inOUT|$customer_sec|"; + } + + ################################################################################ ### RUNurls - request the URLs that are queued up to run for this call ################################################################################ @@ -19420,7 +20057,7 @@ $stmt="SELECT user_group from vicidial_users where user='$user';"; if ($non_latin > 0) {$rslt=mysql_to_mysqli("SET NAMES 'UTF8'", $link);} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00983',$user,$server_ip,$session_name,$one_mysql_log);} $cl_user_ct = mysqli_num_rows($rslt); if ($cl_user_ct > 0) { @@ -19429,7 +20066,7 @@ } $stmt="SELECT agent_call_log_view from vicidial_user_groups where user_group='$VU_user_group';"; $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00984',$user,$server_ip,$session_name,$one_mysql_log);} $cl_ug_ct = mysqli_num_rows($rslt); if ($cl_ug_ct > 0) { @@ -19439,7 +20076,7 @@ } $stmt="SELECT call_log_days from vicidial_campaigns where campaign_id='$campaign';"; $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00985',$user,$server_ip,$session_name,$one_mysql_log);} $cl_camp_ct = mysqli_num_rows($rslt); if ($cl_camp_ct > 0) { @@ -20033,7 +20670,7 @@ { $stmt="SELECT agent_search_list from vicidial_inbound_groups where group_id='$inbound_ingroup' and agent_search_list != '';"; $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00986',$user,$server_ip,$session_name,$one_mysql_log);} $igs_to_parse = mysqli_num_rows($rslt); if ($igs_to_parse > 0) { @@ -22742,7 +23379,7 @@ function manual_dccl_check($temp_lead_id, $temp_no_hopper, $temp_dial_only, $tem if ($temp_dial_only > 0) {$temp_daily_call_count_limit = ($daily_phone_number_call_limit + 1);} $stmt="SELECT called_count FROM vicidial_phone_number_call_daily_counts where phone_number='$temp_phone_number';"; $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00987',$user,$server_ip,$session_name,$one_mysql_log);} if ($DB) {echo "$stmt\n";} $vlcdc_ct = mysqli_num_rows($rslt); if ($vlcdc_ct > 0) @@ -22754,7 +23391,7 @@ function manual_dccl_check($temp_lead_id, $temp_no_hopper, $temp_dial_only, $tem $stmt = "UPDATE vicidial_list set called_since_last_reset='Y' where lead_id='$lead_id';"; if ($DB) {echo "$stmt\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00988',$user,$server_ip,$session_name,$one_mysql_log);} if ($temp_no_hopper > 0) { @@ -22762,7 +23399,7 @@ function manual_dccl_check($temp_lead_id, $temp_no_hopper, $temp_dial_only, $tem $stmt="UPDATE vicidial_agent_log set lead_id=NULL,comments='' where agent_log_id='$agent_log_id';"; if ($format=='debug') {echo "\n";} $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00989',$user,$server_ip,$session_name,$one_mysql_log);} echo " NO-HOPPER DAILY PHONE NUMBER CALL LIMIT\nTRY AGAIN\n"; $stage .= "|$agent_log_id|$vla_status|$agent_dialed_type|$agent_dialed_number|"; diff --git a/www/agc/vicidial.php b/www/agc/vicidial.php index ea85c312d..08143b4d2 100644 --- a/www/agc/vicidial.php +++ b/www/agc/vicidial.php @@ -749,13 +749,14 @@ # 250806-0859 - Added manual_dial_lead_id 'ONLY' option and user override setting # 250808-1322 - Added agent_man_dial_filter & agent_3way_dial_filter system settings # 250916-2055 - Added stereo recording features +# 250924-0953 - Added Talk Seconds URLs features # -$version = '2.14-715c'; -$build = '250916-2055'; +$version = '2.14-716c'; +$build = '250924-0953'; $php_script = 'vicidial.php'; $mel=1; # Mysql Error Log enabled = 1 -$mysql_log_count=103; +$mysql_log_count=108; $one_mysql_log=0; $DB=0; $conf_table = "vicidial_conferences"; @@ -1156,7 +1157,7 @@ $agent_hide_dial_fail_MESSAGE='Dial Failed'; $stmt="SELECT container_entry FROM vicidial_settings_containers WHERE container_id='FAILED_DIAL_MESSAGE_OVERRIDE';"; $rslt=mysql_to_mysqli($stmt, $link); - if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'01XXX',$VD_login,$server_ip,$session_name,$one_mysql_log);} + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'01104',$VD_login,$server_ip,$session_name,$one_mysql_log);} if ($DB) {echo "$stmt\n";} $stde_ct = mysqli_num_rows($rslt); if ($stde_ct > 0) @@ -1820,7 +1821,7 @@ function login_submit() $stmt="SELECT count(*) from vicidial_two_factor_auth where user='$VD_login' and auth_stage='1' and auth_exp_date > NOW();"; if ($DB) {echo "$stmt\n";} $rslt=mysql_to_mysqli($stmt, $link); - if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'01XXX',$VD_login,$server_ip,$session_name,$one_mysql_log);} + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'01105',$VD_login,$server_ip,$session_name,$one_mysql_log);} $auth_check_to_print = mysqli_num_rows($rslt); if ($auth_check_to_print < 1) {$VALID_2FA=0;} @@ -1844,7 +1845,7 @@ function login_submit() $stmt="SELECT full_name,email,mobile_number,user_group from vicidial_users where user='$VD_login' and active='Y' and api_only_user != '1';"; $rslt=mysql_to_mysqli($stmt, $link); - if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'01XXX',$VD_login,$server_ip,$session_name,$one_mysql_log);} + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'01106',$VD_login,$server_ip,$session_name,$one_mysql_log);} $row=mysqli_fetch_row($rslt); $LOGfullname = $row[0]; $LOGemail = $row[1]; @@ -3395,7 +3396,7 @@ function login_submit() { $stmt="SELECT container_entry FROM vicidial_settings_containers WHERE container_id='$state_descriptions';"; $rslt=mysql_to_mysqli($stmt, $link); - if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'01XXX',$VD_login,$server_ip,$session_name,$one_mysql_log);} + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'01107',$VD_login,$server_ip,$session_name,$one_mysql_log);} if ($DB) {echo "$stmt\n";} $stde_ct = mysqli_num_rows($rslt); if ($stde_ct > 0) @@ -3881,7 +3882,7 @@ function login_submit() # Gather list of In-Groups for this user that have hit the daily limit, so we can exclude them $stmt="SELECT group_id FROM vicidial_inbound_group_agents WHERE user='$VD_login' and ( (daily_limit > -1) and (daily_limit <= calls_today) ) limit 1000;"; $rslt=mysql_to_mysqli($stmt, $link); - if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'01XXX',$VD_login,$server_ip,$session_name,$one_mysql_log);} + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'01108',$VD_login,$server_ip,$session_name,$one_mysql_log);} if ($DB) {echo "$stmt\n";} $VD_hit_limit_ingroups_ct = mysqli_num_rows($rslt); $VD_hit_limit_ingroups="'',"; @@ -6318,6 +6319,7 @@ function login_submit() var conf_channels_xtra_display = 0; var display_message = ''; var web_form_vars = ''; + var talk_url_vars = ''; var Nactiveext; var Nbusytrunk; var Nbusyext; @@ -6862,6 +6864,7 @@ function login_submit() var HTheightS=''; var agent_hide_dial_fail=''; var agent_hide_dial_fail_MESSAGE=""; + var talk_sec_url_secs=''; var DiaLControl_auto_HTML = "\" border=\"0\" alt=\"You are paused\" />"; var DiaLControl_auto_HTML_ready = "\" border=\"0\" alt=\"You are active\" />"; var DiaLControl_auto_HTML_OFF = "\" border=\"0\" alt=\"pause button disabled\" />"; @@ -11612,12 +11615,10 @@ function ManualDialCheckChanneL(taskCheckOR) { var MDlookResponse = null; // alert(xmlhttp.responseText); - var debug_response = xmlhttp.responseText; var REGcommentsDBNL = new RegExp("\n","g"); debug_response = debug_response.replace(REGcommentsDBNL, "
"); // document.getElementById("debugbottomspan").innerHTML = "
|" + manDiaLlook_query + "|
\n" + debug_response; - MDlookResponse = xmlhttp.responseText; var MDlookResponse_array=MDlookResponse.split("\n"); var MDlookCID = MDlookResponse_array[0]; @@ -11758,6 +11759,7 @@ function ManualDialCheckChanneL(taskCheckOR) document.vicidial_form.uniqueid.value = MDlookResponse_array[0]; document.getElementById("callchannel").innerHTML = MDlookResponse_array[1]; var stereo_info = MDlookResponse_array[2]; + var talk_sec_url_info = MDlookResponse_array[3]; lastcustchannel = MDlookResponse_array[1]; if( document.images ) { document.images['livecall'].src = image_livecall_ON.src;} document.vicidial_form.SecondS.value = 0; @@ -11781,6 +11783,7 @@ function ManualDialCheckChanneL(taskCheckOR) var regSRC = new RegExp("^SAC|^SPAC","ig"); var regSRD = new RegExp("^SOD","ig"); var regSRAF = new RegExp("ALLFORCE","ig"); + var regTSU = new RegExp("TALKURLS","ig"); if (stereo_info.match(regSRC)) { // stereo recording was started @@ -11802,7 +11805,11 @@ function ManualDialCheckChanneL(taskCheckOR) var conf_rec_start_html = "\" border=\"0\" alt=\"Start Stereo Recording\" />"; document.getElementById("StRecorDControl").innerHTML = conf_rec_start_html; } - + if (talk_sec_url_info.match(regTSU)) + { + talk_sec_url_secs = talk_sec_url_info.replace(regTSU, ''); + // alert('talk_sec_url_secs: |' + talk_sec_url_secs + '|'); + } document.getElementById("ParkControl").innerHTML ="\" border=\"0\" alt=\"Park Call\" />"; if ( (ivr_park_call=='ENABLED') || (ivr_park_call=='ENABLED_PARK_ONLY') ) @@ -13439,6 +13446,7 @@ function ManualDialSkip(MDSclick) manual_entry_dial=0; SCRIPTweb_form_vars=''; SCRIPT2web_form_vars=''; + talk_url_vars=''; MDcheck_for_answer=0; leave_3way_start_recording_trigger=0; leave_3way_start_recording_triggerCALL=0; @@ -14298,7 +14306,8 @@ function check_for_auto_incoming() } VDICstereo_recording = VDIC_data_VDIG[42]; VDICstereo_recording_agent = VDIC_data_VDIG[43]; - + talk_sec_url_secs = VDIC_data_VDIG[44]; + // alert("talk_sec_url_secs: |" + talk_sec_url_secs + "|"); var VDIC_data_VDFR=check_VDIC_array[3].split("|"); if ( (VDIC_data_VDFR[1].length > 1) && (VDCL_fronter_display == 'Y') ) {VDIC_fronter = " " + VDIC_data_VDFR[0] + " - " + VDIC_data_VDFR[1];} @@ -15190,6 +15199,7 @@ function check_for_incoming_other(manual_chat_override) {CalL_ScripT_id_two = VDIC_data_VDIG[36];} if (VDIC_data_VDIG[37].length > 0) {CalL_ScripT_color_two = VDIC_data_VDIG[37];} + talk_sec_url_secs = VDIC_data_VDIG[38]; var VDIC_data_VDFR=check_VDIC_array[3].split("|"); if ( (VDIC_data_VDFR[1].length > 1) && (VDCL_fronter_display == 'Y') ) @@ -17890,6 +17900,7 @@ function DispoSelect_submit(temp_use_pause_code,temp_dispo_pause_code,DSPclick) leave_3way_start_recording_filename=''; three_way_call_cid = orig_three_way_call_cid; APIskip=0; + talk_sec_url_secs=''; document.getElementById("BannerPanel").style.background = panel_bgcolor; document.getElementById("BannerPanel").innerHTML = ''; if (manual_auto_next > 0) @@ -18123,6 +18134,52 @@ function dead_trigger_url_send() } +// ################################################################################ +// Send AJAX request to trigger the Talk Seconds URLs Trigger + function talk_sec_url_send(temp_talk_url_type,temp_call_seconds,temp_inOUT,temp_talk_url_vars) + { + var xmlhttp=false; + /*@cc_on @*/ + /*@if (@_jscript_version >= 5) + // JScript gives us Conditional compilation, we can cope with old IE versions. + // and security blocked creation of the objects. + try { + xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); + } catch (e) { + try { + xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + } catch (E) { + xmlhttp = false; + } + } + @end @*/ + if (!xmlhttp && typeof XMLHttpRequest!='undefined') + { + xmlhttp = new XMLHttpRequest(); + } + if (xmlhttp) + { + TSUupdate_query = "server_ip=" + server_ip + "&session_name=" + session_name + "&ACTION=TALKsecURL&format=text&user=" + user + "&pass=" + pass + "&orig_pass=" + orig_pass + "&lead_id=" + document.vicidial_form.lead_id.value + "&campaign=" + campaign + "&auto_dial_level=" + auto_dial_level + "&agent_log_id=" + agent_log_id + "&list_id=" + document.vicidial_form.list_id.value + "&MDnextCID=" + LasTCID + "&stage=" + group + "&phone_number=" + document.vicidial_form.phone_number.value + "&phone_code=" + document.vicidial_form.phone_code.value + "&dial_method=" + dial_method + "&uniqueid=" + document.vicidial_form.uniqueid.value + "&agent_email=" + LOGemail + "&conf_exten=" + session_id + "&customer_server_ip=" + lastcustserverip + "&exten=" + extension + "&inOUT=" + inOUT + "&customer_sec=" + temp_call_seconds + "&group=" + group + "&original_phone_login=" + original_phone_login + "&phone_pass=" + phone_pass + ""; + xmlhttp.open('POST', 'vdc_db_query.php'); + xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8'); + xmlhttp.send(TSUupdate_query); + xmlhttp.onreadystatechange = function() + { + // document.getElementById("debugbottomspan").innerHTML = TSUupdate_query + "\n" + xmlhttp.responseText; + if (xmlhttp.readyState == 4 && xmlhttp.status == 200) + { + // alert(xmlhttp.responseText); + var check_talk_sec_url_received = null; + check_talk_sec_url_received = xmlhttp.responseText; + var check_DT_array=check_talk_sec_url_received.split("\n"); + agent_events('talk_sec_url_send received', LasTCID, aec); aec++; + } + } + delete xmlhttp; + } + } + + // ################################################################################ // Submit the URLs function SendURLs(newurlids,newurltype) @@ -19836,6 +19893,8 @@ function URLDecode(encodedvar,scriptformat,urlschema,webformnumber) {web_form_vars_two = web_form_varsX;} if (webformnumber == '3') {web_form_vars_three = web_form_varsX;} + if (webformnumber == '9') + {talk_url_vars = web_form_varsX;} var SCvendor_lead_code = encodeURIComponent(document.vicidial_form.vendor_lead_code.value); var SCsource_id = source_id; @@ -22434,6 +22493,20 @@ function start_all_refresh() } } } + // Check for Talk URLs trigger seconds talk_sec_url_secs + if ( (talk_sec_url_secs.length > 0) && (CheckDEADcallON < 1) ) + { + var temp_tsc = '-' + VD_live_call_secondS + '-'; + var regTSC = new RegExp(temp_tsc,"g"); + if (talk_sec_url_secs.match(regTSC)) + { + // alert('Talk Sec URL Trigger: |' + VD_live_call_secondS + '| |' + talk_sec_url_secs + '|'); + // Gather lead and call variables, save them to 'talk_url_vars' variable + // URLDecode('','NO','DEFAULT','9'); + // Send Talk Sec URL trigger for VD_live_call_secondS seconds + talk_sec_url_send('TALK_SEC_TRIGGER',VD_live_call_secondS,inOUT,talk_url_vars); + } + } } if (XD_live_customer_call==1) { diff --git a/www/vicidial/admin.php b/www/vicidial/admin.php index f4e92db32..8ee59f1a2 100644 --- a/www/vicidial/admin.php +++ b/www/vicidial/admin.php @@ -6285,12 +6285,13 @@ # 250806-0841 - Added manual_dial_lead_id user setting, and new 'ONLY' option for campaign setting # 250808-1120 - Added agent_man_dial_filter & agent_3way_dial_filter system settings # 250822-2056 - Added system/campaign/ingroup settings for stereo_recording -# +# 250922-0841 - Added Talk Seconds URL links to multi-url admin page in campaigns and in-groups +# # 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-943a'; -$build = '250822-2056'; +$admin_version = '2.14-944a'; +$build = '250922-0841'; $STARTtime = date("U"); $SQLdate = date("Y-m-d H:i:s"); @@ -29317,6 +29318,16 @@ function ajax_logout_now() echo "
\n"; } + $stmt="SELECT count(*) from vicidial_url_multi where campaign_id='$campaign_id' and entry_type='campaign' and url_type='talk';"; + $rslt=mysql_to_mysqli($stmt, $link); + $vum_to_print = mysqli_num_rows($rslt); + if ($vum_to_print > 0) + { + $rowx=mysqli_fetch_row($rslt); + $vum_count = $rowx[0]; + } + echo "\n"; + echo "\n"; echo "\n"; @@ -35284,6 +35295,28 @@ function ajax_logout_now() echo "\n"; } + # get count of talk seconds urls in this In-Group + $stmt="SELECT count(*) from vicidial_url_multi where campaign_id='$group_id' and entry_type='ingroup' and url_type='talk';"; + $rslt=mysql_to_mysqli($stmt, $link); + $vum_to_print = mysqli_num_rows($rslt); + if ($vum_to_print > 0) + { + $rowx=mysqli_fetch_row($rslt); + $vum_count = $rowx[0]; + } + # check if this In-Group has talk seconds url set to -FORCEDISABLE- + $force_disableHTML=''; + $stmt="SELECT count(*) from vicidial_url_multi where campaign_id='$group_id' and entry_type='ingroup' and url_type='talk' and active='N' and url_address LIKE \"%FORCEDISABLE%\";"; + $rslt=mysql_to_mysqli($stmt, $link); + $fdtsu_to_print = mysqli_num_rows($rslt); + if ($fdtsu_to_print > 0) + { + $rowx=mysqli_fetch_row($rslt); + if ($rowx[0] > 0) + {$force_disableHTML="FORCED DISABLE";} + } + echo "\n"; + echo "\n"; echo "\n"; @@ -36303,6 +36336,28 @@ function ajax_logout_now() echo "\n"; } + # get count of talk seconds urls in this In-Group + $stmt="SELECT count(*) from vicidial_url_multi where campaign_id='$group_id' and entry_type='ingroup' and url_type='talk';"; + $rslt=mysql_to_mysqli($stmt, $link); + $vum_to_print = mysqli_num_rows($rslt); + if ($vum_to_print > 0) + { + $rowx=mysqli_fetch_row($rslt); + $vum_count = $rowx[0]; + } + # check if this In-Group has talk seconds url set to -FORCEDISABLE- + $force_disableHTML=''; + $stmt="SELECT count(*) from vicidial_url_multi where campaign_id='$group_id' and entry_type='ingroup' and url_type='talk' and active='N' and url_address LIKE \"%FORCEDISABLE%\";"; + $rslt=mysql_to_mysqli($stmt, $link); + $fdtsu_to_print = mysqli_num_rows($rslt); + if ($fdtsu_to_print > 0) + { + $rowx=mysqli_fetch_row($rslt); + if ($rowx[0] > 0) + {$force_disableHTML="FORCED DISABLE";} + } + echo "\n"; + echo "\n"; echo "\n"; @@ -37181,6 +37236,29 @@ function ajax_logout_now() { echo "\n"; } + + # get count of talk seconds urls in this In-Group + $stmt="SELECT count(*) from vicidial_url_multi where campaign_id='$group_id' and entry_type='ingroup' and url_type='talk';"; + $rslt=mysql_to_mysqli($stmt, $link); + $vum_to_print = mysqli_num_rows($rslt); + if ($vum_to_print > 0) + { + $rowx=mysqli_fetch_row($rslt); + $vum_count = $rowx[0]; + } + # check if this In-Group has talk seconds url set to -FORCEDISABLE- + $force_disableHTML=''; + $stmt="SELECT count(*) from vicidial_url_multi where campaign_id='$group_id' and entry_type='ingroup' and url_type='talk' and active='N' and url_address LIKE \"%FORCEDISABLE%\";"; + $rslt=mysql_to_mysqli($stmt, $link); + $fdtsu_to_print = mysqli_num_rows($rslt); + if ($fdtsu_to_print > 0) + { + $rowx=mysqli_fetch_row($rslt); + if ($rowx[0] > 0) + {$force_disableHTML="FORCED DISABLE";} + } + echo "\n"; + /* echo "\n"; */ diff --git a/www/vicidial/admin_url_multi.php b/www/vicidial/admin_url_multi.php index 7e67bbba0..04e8036cb 100644 --- a/www/vicidial/admin_url_multi.php +++ b/www/vicidial/admin_url_multi.php @@ -1,7 +1,7 @@ LICENSE: AGPLv2 +# Copyright (C) 2025 Matt Florell LICENSE: AGPLv2 # # this screen will control the *url* settings needed when the Campaign or # In-Group or List URL setting is set to "ALT". This screen allows for multiple @@ -19,10 +19,11 @@ # 211117-2006 - Added minimum call length field # 220127-1900 - Added display of the URL ID # 220222-1959 - Added allow_web_debug system setting +# 250920-2202 - Added talk_sec_urls # -$admin_version = '2.14-9'; -$build = '220222-1959'; +$admin_version = '2.14-10'; +$build = '250920-2202'; require("dbconnect_mysqli.php"); require("functions.php"); @@ -235,6 +236,8 @@ {$stmt="SELECT count(*) from vicidial_campaigns where campaign_id='$campaign_id' and start_call_url='ALT';";} elseif ($url_type == 'noagent') {$stmt="SELECT count(*) from vicidial_campaigns where campaign_id='$campaign_id' and na_call_url='ALT';";} + elseif ($url_type == 'talk') + {$stmt="SELECT count(*) from vicidial_campaigns where campaign_id='$campaign_id';";} else { echo _QXZ("ERROR: no valid url type defined:") . $url_type; @@ -256,6 +259,8 @@ {$stmt="SELECT count(*) from vicidial_inbound_groups where group_id='$campaign_id' and na_call_url='ALT';";} elseif ($url_type == 'addlead') {$stmt="SELECT count(*) from vicidial_inbound_groups where group_id='$campaign_id' and add_lead_url='ALT';";} + elseif ($url_type == 'talk') + {$stmt="SELECT count(*) from vicidial_inbound_groups where group_id='$campaign_id';";} else { echo _QXZ("ERROR: no valid url type defined:") . $url_type; @@ -291,6 +296,8 @@ {$url_type_text='No Agent Call';} elseif ($url_type == 'addlead') {$url_type_text='Add Lead';} +elseif ($url_type == 'talk') + {$url_type_text='Talk Seconds';} else {$url_type_text='Error';} @@ -457,16 +464,25 @@ ##### BEGIN URL multi control form if ($action == "BLANK") { + $min_length_text = 'MIN LENGTH'; + $statuses_text = 'STATUSES'; + if ( ($url_type == 'start') or ($url_type == 'noagent') or ($url_type == 'addlead') ) + {$min_length_text = 'NOT USED';} + if ( ($url_type == 'start') or ($url_type == 'noagent') or ($url_type == 'addlead') or ($url_type == 'talk') ) + {$statuses_text = 'NOT USED';} $bgcolor='bgcolor="#'. $SSstd_row2_background .'"'; echo "
# "._QXZ("LEAD").""._QXZ("DATE/TIME")." "._QXZ("SECONDS")."   "._QXZ("RECID").""._QXZ("FILENAME").""._QXZ("LOCATION").""._QXZ("TSR")."
# "._QXZ("LEAD").""._QXZ("DATE/TIME")." "._QXZ("SECONDS")."   "._QXZ("RECID").""._QXZ("FILENAME").""._QXZ("LOCATION").""._QXZ("TSR")."
$mute_events   $mute_events   $stereo_flag  
"._QXZ("No Agent Call URL").": $NWB#campaigns-na_call_url$NWE
"._QXZ("Talk Seconds URLs").": $NWB#campaigns-talk_sec_url$NWE "._QXZ("Talk Seconds URLs Defined").": $vum_count
"._QXZ("Extension Append CID").": $NWB#campaigns-extension_appended_cidname$NWE
"._QXZ("Blind Monitor Warning").": $NWB#campaigns-blind_monitor_warning$NWE
"._QXZ("No Agent Call URL").": $NWB#inbound_groups-na_call_url$NWE
"._QXZ("Talk Seconds URLs").": $NWB#inbound_groups-talk_sec_url$NWE "._QXZ("Talk Seconds URLs Defined").": $vum_count   $force_disableHTML
"._QXZ("Waiting Call URL On").": $NWB#inbound_groups-waiting_call_url_on$NWE
"._QXZ("Waiting Call URL Off").": $NWB#inbound_groups-waiting_call_url_on$NWE
"._QXZ("Dispo Email URL").": $NWB#inbound_groups-dispo_email_url$NWE
"._QXZ("Talk Seconds URLs").": $NWB#inbound_groups-talk_sec_url$NWE "._QXZ("Talk Seconds URLs Defined").": $vum_count   $force_disableHTML
"._QXZ("Custom 1").": $NWB#inbound_groups-custom_fields$NWE
"._QXZ("Custom 2").": $NWB#inbound_groups-custom_fields$NWE
"._QXZ("No Agent Chat URL").": $NWB#inbound_groups-na_chat_url$NWE
"._QXZ("Talk Seconds URLs").": $NWB#inbound_groups-talk_sec_url$NWE "._QXZ("Talk Seconds URLs Defined").": $vum_count   $force_disableHTML
Extension Append CID: $NWB#inbound_groups-extension_appended_cidname$NWE
\n"; + echo "\n"; + if ($SSdaily_call_count_limit > 0) { echo "\n"; diff --git a/www/vicidial/help_documentation.txt b/www/vicidial/help_documentation.txt index 308f8ee33..254138447 100644 --- a/www/vicidial/help_documentation.txt +++ b/www/vicidial/help_documentation.txt @@ -1,4 +1,4 @@ -# version: 20250920221701 +# version: 20251002142401 users-user User ID 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-. users-pass Password This field is where you put the users password. Must be at least 2 characters in length, unless the User Password Minimum Length system setting is enabled, which will require a longer password. 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. users-force_change_password Force Change Password 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. @@ -157,6 +157,7 @@ campaigns-demographic_quotas_list_resets Demographic Quotas List Resets Thi campaigns-demographic_quotas_container Demographic Quotas Container This setting is where you select a DEMOGRAPHIC_QUOTAS container to be used for the Demographic Quota features to use for quota goals. For more information, read the DEMOGRAPHIC_QUOTAS.txt document. Default is DISABLED. campaigns-call_count_limit Call Count Limit This enforces a limit on the number of call attempts for the leads dialed in this campaign. A lead may go over this limit slightly if Lead Recycling or Auto-Alt-Dialing is enabled. Default is 0 for no limit. campaigns-call_count_target Call Count Target This option is only used for reporting purposes and has no effect on leads dialed. Default is 3. +campaigns-call_count_limit_restrict Call Count Limit Manual Restrict If the Call Count Limit setting is greater than 0 above, then this optional setting can further restrict manual dial lead calls placed from this campaign to not exceed the total lead called count. If RESTRICT_ALL is used, then no manual dial lead calls will be allowed past the call count limit. Even if this option is disabled, if the agent clicks the Dial Next Number button on the agent screen, no leads that have reached the campaign Call Count Limit will be dialed. This option was created to allow for restricting the other manual dialing methods such as callbacks, lead search, call log, etc... Default is DISABLED. campaigns-daily_call_count_limit Daily Call Count Limit This feature, if enabled, will limit the number of times a lead can be called in a single day. Once a lead has reached this set limit, if the lead is selected to be dialed again, the called-since-last-reset flag on the lead will be changed to -Y- and the call will not be dialed. If you want to raise this daily limit during the day, you might need to reset your lists to be able to dial the leads that hit the previous limit earlier in the day. This feature may conflict with Auto-Alt-Dial features if they are enabled on a campaign. Default is 0 for disabled. settings-daily_limit_manual Daily Call Limit Manual If the Daily Call Count Limit is enabled, this setting will determine if manual dial calls will be counted and or restricted in the daily call count limit. The DISABLED option will not count manual dial calls or restrict them as part of the daily call count limits, only auto-dial calls would be counted restricted. If one of the COUNT options is used, then manual dial calls would be included in the daily call counts. If one of the RESTRICT options is used, then manual dial calls would be restricted as part of the daily call count limit. Default is DISABLED. campaigns-daily_phone_number_call_limit Daily Phone Number Call Limit System-wide This feature, if enabled, will limit the number of times a specific phone number can be called in a single day through this campaign. Once a phone number has reached this set limit, if the lead is selected to be dialed again, the called-since-last-reset flag on the lead will be changed to -Y- and the call will not be dialed. If you want to raise this daily limit during the day, you might need to reset your lists to be able to dial the leads that hit the previous limit earlier in the day. This feature may conflict with Auto-Alt-Dial features if they are enabled on a campaign. Default is 0 for disabled. From 707784feed774a53a411e5ecfb8155b35d9ae56b Mon Sep 17 00:00:00 2001 From: Mattf Date: Tue, 21 Oct 2025 13:16:28 +0000 Subject: [PATCH 09/12] Added code for recording_dtmf_muting, fix for Stereo Call Recording on multi-server clusters git-svn-id: svn://svn.eflo.net/agc_2-X/trunk@3949 3d104415-ff17-0410-8863-d5cf3c621b8a --- UPGRADE | 4 + agi/VD_amd.agi | 50 +- agi/agi-DID_route.agi | 22 +- agi/agi-IVR_recording_verification.agi | 30 +- agi/agi-NVA_recording.agi | 69 +- agi/agi-VDAD_ALL_inbound.agi | 127 +- agi/agi-VDAD_ALL_outbound.agi | 244 ++-- agi/agi-VDAD_RINGALL.agi | 50 +- bin/ADMIN_archive_log_tables.pl | 50 + bin/ADMIN_central_lead_repository.pl | 1795 ++++++++++++++++++++++++ bin/ADMIN_keepalive_ALL.pl | 78 +- bin/AST_CRON_audio_1_move_mix.pl | 7 +- bin/AST_flush_DBqueue.pl | 50 +- bin/AST_manager_listen_AMI2.pl | 123 +- bin/AST_update_AMI2.pl | 126 +- docs/STEREO_CALL_RECORDINGS.txt | 61 +- extras/MySQL_AST_CREATE_tables.sql | 23 +- extras/upgrade_2.14.sql | 41 +- www/agc/manager_send.php | 90 +- www/agc/vdc_db_query.php | 96 +- www/agc/vicidial.php | 27 +- www/vicidial/admin.php | 70 +- www/vicidial/admin_modify_lead.php | 50 +- www/vicidial/help_documentation.txt | 10 +- 24 files changed, 3024 insertions(+), 269 deletions(-) create mode 100644 bin/ADMIN_central_lead_repository.pl diff --git a/UPGRADE b/UPGRADE index f8c259423..e3b256769 100644 --- a/UPGRADE +++ b/UPGRADE @@ -886,6 +886,10 @@ OTHER CHANGES: to be sent out from the Agent Screen while the agent is talking to the customer, based on the number of seconds they have been talking. +253. Added Recording DTMF Muting, allowing for the muting of call recordings + for X seconds if any DTMF signal is detected on the call. Configurable + in Campaigns, In-Groups and system-wide. + diff --git a/agi/VD_amd.agi b/agi/VD_amd.agi index 175ba8d0e..abf2c6f50 100644 --- a/agi/VD_amd.agi +++ b/agi/VD_amd.agi @@ -71,15 +71,17 @@ # 230726-0932 - Added manual_vm_status_updates campaign option # 240906-2228 - Added AMD minimum length handling to increase short call durations # 250924-2152 - Added code for deprecation of "Monitor" application after Asterisk 20 +# 251006-0903 - If recording_dtmf_muting enabled, force use of MixMonitor for recording # $script = 'VD_amd.agi'; -$build = '250924-2152'; +$build = '251006-0903'; $A = 1; # set to 1 for AMD output messages mode $AMD_LOG = 3; # set to 1 for logfile and 2 forDB log, 3 for both $wav='.wav'; $US='_'; +$recording_dtmf_muting=0; ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); $year = ($year + 1900); @@ -148,7 +150,7 @@ $dbhA = DBI->connect("DBI:mysql:$VARDB_database:$VARDB_server:$VARDB_port", "$VA ############################################# ##### Gather system_settings ##### -$stmtA = "SELECT sip_event_logging,call_quota_lead_ranking FROM system_settings;"; +$stmtA = "SELECT sip_event_logging,call_quota_lead_ranking,recording_dtmf_muting,recording_dtmf_detection FROM system_settings;"; $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; $sthArows=$sthA->rows; @@ -157,6 +159,8 @@ if ($sthArows > 0) @aryA = $sthA->fetchrow_array; $SSsip_event_logging = $aryA[0]; $SScall_quota_lead_ranking = $aryA[1]; + $SSrecording_dtmf_muting = $aryA[2]; + $SSrecording_dtmf_detection = $aryA[3]; } $sthA->finish(); ########################################### @@ -534,7 +538,7 @@ else $selected_campaign=''; ### Grab vmail forward message values from the database - $stmtA = "SELECT am_message_exten,amd_send_to_vmx,waitforsilence_options,survey_recording,campaign_rec_filename,cpd_amd_action,amd_inbound_group,amd_callmenu,cpd_unknown_action,campaign_id,am_message_wildcards,call_quota_lead_ranking,vmm_daily_limit,manual_vm_status_updates FROM vicidial_campaigns where campaign_id = '$VD_campaign_id' limit 1;"; + $stmtA = "SELECT am_message_exten,amd_send_to_vmx,waitforsilence_options,survey_recording,campaign_rec_filename,cpd_amd_action,amd_inbound_group,amd_callmenu,cpd_unknown_action,campaign_id,am_message_wildcards,call_quota_lead_ranking,vmm_daily_limit,manual_vm_status_updates,recording_dtmf_muting FROM vicidial_campaigns where campaign_id = '$VD_campaign_id' limit 1;"; if ($AGILOG) {$agi_string = "|$stmtA|"; &agi_output;} $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; @@ -556,6 +560,7 @@ else $VD_call_quota_lead_ranking = $aryA[11]; $vmm_daily_limit = $aryA[12]; $manual_vm_status_updates = $aryA[13]; + $recording_dtmf_muting = $aryA[14]; $sthA->finish(); } else @@ -563,7 +568,7 @@ else $sthA->finish(); ### Grab vmail forward message values from the database $SQL_group_id=$VD_campaign_id; $SQL_group_id =~ s/_/\\_/gi; - $stmtA = "SELECT am_message_exten,amd_send_to_vmx,waitforsilence_options,survey_recording,campaign_rec_filename,cpd_amd_action,amd_inbound_group,amd_callmenu,cpd_unknown_action,campaign_id,am_message_wildcards,vmm_daily_limit,manual_vm_status_updates FROM vicidial_campaigns where closer_campaigns LIKE \"% $SQL_group_id %\" order by active,campaign_id limit 1;"; + $stmtA = "SELECT am_message_exten,amd_send_to_vmx,waitforsilence_options,survey_recording,campaign_rec_filename,cpd_amd_action,amd_inbound_group,amd_callmenu,cpd_unknown_action,campaign_id,am_message_wildcards,vmm_daily_limit,manual_vm_status_updates,recording_dtmf_muting FROM vicidial_campaigns where closer_campaigns LIKE \"% $SQL_group_id %\" order by active,campaign_id limit 1;"; if ($AGILOG) {$agi_string = "|$stmtA|"; &agi_output;} $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; @@ -585,6 +590,7 @@ else $VD_call_quota_lead_ranking = 'DISABLED'; $vmm_daily_limit = $aryA[12]; $manual_vm_status_updates = $aryA[13]; + $recording_dtmf_muting = $aryA[14]; $sthA->finish(); if ($AGILOG) {$agi_string = "-- Inbound call, settings gathered from: |$selected_campaign|$DB_am_message_exten|$DB_amd_send_to_vmx|$waitforsilence_options"; &agi_output;} } @@ -710,25 +716,49 @@ else %ast_ver_str = parse_asterisk_version($asterisk_version); if (( $ast_ver_str{major} = 1 ) && ($ast_ver_str{minor} < 6)) { - $AGI->exec("Monitor wav|/var/spool/asterisk/monitor/MIX/$campaign_rec_filename"); + $AGI->exec("Monitor wav|/var/spool/asterisk/monitor/MIX/AMD$campaign_rec_filename"); } else { - if ($ast_ver_str{major} > 20) + if ( ($ast_ver_str{major} > 20) || ($SSrecording_dtmf_muting > 0) ) { # Deprecation of "Monitor" application after Asterisk 20 - $AGI->exec("MixMonitor",",r($PATHmonitor/MIX/$campaign_rec_filename-in.wav)t($PATHmonitor/MIX/$campaign_rec_filename-out.wav)"); + $AGI->exec("MixMonitor",",r($PATHmonitor/MIX/AMD$campaign_rec_filename-in.wav)t($PATHmonitor/MIX/AMD$campaign_rec_filename-out.wav)"); } else { - $AGI->exec("Monitor","wav,/var/spool/asterisk/monitor/MIX/$campaign_rec_filename"); + $AGI->exec("Monitor","wav,/var/spool/asterisk/monitor/MIX/AMD$campaign_rec_filename"); } } ### insert record into recording_log table ### - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,length_in_sec,filename,lead_id,user,location,vicidial_id) values('$channel','$VARserver_ip','$VD_phone_number','$now_date','$now_date_epoch','0','$campaign_rec_filename','$VD_lead_id','VDAD','$campaign_rec_filename','$uniqueid');"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,length_in_sec,filename,lead_id,user,location,vicidial_id) values('$channel','$VARserver_ip','$VD_phone_number','$now_date','$now_date_epoch','0','AMD$campaign_rec_filename','$VD_lead_id','VDAD','AMD$campaign_rec_filename','$uniqueid');"; $SRaffected_rows = $dbhA->do($stmtA); - if ($AGILOG) {$agi_string = "-- AMD RECORDING STARTED : |$SRaffected_rows|$campaign_rec_filename|$stmtA|"; &agi_output;} + + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + { + if ($SSrecording_dtmf_muting > 1) + { + $recording_dtmf_muting = $SSrecording_dtmf_muting; + } + } + + ### insert record into recording_live table ### + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','MONO_LEGACY_AMD','$VARserver_ip','$now_date','$channel','AMD$campaign_rec_filename','$VD_lead_id','VDAD','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + + if ($AGILOG) {$agi_string = "-- AMD RECORDING STARTED : |$SRaffected_rows|$rLIVEaffected_rows|$recording_id|AMD$campaign_rec_filename|$stmtA|"; &agi_output;} } } diff --git a/agi/agi-DID_route.agi b/agi/agi-DID_route.agi index fbfa72b7e..ab2a1f6c0 100644 --- a/agi/agi-DID_route.agi +++ b/agi/agi-DID_route.agi @@ -52,6 +52,7 @@ # 230124-1228 - Added logging of VICIrecGatewayID channel variable, and vicidial_did_gateway_log table # 241208-1748 - Changed DID filter_phone_group_id & pre_filter_phone_group_id to multi-selects # 250924-2156 - Added code for deprecation of "Monitor" application after Asterisk 20 +# 251006-0905 - If recording_dtmf_muting enabled, force use of MixMonitor for recording # @@ -154,7 +155,7 @@ $sthA->finish(); ############################################# ##### START SYSTEM SETTINGS LOOKUP ##### -$stmtA = "SELECT enable_queuemetrics_logging,queuemetrics_server_ip,queuemetrics_dbname,queuemetrics_login,queuemetrics_pass,queuemetrics_log_id,queuemetrics_eq_prepend,did_agent_log,alt_log_server_ip,alt_log_dbname,alt_log_login,alt_log_pass,tables_use_alt_log_db,did_system_filter,inbound_answer_config FROM system_settings;"; +$stmtA = "SELECT enable_queuemetrics_logging,queuemetrics_server_ip,queuemetrics_dbname,queuemetrics_login,queuemetrics_pass,queuemetrics_log_id,queuemetrics_eq_prepend,did_agent_log,alt_log_server_ip,alt_log_dbname,alt_log_login,alt_log_pass,tables_use_alt_log_db,did_system_filter,inbound_answer_config,recording_dtmf_muting,recording_dtmf_detection FROM system_settings;"; $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; $sthArows=$sthA->rows; @@ -176,6 +177,8 @@ if ($sthArows > 0) $tables_use_alt_log_db = $aryA[12]; $SSdid_system_filter = $aryA[13]; $SSinbound_answer_config = $aryA[14]; + $SSrecording_dtmf_muting = $aryA[15]; + $SSrecording_dtmf_detection = $aryA[16]; } $sthA->finish(); ##### END SYSTEM SETTINGS LOOKUP ##### @@ -880,7 +883,7 @@ if ($record_call =~ /Y/) } else { - if ($ast_ver_str{major} > 20) + if ( ($ast_ver_str{major} > 20) || ($SSrecording_dtmf_muting > 0) ) { # Deprecation of "Monitor" application after Asterisk 20 $AGI->exec("MixMonitor",",r($PATHmonitor/MIX/$filename-in.wav)t($PATHmonitor/MIX/$filename-out.wav)"); @@ -908,7 +911,20 @@ if ($record_call =~ /Y/) $sthA->finish(); } - if ($AGILOG) {$did_string = "-- RECORDING LOG : |$affected_rowsR|$insert_recording_id|$stmtA|"; &did_output;} + $recording_dtmf_muting=0; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + { + if ($SSrecording_dtmf_muting > 1) + { + $recording_dtmf_muting = $SSrecording_dtmf_muting; + } + } + + ### insert record into recording_live table ### + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$insert_recording_id','MONO_LEGACY_DID','$VARserver_ip','$now_date','$channel','$filename','$lead_id','$user','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + + if ($AGILOG) {$did_string = "-- RECORDING LOG : |$affected_rowsR|$rLIVEaffected_rows|$insert_recording_id|$stmtA|"; &did_output;} } ### Grab Server values from the database diff --git a/agi/agi-IVR_recording_verification.agi b/agi/agi-IVR_recording_verification.agi index eff0c54c1..e7a2def44 100644 --- a/agi/agi-IVR_recording_verification.agi +++ b/agi/agi-IVR_recording_verification.agi @@ -54,6 +54,7 @@ # 120430-2214 - Converted call to Monitor app to be asterisk 1.8 compatible # 130108-1816 - Changes for Asterisk 1.8 compatibility # 250924-2158 - Added code for deprecation of "Monitor" application after Asterisk 20 +# 251006-0901 - If recording_dtmf_muting enabled, force use of MixMonitor for recording # &get_time_now; @@ -119,6 +120,21 @@ $dbhA = DBI->connect("DBI:mysql:$VARDB_database:$VARDB_server:$VARDB_port", "$VA or die "Couldn't connect to database: " . DBI->errstr; +############################################# +##### Gather system_settings ##### +$stmtA = "SELECT recording_dtmf_muting,recording_dtmf_detection FROM system_settings;"; +$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; +$sthA->execute or die "executing: $stmtA ", $dbhA->errstr; +$sthArows=$sthA->rows; +if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $SSrecording_dtmf_muting = $aryA[0]; + $SSrecording_dtmf_detection = $aryA[1]; + } +$sthA->finish(); +########################################### + ### Grab Server values from the database $stmtA = "SELECT agi_output,ext_context,asterisk_version FROM servers where server_ip = '$VARserver_ip';"; $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; @@ -387,7 +403,7 @@ if ($record_call =~ /Y/) } else { - if ($ast_ver_str{major} > 20) + if ( ($ast_ver_str{major} > 20) || ($SSrecording_dtmf_muting > 0) ) { # Deprecation of "Monitor" application after Asterisk 20 $AGI->exec("MixMonitor",",r($PATHmonitor/MIX/$filename-in.wav)t($PATHmonitor/MIX/$filename-out.wav)"); @@ -418,6 +434,18 @@ if ($record_call =~ /Y/) if ($AGILOG) {$agi_string = "RECORDING- $recording_id $ivr_id START filename: $filename"; &agi_output;} $affected_rows = $dbhA->do($stmtA); + $recording_dtmf_muting=0; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + { + if ($SSrecording_dtmf_muting > 1) + { + $recording_dtmf_muting = $SSrecording_dtmf_muting; + } + } + + ### insert record into recording_live table ### + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','MONO_LEGACY_VERIF','$server_ip','$now_date','$channel','$filename','$lead_id','$user','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); } diff --git a/agi/agi-NVA_recording.agi b/agi/agi-NVA_recording.agi index 49bc1a479..6765a42ca 100644 --- a/agi/agi-NVA_recording.agi +++ b/agi/agi-NVA_recording.agi @@ -61,6 +61,7 @@ # 151214-2148 - Added more variables to be used by nva url feature # 151220-1521 - Added phone NVA List ID option for not found phone numbers # 250924-2137 - Added code for deprecation of "Monitor" application after Asterisk 20 +# 251006-0904 - If recording_dtmf_muting enabled, force use of MixMonitor for recording # &get_time_now; @@ -82,6 +83,7 @@ $now_date = "$year-$mon-$mday $hour:$min:$sec"; $filedate = "$year$mon$mday$hour$min$sec"; $US='_'; +$VLAcampaign=''; # default path to astguiclient configuration file: @@ -126,6 +128,21 @@ $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; +############################################# +##### Gather system_settings ##### +$stmtA = "SELECT recording_dtmf_muting,recording_dtmf_detection FROM system_settings;"; +$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; +$sthA->execute or die "executing: $stmtA ", $dbhA->errstr; +$sthArows=$sthA->rows; +if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $SSrecording_dtmf_muting = $aryA[0]; + $SSrecording_dtmf_detection = $aryA[1]; + } +$sthA->finish(); +########################################### + ### Grab Server values from the database $stmtA = "SELECT agi_output,ext_context,asterisk_version FROM servers where server_ip = '$VARserver_ip';"; $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; @@ -405,7 +422,7 @@ if ($record_call =~ /Y/) } else { - if ($ast_ver_str{major} > 20) + if ( ($ast_ver_str{major} > 20) || ($SSrecording_dtmf_muting > 0) ) { # Deprecation of "Monitor" application after Asterisk 20 $AGI->exec("MixMonitor",",r(/var/spool/asterisk/monitor/MIX/$filename-in.wav)t(/var/spool/asterisk/monitor/MIX/$filename-out.wav)"); @@ -415,6 +432,56 @@ if ($record_call =~ /Y/) $AGI->exec("Monitor","wav,/var/spool/asterisk/monitor/MIX/$filename"); } } + + ### get campaign settings for DTMF muting, if enabled on this system + $recording_dtmf_muting=0; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + { + if ($SSrecording_dtmf_muting > 1) + { + $recording_dtmf_muting = $SSrecording_dtmf_muting; + } + else + { + if (length($VLAcampaign) < 1) + { + $stmtA = "SELECT list_id FROM vicidial_list where lead_id='$lead_id' limit 1;"; + $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; + $VLAlist_id = $aryA[0]; + + $stmtA = "SELECT campaign_id FROM vicidial_lists where list_id='$VLAlist_id' limit 1;"; + $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; + $VLAcampaign = $aryA[0]; + } + } + } + + $stmtA = "SELECT recording_dtmf_muting FROM vicidial_campaigns where campaign_id='$VLAcampaign' limit 1;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_dtmf_muting = $aryA[0]; + } + } + if ($AGILOG) {$agi_string = "DTMF Muting check: $recording_dtmf_muting|$SSrecording_dtmf_muting|$VLAcampaign($lead_id)"; &agi_output;} + } + + ### insert record into recording_live table ### + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','MONO_LEGACY_NVA','$VARserver_ip','$now_date','$channel','$filename','$lead_id','$accountcode','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); } if ( ($phone_url =~ /Y/) && (length($nva_call_url) > 8) ) diff --git a/agi/agi-VDAD_ALL_inbound.agi b/agi/agi-VDAD_ALL_inbound.agi index 8baef744d..8d7cbc82a 100644 --- a/agi/agi-VDAD_ALL_inbound.agi +++ b/agi/agi-VDAD_ALL_inbound.agi @@ -268,6 +268,7 @@ # 250825-1824 - Added stereo_recording code # 250924-2147 - Added code for deprecation of "Monitor" application after Asterisk 20 # 251001-1836 - Fix for rare Stereo recording filename issue +# 251020-0836 - Added code for recording_dtmf_muting, fix for stereo call recording # $script = 'agi-VDAD_ALL_inbound.agi'; @@ -436,7 +437,7 @@ $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,stereo_recording,stereo_parallel_recording FROM system_settings;"; +$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,stereo_recording,stereo_parallel_recording,recording_dtmf_detection,recording_dtmf_muting FROM system_settings;"; $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; $sthArows=$sthA->rows; @@ -469,6 +470,8 @@ if ($sthArows > 0) $SSinbound_credits = $aryA[22]; $SSstereo_recording = $aryA[23]; $SSstereo_parallel_recording = $aryA[24]; + $SSrecording_dtmf_detection = $aryA[25]; + $SSrecording_dtmf_muting = $aryA[26]; } $sthA->finish(); ##### END SYSTEM SETTINGS LOOKUP ##### @@ -907,7 +910,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,second_alert_container,second_alert_only,third_alert_trigger,third_alert_trigger_seconds,third_alert_filename,third_alert_delay,third_alert_container,third_alert_only,stereo_recording,stereo_recording_agent,stereo_rec_filename,stereo_parallel_recording,parallel_rec_co_filename,parallel_rec_cm_filename,parallel_rec_fr_filename 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,third_alert_trigger,third_alert_trigger_seconds,third_alert_filename,third_alert_delay,third_alert_container,third_alert_only,stereo_recording,stereo_recording_agent,stereo_rec_filename,stereo_parallel_recording,parallel_rec_co_filename,parallel_rec_cm_filename,parallel_rec_fr_filename,recording_dtmf_muting 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; @@ -1070,6 +1073,9 @@ if ($sthArows > 0) $parallel_rec_co_filename = $aryA[145]; $parallel_rec_cm_filename = $aryA[146]; $parallel_rec_fr_filename = $aryA[147]; + $recording_dtmf_muting = $aryA[148]; + if ( ($SSrecording_dtmf_detection < 1) || ($SSrecording_dtmf_muting < 1) ) + {$recording_dtmf_muting=0;} 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';} @@ -2693,7 +2699,7 @@ if ( ($CLchannel_group =~ /DID_INBOUND/) && (length($CLend_epoch) < 5) ) } else { - if ($ast_ver_str{major} > 20) + if ( ($ast_ver_str{major} > 20) || ($SSrecording_dtmf_muting > 0) ) { # Deprecation of "Monitor" application after Asterisk 20 $AGI->exec("StopMixMonitor",""); @@ -2704,7 +2710,6 @@ if ( ($CLchannel_group =~ /DID_INBOUND/) && (length($CLend_epoch) < 5) ) } } - $stmtA = "UPDATE recording_log set end_time='$now_date',end_epoch='$now_date_epoch',length_in_sec=$CLlength_in_sec,length_in_min='$CLlength_in_min' where recording_id='$CLrecording_id'"; $affected_rowsRL = $dbhA->do($stmtA); if ($AGILOG) {$agi_string = "Recording stopped: $CLstart_epoch|$now_date_epoch|$affected_rowsRL|$stmtA|"; &agi_output;} @@ -3459,7 +3464,9 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override $affected_rowsC = $dbhA->do($stmtC); $dbhP=$dbhA; $mysql_count='02217'; $MEL_aff_rows=$affected_rowsC; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','MONO_LEGACY_RIR','$VARserver_ip','$now_date','$channel','$campaign_rec_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','MONO_LEGACY_RIR','$VDADserver_ip','$now_date','$channelrec','$campaign_rec_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -3489,7 +3496,7 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override $PATHmonitorT = $PATHmonitorP; ### insert record into recording_log_parallel table ### - $stmtA = "INSERT INTO recording_log_parallel (channel,server_ip,extension,start_time,length_in_sec,filename,lead_id,user,vicidial_id,recording_status) values('$channel','$VDADserver_ip','','$now_date','0','PL$stereo_rec_filename','$insert_lead_id','$VDADuser','$insert_close_id','START');"; + $stmtA = "INSERT INTO recording_log_parallel (channel,server_ip,extension,start_time,length_in_sec,filename,lead_id,user,vicidial_id,recording_status) values('$channel','$VARserver_ip','','$now_date','0','PL$stereo_rec_filename','$insert_lead_id','$VDADuser','$insert_close_id','START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -3529,7 +3536,7 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override $temp_parallel_rec_co_filename =~ s/\"|\'//gi; } ### insert a record into the recording_log table - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPCO','$now_date','$now_date_epoch','$temp_parallel_rec_co_filename','$insert_lead_id','$VDADuser','$insert_close_id')"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VARserver_ip','SPCO','$now_date','$now_date_epoch','$temp_parallel_rec_co_filename','$insert_lead_id','$VDADuser','$insert_close_id')"; $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -3554,11 +3561,13 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override } ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_co_filename','$insert_lead_id','$channel_group STEREO_PARALLEL CUSTOMER-ONLY $stereo_recording','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VARserver_ip','$now_date','0','$temp_parallel_rec_co_filename','$insert_lead_id','$channel_group STEREO_PARALLEL CUSTOMER-ONLY $stereo_recording','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL CUSTOMER-ONLY','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_co_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO_PARALLEL CUSTOMER-ONLY','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_co_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -3584,7 +3593,7 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override $temp_parallel_rec_cm_filename =~ s/\"|\'//gi; } ### insert a record into the recording_log table - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPCM','$now_date','$now_date_epoch','$temp_parallel_rec_cm_filename','$insert_lead_id','$VDADuser','$insert_close_id')"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VARserver_ip','SPCM','$now_date','$now_date_epoch','$temp_parallel_rec_cm_filename','$insert_lead_id','$VDADuser','$insert_close_id')"; $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -3609,11 +3618,13 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override } ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_cm_filename','$insert_lead_id','$channel_group STEREO_PARALLEL CUSTOMER-MUTED $stereo_recording','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VARserver_ip','$now_date','0','$temp_parallel_rec_cm_filename','$insert_lead_id','$channel_group STEREO_PARALLEL CUSTOMER-MUTED $stereo_recording','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL CUSTOMER-MUTED','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_cm_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO_PARALLEL CUSTOMER-MUTED','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_cm_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -3639,7 +3650,7 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override $temp_parallel_rec_fr_filename =~ s/\"|\'//gi; } ### insert a record into the recording_log table - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPFR','$now_date','$now_date_epoch','$temp_parallel_rec_fr_filename','$insert_lead_id','$VDADuser','$insert_close_id')"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VARserver_ip','SPFR','$now_date','$now_date_epoch','$temp_parallel_rec_fr_filename','$insert_lead_id','$VDADuser','$insert_close_id')"; $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -3664,11 +3675,13 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override } ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_fr_filename','$insert_lead_id','$channel_group STEREO_PARALLEL FULL-RECORDING $stereo_recording','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VARserver_ip','$now_date','0','$temp_parallel_rec_fr_filename','$insert_lead_id','$channel_group STEREO_PARALLEL FULL-RECORDING $stereo_recording','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL FULL-RECORDING','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_fr_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO_PARALLEL FULL-RECORDING','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_fr_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -3680,7 +3693,7 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override { $temp_parallel_rec_ag_filename = $stereo_rec_filename; ### insert a record into the recording_log table - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPACI','$now_date','$now_date_epoch','$temp_parallel_rec_ag_filename','$insert_lead_id','$VDADuser','$insert_close_id')"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VARserver_ip','SPACI','$now_date','$now_date_epoch','$temp_parallel_rec_ag_filename','$insert_lead_id','$VDADuser','$insert_close_id')"; $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -3705,7 +3718,7 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override } ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_ag_filename','$insert_lead_id','$channel_group STEREO_PARALLEL AGENT-CONTROLLED RIR $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VARserver_ip','$now_date','0','$temp_parallel_rec_ag_filename','$insert_lead_id','$channel_group STEREO_PARALLEL AGENT-CONTROLLED RIR $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; @@ -3713,7 +3726,9 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override $affected_rowsB = $dbhA->do($stmtB); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rowsB; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL AGENT-CONTROLLED RIR','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_ag_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO_PARALLEL AGENT-CONTROLLED RIR','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_ag_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -3725,8 +3740,14 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override ## Start NON-parallel stereo call recording ## if ($stereo_recording_agent =~ /ALLCALLS|ALLFORCE/) { + $rl_exten='SACIBC'; + if ($stereo_recording =~ /CUSTOMER_ONLY/i) + {$rl_exten='SACICO';} + if ($stereo_recording =~ /CUSTOMER_MUTE/i) + {$rl_exten='SACICM';} + # insert a record into the recording_log table - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SACI','$now_date','$now_date_epoch','$stereo_rec_filename','$insert_lead_id','$VDADuser','$insert_close_id')"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VARserver_ip','$rl_exten','$now_date','$now_date_epoch','$stereo_rec_filename','$insert_lead_id','$VDADuser','$insert_close_id')"; $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -3754,7 +3775,7 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override $retval = $AGI->exec("MixMonitor",",r($PATHmonitorT/$stereo_rec_filename-out.wav)t($PATHmonitorT/$stereo_rec_filename-in.wav)"); ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$stereo_rec_filename','$insert_lead_id','$channel_group STEREO AGENT-CONTROLLED $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|','STEREO START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,recording_status) values('$recording_id','$VARserver_ip','$now_date','0','$stereo_rec_filename','$insert_lead_id','$channel_group STEREO AGENT-CONTROLLED $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|','STEREO START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; @@ -3762,7 +3783,9 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override $affected_rowsB = $dbhA->do($stmtB); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rowsB; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO AGENT-CONTROLLED RIR','$VARserver_ip','$now_date','$channel','$stereo_rec_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO AGENT-CONTROLLED RIR $rl_exten','$VARserver_ip','$now_date','$channel','$stereo_rec_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -3770,14 +3793,14 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override if ($stereo_recording =~ /CUSTOMER_ONLY/i) { $vmgr_callerid = substr($stereo_rec_filename, 0, 16) . 'M...'; - $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VDADserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: write','State: 1','','','','','','');"; + $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VARserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: write','State: 1','','','','','','');"; $mLIVEaffected_rows = $dbhA->do($stmtE); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$mLIVEaffected_rows; &mysql_error_logging; } if ($stereo_recording =~ /CUSTOMER_MUTE/i) { $vmgr_callerid = substr($stereo_rec_filename, 0, 16) . 'M...'; - $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VDADserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: read','State: 1','','','','','','');"; + $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VARserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: read','State: 1','','','','','','');"; $mLIVEaffected_rows = $dbhA->do($stmtE); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$mLIVEaffected_rows; &mysql_error_logging; } @@ -5017,7 +5040,7 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override } else { - if ($ast_ver_str{major} > 20) + if ( ($ast_ver_str{major} > 20) || ($SSrecording_dtmf_muting > 0) ) { # Deprecation of "Monitor" application after Asterisk 20 $retval = $AGI->exec("MixMonitor",",r($PATHmonitor/MIX/$campaign_rec_filename-in.wav)t($PATHmonitor/MIX/$campaign_rec_filename-out.wav)"); @@ -5053,7 +5076,9 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override $dbhP=$dbhA; $mysql_count='02214'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; } - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','MONO_LEGACY_REMOTE','$VARserver_ip','$now_date','$channel','$campaign_rec_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','MONO_LEGACY_REMOTE','$VARserver_ip','$now_date','$channel','$campaign_rec_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -5082,7 +5107,7 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override $PATHmonitorT = $PATHmonitorP; ### insert record into recording_log_parallel table ### - $stmtA = "INSERT INTO recording_log_parallel (channel,server_ip,extension,start_time,length_in_sec,filename,lead_id,user,vicidial_id,recording_status) values('$channel','$VDADserver_ip','','$now_date','0','PL$stereo_rec_filename','$insert_lead_id','$VDADuser','$insert_close_id','START');"; + $stmtA = "INSERT INTO recording_log_parallel (channel,server_ip,extension,start_time,length_in_sec,filename,lead_id,user,vicidial_id,recording_status) values('$channel','$VARserver_ip','','$now_date','0','PL$stereo_rec_filename','$insert_lead_id','$VDADuser','$insert_close_id','START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -5122,7 +5147,7 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override $temp_parallel_rec_co_filename =~ s/\"|\'//gi; } ### insert a record into the recording_log table - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPCOR','$now_date','$now_date_epoch','$temp_parallel_rec_co_filename','$insert_lead_id','$VDADuser','$insert_close_id')"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VARserver_ip','SPCOR','$now_date','$now_date_epoch','$temp_parallel_rec_co_filename','$insert_lead_id','$VDADuser','$insert_close_id')"; $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -5147,11 +5172,13 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override } ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_co_filename','$insert_lead_id','$channel_group STEREO_PARALLEL CUSTOMER-ONLY REMOTE $stereo_recording','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VARserver_ip','$now_date','0','$temp_parallel_rec_co_filename','$insert_lead_id','$channel_group STEREO_PARALLEL CUSTOMER-ONLY REMOTE $stereo_recording','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL CUSTOMER-ONLY REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_co_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO_PARALLEL CUSTOMER-ONLY REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_co_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -5177,7 +5204,7 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override $temp_parallel_rec_cm_filename =~ s/\"|\'//gi; } ### insert a record into the recording_log table - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPCMR','$now_date','$now_date_epoch','$temp_parallel_rec_cm_filename','$insert_lead_id','$VDADuser','$insert_close_id')"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VARserver_ip','SPCMR','$now_date','$now_date_epoch','$temp_parallel_rec_cm_filename','$insert_lead_id','$VDADuser','$insert_close_id')"; $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -5202,11 +5229,13 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override } ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_cm_filename','$insert_lead_id','$channel_group STEREO_PARALLEL CUSTOMER-MUTED REMOTE $stereo_recording','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VARserver_ip','$now_date','0','$temp_parallel_rec_cm_filename','$insert_lead_id','$channel_group STEREO_PARALLEL CUSTOMER-MUTED REMOTE $stereo_recording','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL CUSTOMER-MUTED REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_cm_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO_PARALLEL CUSTOMER-MUTED REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_cm_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -5232,7 +5261,7 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override $temp_parallel_rec_fr_filename =~ s/\"|\'//gi; } ### insert a record into the recording_log table - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPFRR','$now_date','$now_date_epoch','$temp_parallel_rec_fr_filename','$insert_lead_id','$VDADuser','$insert_close_id')"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VARserver_ip','SPFRR','$now_date','$now_date_epoch','$temp_parallel_rec_fr_filename','$insert_lead_id','$VDADuser','$insert_close_id')"; $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -5257,11 +5286,13 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override } ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_fr_filename','$insert_lead_id','$channel_group STEREO_PARALLEL FULL-RECORDING REMOTE $stereo_recording','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VARserver_ip','$now_date','0','$temp_parallel_rec_fr_filename','$insert_lead_id','$channel_group STEREO_PARALLEL FULL-RECORDING REMOTE $stereo_recording','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL FULL-RECORDING REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_fr_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO_PARALLEL FULL-RECORDING REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_fr_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -5273,7 +5304,7 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override { $temp_parallel_rec_ag_filename = $stereo_rec_filename; ### insert a record into the recording_log table - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPACR','$now_date','$now_date_epoch','$temp_parallel_rec_ag_filename','$insert_lead_id','$VDADuser','$insert_close_id')"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VARserver_ip','SPACR','$now_date','$now_date_epoch','$temp_parallel_rec_ag_filename','$insert_lead_id','$VDADuser','$insert_close_id')"; $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -5298,11 +5329,13 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override } ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_ag_filename','$insert_lead_id','$channel_group STEREO_PARALLEL AGENT-CONTROLLED REMOTE $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VARserver_ip','$now_date','0','$temp_parallel_rec_ag_filename','$insert_lead_id','$channel_group STEREO_PARALLEL AGENT-CONTROLLED REMOTE $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL AGENT-CONTROLLED REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_ag_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO_PARALLEL AGENT-CONTROLLED REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_ag_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -5314,8 +5347,14 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override ## Start NON-parallel stereo call recording ## if ($stereo_recording_agent =~ /ALLCALLS|ALLFORCE/) { + $rl_exten='SACRBC'; + if ($stereo_recording =~ /CUSTOMER_ONLY/i) + {$rl_exten='SACRCO';} + if ($stereo_recording =~ /CUSTOMER_MUTE/i) + {$rl_exten='SACRCM';} + # insert a record into the recording_log table - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SACR','$now_date','$now_date_epoch','$stereo_rec_filename','$insert_lead_id','$VDADuser','$insert_close_id')"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VARserver_ip','$rl_exten','$now_date','$now_date_epoch','$stereo_rec_filename','$insert_lead_id','$VDADuser','$insert_close_id')"; $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -5343,11 +5382,13 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override $retval = $AGI->exec("MixMonitor",",r($PATHmonitorT/$stereo_rec_filename-out.wav)t($PATHmonitorT/$stereo_rec_filename-in.wav)"); ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$stereo_rec_filename','$insert_lead_id','$channel_group STEREO AGENT-CONTROLLED REMOTE RIR $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|','STEREO START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,recording_status) values('$recording_id','$VARserver_ip','$now_date','0','$stereo_rec_filename','$insert_lead_id','$channel_group STEREO AGENT-CONTROLLED REMOTE RIR $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $insert_close_id|user: $VDADuser|channel: $channel|','STEREO START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO AGENT-CONTROLLED REMOTE','$VARserver_ip','$now_date','$channel','$stereo_rec_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO AGENT-CONTROLLED REMOTE $rl_exten','$VARserver_ip','$now_date','$channel','$stereo_rec_filename','$insert_lead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -5355,14 +5396,14 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override if ($stereo_recording =~ /CUSTOMER_ONLY/i) { $vmgr_callerid = substr($stereo_rec_filename, 0, 16) . 'M...'; - $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VDADserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: write','State: 1','','','','','','');"; + $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VARserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: write','State: 1','','','','','','');"; $mLIVEaffected_rows = $dbhA->do($stmtE); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$mLIVEaffected_rows; &mysql_error_logging; } if ($stereo_recording =~ /CUSTOMER_MUTE/i) { $vmgr_callerid = substr($stereo_rec_filename, 0, 16) . 'M...'; - $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VDADserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: read','State: 1','','','','','','');"; + $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VARserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: read','State: 1','','','','','','');"; $mLIVEaffected_rows = $dbhA->do($stmtE); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$mLIVEaffected_rows; &mysql_error_logging; } diff --git a/agi/agi-VDAD_ALL_outbound.agi b/agi/agi-VDAD_ALL_outbound.agi index ec87a3761..fa66bb117 100644 --- a/agi/agi-VDAD_ALL_outbound.agi +++ b/agi/agi-VDAD_ALL_outbound.agi @@ -135,6 +135,7 @@ # 250827-1556 - Added stereo_recording code # 250924-2150 - Added code for deprecation of "Monitor" application after Asterisk 20 # 251001-1837 - Fix for rare Stereo recording filename issue +# 251020-0835 - Added code for recording_dtmf_muting, fix for stereo call recording # $script = 'agi-VDAD_ALL_outbound.agi'; @@ -292,7 +293,7 @@ $dbhA = DBI->connect("DBI:mysql:$VARDB_database:$VARDB_server:$VARDB_port", "$VA ############################################# ##### Gather system_settings ##### -$stmtA = "SELECT sip_event_logging,call_quota_lead_ranking,agent_search_method,abandon_check_queue,stereo_recording,stereo_parallel_recording FROM system_settings;"; +$stmtA = "SELECT sip_event_logging,call_quota_lead_ranking,agent_search_method,abandon_check_queue,stereo_recording,stereo_parallel_recording,recording_dtmf_detection,recording_dtmf_muting FROM system_settings;"; $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; $sthArows=$sthA->rows; @@ -305,6 +306,8 @@ if ($sthArows > 0) $SSabandon_check_queue = $aryA[3]; $SSstereo_recording = $aryA[4]; $SSstereo_parallel_recording = $aryA[5]; + $SSrecording_dtmf_detection = $aryA[6]; + $SSrecording_dtmf_muting = $aryA[7]; } $sthA->finish(); ########################################### @@ -838,7 +841,7 @@ if ($VDACaffected_rows > 0) ##### END - Max call stats ### Grab campaign values from the database - $stmtA = "SELECT drop_call_seconds,drop_action,safe_harbor_exten,concurrent_transfers,next_agent_call,voicemail_ext,drop_inbound_group,use_internal_dnc,use_campaign_dnc,cpd_amd_action,am_message_exten,three_way_call_cid,campaign_cid,survey_first_audio_file,survey_opt_in_audio_file,survey_ni_audio_file,survey_third_audio_file,survey_fourth_audio_file,extension_appended_cidname,queue_priority,closer_campaigns,queuemetrics_phone_environment,campaign_recording,campaign_rec_filename,safe_harbor_audio,safe_harbor_menu_id,survey_recording,safe_harbor_audio_field,use_other_campaign_dnc,cpd_unknown_action,routing_initiated_recordings,campaign_rec_exten,call_quota_lead_ranking,sip_event_logging,amd_type,agent_search_method,dial_method,stereo_recording,khomp_settings_container,stereo_recording_agent,stereo_rec_filename,stereo_parallel_recording,parallel_rec_co_filename,parallel_rec_cm_filename,parallel_rec_fr_filename FROM vicidial_campaigns where campaign_id = '$VDADcampaign';"; + $stmtA = "SELECT drop_call_seconds,drop_action,safe_harbor_exten,concurrent_transfers,next_agent_call,voicemail_ext,drop_inbound_group,use_internal_dnc,use_campaign_dnc,cpd_amd_action,am_message_exten,three_way_call_cid,campaign_cid,survey_first_audio_file,survey_opt_in_audio_file,survey_ni_audio_file,survey_third_audio_file,survey_fourth_audio_file,extension_appended_cidname,queue_priority,closer_campaigns,queuemetrics_phone_environment,campaign_recording,campaign_rec_filename,safe_harbor_audio,safe_harbor_menu_id,survey_recording,safe_harbor_audio_field,use_other_campaign_dnc,cpd_unknown_action,routing_initiated_recordings,campaign_rec_exten,call_quota_lead_ranking,sip_event_logging,amd_type,agent_search_method,dial_method,stereo_recording,khomp_settings_container,stereo_recording_agent,stereo_rec_filename,stereo_parallel_recording,parallel_rec_co_filename,parallel_rec_cm_filename,parallel_rec_fr_filename,recording_dtmf_muting FROM vicidial_campaigns where campaign_id = '$VDADcampaign';"; $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; $sthArows=$sthA->rows; @@ -894,6 +897,9 @@ if ($VDACaffected_rows > 0) $parallel_rec_co_filename = $aryA[42]; $parallel_rec_cm_filename = $aryA[43]; $parallel_rec_fr_filename = $aryA[44]; + $recording_dtmf_muting = $aryA[45]; + if ( ($SSrecording_dtmf_detection < 1) || ($SSrecording_dtmf_muting < 1) ) + {$recording_dtmf_muting=0;} if (length($closer_campaigns) > 2) { @@ -1200,7 +1206,7 @@ if ($VDACaffected_rows > 0) } else { - if ($ast_ver_str{major} > 20) + if ( ($ast_ver_str{major} > 20) || ($SSrecording_dtmf_muting > 0) ) { # Deprecation of "Monitor" application after Asterisk 20 $AGI->exec("MixMonitor",",r($PATHmonitor/MIX/$campaign_rec_filename-in.wav)t($PATHmonitor/MIX/$campaign_rec_filename-out.wav)"); @@ -1236,7 +1242,9 @@ if ($VDACaffected_rows > 0) $dbhP=$dbhA; $mysql_count='02214'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; } - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','MONO_LEGACY_SURVEY','$VARserver_ip','$now_date','$channel','$campaign_rec_filename','$CIDlead_id','VDAD','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','MONO_LEGACY_SURVEY','$VARserver_ip','$now_date','$channel','$campaign_rec_filename','$CIDlead_id','VDAD','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -3210,7 +3218,7 @@ while ($drop_timer <= $DROP_TIME) } else { - if ($ast_ver_str{major} > 20) + if ( ($ast_ver_str{major} > 20) || ($SSrecording_dtmf_muting > 0) ) { # Deprecation of "Monitor" application after Asterisk 20 $retval = $AGI->exec("MixMonitor",",r($PATHmonitor/MIX/$campaign_rec_filename-in.wav)t($PATHmonitor/MIX/$campaign_rec_filename-out.wav)"); @@ -3248,7 +3256,9 @@ while ($drop_timer <= $DROP_TIME) $dbhP=$dbhA; $mysql_count='02214'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; } - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','MONO_LEGACY_REMOTE','$VARserver_ip','$now_date','$channel','$campaign_rec_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','MONO_LEGACY_REMOTE','$VARserver_ip','$now_date','$channel','$campaign_rec_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -3278,7 +3288,7 @@ while ($drop_timer <= $DROP_TIME) $PATHmonitorT = $PATHmonitorP; ### insert record into recording_log_parallel table ### - $stmtA = "INSERT INTO recording_log_parallel (channel,server_ip,extension,start_time,length_in_sec,filename,lead_id,user,vicidial_id,recording_status) values('$channel','$VDADserver_ip','','$now_date','0','PL$stereo_rec_filename','$CIDlead_id','$VDADuser','$uniqueid','START');"; + $stmtA = "INSERT INTO recording_log_parallel (channel,server_ip,extension,start_time,length_in_sec,filename,lead_id,user,vicidial_id,recording_status) values('$channel','$VARserver_ip','','$now_date','0','PL$stereo_rec_filename','$CIDlead_id','$VDADuser','$uniqueid','START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -3318,7 +3328,7 @@ while ($drop_timer <= $DROP_TIME) $temp_parallel_rec_co_filename =~ s/\"|\'//gi; } ### insert a record into the recording_log table - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPCOR','$now_date','$now_date_epoch','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VARserver_ip','SPCOR','$now_date','$now_date_epoch','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADuser','$uniqueid')"; $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -3343,11 +3353,13 @@ while ($drop_timer <= $DROP_TIME) } ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL CUSTOMER-ONLY REMOTE $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VARserver_ip','$now_date','0','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL CUSTOMER-ONLY REMOTE $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL CUSTOMER-ONLY REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO_PARALLEL CUSTOMER-ONLY REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -3373,7 +3385,7 @@ while ($drop_timer <= $DROP_TIME) $temp_parallel_rec_cm_filename =~ s/\"|\'//gi; } ### insert a record into the recording_log table - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPCMR','$now_date','$now_date_epoch','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VARserver_ip','SPCMR','$now_date','$now_date_epoch','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADuser','$uniqueid')"; $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -3398,11 +3410,13 @@ while ($drop_timer <= $DROP_TIME) } ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL CUSTOMER-MUTED REMOTE $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VARserver_ip','$now_date','0','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL CUSTOMER-MUTED REMOTE $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL CUSTOMER-MUTED REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO_PARALLEL CUSTOMER-MUTED REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -3428,7 +3442,7 @@ while ($drop_timer <= $DROP_TIME) $temp_parallel_rec_fr_filename =~ s/\"|\'//gi; } ### insert a record into the recording_log table - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPFRR','$now_date','$now_date_epoch','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VARserver_ip','SPFRR','$now_date','$now_date_epoch','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADuser','$uniqueid')"; $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -3453,11 +3467,13 @@ while ($drop_timer <= $DROP_TIME) } ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL FULL-RECORDING REMOTE $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VARserver_ip','$now_date','0','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL FULL-RECORDING REMOTE $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL FULL-RECORDING REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO_PARALLEL FULL-RECORDING REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -3469,7 +3485,7 @@ while ($drop_timer <= $DROP_TIME) { $temp_parallel_rec_ag_filename = $stereo_rec_filename; ### insert a record into the recording_log table - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPACR','$now_date','$now_date_epoch','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VARserver_ip','SPACR','$now_date','$now_date_epoch','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADuser','$uniqueid')"; $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -3494,11 +3510,13 @@ while ($drop_timer <= $DROP_TIME) } ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL AGENT-CONTROLLED REMOTE $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VARserver_ip','$now_date','0','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL AGENT-CONTROLLED REMOTE $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL AGENT-CONTROLLED REMOTE','$VARserver_ip','$now_date','$channel','$stereo_recording_agent','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO_PARALLEL AGENT-CONTROLLED REMOTE','$VARserver_ip','$now_date','$channel','$stereo_recording_agent','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -3510,8 +3528,14 @@ while ($drop_timer <= $DROP_TIME) ## Start NON-parallel stereo call recording ## if ($stereo_recording_agent =~ /ALLCALLS|ALLFORCE/) { + $rl_exten='SACRBC'; + if ($stereo_recording =~ /CUSTOMER_ONLY/i) + {$rl_exten='SACRCO';} + if ($stereo_recording =~ /CUSTOMER_MUTE/i) + {$rl_exten='SACRCM';} + # insert a record into the recording_log table - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SACR','$now_date','$now_date_epoch','$stereo_rec_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VARserver_ip','$rl_exten','$now_date','$now_date_epoch','$stereo_rec_filename','$CIDlead_id','$VDADuser','$uniqueid')"; $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -3539,11 +3563,13 @@ while ($drop_timer <= $DROP_TIME) $retval = $AGI->exec("MixMonitor",",r($PATHmonitorT/$stereo_rec_filename-out.wav)t($PATHmonitorT/$stereo_rec_filename-in.wav)"); ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$stereo_rec_filename','$CIDlead_id','$VDADcampaign STEREO AGENT-CONTROLLED REMOTE $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','STEREO START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,recording_status) values('$recording_id','$VARserver_ip','$now_date','0','$stereo_rec_filename','$CIDlead_id','$VDADcampaign STEREO AGENT-CONTROLLED REMOTE $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','STEREO START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO AGENT-CONTROLLED REMOTE','$VARserver_ip','$now_date','$channel','$stereo_rec_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO AGENT-CONTROLLED REMOTE $rl_exten','$VARserver_ip','$now_date','$channel','$stereo_rec_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -3551,14 +3577,14 @@ while ($drop_timer <= $DROP_TIME) if ($stereo_recording =~ /CUSTOMER_ONLY/i) { $vmgr_callerid = substr($stereo_rec_filename, 0, 16) . 'M...'; - $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VDADserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: write','State: 1','','','','','','');"; + $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VARserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: write','State: 1','','','','','','');"; $mLIVEaffected_rows = $dbhA->do($stmtE); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$mLIVEaffected_rows; &mysql_error_logging; } if ($stereo_recording =~ /CUSTOMER_MUTE/i) { $vmgr_callerid = substr($stereo_rec_filename, 0, 16) . 'M...'; - $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VDADserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: read','State: 1','','','','','','');"; + $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VARserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: read','State: 1','','','','','','');"; $mLIVEaffected_rows = $dbhA->do($stmtE); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$mLIVEaffected_rows; &mysql_error_logging; } @@ -3664,7 +3690,9 @@ while ($drop_timer <= $DROP_TIME) $affected_rowsC = $dbhA->do($stmtC); $dbhP=$dbhA; $mysql_count='02128'; $MEL_aff_rows=$affected_rowsC; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','MONO_LEGACY_RIR','$VARserver_ip','$now_date','$channel','$campaign_rec_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','MONO_LEGACY_RIR','$VDADserver_ip','$now_date','$channelrec','$campaign_rec_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -3696,7 +3724,7 @@ while ($drop_timer <= $DROP_TIME) $PATHmonitorT = $PATHmonitorP; ### insert record into recording_log_parallel table ### - $stmtA = "INSERT INTO recording_log_parallel (channel,server_ip,extension,start_time,length_in_sec,filename,lead_id,user,vicidial_id,recording_status) values('$channel','$VDADserver_ip','','$now_date','0','PL$stereo_rec_filename','$CIDlead_id','$VDADuser','$uniqueid','START');"; + $stmtA = "INSERT INTO recording_log_parallel (channel,server_ip,extension,start_time,length_in_sec,filename,lead_id,user,vicidial_id,recording_status) values('$channel','$VARserver_ip','','$now_date','0','PL$stereo_rec_filename','$CIDlead_id','$VDADuser','$uniqueid','START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -3736,7 +3764,7 @@ while ($drop_timer <= $DROP_TIME) $temp_parallel_rec_co_filename =~ s/\"|\'//gi; } ### insert a record into the recording_log table - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPCO','$now_date','$now_date_epoch','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VARserver_ip','SPCO','$now_date','$now_date_epoch','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADuser','$uniqueid')"; $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -3761,11 +3789,13 @@ while ($drop_timer <= $DROP_TIME) } ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL CUSTOMER-ONLY $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VARserver_ip','$now_date','0','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL CUSTOMER-ONLY $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL CUSTOMER-ONLY','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO_PARALLEL CUSTOMER-ONLY','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -3791,7 +3821,7 @@ while ($drop_timer <= $DROP_TIME) $temp_parallel_rec_cm_filename =~ s/\"|\'//gi; } ### insert a record into the recording_log table - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPCM','$now_date','$now_date_epoch','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VARserver_ip','SPCM','$now_date','$now_date_epoch','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADuser','$uniqueid')"; $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -3816,11 +3846,13 @@ while ($drop_timer <= $DROP_TIME) } ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL CUSTOMER-MUTED $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VARserver_ip','$now_date','0','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL CUSTOMER-MUTED $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL CUSTOMER-MUTED','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO_PARALLEL CUSTOMER-MUTED','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -3846,7 +3878,7 @@ while ($drop_timer <= $DROP_TIME) $temp_parallel_rec_fr_filename =~ s/\"|\'//gi; } ### insert a record into the recording_log table - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPFR','$now_date','$now_date_epoch','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VARserver_ip','SPFR','$now_date','$now_date_epoch','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADuser','$uniqueid')"; $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -3871,11 +3903,13 @@ while ($drop_timer <= $DROP_TIME) } ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL FULL-RECORDING $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VARserver_ip','$now_date','0','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL FULL-RECORDING $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL FULL-RECORDING','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO_PARALLEL FULL-RECORDING','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -3887,7 +3921,7 @@ while ($drop_timer <= $DROP_TIME) { $temp_parallel_rec_ag_filename = $stereo_rec_filename; ### insert a record into the recording_log table - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPACI','$now_date','$now_date_epoch','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VARserver_ip','SPACI','$now_date','$now_date_epoch','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADuser','$uniqueid')"; $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -3912,7 +3946,7 @@ while ($drop_timer <= $DROP_TIME) } ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL AGENT-CONTROLLED RIR $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VARserver_ip','$now_date','0','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL AGENT-CONTROLLED RIR $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; @@ -3920,7 +3954,9 @@ while ($drop_timer <= $DROP_TIME) $affected_rowsB = $dbhA->do($stmtB); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rowsB; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL AGENT-CONTROLLED RIR','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO_PARALLEL AGENT-CONTROLLED RIR','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -3932,8 +3968,14 @@ while ($drop_timer <= $DROP_TIME) ## Start NON-parallel stereo call recording ## if ($stereo_recording_agent =~ /ALLCALLS|ALLFORCE/) { + $rl_exten='SACIBC'; + if ($stereo_recording =~ /CUSTOMER_ONLY/i) + {$rl_exten='SACICO';} + if ($stereo_recording =~ /CUSTOMER_MUTE/i) + {$rl_exten='SACICM';} + # insert a record into the recording_log table - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SACI','$now_date','$now_date_epoch','$stereo_rec_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VARserver_ip','$rl_exten','$now_date','$now_date_epoch','$stereo_rec_filename','$CIDlead_id','$VDADuser','$uniqueid')"; $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -3961,7 +4003,7 @@ while ($drop_timer <= $DROP_TIME) $retval = $AGI->exec("MixMonitor",",r($PATHmonitorT/$stereo_rec_filename-out.wav)t($PATHmonitorT/$stereo_rec_filename-in.wav)"); ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$stereo_rec_filename','$CIDlead_id','$VDADcampaign STEREO AGENT-CONTROLLED RIR $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','STEREO START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,recording_status) values('$recording_id','$VARserver_ip','$now_date','0','$stereo_rec_filename','$CIDlead_id','$VDADcampaign STEREO AGENT-CONTROLLED RIR $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','STEREO START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; @@ -3969,7 +4011,9 @@ while ($drop_timer <= $DROP_TIME) $affected_rowsB = $dbhA->do($stmtB); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rowsB; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO AGENT-CONTROLLED RIR','$VARserver_ip','$now_date','$channel','$stereo_rec_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO AGENT-CONTROLLED RIR $rl_exten','$VARserver_ip','$now_date','$channel','$stereo_rec_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -3977,14 +4021,14 @@ while ($drop_timer <= $DROP_TIME) if ($stereo_recording =~ /CUSTOMER_ONLY/i) { $vmgr_callerid = substr($stereo_rec_filename, 0, 16) . 'M...'; - $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VDADserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: write','State: 1','','','','','','');"; + $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VARserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: write','State: 1','','','','','','');"; $mLIVEaffected_rows = $dbhA->do($stmtE); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$mLIVEaffected_rows; &mysql_error_logging; } if ($stereo_recording =~ /CUSTOMER_MUTE/i) { $vmgr_callerid = substr($stereo_rec_filename, 0, 16) . 'M...'; - $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VDADserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: read','State: 1','','','','','','');"; + $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VARserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: read','State: 1','','','','','','');"; $mLIVEaffected_rows = $dbhA->do($stmtE); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$mLIVEaffected_rows; &mysql_error_logging; } @@ -4606,7 +4650,7 @@ while ($drop_timer <= $DROP_TIME) } else { - if ($ast_ver_str{major} > 20) + if ( ($ast_ver_str{major} > 20) || ($SSrecording_dtmf_muting > 0) ) { # Deprecation of "Monitor" application after Asterisk 20 $retval = $AGI->exec("MixMonitor",",r($PATHmonitor/MIX/$campaign_rec_filename-in.wav)t($PATHmonitor/MIX/$campaign_rec_filename-out.wav)"); @@ -4644,7 +4688,9 @@ while ($drop_timer <= $DROP_TIME) $dbhP=$dbhA; $mysql_count='02214'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; } - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','MONO_LEGACY_REMOTE','$VARserver_ip','$now_date','$channel','$campaign_rec_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','MONO_LEGACY_REMOTE','$VARserver_ip','$now_date','$channel','$campaign_rec_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -4673,7 +4719,7 @@ while ($drop_timer <= $DROP_TIME) $PATHmonitorT = $PATHmonitorP; ### insert record into recording_log_parallel table ### - $stmtA = "INSERT INTO recording_log_parallel (channel,server_ip,extension,start_time,length_in_sec,filename,lead_id,user,vicidial_id,recording_status) values('$channel','$VDADserver_ip','','$now_date','0','PL$stereo_rec_filename','$CIDlead_id','$VDADuser','$uniqueid','START');"; + $stmtA = "INSERT INTO recording_log_parallel (channel,server_ip,extension,start_time,length_in_sec,filename,lead_id,user,vicidial_id,recording_status) values('$channel','$VARserver_ip','','$now_date','0','PL$stereo_rec_filename','$CIDlead_id','$VDADuser','$uniqueid','START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -4713,7 +4759,7 @@ while ($drop_timer <= $DROP_TIME) $temp_parallel_rec_co_filename =~ s/\"|\'//gi; } ### insert a record into the recording_log table - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPCOR','$now_date','$now_date_epoch','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VARserver_ip','SPCOR','$now_date','$now_date_epoch','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADuser','$uniqueid')"; $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -4738,11 +4784,13 @@ while ($drop_timer <= $DROP_TIME) } ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL CUSTOMER-ONLY REMOTE $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VARserver_ip','$now_date','0','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL CUSTOMER-ONLY REMOTE $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL CUSTOMER-ONLY REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO_PARALLEL CUSTOMER-ONLY REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -4768,7 +4816,7 @@ while ($drop_timer <= $DROP_TIME) $temp_parallel_rec_cm_filename =~ s/\"|\'//gi; } ### insert a record into the recording_log table - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPCMR','$now_date','$now_date_epoch','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VARserver_ip','SPCMR','$now_date','$now_date_epoch','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADuser','$uniqueid')"; $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -4793,11 +4841,13 @@ while ($drop_timer <= $DROP_TIME) } ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL CUSTOMER-MUTED REMOTE $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VARserver_ip','$now_date','0','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL CUSTOMER-MUTED REMOTE $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL CUSTOMER-MUTED REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO_PARALLEL CUSTOMER-MUTED REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -4823,7 +4873,7 @@ while ($drop_timer <= $DROP_TIME) $temp_parallel_rec_fr_filename =~ s/\"|\'//gi; } ### insert a record into the recording_log table - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPRFR','$now_date','$now_date_epoch','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VARserver_ip','SPRFR','$now_date','$now_date_epoch','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADuser','$uniqueid')"; $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -4848,11 +4898,13 @@ while ($drop_timer <= $DROP_TIME) } ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL FULL-RECORDING REMOTE $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VARserver_ip','$now_date','0','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL FULL-RECORDING REMOTE $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL FULL-RECORDING REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO_PARALLEL FULL-RECORDING REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -4864,7 +4916,7 @@ while ($drop_timer <= $DROP_TIME) { $temp_parallel_rec_ag_filename = $stereo_rec_filename; ### insert a record into the recording_log table - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPACR','$now_date','$now_date_epoch','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VARserver_ip','SPACR','$now_date','$now_date_epoch','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADuser','$uniqueid')"; $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -4889,11 +4941,13 @@ while ($drop_timer <= $DROP_TIME) } ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL AGENT-CONTROLLED REMOTE $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VARserver_ip','$now_date','0','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL AGENT-CONTROLLED REMOTE $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL AGENT-CONTROLLED REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO_PARALLEL AGENT-CONTROLLED REMOTE','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -4905,8 +4959,14 @@ while ($drop_timer <= $DROP_TIME) ## Start NON-parallel stereo call recording ## if ($stereo_recording_agent =~ /ALLCALLS|ALLFORCE/) { + $rl_exten='SACRBC'; + if ($stereo_recording =~ /CUSTOMER_ONLY/i) + {$rl_exten='SACRCO';} + if ($stereo_recording =~ /CUSTOMER_MUTE/i) + {$rl_exten='SACRCM';} + # insert a record into the recording_log table - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SACR','$now_date','$now_date_epoch','$stereo_rec_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VARserver_ip','$rl_exten','$now_date','$now_date_epoch','$stereo_rec_filename','$CIDlead_id','$VDADuser','$uniqueid')"; $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -4934,11 +4994,13 @@ while ($drop_timer <= $DROP_TIME) $retval = $AGI->exec("MixMonitor",",r($PATHmonitorT/$stereo_rec_filename-out.wav)t($PATHmonitorT/$stereo_rec_filename-in.wav)"); ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$stereo_rec_filename','$CIDlead_id','$VDADcampaign STEREO AGENT-CONTROLLED REMOTE $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','STEREO START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,recording_status) values('$recording_id','$VARserver_ip','$now_date','0','$stereo_rec_filename','$CIDlead_id','$VDADcampaign STEREO AGENT-CONTROLLED REMOTE $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','STEREO START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO AGENT-CONTROLLED REMOTE','$VARserver_ip','$now_date','$channel','$stereo_rec_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO AGENT-CONTROLLED REMOTE $rl_exten','$VARserver_ip','$now_date','$channel','$stereo_rec_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -4946,14 +5008,14 @@ while ($drop_timer <= $DROP_TIME) if ($stereo_recording =~ /CUSTOMER_ONLY/i) { $vmgr_callerid = substr($stereo_rec_filename, 0, 16) . 'M...'; - $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VDADserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: write','State: 1','','','','','','');"; + $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VARserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: write','State: 1','','','','','','');"; $mLIVEaffected_rows = $dbhA->do($stmtE); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$mLIVEaffected_rows; &mysql_error_logging; } if ($stereo_recording =~ /CUSTOMER_MUTE/i) { $vmgr_callerid = substr($stereo_rec_filename, 0, 16) . 'M...'; - $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VDADserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: read','State: 1','','','','','','');"; + $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VARserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: read','State: 1','','','','','','');"; $mLIVEaffected_rows = $dbhA->do($stmtE); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$mLIVEaffected_rows; &mysql_error_logging; } @@ -5058,7 +5120,9 @@ while ($drop_timer <= $DROP_TIME) $affected_rowsC = $dbhA->do($stmtC); $dbhP=$dbhA; $mysql_count='02136'; $MEL_aff_rows=$affected_rowsC; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','MONO_LEGACY_RIR','$VARserver_ip','$now_date','$channel','$campaign_rec_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','MONO_LEGACY_RIR','$VDADserver_ip','$now_date','$channelrec','$campaign_rec_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -5089,7 +5153,7 @@ while ($drop_timer <= $DROP_TIME) $PATHmonitorT = $PATHmonitorP; ### insert record into recording_log_parallel table ### - $stmtA = "INSERT INTO recording_log_parallel (channel,server_ip,extension,start_time,length_in_sec,filename,lead_id,user,vicidial_id,recording_status) values('$channel','$VDADserver_ip','','$now_date','0','PL$stereo_rec_filename','$CIDlead_id','$VDADuser','$uniqueid','START');"; + $stmtA = "INSERT INTO recording_log_parallel (channel,server_ip,extension,start_time,length_in_sec,filename,lead_id,user,vicidial_id,recording_status) values('$channel','$VARserver_ip','','$now_date','0','PL$stereo_rec_filename','$CIDlead_id','$VDADuser','$uniqueid','START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -5129,7 +5193,7 @@ while ($drop_timer <= $DROP_TIME) $temp_parallel_rec_co_filename =~ s/\"|\'//gi; } ### insert a record into the recording_log table - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPCO','$now_date','$now_date_epoch','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VARserver_ip','SPCO','$now_date','$now_date_epoch','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADuser','$uniqueid')"; $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -5154,11 +5218,13 @@ while ($drop_timer <= $DROP_TIME) } ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL CUSTOMER-ONLY $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VARserver_ip','$now_date','0','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL CUSTOMER-ONLY $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL CUSTOMER-ONLY','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO_PARALLEL CUSTOMER-ONLY','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_co_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -5184,7 +5250,7 @@ while ($drop_timer <= $DROP_TIME) $temp_parallel_rec_cm_filename =~ s/\"|\'//gi; } ### insert a record into the recording_log table - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPCM','$now_date','$now_date_epoch','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VARserver_ip','SPCM','$now_date','$now_date_epoch','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADuser','$uniqueid')"; $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -5209,11 +5275,13 @@ while ($drop_timer <= $DROP_TIME) } ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL CUSTOMER-MUTED $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VARserver_ip','$now_date','0','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL CUSTOMER-MUTED $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL CUSTOMER-MUTED','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO_PARALLEL CUSTOMER-MUTED','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_cm_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -5239,7 +5307,7 @@ while ($drop_timer <= $DROP_TIME) $temp_parallel_rec_fr_filename =~ s/\"|\'//gi; } ### insert a record into the recording_log table - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPFR','$now_date','$now_date_epoch','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VARserver_ip','SPFR','$now_date','$now_date_epoch','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADuser','$uniqueid')"; $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -5264,11 +5332,13 @@ while ($drop_timer <= $DROP_TIME) } ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL FULL-RECORDING $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VARserver_ip','$now_date','0','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL FULL-RECORDING $stereo_recording','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL FULL-RECORDING','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO_PARALLEL FULL-RECORDING','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_fr_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -5280,7 +5350,7 @@ while ($drop_timer <= $DROP_TIME) { $temp_parallel_rec_ag_filename = $stereo_rec_filename; ### insert a record into the recording_log table - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SPACI','$now_date','$now_date_epoch','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VARserver_ip','SPACI','$now_date','$now_date_epoch','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADuser','$uniqueid')"; $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -5305,7 +5375,7 @@ while ($drop_timer <= $DROP_TIME) } ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL AGENT-CONTROLLED RIR $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,parallel_recording_id,recording_status) values('$recording_id','$VARserver_ip','$now_date','0','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADcampaign STEREO_PARALLEL AGENT-CONTROLLED RIR $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','$parallel_recording_id','PARALLEL START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; @@ -5313,7 +5383,9 @@ while ($drop_timer <= $DROP_TIME) $affected_rowsB = $dbhA->do($stmtB); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rowsB; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL AGENT-CONTROLLED RIR','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO_PARALLEL AGENT-CONTROLLED RIR','$VARserver_ip','$now_date','$channel','$temp_parallel_rec_ag_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -5325,8 +5397,14 @@ while ($drop_timer <= $DROP_TIME) ## Start NON-parallel stereo call recording ## if ($stereo_recording_agent =~ /ALLCALLS|ALLFORCE/) { + $rl_exten='SACIBC'; + if ($stereo_recording =~ /CUSTOMER_ONLY/i) + {$rl_exten='SACICO';} + if ($stereo_recording =~ /CUSTOMER_MUTE/i) + {$rl_exten='SACICM';} + # insert a record into the recording_log table - $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VDADserver_ip','SACI','$now_date','$now_date_epoch','$stereo_rec_filename','$CIDlead_id','$VDADuser','$uniqueid')"; + $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$VARserver_ip','$rl_exten','$now_date','$now_date_epoch','$stereo_rec_filename','$CIDlead_id','$VDADuser','$uniqueid')"; $affected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging; $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; @@ -5354,7 +5432,7 @@ while ($drop_timer <= $DROP_TIME) $retval = $AGI->exec("MixMonitor",",r($PATHmonitorT/$stereo_rec_filename-out.wav)t($PATHmonitorT/$stereo_rec_filename-in.wav)"); ### insert record into recording_log_stereo table ### - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,recording_status) values('$recording_id','$VDADserver_ip','$now_date','0','$stereo_rec_filename','$CIDlead_id','$VDADcampaign STEREO AGENT-CONTROLLED RIR $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','STEREO START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,recording_status) values('$recording_id','$VARserver_ip','$now_date','0','$stereo_rec_filename','$CIDlead_id','$VDADcampaign STEREO AGENT-CONTROLLED RIR $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $uniqueid|user: $VDADuser|channel: $channel|','STEREO START');"; $SRaffected_rows = $dbhA->do($stmtA); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$SRaffected_rows; &mysql_error_logging; @@ -5362,7 +5440,9 @@ while ($drop_timer <= $DROP_TIME) $affected_rowsB = $dbhA->do($stmtB); $dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rowsB; &mysql_error_logging; - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO AGENT-CONTROLLED RIR','$VARserver_ip','$now_date','$channel','$stereo_rec_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO AGENT-CONTROLLED RIR $rl_exten','$VARserver_ip','$now_date','$channel','$stereo_rec_filename','$CIDlead_id','$VDADuser','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; $rLIVEaffected_rows = $dbhA->do($stmtD); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$rLIVEaffected_rows; &mysql_error_logging; @@ -5370,14 +5450,14 @@ while ($drop_timer <= $DROP_TIME) if ($stereo_recording =~ /CUSTOMER_ONLY/i) { $vmgr_callerid = substr($stereo_rec_filename, 0, 16) . 'M...'; - $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VDADserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: write','State: 1','','','','','','');"; + $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VARserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: write','State: 1','','','','','','');"; $mLIVEaffected_rows = $dbhA->do($stmtE); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$mLIVEaffected_rows; &mysql_error_logging; } if ($stereo_recording =~ /CUSTOMER_MUTE/i) { $vmgr_callerid = substr($stereo_rec_filename, 0, 16) . 'M...'; - $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VDADserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: read','State: 1','','','','','','');"; + $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$VARserver_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: read','State: 1','','','','','','');"; $mLIVEaffected_rows = $dbhA->do($stmtE); $dbhP=$dbhA; $mysql_count='01XXX'; $MEL_aff_rows=$mLIVEaffected_rows; &mysql_error_logging; } diff --git a/agi/agi-VDAD_RINGALL.agi b/agi/agi-VDAD_RINGALL.agi index 97301fb62..546228315 100644 --- a/agi/agi-VDAD_RINGALL.agi +++ b/agi/agi-VDAD_RINGALL.agi @@ -25,6 +25,7 @@ # 240420-2241 - Added ConfBridge code # 240415-1702 - Fix for ConfBridge code # 250924-2157 - Added code for deprecation of "Monitor" application after Asterisk 20 +# 251006-0902 - If recording_dtmf_muting enabled, force use of MixMonitor for recording # $script = 'agi-VDAD_RINGALL.agi'; @@ -42,6 +43,7 @@ $now_date = "$year-$mon-$mday $hour:$min:$sec"; $now_num = "$year$mon$mday$hour$min$sec"; $CIDdate = "$mon$mday$hour$min$sec"; $S='*'; +$recording_dtmf_muting=0; # default path to astguiclient configuration file: $PATHconf = '/etc/astguiclient.conf'; @@ -92,6 +94,21 @@ $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; +############################################# +##### Gather system_settings ##### +$stmtA = "SELECT recording_dtmf_muting,recording_dtmf_detection FROM system_settings;"; +$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; +$sthA->execute or die "executing: $stmtA ", $dbhA->errstr; +$sthArows=$sthA->rows; +if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $SSrecording_dtmf_muting = $aryA[0]; + $SSrecording_dtmf_detection = $aryA[1]; + } +$sthA->finish(); +########################################### + ### Grab Server values from the database $stmtA = "SELECT agi_output,ext_context,asterisk_version,conf_engine FROM servers where server_ip = '$VARserver_ip';"; $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; @@ -308,7 +325,7 @@ if ($NAGcount > 0) ### get the recording settings for the campaign that this remote agent is logged into if (length($VLAcampaign_id) > 0) { - $stmtA = "SELECT campaign_recording,campaign_rec_filename FROM vicidial_campaigns where campaign_id='$VLAcampaign_id';"; + $stmtA = "SELECT campaign_recording,campaign_rec_filename,recording_dtmf_muting FROM vicidial_campaigns where campaign_id='$VLAcampaign_id';"; $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; $VCRcount=$sthA->rows; @@ -317,6 +334,9 @@ if ($NAGcount > 0) @aryA = $sthA->fetchrow_array; $campaign_recording = $aryA[0]; $campaign_rec_filename = $aryA[1]; + $recording_dtmf_muting = $aryA[2]; + if ( ($SSrecording_dtmf_detection < 1) || ($SSrecording_dtmf_muting < 1) ) + {$recording_dtmf_muting=0;} } $sthA->finish(); } @@ -388,7 +408,7 @@ if ($NAGcount > 0) } else { - if ($ast_ver_str{major} > 20) + if ( ($ast_ver_str{major} > 20) || ($SSrecording_dtmf_muting > 0) ) { # Deprecation of "Monitor" application after Asterisk 20 $AGI->exec("MixMonitor",",r($PATHmonitor/MIX/$campaign_rec_filename-in.wav)t($PATHmonitor/MIX/$campaign_rec_filename-out.wav)"); @@ -402,7 +422,31 @@ if ($NAGcount > 0) ### insert record into recording_log table ### $stmtA = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,length_in_sec,filename,lead_id,user,location,vicidial_id) values('$channel','$VARserver_ip','$VAC_phone_number','$now_date','$now_date_epoch','0','$campaign_rec_filename','$VAC_lead_id','$dial_user','$campaign_rec_filename','$uniqueid');"; $RLRAaffected_rows = $dbhA->do($stmtA); - if ($AGILOG) {$agi_string = "-- REMOTE RECORDING STARTED : |$RLRAaffected_rows|$campaign_rec_filename|$stmtA|"; &agi_output;} + + $stmtB = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtB) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_id = $aryA[0]; + } + $sthA->finish(); + + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + { + if ($SSrecording_dtmf_muting > 1) + { + $recording_dtmf_muting = $SSrecording_dtmf_muting; + } + } + + ### insert record into recording_live table ### + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','MONO_LEGACY_REMOTE','$VARserver_ip','$now_date','$channel','$campaign_rec_filename','$VAC_lead_id','$dial_user','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; + $rLIVEaffected_rows = $dbhA->do($stmtD); + + if ($AGILOG) {$agi_string = "-- REMOTE RECORDING STARTED : |$RLRAaffected_rows|$rLIVEaffected_rows|$recording_id|$campaign_rec_filename|$stmtA|"; &agi_output;} } } else diff --git a/bin/ADMIN_archive_log_tables.pl b/bin/ADMIN_archive_log_tables.pl index 2eb270301..8b60414b0 100644 --- a/bin/ADMIN_archive_log_tables.pl +++ b/bin/ADMIN_archive_log_tables.pl @@ -74,6 +74,7 @@ # 240916-2159 - Added --extended-log-only # 240924-2041 - Added --vicidial-log-only # 250914-1537 - Added archiving of recording_log_stereo and recording_log_parallel tables +# 251011-2048 - Added archiving of recording_live_log table # $CALC_TEST=0; @@ -4136,6 +4137,55 @@ $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; } + + ##### recording_live_log + $stmtA = "SELECT count(*) from recording_live_log;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_live_log_count = $aryA[0]; + } + $sthA->finish(); + + $stmtA = "SELECT count(*) from recording_live_log_archive;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $recording_live_log_archive_count = $aryA[0]; + } + $sthA->finish(); + + if (!$Q) {print "\nProcessing recording_live_log table... ($recording_live_log_count|$recording_live_log_archive_count)\n";} + $stmtA = "INSERT IGNORE INTO recording_live_log_archive SELECT * from recording_live_log;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + + $sthArows = $sthA->rows; + if (!$Q) {print "$sthArows rows inserted into recording_live_log_archive table \n";} + + $rv = $sthA->err(); + if (!$rv) + { + $stmtA = "DELETE FROM recording_live_log WHERE start_time < '$RECdel_time';"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows = $sthA->rows; + if (!$Q) {print "$sthArows rows deleted from recording_live_log table \n";} + + $stmtA = "optimize table recording_live_log;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + + $stmtA = "optimize table recording_live_log_archive;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + } } diff --git a/bin/ADMIN_central_lead_repository.pl b/bin/ADMIN_central_lead_repository.pl new file mode 100644 index 000000000..224d620fc --- /dev/null +++ b/bin/ADMIN_central_lead_repository.pl @@ -0,0 +1,1795 @@ +#!/usr/bin/perl +# +# ADMIN_central_lead_repository.pl version 2.14 +# +# This script is designed to gather recently changed log entries and look up the lead data for those logs and update a central vicidial_list table on a separate database server. Then after a set cut-off time, check for the previous X hours of leads being modified and update anything that is missing and provide a report. Then early in the morning the changed leads will be sync'd back to the original database server +# +# This script also can sync settings from campaigns, lists, dids, in-groups and users to the CLR database +# +# WARNING!!! This script is experimental and is not recommended for production systems at this time +# +# NOTE: for more information on using this in a multi-cluster situation, read the MySQL_Multi-source-replication.txt document +# NOTE: this script makes use of some non-standard database fields, to use it you may need to run these, which you should not do during production: +# +# ALTER TABLE vicidial_log ADD modify_stamp TIMESTAMP; +# ALTER TABLE vicidial_closer_log ADD modify_stamp TIMESTAMP; +# +# Place in the crontab and run every month after one in the morning, or whenever +# your server is not busy with other tasks +# 30 1 1 * * /usr/share/astguiclient/ADMIN_central_lead_repository.pl +# +# Copyright (C) 2025 Matt Florell LICENSE: AGPLv2 +# +# CHANGES +# 241018-1001 - First version work started, ongoing development +# + +$DB=0; +$DBX=0; +$CALC_TEST=0; +$QUERY_COUNT_TEST=0; +$NIGHTLY_UPDATE=0; +$BACK_TO_CLUSTERS=0; +$SETTINGS_TO_CLR=0; +$ALL_SETTINGS=0; +$T=0; $TEST=0; +$MT[0]=''; +$u_ct=0; +$process_output=''; + +### begin parsing run-time options ### +if (length($ARGV[0])>1) + { + $i=0; + while ($#ARGV >= $i) + { + $args = "$args $ARGV[$i]"; + $i++; + } + + if ($args =~ /--help/i) + { + print "allowed run time options:\n"; + print " [--minutes=XX] = number of minutes to gather leads for, default is 1 \n"; + print " [--quiet] = quiet\n"; + print " [--calc-test] = date calculation test only\n"; + print " [--query-count-test] = run archive counts test only\n"; + print " [--nightly-update] = update CLR leads with all modified leads from ORIGINAL db \n"; + print " [--back-to-clusters] = update ORIGINAL leads with all modified leads from CLR db \n"; + print " [--settings-to-clr] = update ORIGINAL settings to the CLR db \n"; + print " [--all-settings] = update all settings instead of by date \n"; + print " [--test] = test\n"; + print " [--debug] = debug output for some options\n"; + print " [--debugX] = extra debug output for some options\n"; + print "\n"; + exit; + } + else + { + if ($args =~ /-quiet/i) + { + $q=1; $Q=1; + } + if ($args =~ /--test/i) + { + $T=1; $TEST=1; + print "\n----- TESTING -----\n\n"; + } + if ($args =~ /--debug/i) + { + $DB=1; + print "\n----- DEBUG -----\n\n"; + } + if ($args =~ /--debugX/i) + { + $DBX=1; + print "\n----- DEBUG EXTRA -----\n\n"; + } + if ($args =~ /--calc-test/i) + { + $CALC_TEST=1; + print "\n----- DATE CALCULATION TESTING ONLY: $CALC_TEST -----\n\n"; + } + if ($args =~ /--query-count-test/i) + { + $QUERY_COUNT_TEST=1; + print "\n----- ARCHIVE TABLES QUERY COUNT TESTING ONLY: $QUERY_COUNT_TEST -----\n\n"; + } + if ($args =~ /--nightly-update/i) + { + $NIGHTLY_UPDATE=1; + print "\n----- NIGHTLY CLR UPDATE: $NIGHTLY_UPDATE -----\n\n"; + } + if ($args =~ /--back-to-clusters/i) + { + $BACK_TO_CLUSTERS=1; + print "\n----- BACK TO CLUSTERS UPDATE: $BACK_TO_CLUSTERS -----\n\n"; + } + if ($args =~ /--settings-to-clr/i) + { + $SETTINGS_TO_CLR=1; + print "\n----- SETTINGS TO CLR UPDATE: $SETTINGS_TO_CLR -----\n\n"; + } + if ($args =~ /--all-settings/i) + { + $ALL_SETTINGS=1; + print "\n----- ALL SETTINGS OVERRIDE: $ALL_SETTINGS -----\n\n"; + } + if ($args =~ /--minutes=/i) + { + @data_in = split(/--minutes=/,$args); + $CLIminutes = $data_in[1]; + $CLIminutes =~ s/ .*$//gi; + $CLIminutes =~ s/\D//gi; + if ($CLIminutes > 999999) + {$CLIminutes=730;} + if ($Q < 1) + {print "\n----- MINUTES OVERRIDE: $CLIminutes -----\n\n";} + } + } + } +else + { + print "no command line options set\n"; + } +### end parsing run-time options ### +if ( (length($CLIminutes)<1) || ($CLIminutes < 1) ) + { + $CLIminutes = 1; + } + +$secX = time(); +($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); + +$now_epoch = ($secX); # now +($Nsec,$Nmin,$Nhour,$Nmday,$Nmon,$Nyear,$Nwday,$Nyday,$Nisdst) = localtime($now_epoch); +$Nyear = ($Nyear + 1900); +$Nmon++; +if ($Nmon < 10) {$Nmon = "0$Nmon";} +if ($Nmday < 10) {$Nmday = "0$Nmday";} +if ($Nhour < 10) {$Nhour = "0$Nhour";} +if ($Nmin < 10) {$Nmin = "0$Nmin";} +if ($Nsec < 10) {$Nsec = "0$Nsec";} +$now_time = "$Nyear-$Nmon-$Nmday $Nhour:$Nmin:$Nsec"; +$now_date = "$Nyear-$Nmon-$Nmday"; +$now_test_date = "$Nyear$Nmon$Nmday$Nhour$Nmin$Nsec"; + +$del_epoch = ($secX - 60); # 1 minute ago 0 seconds +($RMsec,$RMmin,$RMhour,$RMmday,$RMmon,$RMyear,$RMwday,$RMyday,$RMisdst) = localtime($del_epoch); +$RMyear = ($RMyear + 1900); +$RMmon++; +if ($RMmon < 10) {$RMmon = "0$RMmon";} +if ($RMmday < 10) {$RMmday = "0$RMmday";} +if ($RMhour < 10) {$RMhour = "0$RMhour";} +if ($RMmin < 10) {$RMmin = "0$RMmin";} +if ($RMsec < 10) {$RMsec = "0$RMsec";} +$del_time = "$RMyear-$RMmon-$RMmday $RMhour:$RMmin:00"; + +$Bdel_epoch = (($secX - (60 * $CLIminutes)) - 60); # X+1 minutes ago 0 seconds +($BRMsec,$BRMmin,$BRMhour,$BRMmday,$BRMmon,$BRMyear,$BRMwday,$BRMyday,$BRMisdst) = localtime($Bdel_epoch); +$BRMyear = ($BRMyear + 1900); +$BRMmon++; +if ($BRMmon < 10) {$BRMmon = "0$BRMmon";} +if ($BRMmday < 10) {$BRMmday = "0$BRMmday";} +if ($BRMhour < 10) {$BRMhour = "0$BRMhour";} +if ($BRMmin < 10) {$BRMmin = "0$BRMmin";} +if ($BRMsec < 10) {$BRMsec = "0$BRMsec";} +$Bdel_time = "$BRMyear-$BRMmon-$BRMmday $BRMhour:$BRMmin:00"; + +if (!$Q) {print "\n\n-- ADMIN_central_lead_repository.pl --\n\n";} +if (!$Q) {print "This script is designed take recently modified lead records from the vicidial_list\n";} +if (!$Q) {print "table and sync them to a central lead repository server during the day, then confirm\n";} +if (!$Q) {print "at night, then push back any updated records from the CLR back to the cluster database\n";} +if (!$Q) {print "early in the morning.\n";} +$begin_output = "$CLIminutes minutes ($Bdel_time -> $del_time |$Bdel_epoch$del_epoch| ) NOW: $now_time \n"; +if (!$Q) {print "$begin_output\n";} + +$process_output .= $begin_output; + +# default path to astguiclient configuration file: +$PATHconf = '/etc/astguiclient.conf'; + +open(conf, "$PATHconf") || die "can't open $PATHconf: $!\n"; +@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;} + if ( ($line =~ /^VARCS_server/) && ($CLICS_server < 1) ) + {$VARCS_server = $line; $VARCS_server =~ s/.*=//gi;} + if ( ($line =~ /^VARCS_database/) && ($CLICS_database < 1) ) + {$VARCS_database = $line; $VARCS_database =~ s/.*=//gi;} + if ( ($line =~ /^VARCS_user/) && ($CLICS_user < 1) ) + {$VARCS_user = $line; $VARCS_user =~ s/.*=//gi;} + if ( ($line =~ /^VARCS_pass/) && ($CLICS_pass < 1) ) + {$VARCS_pass = $line; $VARCS_pass =~ s/.*=//gi;} + if ( ($line =~ /^VARCS_port/) && ($CLICS_port < 1) ) + {$VARCS_port = $line; $VARCS_port =~ s/.*=//gi;} + $i++; + } + +# Customized Variables +$server_ip = $VARserver_ip; # Asterisk server IP + +# default path to Central Lead Repository configuration file: +$PATHclr = '/etc/vicidial_CLR.conf'; + +open(conf, "$PATHclr") || die "can't open $PATHclr: $!\n"; +@conf = ; +close(conf); +$i=0; +foreach(@conf) + { + $line = $conf[$i]; + $line =~ s/ |>|\n|\r|\t|\#.*|;.*//gi; + if ( ($line =~ /^VARCLR_server/) && ($CLICLR_server < 1) ) + {$VARCLR_server = $line; $VARCLR_server =~ s/.*=//gi;} + if ( ($line =~ /^VARCLR_database/) && ($CLICLR_database < 1) ) + {$VARCLR_database = $line; $VARCLR_database =~ s/.*=//gi;} + if ( ($line =~ /^VARCLR_user/) && ($CLICLR_user < 1) ) + {$VARCLR_user = $line; $VARCLR_user =~ s/.*=//gi;} + if ( ($line =~ /^VARCLR_pass/) && ($CLICLR_pass < 1) ) + {$VARCLR_pass = $line; $VARCLR_pass =~ s/.*=//gi;} + if ( ($line =~ /^VARCLR_port/) && ($CLICLR_port < 1) ) + {$VARCLR_port = $line; $VARCLR_port =~ s/.*=//gi;} + $i++; + } + +use DBI; +$dbhA = DBI->connect("DBI:mysql:$VARDB_database:$VARDB_server:$VARDB_port", "$VARDB_user", "$VARDB_pass") + or die "Couldn't connect to database: " . DBI->errstr; +$dbhB = DBI->connect("DBI:mysql:$VARCLR_database:$VARCLR_server:$VARCLR_port", "$VARCLR_user", "$VARCLR_pass") + or die "Couldn't connect to database: " . DBI->errstr; + +############################################# +##### Gather system_settings ##### +$stmtA = "SELECT count(*) FROM vicidial_list;"; +$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; + $MAINvl_ct = $aryA[0]; + if ($DB > 0) {print "MAIN Database test: $MAINvl_ct \n";} + } +$sthA->finish(); +########################################### + +############################################# +##### Test Central-Lead-Repository Database connection with query of vicidial_list table ##### +$stmtB = "SELECT count(*) FROM vicidial_list;"; +$sthB = $dbhB->prepare($stmtB) or die "preparing: ",$dbhB->errstr; +$sthB->execute or die "executing: $stmtB ", $dbhB->errstr; +$sthBrows=$sthB->rows; +if ($sthBrows > 0) + { + @aryB = $sthB->fetchrow_array; + $CLRvl_ct = $aryB[0]; + if ($DB > 0) {print "CLR Database test: $CLRvl_ct \n";} + } +$sthB->finish(); +########################################### + +if ($CALC_TEST > 0) + { + exit; + } + + + +################################################################################ +##### BEGIN settings update ORIGINAL to CLR db updates: campaigns, lists, dids, in-groups, users, etc... +################################################################################ +if ($SETTINGS_TO_CLR > 0) + { + if (!$Q) {print "\nStarting settings ORIGINAL to CLR update process...\n";} + + $clr_id=''; + $process_options=''; + + # insert clr_log entry into database + $stmtA = "INSERT INTO clr_log SET start_time=NOW(),begin_range='$Bdel_time',range_minutes='$CLIminutes',phase='BEGIN',server_ip='$server_ip',processing_log='';"; + $affected_rowsA = $dbhA->do($stmtA); + $stmtC = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtC) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtC ", $dbhA->errstr; + $sthArows=$sthA->rows; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $clr_id = $aryA[0]; + } + $sthA->finish(); + if ($DB) {print "clr_id: $clr_id \n";} + + $phase='SETTINGS_UPDATE'; + + ##################################### + ### BEGIN update each setting type + ##################################### + + $v=0; + $temp_type_ARY[$v] = 'users'; + $temp_typeS_ARY[$v] = 'user'; + $temp_table_ARY[$v] = 'vicidial_users'; + $temp_id_field_ARY[$v] = 'user'; + $temp_date_check_SQL_ARY[$v] = "modify_stamp >= \"$Bdel_time\""; + $temp_first_fields_ARY[$v] = "user,modify_stamp,UNIX_TIMESTAMP(modify_stamp)"; + $temp_date_field_ARY[$v] = 'modify_stamp'; + $fields_skip_list_ARY[$v] = "user,active"; + $fields_insert_list_ARY[$v] = ",active='N'"; + $SUBS_tables_list_ARY[$v] = "vicidial_inbound_group_agents,vicidial_campaign_agents"; + $SUBS_delete_first_ARY[$v] = 1; + $SUBS_tables_details_ARY[$v] = "vicidial_inbound_group_agents---group_id,vicidial_campaign_agents---campaign_id"; + + $v++; + $temp_type_ARY[$v] = 'lists'; + $temp_typeS_ARY[$v] = 'list'; + $temp_table_ARY[$v] = 'vicidial_lists'; + $temp_id_field_ARY[$v] = 'list_id'; + $temp_date_check_SQL_ARY[$v] = "list_changedate >= \"$Bdel_time\""; + $temp_first_fields_ARY[$v] = "list_id,list_changedate,UNIX_TIMESTAMP(list_changedate)"; + $temp_date_field_ARY[$v] = 'list_changedate'; + $fields_skip_list_ARY[$v] = "list_id,active"; + $fields_insert_list_ARY[$v] = ",active='N'"; + $SUBS_tables_list_ARY[$v] = ""; + $SUBS_delete_first_ARY[$v] = 0; + $SUBS_tables_details_ARY[$v] = ""; + + $v++; + $temp_type_ARY[$v] = 'dids'; + $temp_typeS_ARY[$v] = 'did'; + $temp_table_ARY[$v] = 'vicidial_inbound_dids'; + $temp_id_field_ARY[$v] = 'did_id'; + $temp_date_check_SQL_ARY[$v] = "modify_stamp >= \"$Bdel_time\""; + $temp_first_fields_ARY[$v] = "did_id,modify_stamp,UNIX_TIMESTAMP(modify_stamp)"; + $temp_date_field_ARY[$v] = 'modify_stamp'; + $fields_skip_list_ARY[$v] = "did_id,did_active"; + $fields_insert_list_ARY[$v] = ",did_active='N'"; + $SUBS_tables_list_ARY[$v] = ""; + $SUBS_delete_first_ARY[$v] = 0; + $SUBS_tables_details_ARY[$v] = ""; + + $v++; + $temp_type_ARY[$v] = 'in-groups'; + $temp_typeS_ARY[$v] = 'in-group'; + $temp_table_ARY[$v] = 'vicidial_inbound_groups'; + $temp_id_field_ARY[$v] = 'group_id'; + $temp_date_check_SQL_ARY[$v] = "modify_stamp >= \"$Bdel_time\""; + $temp_first_fields_ARY[$v] = "group_id,modify_stamp,UNIX_TIMESTAMP(modify_stamp)"; + $temp_date_field_ARY[$v] = 'modify_stamp'; + $fields_skip_list_ARY[$v] = "group_id,active"; + $fields_insert_list_ARY[$v] = ",active='N'"; + $SUBS_tables_list_ARY[$v] = ""; + $SUBS_delete_first_ARY[$v] = 0; + $SUBS_tables_details_ARY[$v] = ""; + + $v++; + $temp_type_ARY[$v] = 'campaigns'; + $temp_typeS_ARY[$v] = 'campaign'; + $temp_table_ARY[$v] = 'vicidial_campaigns'; + $temp_id_field_ARY[$v] = 'campaign_id'; + $temp_date_check_SQL_ARY[$v] = "campaign_changedate >= \"$Bdel_time\""; + $temp_first_fields_ARY[$v] = "campaign_id,campaign_changedate,UNIX_TIMESTAMP(campaign_changedate)"; + $temp_date_field_ARY[$v] = 'campaign_changedate'; + $fields_skip_list_ARY[$v] = "campaign_id,active"; + $fields_insert_list_ARY[$v] = ",active='N'"; + $SUBS_tables_list_ARY[$v] = "vicidial_campaign_statuses,vicidial_campaign_hotkeys"; + $SUBS_delete_first_ARY[$v] = 1; + $SUBS_tables_details_ARY[$v] = "vicidial_campaign_statuses---status,vicidial_campaign_hotkeys---hotkey"; + + # generate list of local affected tables, so we can back them up before starting sync + $e_ct=0; + while ($v >= $e_ct) + { + if ($e_ct > 0) {$dump_table_list .= " ";} + $dump_table_list .= "$temp_table_ARY[$e_ct]"; + if (length($SUBS_tables_list_ARY[$e_ct]) > 0) + { + $dump_table_list .= " $SUBS_tables_list_ARY[$e_ct]"; + } + $e_ct++; + } + $dump_table_list =~ s/,/ /gi; + + print "DEBUG: dump tables: |$dump_table_list|\n"; + + $v=0; + &populate_main_section; + + $secY = time(); + $secZ = ($secY - $secX); + +print "DEV EXIT! $secZ seconds\n"; +exit; + + # insert clr_log entry into database + $stmtA = "UPDATE clr_log SET phase='$phase',records_ct='$u_ct',length_in_sec='$secZ',processing_log='$process_output',options='$process_options' where clr_id='$clr_id';"; + $affected_rowsA = $dbhA->do($stmtA); + + + ##################################### + ### END update each setting type + ##################################### + + + $secY = time(); + $secZ = ($secY - $secX); + + # insert clr_log entry into database + $stmtA = "UPDATE clr_log SET phase='$phase',records_ct='$u_ct',length_in_sec='$secZ',processing_log='$process_output',options='$process_options' where clr_id='$clr_id';"; + $affected_rowsA = $dbhA->do($stmtA); + } +################################################################################ +##### END settings update ORIGINAL to CLR db updates: campaigns, lists, dids, in-groups, users +################################################################################ + +print "DEV EXIT! $secZ seconds\n"; +exit; + + + + + + + + + + + + + + +################################################################################ +##### BEGIN incremental or nightly ORIGINAL to CLR db updates +################################################################################ +if ($BACK_TO_CLUSTERS < 1) + { + if (!$Q) {print "\nStarting Central-Lead-Repository calling-time ORIGINAL to CLR process...\n";} + + $clr_id=''; + # insert clr_log entry into database + $stmtA = "INSERT INTO clr_log SET start_time=NOW(),begin_range='$Bdel_time',range_minutes='$CLIminutes',phase='BEGIN',server_ip='$server_ip',processing_log='';"; + $affected_rowsA = $dbhA->do($stmtA); + $stmtC = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtC) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtC ", $dbhA->errstr; + $sthArows=$sthA->rows; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $clr_id = $aryA[0]; + } + $sthA->finish(); + if ($DB) {print "clr_id: $clr_id \n";} + + $vicidial_list_ct=0; + $vicidial_log_ct=0; + $vicidial_closer_log_ct=0; + + if ($NIGHTLY_UPDATE > 0) + { + $phase='NIGHTLY_UPDATE'; + ### Check if there are any leads modified since X minutes ago + $stmtA = "SELECT count(*) from vicidial_list where modify_date >= \"$Bdel_time\";"; + $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; + $vicidial_list_ct = $aryA[0]; + } + $sthA->finish(); + } + else + { + $phase='DAYTIME_INCREMENTAL'; + ### Check if there are any calls within the previous X minutes + $stmtA = "SELECT count(*) from vicidial_closer_log where modify_stamp >= \"$Bdel_time\" and modify_stamp < \"$del_time\";"; + $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; + $vicidial_closer_log_ct = $aryA[0]; + } + $sthA->finish(); + + $stmtA = "SELECT count(*) from vicidial_log where modify_stamp >= \"$Bdel_time\" and modify_stamp < \"$del_time\";"; + $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; + $vicidial_log_ct = $aryA[0]; + } + $sthA->finish(); + } + + if ( ($vicidial_closer_log_ct < 1) && ($vicidial_log_ct < 1) && ($vicidial_list_ct < 1) ) + { + if (!$Q) {print "No recent calls or changed leads, nothing to do, exiting... \n";} + exit; + } + else + { + if (!$Q) {print "Recent calls - Outbound: $vicidial_log_ct Inbound: $vicidial_closer_log_ct Leads: $vicidial_list_ct \n";} + + if ($NIGHTLY_UPDATE > 0) + { + $o_ct=0; + $stmtA = "SELECT lead_id from vicidial_list where modify_date >= \"$Bdel_time\" limit 10000000;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + while ($sthArows > $o_ct) + { + @aryA = $sthA->fetchrow_array; + $updated_LEADS[$o_ct] = $aryA[0]; + $o_ct++; + } + $sthA->finish(); + $updated_LEADSsize = $o_ct; + } + else + { + $o_ct=0; + $stmtA = "SELECT lead_id from vicidial_log where modify_stamp >= \"$Bdel_time\" and modify_stamp < \"$del_time\" limit 10000000;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + while ($sthArows > $o_ct) + { + @aryA = $sthA->fetchrow_array; + $updated_LEADS[$o_ct] = $aryA[0]; + $o_ct++; + } + $sthA->finish(); + + $i_ct=0; + $stmtA = "SELECT lead_id from vicidial_closer_log where modify_stamp >= \"$Bdel_time\" and modify_stamp < \"$del_time\" limit 10000000;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + while ($sthArows > $o_ct) + { + @aryA = $sthA->fetchrow_array; + $updated_LEADS[$o_ct] = $aryA[0]; + $i_ct++; + $o_ct++; + } + $sthA->finish(); + + # remove duplicate lead_ids + my %h1; + foreach my $x (@updated_LEADS) + { + $h1{$x}=1; + } + @updated_LEADS=keys%h1; + $updated_LEADSsize = @updated_LEADS; + $updated_LEADSdupCT = ($o_ct - $updated_LEADSsize); + + $duplicate_output = "Duplicate check - Dups: $updated_LEADSdupCT Unique: $updated_LEADSsize \n"; + if (!$Q) {print $duplicate_output;} + $process_output .= $duplicate_output; + } + + ### loop through all leads, gather lead data, compare to record on CLR server, update/insert if needed + $u_ct=0; + $CLRupdate_ct=0; $CLRupdate_aff=0; + $CLRinsert_ct=0; $CLRinsert_aff=0; + $CLRnochange_ct=0; + while ($updated_LEADSsize > $u_ct) + { + $update_phase=1; + # gather lead data from ORIGINAL database + $stmtA = "SELECT lead_id,entry_date,modify_date,status,user,vendor_lead_code,source_id,list_id,gmt_offset_now,called_since_last_reset,phone_code,phone_number,title,first_name,middle_initial,last_name,address1,address2,address3,city,state,province,postal_code,country_code,gender,date_of_birth,alt_phone,email,security_phrase,comments,called_count,last_local_call_time,rank,owner,entry_list_id from vicidial_list where lead_id=$updated_LEADS[$u_ct];"; + $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; + $lead_id = $aryA[0]; + if (defined $aryA[1]) {$entry_date = $aryA[1]; $entry_dateSQL = "\"$aryA[1]\"";} + else {$entry_dateSQL = 'NULL'; $entry_date='NULL';} + if (defined $aryA[2]) {$modify_date = $aryA[2]; $modify_dateSQL = "\"$aryA[2]\"";} + else {$modify_dateSQL = 'NULL'; $modify_date='NULL';} + if (defined $aryA[3]) {$status = $aryA[3]; $statusSQL = "\"$aryA[3]\"";} + else {$statusSQL = 'NULL'; $status='NULL';} + if (defined $aryA[4]) {$user = $aryA[4]; $userSQL = "\"$aryA[4]\"";} + else {$userSQL = 'NULL'; $user='NULL';} + if (defined $aryA[5]) {$vendor_lead_code = $aryA[5]; $vendor_lead_codeSQL = "\"$aryA[5]\"";} + else {$vendor_lead_codeSQL = 'NULL'; $vendor_lead_code='NULL';} + if (defined $aryA[6]) {$source_id = $aryA[6]; $source_idSQL = "\"$aryA[6]\"";} + else {$source_idSQL = 'NULL'; $source_id='NULL';} + if (defined $aryA[7]) {$list_id = $aryA[7]; $list_idSQL = "\"$aryA[7]\"";} + else {$list_idSQL = 'NULL'; $list_id='NULL';} + if (defined $aryA[8]) {$gmt_offset_now = $aryA[8]; $gmt_offset_nowSQL = "\"$aryA[8]\"";} + else {$gmt_offset_nowSQL = 'NULL'; $gmt_offset_now='NULL';} + if (defined $aryA[9]) {$called_since_last_reset = $aryA[9]; $called_since_last_resetSQL = "\"$aryA[9]\"";} + else {$called_since_last_resetSQL = 'NULL'; $called_since_last_reset='NULL';} + if (defined $aryA[10]) {$phone_code = $aryA[10]; $phone_codeSQL = "\"$aryA[10]\"";} + else {$phone_codeSQL = 'NULL'; $phone_code='NULL';} + if (defined $aryA[11]) {$phone_number = $aryA[11]; $phone_numberSQL = "\"$aryA[11]\"";} + else {$phone_numberSQL = 'NULL'; $phone_number='NULL';} + if (defined $aryA[12]) {$title = $aryA[12]; $titleSQL = "\"$aryA[12]\"";} + else {$titleSQL = 'NULL'; $title='NULL';} + if (defined $aryA[13]) {$first_name = $aryA[13]; $first_nameSQL = "\"$aryA[13]\"";} + else {$first_nameSQL = 'NULL'; $first_name='NULL';} + if (defined $aryA[14]) {$middle_initial = $aryA[14]; $middle_initialSQL = "\"$aryA[14]\"";} + else {$middle_initialSQL = 'NULL'; $middle_initial='NULL';} + if (defined $aryA[15]) {$last_name = $aryA[15]; $last_nameSQL = "\"$aryA[15]\"";} + else {$last_nameSQL = 'NULL'; $last_name='NULL';} + if (defined $aryA[16]) {$address1 = $aryA[16]; $address1SQL = "\"$aryA[16]\"";} + else {$address1SQL = 'NULL'; $address1='NULL';} + if (defined $aryA[17]) {$address2 = $aryA[17]; $address2SQL = "\"$aryA[17]\"";} + else {$address2SQL = 'NULL'; $address2='NULL';} + if (defined $aryA[18]) {$address3 = $aryA[18]; $address3SQL = "\"$aryA[18]\"";} + else {$address3SQL = 'NULL'; $address3='NULL';} + if (defined $aryA[19]) {$city = $aryA[19]; $citySQL = "\"$aryA[19]\"";} + else {$citySQL = 'NULL'; $city='NULL';} + if (defined $aryA[20]) {$state = $aryA[20]; $stateSQL = "\"$aryA[20]\"";} + else {$stateSQL = 'NULL'; $state='NULL';} + if (defined $aryA[21]) {$province = $aryA[21]; $provinceSQL = "\"$aryA[21]\"";} + else {$provinceSQL = 'NULL'; $province='NULL';} + if (defined $aryA[22]) {$postal_code = $aryA[22]; $postal_codeSQL = "\"$aryA[22]\"";} + else {$postal_codeSQL = 'NULL'; $postal_code='NULL';} + if (defined $aryA[23]) {$country_code = $aryA[23]; $country_codeSQL = "\"$aryA[23]\"";} + else {$country_codeSQL = 'NULL'; $country_code='NULL';} + if (defined $aryA[24]) {$gender = $aryA[24]; $genderSQL = "\"$aryA[24]\"";} + else {$genderSQL = 'NULL'; $gender='NULL';} + if (defined $aryA[25]) {$date_of_birth = $aryA[25]; $date_of_birthSQL = "\"$aryA[25]\"";} + else {$date_of_birthSQL = 'NULL'; $date_of_birth='NULL';} + if (defined $aryA[26]) {$alt_phone = $aryA[26]; $alt_phoneSQL = "\"$aryA[26]\"";} + else {$alt_phoneSQL = 'NULL'; $alt_phone='NULL';} + if (defined $aryA[27]) {$email = $aryA[27]; $emailSQL = "\"$aryA[27]\"";} + else {$emailSQL = 'NULL'; $email='NULL';} + if (defined $aryA[28]) {$security_phrase = $aryA[28]; $security_phraseSQL = "\"$aryA[28]\"";} + else {$security_phraseSQL = 'NULL'; $security_phrase='NULL';} + if (defined $aryA[29]) {$comments = $aryA[29]; $commentsSQL = "\"$aryA[29]\"";} + else {$commentsSQL = 'NULL'; $comments='NULL';} + if (defined $aryA[30]) {$called_count = $aryA[30]; $called_countSQL = "\"$aryA[30]\"";} + else {$called_countSQL = 'NULL'; $called_count='NULL';} + if (defined $aryA[31]) {$last_local_call_time = $aryA[31]; $last_local_call_timeSQL = "\"$aryA[31]\"";} + else {$last_local_call_timeSQL = 'NULL'; $last_local_call_time='NULL';} + if (defined $aryA[32]) {$rank = $aryA[32]; $rankSQL = "\"$aryA[32]\"";} + else {$rankSQL = 'NULL'; $rank='NULL';} + if (defined $aryA[33]) {$owner = $aryA[33]; $ownerSQL = "\"$aryA[33]\"";} + else {$ownerSQL = 'NULL'; $owner='NULL';} + if (defined $aryA[34]) {$entry_list_id = $aryA[34]; $entry_list_idSQL = "\"$aryA[34]\"";} + else {$entry_list_idSQL = 'NULL'; $entry_list_id='NULL';} + $Acompare = "$entry_date|$status|$user|$vendor_lead_code|$source_id|$list_id|$gmt_offset_now|$called_since_last_reset|$phone_code|$phone_number|$title|$first_name|$middle_initial|$last_name|$address1|$address2|$address3|$city|$state|$province|$postal_code|$country_code|$gender|$date_of_birth|$alt_phone|$email|$security_phrase|$comments|$called_count|$last_local_call_time|$rank|$owner|$entry_list_id"; + } + else + { + $update_phase=0; + if ($DBX > 0) + {print "DEBUG: No ORIGINAL lead found for lead $updated_LEADS[$u_ct], skipping \n";} + } + $sthA->finish(); + + # gather lead data from CLR database + $stmtB = "SELECT lead_id,entry_date,modify_date,status,user,vendor_lead_code,source_id,list_id,gmt_offset_now,called_since_last_reset,phone_code,phone_number,title,first_name,middle_initial,last_name,address1,address2,address3,city,state,province,postal_code,country_code,gender,date_of_birth,alt_phone,email,security_phrase,comments,called_count,last_local_call_time,rank,owner,entry_list_id from vicidial_list where lead_id=$updated_LEADS[$u_ct];"; + $sthB = $dbhB->prepare($stmtB) or die "preparing: ",$dbhB->errstr; + $sthB->execute or die "executing: $stmtB ", $dbhB->errstr; + $sthBrows=$sthB->rows; + if ($sthBrows > 0) + { + @aryB = $sthB->fetchrow_array; + $Blead_id = $aryB[0]; + if (defined $aryB[1]) {$Bentry_date = $aryB[1]; $Bentry_dateSQL = "\"$aryB[1]\"";} + else {$Bentry_dateSQL = 'NULL'; $Bentry_date='NULL';} + if (defined $aryB[2]) {$Bmodify_date = $aryB[2]; $Bmodify_dateSQL = "\"$aryB[2]\"";} + else {$Bmodify_dateSQL = 'NULL'; $Bmodify_date='NULL';} + if (defined $aryB[3]) {$Bstatus = $aryB[3]; $BstatusSQL = "\"$aryB[3]\"";} + else {$BstatusSQL = 'NULL'; $Bstatus='NULL';} + if (defined $aryB[4]) {$Buser = $aryB[4]; $BuserSQL = "\"$aryB[4]\"";} + else {$BuserSQL = 'NULL'; $Buser='NULL';} + if (defined $aryB[5]) {$Bvendor_lead_code = $aryB[5]; $Bvendor_lead_codeSQL = "\"$aryB[5]\"";} + else {$Bvendor_lead_codeSQL = 'NULL'; $Bvendor_lead_code='NULL';} + if (defined $aryB[6]) {$Bsource_id = $aryB[6]; $Bsource_idSQL = "\"$aryB[6]\"";} + else {$Bsource_idSQL = 'NULL'; $Bsource_id='NULL';} + if (defined $aryB[7]) {$Blist_id = $aryB[7]; $Blist_idSQL = "\"$aryB[7]\"";} + else {$Blist_idSQL = 'NULL'; $Blist_id='NULL';} + if (defined $aryB[8]) {$Bgmt_offset_now = $aryB[8]; $Bgmt_offset_nowSQL = "\"$aryB[8]\"";} + else {$Bgmt_offset_nowSQL = 'NULL'; $Bgmt_offset_now='NULL';} + if (defined $aryB[9]) {$Bcalled_since_last_reset = $aryB[9]; $Bcalled_since_last_resetSQL = "\"$aryB[9]\"";} + else {$Bcalled_since_last_resetSQL = 'NULL'; $Bcalled_since_last_reset='NULL';} + if (defined $aryB[10]) {$Bphone_code = $aryB[10]; $Bphone_codeSQL = "\"$aryB[10]\"";} + else {$Bphone_codeSQL = 'NULL'; $Bphone_code='NULL';} + if (defined $aryB[11]) {$Bphone_number = $aryB[11]; $Bphone_numberSQL = "\"$aryB[11]\"";} + else {$Bphone_numberSQL = 'NULL'; $Bphone_number='NULL';} + if (defined $aryB[12]) {$Btitle = $aryB[12]; $BtitleSQL = "\"$aryB[12]\"";} + else {$BtitleSQL = 'NULL'; $Btitle='NULL';} + if (defined $aryB[13]) {$Bfirst_name = $aryB[13]; $Bfirst_nameSQL = "\"$aryB[13]\"";} + else {$Bfirst_nameSQL = 'NULL'; $Bfirst_name='NULL';} + if (defined $aryB[14]) {$Bmiddle_initial = $aryB[14]; $Bmiddle_initialSQL = "\"$aryB[14]\"";} + else {$Bmiddle_initialSQL = 'NULL'; $Bmiddle_initial='NULL';} + if (defined $aryB[15]) {$Blast_name = $aryB[15]; $Blast_nameSQL = "\"$aryB[15]\"";} + else {$Blast_nameSQL = 'NULL'; $Blast_name='NULL';} + if (defined $aryB[16]) {$Baddress1 = $aryB[16]; $Baddress1SQL = "\"$aryB[16]\"";} + else {$Baddress1SQL = 'NULL'; $Baddress1='NULL';} + if (defined $aryB[17]) {$Baddress2 = $aryB[17]; $Baddress2SQL = "\"$aryB[17]\"";} + else {$Baddress2SQL = 'NULL'; $Baddress2='NULL';} + if (defined $aryB[18]) {$Baddress3 = $aryB[18]; $Baddress3SQL = "\"$aryB[18]\"";} + else {$Baddress3SQL = 'NULL'; $Baddress3='NULL';} + if (defined $aryB[19]) {$Bcity = $aryB[19]; $BcitySQL = "\"$aryB[19]\"";} + else {$BcitySQL = 'NULL'; $Bcity='NULL';} + if (defined $aryB[20]) {$Bstate = $aryB[20]; $BstateSQL = "\"$aryB[20]\"";} + else {$BstateSQL = 'NULL'; $Bstate='NULL';} + if (defined $aryB[21]) {$Bprovince = $aryB[21]; $BprovinceSQL = "\"$aryB[21]\"";} + else {$BprovinceSQL = 'NULL'; $Bprovince='NULL';} + if (defined $aryB[22]) {$Bpostal_code = $aryB[22]; $Bpostal_codeSQL = "\"$aryB[22]\"";} + else {$Bpostal_codeSQL = 'NULL'; $Bpostal_code='NULL';} + if (defined $aryB[23]) {$Bcountry_code = $aryB[23]; $Bcountry_codeSQL = "\"$aryB[23]\"";} + else {$Bcountry_codeSQL = 'NULL'; $Bcountry_code='NULL';} + if (defined $aryB[24]) {$Bgender = $aryB[24]; $BgenderSQL = "\"$aryB[24]\"";} + else {$BgenderSQL = 'NULL'; $Bgender='NULL';} + if (defined $aryB[25]) {$Bdate_of_birth = $aryB[25]; $Bdate_of_birthSQL = "\"$aryB[25]\"";} + else {$Bdate_of_birthSQL = 'NULL'; $Bdate_of_birth='NULL';} + if (defined $aryB[26]) {$Balt_phone = $aryB[26]; $Balt_phoneSQL = "\"$aryB[26]\"";} + else {$Balt_phoneSQL = 'NULL'; $Balt_phone='NULL';} + if (defined $aryB[27]) {$Bemail = $aryB[27]; $BemailSQL = "\"$aryB[27]\"";} + else {$BemailSQL = 'NULL'; $Bemail='NULL';} + if (defined $aryB[28]) {$Bsecurity_phrase = $aryB[28]; $Bsecurity_phraseSQL = "\"$aryB[28]\"";} + else {$Bsecurity_phraseSQL = 'NULL'; $Bsecurity_phrase='NULL';} + if (defined $aryB[29]) {$Bcomments = $aryB[29]; $BcommentsSQL = "\"$aryB[29]\"";} + else {$BcommentsSQL = 'NULL'; $Bcomments='NULL';} + if (defined $aryB[30]) {$Bcalled_count = $aryB[30]; $Bcalled_countSQL = "\"$aryB[30]\"";} + else {$Bcalled_countSQL = 'NULL'; $Bcalled_count='NULL';} + if (defined $aryB[31]) {$Blast_local_call_time = $aryB[31]; $Blast_local_call_timeSQL = "\"$aryB[31]\"";} + else {$Blast_local_call_timeSQL = 'NULL'; $Blast_local_call_time='NULL';} + if (defined $aryB[32]) {$Brank = $aryB[32]; $BrankSQL = "\"$aryB[32]\"";} + else {$BrankSQL = 'NULL'; $Brank='NULL';} + if (defined $aryB[33]) {$Bowner = $aryB[33]; $BownerSQL = "\"$aryB[33]\"";} + else {$BownerSQL = 'NULL'; $Bowner='NULL';} + if (defined $aryB[34]) {$Bentry_list_id = $aryB[34]; $Bentry_list_idSQL = "\"$aryB[34]\"";} + else {$Bentry_list_idSQL = 'NULL'; $Bentry_list_id='NULL';} + + $Bcompare = "$Bentry_date|$Bstatus|$Buser|$Bvendor_lead_code|$Bsource_id|$Blist_id|$Bgmt_offset_now|$Bcalled_since_last_reset|$Bphone_code|$Bphone_number|$Btitle|$Bfirst_name|$Bmiddle_initial|$Blast_name|$Baddress1|$Baddress2|$Baddress3|$Bcity|$Bstate|$Bprovince|$Bpostal_code|$Bcountry_code|$Bgender|$Bdate_of_birth|$Balt_phone|$Bemail|$Bsecurity_phrase|$Bcomments|$Bcalled_count|$Blast_local_call_time|$Brank|$Bowner|$Bentry_list_id"; + } + else + { + if ($update_phase > 0) + { + $update_phase=2; + if ($DBX > 0) {print "DEBUG: No CLR match found for lead $updated_LEADS[$u_ct], inserting instead \n";} + } + } + $sthB->finish(); + + if ($update_phase >= 2) + { + # insert lead into CLR database + + $stmtB = "INSERT INTO vicidial_list SET lead_id='$lead_id',entry_date=$entry_dateSQL,modify_date=$modify_dateSQL,status=$statusSQL,user=$userSQL,vendor_lead_code=$vendor_lead_codeSQL,source_id=$source_idSQL,list_id=$list_idSQL,gmt_offset_now=$gmt_offset_nowSQL,called_since_last_reset=$called_since_last_resetSQL,phone_code=$phone_codeSQL,phone_number=$phone_numberSQL,title=$titleSQL,first_name=$first_nameSQL,middle_initial=$middle_initialSQL,last_name=$last_nameSQL,address1=$address1SQL,address2=$address2SQL,address3=$address3SQL,city=$citySQL,state=$stateSQL,province=$provinceSQL,postal_code=$postal_codeSQL,country_code=$country_codeSQL,gender=$genderSQL,date_of_birth=$date_of_birthSQL,alt_phone=$alt_phoneSQL,email=$emailSQL,security_phrase=$security_phraseSQL,comments=$commentsSQL,called_count=$called_countSQL,last_local_call_time=$last_local_call_timeSQL,rank=$rankSQL,owner=$ownerSQL,entry_list_id=$entry_list_idSQL;"; + $affected_rowsB = $dbhB->do($stmtB); + $CLRinsert_aff = ($CLRinsert_aff + $affected_rowsB); + if ($DBX > 0) {print "DEBUG: CLR lead inserted $updated_LEADS[$u_ct]: $affected_rowsB|$stmtB| \n";} + + $CLRinsert_ct++; + } + else + { + # compare ORIGINAL and CLR lead data to see if update is needed + if ($Acompare eq $Bcompare) + { + $update_phase=0; + if ($DBX > 0) {print "DEBUG: ORIGINAL and CLR lead data is identical: $updated_LEADS[$u_ct] \n";} + } + if ($DBX > 0) {print "$lead_id compare:\n$Acompare \n$Bcompare \n";} + + if ($update_phase >= 1) + { + # update existing lead in CLR database + $stmtB = "UPDATE vicidial_list SET entry_date=$entry_dateSQL,modify_date=$modify_dateSQL,status=$statusSQL,user=$userSQL,vendor_lead_code=$vendor_lead_codeSQL,source_id=$source_idSQL,list_id=$list_idSQL,gmt_offset_now=$gmt_offset_nowSQL,called_since_last_reset=$called_since_last_resetSQL,phone_code=$phone_codeSQL,phone_number=$phone_numberSQL,title=$titleSQL,first_name=$first_nameSQL,middle_initial=$middle_initialSQL,last_name=$last_nameSQL,address1=$address1SQL,address2=$address2SQL,address3=$address3SQL,city=$citySQL,state=$stateSQL,province=$provinceSQL,postal_code=$postal_codeSQL,country_code=$country_codeSQL,gender=$genderSQL,date_of_birth=$date_of_birthSQL,alt_phone=$alt_phoneSQL,email=$emailSQL,security_phrase=$security_phraseSQL,comments=$commentsSQL,called_count=$called_countSQL,last_local_call_time=$last_local_call_timeSQL,rank=$rankSQL,owner=$ownerSQL,entry_list_id=$entry_list_idSQL where lead_id='$lead_id';"; + $affected_rowsB = $dbhB->do($stmtB); + $CLRupdate_aff = ($CLRupdate_aff + $affected_rowsB); + if ($DBX > 0) {print "DEBUG: CLR lead updated $updated_LEADS[$u_ct]: $affected_rowsB|$stmtB| \n";} + + $CLRupdate_ct++; + } + else + { + # no change needed to lead in CLR database + $CLRnochange_ct++; + } + } + + $u_ct++; + if ($Q < 1) + { + if ($u_ct =~ /100$/i) {print STDERR "> $u_ct / $updated_LEADSsize \r";} + if ($u_ct =~ /200$/i) {print STDERR "-> $u_ct / $updated_LEADSsize \r";} + if ($u_ct =~ /300$/i) {print STDERR " -> $u_ct / $updated_LEADSsize \r";} + if ($u_ct =~ /400$/i) {print STDERR " -> $u_ct / $updated_LEADSsize \r";} + if ($u_ct =~ /500$/i) {print STDERR " -> $u_ct / $updated_LEADSsize \r";} + if ($u_ct =~ /600$/i) {print STDERR " -> $u_ct / $updated_LEADSsize \r";} + if ($u_ct =~ /700$/i) {print STDERR " -> $u_ct / $updated_LEADSsize \r";} + if ($u_ct =~ /800$/i) {print STDERR " -> $u_ct / $updated_LEADSsize \r";} + if ($u_ct =~ /900$/i) {print STDERR " -> $u_ct / $updated_LEADSsize \r";} + if ($u_ct =~ /000$/i) {print STDERR " ->$u_ct / $updated_LEADSsize \r";} + if ($u_ct =~ /0000$/i) + { + $secY = time(); + $secZ = ($secY - $secX); + print "$u_ct|$CLRupdate_ct|$CLRinsert_ct|$CLRnochange_ct| $secZ sec \n"; + } + } + } + } + + + $lead_output = "CLR lead updates: $CLRupdate_ct ($CLRupdate_aff) \n"; + $lead_output .= "CLR lead inserts: $CLRinsert_ct ($CLRinsert_aff) \n"; + $lead_output .= "CLR lead no changes: $CLRnochange_ct \n"; + if (!$Q) {print $lead_output;} + + $process_output .= $lead_output; + + $secY = time(); + $secZ = ($secY - $secX); + + # insert clr_log entry into database + $stmtA = "UPDATE clr_log SET phase='$phase',records_ct='$u_ct',length_in_sec='$secZ',processing_log='$process_output' where clr_id='$clr_id';"; + $affected_rowsA = $dbhA->do($stmtA); + } +################################################################################ +##### END incremental or nightly ORIGINAL to CLR db updates +################################################################################ + + + + +################################################################################ +##### BEGIN morning CLR to ORIGINAL db updates +################################################################################ +else + { + if (!$Q) {print "\nStarting Central-Lead-Repository CLR to ORIGINAL process...\n";} + + $clr_id=''; + # insert clr_log entry into database + $stmtA = "INSERT INTO clr_log SET start_time=NOW(),begin_range='$Bdel_time',range_minutes='$CLIminutes',phase='BEGIN',server_ip='$server_ip',processing_log='';"; + $affected_rowsA = $dbhA->do($stmtA); + $stmtC = "SELECT LAST_INSERT_ID() LIMIT 1;"; + $sthA = $dbhA->prepare($stmtC) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtC ", $dbhA->errstr; + $sthArows=$sthA->rows; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $clr_id = $aryA[0]; + } + $sthA->finish(); + if ($DB) {print "clr_id: $clr_id \n";} + + $vicidial_list_ct=0; + $vicidial_log_ct=0; + $vicidial_closer_log_ct=0; + + $phase='MORNING_UPDATE'; + ### Check if there are any leads modified since X minutes ago + $stmtB = "SELECT count(*) from vicidial_list where modify_date >= \"$Bdel_time\";"; + $sthB = $dbhB->prepare($stmtB) or die "preparing: ",$dbhB->errstr; + $sthB->execute or die "executing: $stmtB ", $dbhB->errstr; + $sthBrows=$sthB->rows; + if ($sthBrows > 0) + { + @aryB = $sthB->fetchrow_array; + $vicidial_list_ct = $aryB[0]; + } + $sthB->finish(); + + if ($vicidial_list_ct < 1) + { + if (!$Q) {print "No recent changed leads, nothing to do, exiting... \n";} + exit; + } + else + { + if (!$Q) {print "Recent changed Leads: $vicidial_list_ct \n";} + + $o_ct=0; + $stmtB = "SELECT lead_id from vicidial_list where modify_date >= \"$Bdel_time\" limit 10000000;"; + $sthB = $dbhB->prepare($stmtB) or die "preparing: ",$dbhB->errstr; + $sthB->execute or die "executing: $stmtB ", $dbhB->errstr; + $sthBrows=$sthB->rows; + while ($sthBrows > $o_ct) + { + @aryB = $sthB->fetchrow_array; + $updated_LEADS[$o_ct] = $aryB[0]; + $o_ct++; + } + $sthB->finish(); + $updated_LEADSsize = $o_ct; + + ### loop through all leads, gather lead data, compare to record on CLR server, update/insert if needed + $u_ct=0; + $CLRupdate_ct=0; $CLRupdate_aff=0; + $CLRreverse_update_ct=0; $CLRreverse_update_aff=0; + $CLRinsert_ct=0; $CLRinsert_aff=0; + $CLRnochange_ct=0; + while ($updated_LEADSsize > $u_ct) + { + $update_phase=1; + # gather lead data from CLR database + $stmtB = "SELECT lead_id,entry_date,modify_date,status,user,vendor_lead_code,source_id,list_id,gmt_offset_now,called_since_last_reset,phone_code,phone_number,title,first_name,middle_initial,last_name,address1,address2,address3,city,state,province,postal_code,country_code,gender,date_of_birth,alt_phone,email,security_phrase,comments,called_count,last_local_call_time,rank,owner,entry_list_id,UNIX_TIMESTAMP(modify_date) from vicidial_list where lead_id=$updated_LEADS[$u_ct];"; + $sthB = $dbhB->prepare($stmtB) or die "preparing: ",$dbhB->errstr; + $sthB->execute or die "executing: $stmtB ", $dbhB->errstr; + $sthBrows=$sthB->rows; + if ($sthBrows > 0) + { + @aryB = $sthB->fetchrow_array; + $lead_id = $aryB[0]; + if (defined $aryB[1]) {$entry_date = $aryB[1]; $entry_dateSQL = "\"$aryB[1]\"";} + else {$entry_dateSQL = 'NULL'; $entry_date='NULL';} + if (defined $aryB[2]) {$modify_date = $aryB[2]; $modify_dateSQL = "\"$aryB[2]\"";} + else {$modify_dateSQL = 'NULL'; $modify_date='NULL';} + if (defined $aryB[3]) {$status = $aryB[3]; $statusSQL = "\"$aryB[3]\"";} + else {$statusSQL = 'NULL'; $status='NULL';} + if (defined $aryB[4]) {$user = $aryB[4]; $userSQL = "\"$aryB[4]\"";} + else {$userSQL = 'NULL'; $user='NULL';} + if (defined $aryB[5]) {$vendor_lead_code = $aryB[5]; $vendor_lead_codeSQL = "\"$aryB[5]\"";} + else {$vendor_lead_codeSQL = 'NULL'; $vendor_lead_code='NULL';} + if (defined $aryB[6]) {$source_id = $aryB[6]; $source_idSQL = "\"$aryB[6]\"";} + else {$source_idSQL = 'NULL'; $source_id='NULL';} + if (defined $aryB[7]) {$list_id = $aryB[7]; $list_idSQL = "\"$aryB[7]\"";} + else {$list_idSQL = 'NULL'; $list_id='NULL';} + if (defined $aryB[8]) {$gmt_offset_now = $aryB[8]; $gmt_offset_nowSQL = "\"$aryB[8]\"";} + else {$gmt_offset_nowSQL = 'NULL'; $gmt_offset_now='NULL';} + if (defined $aryB[9]) {$called_since_last_reset = $aryB[9]; $called_since_last_resetSQL = "\"$aryB[9]\"";} + else {$called_since_last_resetSQL = 'NULL'; $called_since_last_reset='NULL';} + if (defined $aryB[10]) {$phone_code = $aryB[10]; $phone_codeSQL = "\"$aryB[10]\"";} + else {$phone_codeSQL = 'NULL'; $phone_code='NULL';} + if (defined $aryB[11]) {$phone_number = $aryB[11]; $phone_numberSQL = "\"$aryB[11]\"";} + else {$phone_numberSQL = 'NULL'; $phone_number='NULL';} + if (defined $aryB[12]) {$title = $aryB[12]; $titleSQL = "\"$aryB[12]\"";} + else {$titleSQL = 'NULL'; $title='NULL';} + if (defined $aryB[13]) {$first_name = $aryB[13]; $first_nameSQL = "\"$aryB[13]\"";} + else {$first_nameSQL = 'NULL'; $first_name='NULL';} + if (defined $aryB[14]) {$middle_initial = $aryB[14]; $middle_initialSQL = "\"$aryB[14]\"";} + else {$middle_initialSQL = 'NULL'; $middle_initial='NULL';} + if (defined $aryB[15]) {$last_name = $aryB[15]; $last_nameSQL = "\"$aryB[15]\"";} + else {$last_nameSQL = 'NULL'; $last_name='NULL';} + if (defined $aryB[16]) {$address1 = $aryB[16]; $address1SQL = "\"$aryB[16]\"";} + else {$address1SQL = 'NULL'; $address1='NULL';} + if (defined $aryB[17]) {$address2 = $aryB[17]; $address2SQL = "\"$aryB[17]\"";} + else {$address2SQL = 'NULL'; $address2='NULL';} + if (defined $aryB[18]) {$address3 = $aryB[18]; $address3SQL = "\"$aryB[18]\"";} + else {$address3SQL = 'NULL'; $address3='NULL';} + if (defined $aryB[19]) {$city = $aryB[19]; $citySQL = "\"$aryB[19]\"";} + else {$citySQL = 'NULL'; $city='NULL';} + if (defined $aryB[20]) {$state = $aryB[20]; $stateSQL = "\"$aryB[20]\"";} + else {$stateSQL = 'NULL'; $state='NULL';} + if (defined $aryB[21]) {$province = $aryB[21]; $provinceSQL = "\"$aryB[21]\"";} + else {$provinceSQL = 'NULL'; $province='NULL';} + if (defined $aryB[22]) {$postal_code = $aryB[22]; $postal_codeSQL = "\"$aryB[22]\"";} + else {$postal_codeSQL = 'NULL'; $postal_code='NULL';} + if (defined $aryB[23]) {$country_code = $aryB[23]; $country_codeSQL = "\"$aryB[23]\"";} + else {$country_codeSQL = 'NULL'; $country_code='NULL';} + if (defined $aryB[24]) {$gender = $aryB[24]; $genderSQL = "\"$aryB[24]\"";} + else {$genderSQL = 'NULL'; $gender='NULL';} + if (defined $aryB[25]) {$date_of_birth = $aryB[25]; $date_of_birthSQL = "\"$aryB[25]\"";} + else {$date_of_birthSQL = 'NULL'; $date_of_birth='NULL';} + if (defined $aryB[26]) {$alt_phone = $aryB[26]; $alt_phoneSQL = "\"$aryB[26]\"";} + else {$alt_phoneSQL = 'NULL'; $alt_phone='NULL';} + if (defined $aryB[27]) {$email = $aryB[27]; $emailSQL = "\"$aryB[27]\"";} + else {$emailSQL = 'NULL'; $email='NULL';} + if (defined $aryB[28]) {$security_phrase = $aryB[28]; $security_phraseSQL = "\"$aryB[28]\"";} + else {$security_phraseSQL = 'NULL'; $security_phrase='NULL';} + if (defined $aryB[29]) {$comments = $aryB[29]; $commentsSQL = "\"$aryB[29]\"";} + else {$commentsSQL = 'NULL'; $comments='NULL';} + if (defined $aryB[30]) {$called_count = $aryB[30]; $called_countSQL = "\"$aryB[30]\"";} + else {$called_countSQL = 'NULL'; $called_count='NULL';} + if (defined $aryB[31]) {$last_local_call_time = $aryB[31]; $last_local_call_timeSQL = "\"$aryB[31]\"";} + else {$last_local_call_timeSQL = 'NULL'; $last_local_call_time='NULL';} + if (defined $aryB[32]) {$rank = $aryB[32]; $rankSQL = "\"$aryB[32]\"";} + else {$rankSQL = 'NULL'; $rank='NULL';} + if (defined $aryB[33]) {$owner = $aryB[33]; $ownerSQL = "\"$aryB[33]\"";} + else {$ownerSQL = 'NULL'; $owner='NULL';} + if (defined $aryB[34]) {$entry_list_id = $aryB[34]; $entry_list_idSQL = "\"$aryB[34]\"";} + else {$entry_list_idSQL = 'NULL'; $entry_list_id='NULL';} + $Amodify_epoch = $aryB[35]; + $Acompare = "$entry_date|$status|$user|$vendor_lead_code|$source_id|$list_id|$gmt_offset_now|$called_since_last_reset|$phone_code|$phone_number|$title|$first_name|$middle_initial|$last_name|$address1|$address2|$address3|$city|$state|$province|$postal_code|$country_code|$gender|$date_of_birth|$alt_phone|$email|$security_phrase|$comments|$called_count|$last_local_call_time|$rank|$owner|$entry_list_id"; + } + else + { + $update_phase=0; + if ($DBX > 0) + {print "DEBUG: No CLR lead found for lead $updated_LEADS[$u_ct], skipping \n";} + } + $sthB->finish(); + + # gather lead data from ORIGINAL database + $stmtA = "SELECT lead_id,entry_date,modify_date,status,user,vendor_lead_code,source_id,list_id,gmt_offset_now,called_since_last_reset,phone_code,phone_number,title,first_name,middle_initial,last_name,address1,address2,address3,city,state,province,postal_code,country_code,gender,date_of_birth,alt_phone,email,security_phrase,comments,called_count,last_local_call_time,rank,owner,entry_list_id,UNIX_TIMESTAMP(modify_date) from vicidial_list where lead_id=$updated_LEADS[$u_ct];"; + $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; + $Blead_id = $aryA[0]; + if (defined $aryA[1]) {$Bentry_date = $aryA[1]; $Bentry_dateSQL = "\"$aryA[1]\"";} + else {$Bentry_dateSQL = 'NULL'; $Bentry_date='NULL';} + if (defined $aryA[2]) {$Bmodify_date = $aryA[2]; $Bmodify_dateSQL = "\"$aryA[2]\"";} + else {$Bmodify_dateSQL = 'NULL'; $Bmodify_date='NULL';} + if (defined $aryA[3]) {$Bstatus = $aryA[3]; $BstatusSQL = "\"$aryA[3]\"";} + else {$BstatusSQL = 'NULL'; $Bstatus='NULL';} + if (defined $aryA[4]) {$Buser = $aryA[4]; $BuserSQL = "\"$aryA[4]\"";} + else {$BuserSQL = 'NULL'; $Buser='NULL';} + if (defined $aryA[5]) {$Bvendor_lead_code = $aryA[5]; $Bvendor_lead_codeSQL = "\"$aryA[5]\"";} + else {$Bvendor_lead_codeSQL = 'NULL'; $Bvendor_lead_code='NULL';} + if (defined $aryA[6]) {$Bsource_id = $aryA[6]; $Bsource_idSQL = "\"$aryA[6]\"";} + else {$Bsource_idSQL = 'NULL'; $Bsource_id='NULL';} + if (defined $aryA[7]) {$Blist_id = $aryA[7]; $Blist_idSQL = "\"$aryA[7]\"";} + else {$Blist_idSQL = 'NULL'; $Blist_id='NULL';} + if (defined $aryA[8]) {$Bgmt_offset_now = $aryA[8]; $Bgmt_offset_nowSQL = "\"$aryA[8]\"";} + else {$Bgmt_offset_nowSQL = 'NULL'; $Bgmt_offset_now='NULL';} + if (defined $aryA[9]) {$Bcalled_since_last_reset = $aryA[9]; $Bcalled_since_last_resetSQL = "\"$aryA[9]\"";} + else {$Bcalled_since_last_resetSQL = 'NULL'; $Bcalled_since_last_reset='NULL';} + if (defined $aryA[10]) {$Bphone_code = $aryA[10]; $Bphone_codeSQL = "\"$aryA[10]\"";} + else {$Bphone_codeSQL = 'NULL'; $Bphone_code='NULL';} + if (defined $aryA[11]) {$Bphone_number = $aryA[11]; $Bphone_numberSQL = "\"$aryA[11]\"";} + else {$Bphone_numberSQL = 'NULL'; $Bphone_number='NULL';} + if (defined $aryA[12]) {$Btitle = $aryA[12]; $BtitleSQL = "\"$aryA[12]\"";} + else {$BtitleSQL = 'NULL'; $Btitle='NULL';} + if (defined $aryA[13]) {$Bfirst_name = $aryA[13]; $Bfirst_nameSQL = "\"$aryA[13]\"";} + else {$Bfirst_nameSQL = 'NULL'; $Bfirst_name='NULL';} + if (defined $aryA[14]) {$Bmiddle_initial = $aryA[14]; $Bmiddle_initialSQL = "\"$aryA[14]\"";} + else {$Bmiddle_initialSQL = 'NULL'; $Bmiddle_initial='NULL';} + if (defined $aryA[15]) {$Blast_name = $aryA[15]; $Blast_nameSQL = "\"$aryA[15]\"";} + else {$Blast_nameSQL = 'NULL'; $Blast_name='NULL';} + if (defined $aryA[16]) {$Baddress1 = $aryA[16]; $Baddress1SQL = "\"$aryA[16]\"";} + else {$Baddress1SQL = 'NULL'; $Baddress1='NULL';} + if (defined $aryA[17]) {$Baddress2 = $aryA[17]; $Baddress2SQL = "\"$aryA[17]\"";} + else {$Baddress2SQL = 'NULL'; $Baddress2='NULL';} + if (defined $aryA[18]) {$Baddress3 = $aryA[18]; $Baddress3SQL = "\"$aryA[18]\"";} + else {$Baddress3SQL = 'NULL'; $Baddress3='NULL';} + if (defined $aryA[19]) {$Bcity = $aryA[19]; $BcitySQL = "\"$aryA[19]\"";} + else {$BcitySQL = 'NULL'; $Bcity='NULL';} + if (defined $aryA[20]) {$Bstate = $aryA[20]; $BstateSQL = "\"$aryA[20]\"";} + else {$BstateSQL = 'NULL'; $Bstate='NULL';} + if (defined $aryA[21]) {$Bprovince = $aryA[21]; $BprovinceSQL = "\"$aryA[21]\"";} + else {$BprovinceSQL = 'NULL'; $Bprovince='NULL';} + if (defined $aryA[22]) {$Bpostal_code = $aryA[22]; $Bpostal_codeSQL = "\"$aryA[22]\"";} + else {$Bpostal_codeSQL = 'NULL'; $Bpostal_code='NULL';} + if (defined $aryA[23]) {$Bcountry_code = $aryA[23]; $Bcountry_codeSQL = "\"$aryA[23]\"";} + else {$Bcountry_codeSQL = 'NULL'; $Bcountry_code='NULL';} + if (defined $aryA[24]) {$Bgender = $aryA[24]; $BgenderSQL = "\"$aryA[24]\"";} + else {$BgenderSQL = 'NULL'; $Bgender='NULL';} + if (defined $aryA[25]) {$Bdate_of_birth = $aryA[25]; $Bdate_of_birthSQL = "\"$aryA[25]\"";} + else {$Bdate_of_birthSQL = 'NULL'; $Bdate_of_birth='NULL';} + if (defined $aryA[26]) {$Balt_phone = $aryA[26]; $Balt_phoneSQL = "\"$aryA[26]\"";} + else {$Balt_phoneSQL = 'NULL'; $Balt_phone='NULL';} + if (defined $aryA[27]) {$Bemail = $aryA[27]; $BemailSQL = "\"$aryA[27]\"";} + else {$BemailSQL = 'NULL'; $Bemail='NULL';} + if (defined $aryA[28]) {$Bsecurity_phrase = $aryA[28]; $Bsecurity_phraseSQL = "\"$aryA[28]\"";} + else {$Bsecurity_phraseSQL = 'NULL'; $Bsecurity_phrase='NULL';} + if (defined $aryA[29]) {$Bcomments = $aryA[29]; $BcommentsSQL = "\"$aryA[29]\"";} + else {$BcommentsSQL = 'NULL'; $Bcomments='NULL';} + if (defined $aryA[30]) {$Bcalled_count = $aryA[30]; $Bcalled_countSQL = "\"$aryA[30]\"";} + else {$Bcalled_countSQL = 'NULL'; $Bcalled_count='NULL';} + if (defined $aryA[31]) {$Blast_local_call_time = $aryA[31]; $Blast_local_call_timeSQL = "\"$aryA[31]\"";} + else {$Blast_local_call_timeSQL = 'NULL'; $Blast_local_call_time='NULL';} + if (defined $aryA[32]) {$Brank = $aryA[32]; $BrankSQL = "\"$aryA[32]\"";} + else {$BrankSQL = 'NULL'; $Brank='NULL';} + if (defined $aryA[33]) {$Bowner = $aryA[33]; $BownerSQL = "\"$aryA[33]\"";} + else {$BownerSQL = 'NULL'; $Bowner='NULL';} + if (defined $aryA[34]) {$Bentry_list_id = $aryA[34]; $Bentry_list_idSQL = "\"$aryA[34]\"";} + else {$Bentry_list_idSQL = 'NULL'; $Bentry_list_id='NULL';} + $Bmodify_epoch = $aryA[35]; + + $Bcompare = "$Bentry_date|$Bstatus|$Buser|$Bvendor_lead_code|$Bsource_id|$Blist_id|$Bgmt_offset_now|$Bcalled_since_last_reset|$Bphone_code|$Bphone_number|$Btitle|$Bfirst_name|$Bmiddle_initial|$Blast_name|$Baddress1|$Baddress2|$Baddress3|$Bcity|$Bstate|$Bprovince|$Bpostal_code|$Bcountry_code|$Bgender|$Bdate_of_birth|$Balt_phone|$Bemail|$Bsecurity_phrase|$Bcomments|$Bcalled_count|$Blast_local_call_time|$Brank|$Bowner|$Bentry_list_id"; + } + else + { + if ($update_phase > 0) + { + $update_phase=2; + if ($DBX > 0) {print "DEBUG: No ORIGINAL match found for lead $updated_LEADS[$u_ct], inserting instead \n";} + } + } + $sthA->finish(); + + if ($update_phase >= 2) + { + # insert lead into ORIGINAL database + + $stmtA = "INSERT INTO vicidial_list SET lead_id='$lead_id',entry_date=$entry_dateSQL,modify_date=$modify_dateSQL,status=$statusSQL,user=$userSQL,vendor_lead_code=$vendor_lead_codeSQL,source_id=$source_idSQL,list_id=$list_idSQL,gmt_offset_now=$gmt_offset_nowSQL,called_since_last_reset=$called_since_last_resetSQL,phone_code=$phone_codeSQL,phone_number=$phone_numberSQL,title=$titleSQL,first_name=$first_nameSQL,middle_initial=$middle_initialSQL,last_name=$last_nameSQL,address1=$address1SQL,address2=$address2SQL,address3=$address3SQL,city=$citySQL,state=$stateSQL,province=$provinceSQL,postal_code=$postal_codeSQL,country_code=$country_codeSQL,gender=$genderSQL,date_of_birth=$date_of_birthSQL,alt_phone=$alt_phoneSQL,email=$emailSQL,security_phrase=$security_phraseSQL,comments=$commentsSQL,called_count=$called_countSQL,last_local_call_time=$last_local_call_timeSQL,rank=$rankSQL,owner=$ownerSQL,entry_list_id=$entry_list_idSQL;"; + # $affected_rowsA = $dbhA->do($stmtA); + $CLRinsert_aff = ($CLRinsert_aff + $affected_rowsA); + if ($DBX > 0) {print "DEBUG: CLR lead inserted $updated_LEADS[$u_ct]: $affected_rowsA|$stmtA| \n";} + + $CLRinsert_ct++; + } + else + { + # compare ORIGINAL and CLR lead data to see if update is needed + if ($Acompare eq $Bcompare) + { + $update_phase=0; + if ($DBX > 0) {print "DEBUG: ORIGINAL and CLR lead data is identical: $updated_LEADS[$u_ct] \n";} + } + if ($DBX > 0) {print "$lead_id compare:\n$Acompare \n$Bcompare \n";} + + if ($update_phase >= 1) + { + # If ORIGINAL is newer than CLR record, than update the CLR record instead + if ($Amodify_epoch < $Bmodify_epoch) + { + if ($DBX > 0) {print "REVERSE UPDATE: ORIGINAL to CLR ($Amodify_epoch < $Bmodify_epoch): $updated_LEADS[$u_ct] \n";} + + $stmtB = "UPDATE vicidial_list SET entry_date=$Bentry_dateSQL,modify_date=$Bmodify_dateSQL,status=$BstatusSQL,user=$BuserSQL,vendor_lead_code=$Bvendor_lead_codeSQL,source_id=$Bsource_idSQL,list_id=$Blist_idSQL,gmt_offset_now=$Bgmt_offset_nowSQL,called_since_last_reset=$Bcalled_since_last_resetSQL,phone_code=$Bphone_codeSQL,phone_number=$Bphone_numberSQL,title=$BtitleSQL,first_name=$Bfirst_nameSQL,middle_initial=$Bmiddle_initialSQL,last_name=$Blast_nameSQL,address1=$Baddress1SQL,address2=$Baddress2SQL,address3=$Baddress3SQL,city=$BcitySQL,state=$BstateSQL,province=$BprovinceSQL,postal_code=$Bpostal_codeSQL,country_code=$Bcountry_codeSQL,gender=$BgenderSQL,date_of_birth=$Bdate_of_birthSQL,alt_phone=$Balt_phoneSQL,email=$BemailSQL,security_phrase=$Bsecurity_phraseSQL,comments=$BcommentsSQL,called_count=$Bcalled_countSQL,last_local_call_time=$Blast_local_call_timeSQL,rank=$BrankSQL,owner=$BownerSQL,entry_list_id=$Bentry_list_idSQL where lead_id='$lead_id';"; + $affected_rowsB = $dbhB->do($stmtB); + $CLRreverse_update_aff = ($CLRreverse_update_aff + $affected_rowsB); + if ($DBX > 0) {print "DEBUG: CLR lead updated $updated_LEADS[$u_ct]: $affected_rowsB|$stmtB| \n";} + + $CLRreverse_update_ct++; + } + else + { + # update existing lead in ORIGINAL database + $stmtA = "UPDATE vicidial_list SET entry_date=$entry_dateSQL,modify_date=$modify_dateSQL,status=$statusSQL,user=$userSQL,vendor_lead_code=$vendor_lead_codeSQL,source_id=$source_idSQL,list_id=$list_idSQL,gmt_offset_now=$gmt_offset_nowSQL,called_since_last_reset=$called_since_last_resetSQL,phone_code=$phone_codeSQL,phone_number=$phone_numberSQL,title=$titleSQL,first_name=$first_nameSQL,middle_initial=$middle_initialSQL,last_name=$last_nameSQL,address1=$address1SQL,address2=$address2SQL,address3=$address3SQL,city=$citySQL,state=$stateSQL,province=$provinceSQL,postal_code=$postal_codeSQL,country_code=$country_codeSQL,gender=$genderSQL,date_of_birth=$date_of_birthSQL,alt_phone=$alt_phoneSQL,email=$emailSQL,security_phrase=$security_phraseSQL,comments=$commentsSQL,called_count=$called_countSQL,last_local_call_time=$last_local_call_timeSQL,rank=$rankSQL,owner=$ownerSQL,entry_list_id=$entry_list_idSQL where lead_id='$lead_id';"; + # $affected_rowsA = $dbhA->do($stmtA); + $CLRupdate_aff = ($CLRupdate_aff + $affected_rowsA); + if ($DB > 0) {print "DEBUG: CLR lead updated $updated_LEADS[$u_ct]: $affected_rowsA|$stmtA| \n";} + + $CLRupdate_ct++; + } + } + else + { + # no change needed to lead in CLR database + $CLRnochange_ct++; + } + } + + $u_ct++; + if ($Q < 1) + { + if ($u_ct =~ /000$/i) {print STDERR " <$u_ct / $updated_LEADSsize \r";} + if ($u_ct =~ /100$/i) {print STDERR " < $u_ct / $updated_LEADSsize \r";} + if ($u_ct =~ /200$/i) {print STDERR " <- $u_ct / $updated_LEADSsize \r";} + if ($u_ct =~ /300$/i) {print STDERR " <- $u_ct / $updated_LEADSsize \r";} + if ($u_ct =~ /400$/i) {print STDERR " <- $u_ct / $updated_LEADSsize \r";} + if ($u_ct =~ /500$/i) {print STDERR " <- $u_ct / $updated_LEADSsize \r";} + if ($u_ct =~ /600$/i) {print STDERR " <- $u_ct / $updated_LEADSsize \r";} + if ($u_ct =~ /700$/i) {print STDERR " <- $u_ct / $updated_LEADSsize \r";} + if ($u_ct =~ /800$/i) {print STDERR " <- $u_ct / $updated_LEADSsize \r";} + if ($u_ct =~ /900$/i) {print STDERR "<- $u_ct / $updated_LEADSsize \r";} + if ($u_ct =~ /0000$/i) + { + $secY = time(); + $secZ = ($secY - $secX); + print "$u_ct|$CLRupdate_ct/$CLRreverse_update_ct|$CLRinsert_ct|$CLRnochange_ct| $secZ sec \n"; + } + } + } + } + + + $lead_output = "ORIGINAL lead updates: $CLRupdate_ct ($CLRupdate_aff) \n"; + $lead_output .= "REV CLR lead updates: $CLRreverse_update_ct ($CLRreverse_update_aff) \n"; + $lead_output .= "ORIGINAL lead inserts: $CLRinsert_ct ($CLRinsert_aff) \n"; + $lead_output .= "ORIGINAL lead no changes: $CLRnochange_ct \n"; + if (!$Q) {print $lead_output;} + + $process_output .= $lead_output; + + $secY = time(); + $secZ = ($secY - $secX); + + # insert clr_log entry into database + $stmtA = "UPDATE clr_log SET phase='$phase',records_ct='$u_ct',length_in_sec='$secZ',processing_log='$process_output' where clr_id='$clr_id';"; + $affected_rowsA = $dbhA->do($stmtA); + } +################################################################################ +##### END morning CLR to ORIGINAL db updates +################################################################################ + + + + + + + + + + + + + + + + + + + +### calculate time to run script ### +$secY = time(); +$secZ = ($secY - $secX); +$secZm = ($secZ /60); +if (!$Q) {print "\nscript execution time in seconds: $secZ minutes: $secZm\n";} + +exit; + + + + + +################################################################################ +##### SUBROUTINES +################################################################################ + +sub populate_main_section + { + # break out settings into local variables + $temp_type = $temp_type_ARY[$v]; + $temp_typeS = $temp_typeS_ARY[$v]; + $temp_table = $temp_table_ARY[$v]; + $temp_id_field = $temp_id_field_ARY[$v]; + $temp_date_check_SQL = $temp_date_check_SQL_ARY[$v]; + $temp_first_fields = $temp_first_fields_ARY[$v]; + $temp_date_field = $temp_date_field_ARY[$v]; + $fields_skip_list = $fields_skip_list_ARY[$v]; + $fields_insert_list = $fields_insert_list_ARY[$v]; + $SUBS_tables_list = $SUBS_tables_list_ARY[$v]; + $SUBS_delete_first = $SUBS_delete_first_ARY[$v]; + $SUBS_tables_details = $SUBS_tables_details_ARY[$v]; + @SUBS_tables_details_split = split(/,/,$SUBS_tables_details); + $SUBS_tables_details_split_rows = scalar(@SUBS_tables_details_split); + $d_ct=0; + while ($d_ct < $SUBS_tables_details_split_rows) + { + @SUBS_tables_details_detail = split(/---/,$SUBS_tables_details_split[$d_ct]); + $SUB_table[$d_ct] = $SUBS_tables_details_detail[0]; + $SUB_fields[$d_ct] = $SUBS_tables_details_detail[1]; + $d_ct++; + } + if ($d_ct < 1) + { + @SUB_table=@MT; + @SUB_fields=@MT; + } + + ######################################################## + ### BEGIN Check if there are any MAIN changes within the previous X minutes, or ALL + $vicidial_main_ct=0; + $stmtA = "SELECT count(*) from $temp_table where $temp_date_check_SQL;"; + if ($ALL_SETTINGS > 0) + {$stmtA = "SELECT count(*) from $temp_table;"; $process_options.='ALL_SETTINGS';} + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $vicidial_main_ct = $aryA[0]; + } + $sthA->finish(); + + if ( ($vicidial_main_ct < 1) ) + { + if (!$Q) {print "No $temp_type updated recently, nothing to do, skipping... \n";} + } + else + { + if (!$Q) {print "Recent changes - $temp_type: $vicidial_main_ct \n";} + + $o_ct=0; + $stmtA = "SELECT $temp_first_fields from $temp_table where $temp_date_check_SQL limit 10000000;"; + if ($ALL_SETTINGS > 0) + {$stmtA = "SELECT $temp_first_fields from $temp_table;";} + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + while ($sthArows > $o_ct) + { + @aryA = $sthA->fetchrow_array; + $updated_MAINS[$o_ct] = $aryA[0]; + $updated_MAINSepoch[$o_ct] = $aryA[2]; + $o_ct++; + } + $sthA->finish(); + $updated_MAINSsize = $o_ct; + + ### loop through all mains, compare to record on CLR server, update/insert if needed + $u_ct=0; + $CLRupdate_ct=0; $CLRupdate_aff=0; + $CLRinsert_ct=0; $CLRinsert_aff=0; + $CLRskip_ct=0; + $CLRnochange_ct=0; + $MAIN_updated=0; + while ($updated_MAINSsize > $u_ct) + { + $o_ct=0; + $fields_list=''; + $stmtA = "SHOW COLUMNS from $temp_table;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + while ($sthArows > $o_ct) + { + @aryA = $sthA->fetchrow_array; + $fields_list .= "$aryA[0],"; + $o_ct++; + } + $sthA->finish(); + $fields_list =~ s/,$//gi; + + $update_phase=1; + # gather main data from ORIGINAL database + $stmtA = "SELECT $fields_list from $temp_table where $temp_id_field='$updated_MAINS[$u_ct]';"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + if ($sthArows > 0) + { + @proc_fields = split(/,/,$fields_list); + $proc_fields_size = @proc_fields; + $proc_skip_fields = ",$fields_skip_list,"; + $AupdateSQL=''; + $Acompare=''; + $p_ct=0; + @aryA = $sthA->fetchrow_array; + while($proc_fields_size > $p_ct) + { + if ($proc_skip_fields =~ /,$proc_fields[$p_ct],/) + {if ($DBX > 0) {print "SKIP $p_ct|$proc_fields[$p_ct]|$aryA[$p_ct]| \n";}} + else + { + if (defined $aryA[$p_ct]) + { + $temp_field = $aryA[$p_ct]; + $temp_fieldSQL = "\"$temp_field\""; + } + else + { + $temp_field='NULL'; + $temp_fieldSQL = 'NULL'; + } + $Acompare .= "$temp_field|"; + $AupdateSQL .= "$proc_fields[$p_ct]=$temp_fieldSQL,"; + } + $p_ct++; + } + $AupdateSQL =~ s/,$//gi; + } + else + { + $update_phase=0; + if ($DBX > 0) + {print "DEBUG: No ORIGINAL $temp_typeS found for $temp_typeS $updated_MAINS[$u_ct], skipping \n";} + } + $sthA->finish(); + + # gather main data from CLR database + $stmtB = "SELECT $fields_list,UNIX_TIMESTAMP($temp_date_field) from $temp_table where $temp_id_field='$updated_MAINS[$u_ct]';"; + $sthB = $dbhB->prepare($stmtB) or die "preparing: ",$dbhB->errstr; + $sthB->execute or die "executing: $stmtB ", $dbhB->errstr; + $sthBrows=$sthB->rows; + if ($sthBrows > 0) + { + $BupdateSQL=''; + $Bcompare=''; + $Bupdated_MAINSepoch=0; + $p_ct=0; + @aryB = $sthB->fetchrow_array; + while($proc_fields_size > $p_ct) + { + if ($proc_skip_fields =~ /,$proc_fields[$p_ct],/) + {if ($DBX > 0) {print "SKIP $p_ct|$proc_fields[$p_ct]|$aryA[$p_ct]| \n";}} + else + { + if (defined $aryB[$p_ct]) + { + $temp_field = $aryB[$p_ct]; + $temp_fieldSQL = "\"$temp_field\""; + } + else + { + $temp_field='NULL'; + $temp_fieldSQL = 'NULL'; + } + $Bcompare .= "$temp_field|"; + $BupdateSQL .= "$proc_fields[$p_ct]=$temp_fieldSQL,"; + } + $p_ct++; + $Bupdated_MAINSepoch = $aryB[$p_ct]; + } + $BupdateSQL =~ s/,$//gi; + } + else + { + if ($update_phase > 0) + { + $update_phase=2; + if ($DBX > 0) {print "DEBUG: No CLR match found for $temp_typeS $updated_MAINS[$u_ct], inserting instead \n";} + } + } + $sthB->finish(); + + if ($update_phase >= 2) + { + # insert main into CLR database + + $stmtB = "INSERT IGNORE INTO $temp_table SET $temp_id_field='$updated_MAINS[$u_ct]'$fields_insert_list,$AupdateSQL;"; + $affected_rowsB = $dbhB->do($stmtB); + $CLRinsert_aff = ($CLRinsert_aff + $affected_rowsB); + if ($DBX > 0) {print "DEBUG: CLR $temp_typeS inserted $updated_MAINS[$u_ct]: $affected_rowsB|$stmtB| \n";} + + $CLRinsert_ct++; + $MAIN_updated++; + } + else + { + # compare ORIGINAL and CLR main data to see if update is needed + if ($Acompare eq $Bcompare) + { + $update_phase=0; + if ($DBX > 0) {print "DEBUG: ORIGINAL and CLR $temp_typeS data is identical: $updated_MAINS[$u_ct] \n";} + if ($ALL_SETTINGS > 0) + {$MAIN_updated++;} + } + if ($DBX > 0) {print "$updated_MAINS[$u_ct] compare:\n$Acompare \n$Bcompare \n";} + + if ($update_phase >= 1) + { + if ($updated_MAINSepoch[$u_ct] < $Bupdated_MAINSepoch) + { + if ($DBX > 0) {print "DEBUG: CLR $temp_typeS record is newer than ORIGINAL: $updated_MAINS[$u_ct] ($updated_MAINSepoch[$u_ct] > $Bupdated_MAINSepoch) \n";} + $CLRskip_ct++; + } + else + { + if ($DBX > 0) {print "DEBUG: CLR $temp_typeS record is older or same age as ORIGINAL: $updated_MAINS[$u_ct] ($updated_MAINSepoch[$u_ct] > $Bupdated_MAINSepoch) \n";} + # update existing main in CLR database + $stmtB = "UPDATE $temp_table SET $AupdateSQL where $temp_id_field='$updated_MAINS[$u_ct]';"; + $affected_rowsB = $dbhB->do($stmtB); + $CLRupdate_aff = ($CLRupdate_aff + $affected_rowsB); + if ($DBX > 0) {print "DEBUG: CLR $temp_typeS updated $updated_MAINS[$u_ct]: $affected_rowsB|$stmtB| \n";} + + $CLRupdate_ct++; + $MAIN_updated++; + } + } + else + { + # no change needed to main in CLR database + $CLRnochange_ct++; + } + } + + ### If main has been updated or inserted, then insert/update the statuses/hotkeys/pause-codes/presets/etc... data for this main + if ( ($MAIN_updated > 0) && (length($SUBS_tables_list) > 5) ) + { + # subs-table processing goes here + @subs_to_process = split(/,/,$SUBS_tables_list); + + $sub_ct=0; + foreach(@subs_to_process) + { + if ($DBX > 0) {print "DEBUG: sub-category to process: $subs_to_process[$sub_ct] \n";} + + if ( ($SUBS_delete_first > 0) && ($ALL_SETTINGS > 0) ) + { + # delete and optimize all secondary records from the CLR database for this MAIN before re-populating + $stmtB = "DELETE from $subs_to_process[$sub_ct] WHERE $temp_id_field='$updated_MAINS[$u_ct]';"; + # $affected_rowsB = $dbhB->do($stmtB); + $CLRupdate_aff = ($CLRupdate_aff + $affected_rowsB); + if ($DB > 0) {print "DEBUG: CLR $subs_to_process[$sub_ct] purged: $affected_rowsB|$stmtB| \n";} + + $stmtB = "OPTIMIZE TABLE $subs_to_process[$sub_ct];"; + # $affected_rowsB = $dbhB->do($stmtB); + $CLRupdate_aff = ($CLRupdate_aff + $affected_rowsB); + if ($DB > 0) {print "DEBUG: CLR $subs_to_process[$sub_ct] optimized: $affected_rowsB|$stmtB| \n";} + } + + $temp_subs_table = $subs_to_process[$sub_ct]; + $temp_subs_fields = $SUB_table[$sub_ct]; + + &populate_subs_section; + + $sub_ct++; + } + } + + $u_ct++; + if ($Q < 1) + { + if ($u_ct =~ /100$/i) {print STDERR "> $u_ct / $updated_MAINSsize \r";} + if ($u_ct =~ /200$/i) {print STDERR "-> $u_ct / $updated_MAINSsize \r";} + if ($u_ct =~ /300$/i) {print STDERR " -> $u_ct / $updated_MAINSsize \r";} + if ($u_ct =~ /400$/i) {print STDERR " -> $u_ct / $updated_MAINSsize \r";} + if ($u_ct =~ /500$/i) {print STDERR " -> $u_ct / $updated_MAINSsize \r";} + if ($u_ct =~ /600$/i) {print STDERR " -> $u_ct / $updated_MAINSsize \r";} + if ($u_ct =~ /700$/i) {print STDERR " -> $u_ct / $updated_MAINSsize \r";} + if ($u_ct =~ /800$/i) {print STDERR " -> $u_ct / $updated_MAINSsize \r";} + if ($u_ct =~ /900$/i) {print STDERR " -> $u_ct / $updated_MAINSsize \r";} + if ($u_ct =~ /000$/i) {print STDERR " ->$u_ct / $updated_MAINSsize \r";} + if ($u_ct =~ /0000$/i) + { + $secY = time(); + $secZ = ($secY - $secX); + print "$u_ct|$CLRupdate_ct|$CLRinsert_ct|$CLRnochange_ct| $secZ sec \n"; + } + } + } + } + + $lead_output = "CLR $temp_typeS updates: $CLRupdate_ct ($CLRupdate_aff) \n"; + $lead_output .= "CLR $temp_typeS inserts: $CLRinsert_ct ($CLRinsert_aff) \n"; + $lead_output .= "CLR $temp_typeS skips: $CLRskip_ct \n"; + $lead_output .= "CLR $temp_typeS no changes: $CLRnochange_ct \n"; + if (!$Q) {print $lead_output;} + + $process_output .= $lead_output; + ######################################################## + ### END Check if there are any main changes within the previous X minutes + } + + + +sub populate_subs_section + { + ######################################################## + ### BEGIN Check if there are any SUBS changes within the previous X minutes, or ALL + $temp_subs_table = $subs_to_process[$sub_ct]; + $temp_subs_fields = $SUB_fields[$sub_ct]; + $vicidial_sub_ct=0; + $stmtA = "SELECT count(*) from $temp_subs_table where $temp_id_field='$updated_MAINS[$u_ct]';"; + $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; + $vicidial_sub_ct = $aryA[0]; + } + $sthA->finish(); + + if ( ($vicidial_sub_ct < 1) ) + { + if (!$Q) {print "No $temp_subs_table updated recently, nothing to do, skipping... \n";} + } + else + { + if (!$Q) {print "Recent changes - $temp_subs_table: $vicidial_sub_ct \n";} + + $o_ct=0; + $stmtA = "SELECT $temp_subs_fields from $temp_subs_table where $temp_id_field='$updated_MAINS[$u_ct]' limit 10000000;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + while ($sthArows > $o_ct) + { + @aryA = $sthA->fetchrow_array; + $updated_SUBS[$o_ct] = $aryA[0]; + $o_ct++; + } + $sthA->finish(); + $updated_SUBSsize = $o_ct; + + ### loop through all subs, compare to record on CLR server, update/insert if needed + $s_ct=0; + $sCLRupdate_ct=0; $sCLRupdate_aff=0; + $sCLRinsert_ct=0; $sCLRinsert_aff=0; + $sCLRskip_ct=0; + $sCLRnochange_ct=0; + $SUB_updated=0; + while ($updated_SUBSsize > $s_ct) + { + $o_ct=0; + $subs_fields_list=''; + $stmtA = "SHOW COLUMNS from $temp_subs_table;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + while ($sthArows > $o_ct) + { + @aryA = $sthA->fetchrow_array; + $subs_fields_list .= "$aryA[0],"; + $o_ct++; + } + $sthA->finish(); + $subs_fields_list =~ s/,$//gi; + + $update_phase=1; + # gather subs data from ORIGINAL database + $stmtA = "SELECT $subs_fields_list from $temp_subs_table where $temp_id_field='$updated_MAINS[$u_ct]' and $temp_subs_fields='$updated_SUBS[$s_ct]';"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + if ($sthArows > 0) + { + @tsub_fields = split(/,/,$subs_fields_list); + $tsub_fields_size = @tsub_fields; + $tsub_skip_fields = ",$temp_subs_fields,"; + $AupdateSQL=''; + $Acompare=''; + $p_ct=0; + @aryA = $sthA->fetchrow_array; + while($tsub_fields_size > $p_ct) + { + if ($tsub_skip_fields =~ /,$tsub_fields[$p_ct],/) + {if ($DBX > 0) {print "SKIP $p_ct|$tsub_fields[$p_ct]|$aryA[$p_ct]| \n";}} + else + { + if (defined $aryA[$p_ct]) + { + $temp_field = $aryA[$p_ct]; + $temp_fieldSQL = "\"$temp_field\""; + } + else + { + $temp_field='NULL'; + $temp_fieldSQL = 'NULL'; + } + $Acompare .= "$temp_field|"; + $AupdateSQL .= "$tsub_fields[$p_ct]=$temp_fieldSQL,"; + } + $p_ct++; + } + $AupdateSQL =~ s/,$//gi; + } + else + { + $update_phase=0; + if ($DBX > 0) + {print "DEBUG: No ORIGINAL $temp_subs_table found for $updated_SUBS[$s_ct], skipping \n";} + } + $sthA->finish(); + + # gather subs data from CLR database + $stmtB = "SELECT $subs_fields_list from $temp_subs_table where $temp_id_field='$updated_MAINS[$u_ct]' and $temp_subs_fields='$updated_SUBS[$s_ct]';"; + $sthB = $dbhB->prepare($stmtB) or die "preparing: ",$dbhB->errstr; + $sthB->execute or die "executing: $stmtB ", $dbhB->errstr; + $sthBrows=$sthB->rows; + if ($sthBrows > 0) + { + $BupdateSQL=''; + $Bcompare=''; + $p_ct=0; + @aryB = $sthB->fetchrow_array; + while($tsub_fields_size > $p_ct) + { + if ($tsub_skip_fields =~ /,$tsub_fields[$p_ct],/) + {if ($DBX > 0) {print "SKIP $p_ct|$tsub_fields[$p_ct]|$aryB[$p_ct]| \n";}} + else + { + if (defined $aryB[$p_ct]) + { + $temp_field = $aryB[$p_ct]; + $temp_fieldSQL = "\"$temp_field\""; + } + else + { + $temp_field='NULL'; + $temp_fieldSQL = 'NULL'; + } + $Bcompare .= "$temp_field|"; + $BupdateSQL .= "$tsub_fields[$p_ct]=$temp_fieldSQL,"; + } + $p_ct++; + } + $BupdateSQL =~ s/,$//gi; + } + else + { + if ($update_phase > 0) + { + $update_phase=2; + if ($DBX > 0) {print "DEBUG: No CLR match found for $temp_subs_table $updated_SUBS[$s_ct], inserting instead \n";} + } + } + $sthB->finish(); + + if ($update_phase >= 2) + { + # insert subs into CLR database + + $stmtB = "INSERT IGNORE INTO $temp_subs_table SET $temp_subs_fields='$updated_SUBS[$s_ct]',$AupdateSQL;"; + $affected_rowsB = $dbhB->do($stmtB); + $sCLRinsert_aff = ($sCLRinsert_aff + $affected_rowsB); + if ($DBX > 0) {print "DEBUG: CLR $temp_typeS inserted $updated_SUBS[$s_ct]: $affected_rowsB|$stmtB| \n";} + + $sCLRinsert_ct++; + $SUB_updated++; + } + else + { + # compare ORIGINAL and CLR sub data to see if update is needed + if ($Acompare eq $Bcompare) + { + $update_phase=0; + if ($DBX > 0) {print "DEBUG: ORIGINAL and CLR $temp_subs_table data is identical: $updated_SUBS[$s_ct] \n";} + if ($ALL_SETTINGS > 0) + {$SUB_updated++;} + } + if ($DBX > 0) {print "$updated_SUBS[$s_ct] compare:\n$Acompare \n$Bcompare \n";} + + if ($update_phase >= 1) + { + if ($DBX > 0) {print "DEBUG: CLR $temp_subs_table record is older or same age as ORIGINAL: $updated_SUBS[$s_ct] ($updated_SUBSepoch[$s_ct] > $Bupdated_SUBSepoch) \n";} + # update existing sub in CLR database + $stmtB = "UPDATE $temp_subs_table SET $AupdateSQL where $temp_id_field='$updated_MAINS[$u_ct]' and $temp_subs_fields='$updated_SUBS[$s_ct]';"; + $affected_rowsB = $dbhB->do($stmtB); + $sCLRupdate_aff = ($sCLRupdate_aff + $affected_rowsB); + if ($DBX > 0) {print "DEBUG: CLR $temp_typeS updated $updated_SUBS[$s_ct]: $affected_rowsB|$stmtB| \n";} + + $sCLRupdate_ct++; + $SUB_updated++; + } + else + { + # no change needed to sub in CLR database + $sCLRnochange_ct++; + } + } + + $s_ct++; + if ($Q < 1) + { + if ($s_ct =~ /100$/i) {print STDERR "> $s_ct / $updated_SUBSsize \r";} + if ($s_ct =~ /200$/i) {print STDERR "-> $s_ct / $updated_SUBSsize \r";} + if ($s_ct =~ /300$/i) {print STDERR " -> $s_ct / $updated_SUBSsize \r";} + if ($s_ct =~ /400$/i) {print STDERR " -> $s_ct / $updated_SUBSsize \r";} + if ($s_ct =~ /500$/i) {print STDERR " -> $s_ct / $updated_SUBSsize \r";} + if ($s_ct =~ /600$/i) {print STDERR " -> $s_ct / $updated_SUBSsize \r";} + if ($s_ct =~ /700$/i) {print STDERR " -> $s_ct / $updated_SUBSsize \r";} + if ($s_ct =~ /800$/i) {print STDERR " -> $s_ct / $updated_SUBSsize \r";} + if ($s_ct =~ /900$/i) {print STDERR " -> $s_ct / $updated_SUBSsize \r";} + if ($s_ct =~ /000$/i) {print STDERR " ->$s_ct / $updated_SUBSsize \r";} + if ($s_ct =~ /0000$/i) + { + $secY = time(); + $secZ = ($secY - $secX); + print "$s_ct|$sCLRupdate_ct|$sCLRinsert_ct|$sCLRnochange_ct| $secZ sec \n"; + } + } + } + } + + $lead_output = " CLR sub $temp_subs_table updates: $sCLRupdate_ct ($sCLRupdate_aff) \n"; + $lead_output .= " CLR sub $temp_subs_table inserts: $sCLRinsert_ct ($sCLRinsert_aff) \n"; + $lead_output .= " CLR sub $temp_subs_table skips: $sCLRskip_ct \n"; + $lead_output .= " CLR sub $temp_subs_table no changes: $sCLRnochange_ct \n"; + if (!$Q) {print $lead_output;} + + $process_output .= $lead_output; + ######################################################## + ### END Check if there are any subs changes within the previous X minutes + } diff --git a/bin/ADMIN_keepalive_ALL.pl b/bin/ADMIN_keepalive_ALL.pl index 02c3e9853..b97a8b3e3 100644 --- a/bin/ADMIN_keepalive_ALL.pl +++ b/bin/ADMIN_keepalive_ALL.pl @@ -175,9 +175,11 @@ # 250103-0932 - Added ConfBridge code and enhanced_agent_monitoring system setting code # 250914-1601 - Added pruning of recording_live table entries over 7 days old, deletion of parallel recording source files 3+ days # 250924-2212 - Added code for deprecation of "Monitor" application after Asterisk 20 +# 251006-0832 - Added truncating of vicidial_dtmf_log older than 24 hours & If recording_dtmf_muting enabled, force use of MixMonitor for recording +# 251011-1000 - Added archiving of recording_dtmf_muting_log, disabled purging of recording_live_log after 7 days # -$build = '250924-2212'; +$build = '251011-1000'; $DB=0; # Debug flag $teodDB=0; # flag to log Timeclock End of Day processes to log file @@ -500,7 +502,7 @@ ##### Get the settings from system_settings ##### -$stmtA = "SELECT sounds_central_control_active,active_voicemail_server,custom_dialplan_entry,default_codecs,generate_cross_server_exten,voicemail_timezones,default_voicemail_timezone,call_menu_qualify_enabled,allow_voicemail_greeting,reload_timestamp,meetme_enter_login_filename,meetme_enter_leave3way_filename,allow_chats,enable_auto_reports,enable_drop_lists,expired_lists_inactive,sip_event_logging,call_quota_lead_ranking,inbound_answer_config,log_latency_gaps,demographic_quotas,weekday_resets,highest_lead_id,hopper_hold_inserts,stereo_recording,stereo_parallel_recording FROM system_settings;"; +$stmtA = "SELECT sounds_central_control_active,active_voicemail_server,custom_dialplan_entry,default_codecs,generate_cross_server_exten,voicemail_timezones,default_voicemail_timezone,call_menu_qualify_enabled,allow_voicemail_greeting,reload_timestamp,meetme_enter_login_filename,meetme_enter_leave3way_filename,allow_chats,enable_auto_reports,enable_drop_lists,expired_lists_inactive,sip_event_logging,call_quota_lead_ranking,inbound_answer_config,log_latency_gaps,demographic_quotas,weekday_resets,highest_lead_id,hopper_hold_inserts,stereo_recording,stereo_parallel_recording,recording_dtmf_muting FROM system_settings;"; # print "$stmtA\n"; $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; @@ -534,6 +536,7 @@ $SShopper_hold_inserts = $aryA[23]; $SSstereo_recording = $aryA[24]; $SSstereo_parallel_recording = $aryA[25]; + $SSrecording_dtmf_muting = $aryA[26]; } $sthA->finish(); if ($DBXXX > 0) {print "SYSTEM SETTINGS: $sounds_central_control_active|$active_voicemail_server|$SScustom_dialplan_entry|$SSdefault_codecs\n";} @@ -2313,6 +2316,24 @@ $sthA->finish(); ##### END vicidial_two_factor_auth end of day process removing records older than 7 days ##### + + ##### BEGIN vicidial_dtmf_log end of day process removing records older than 24 hours ##### + $stmtA = "DELETE from vicidial_dtmf_log where vicidial_dtmf_log < \"$RMSQLdate\";"; + if($DBX){print STDERR "\n|$stmtA|\n";} + $affected_rows = $dbhA->do($stmtA); + if($DB){print STDERR "\n|$affected_rows vicidial_dtmf_log records older than 1 day purged|\n";} + if ($teodDB) {$event_string = "vicidial_dtmf_log records older than 1 day purged: |$stmtA|$affected_rows|"; &teod_logger;} + + $stmtA = "optimize table vicidial_dtmf_log;"; + if($DBX){print STDERR "\n|$stmtA|\n";} + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + @aryA = $sthA->fetchrow_array; + if ($DB) {print "|",$aryA[0],"|",$aryA[1],"|",$aryA[2],"|",$aryA[3],"|","\n";} + $sthA->finish(); + ##### END vicidial_dtmf_log end of day process removing records older than 7 days ##### + ##### BEGIN vicidial_lead_messages end of day process removing records older than 1 day ##### $stmtA = "DELETE FROM vicidial_lead_messages WHERE call_date < \"$RMSQLdate\";"; @@ -2345,18 +2366,59 @@ ##### BEGIN recording_live_log end of day process removing records older than 7 days ##### - $stmtA = "DELETE FROM recording_live_log WHERE start_time < \"$SDSQLdate\";"; + # $stmtA = "DELETE FROM recording_live_log WHERE start_time < \"$SDSQLdate\";"; + # $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + # $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + # $sthArows = $sthA->rows; + # $event_string = "$sthArows rows deleted from recording_live_log table"; + # if (!$Q) {print "$event_string \n";} + # if ($teodDB) {&teod_logger;} + + # $stmtA = "optimize table recording_live_log;"; + # $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + # $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + ##### END recording_live_log end of day process removing records older than 7 days ##### + + + # archive recording_dtmf_muting_log table every night + if (!$Q) {print "\nProcessing recording_dtmf_muting_log table...\n";} + $stmtA = "INSERT IGNORE INTO recording_dtmf_muting_log_archive SELECT * from recording_dtmf_muting_log;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows = $sthA->rows; + $event_string = "$sthArows rows inserted into recording_dtmf_muting_log_archive table"; + if (!$Q) {print "$event_string \n";} + if ($teodDB) {&teod_logger;} + + $rv = $sthA->err(); + if (!$rv) + { + $stmtA = "DELETE FROM recording_dtmf_muting_log WHERE dtmf_muting_end_time < \"$now_date\";"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows = $sthA->rows; + $event_string = "$sthArows rows deleted from in recording_dtmf_muting_log table"; + if (!$Q) {print "$event_string \n";} + if ($teodDB) {&teod_logger;} + + $stmtA = "optimize table recording_dtmf_muting_log;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + } + + # delete recording_dtmf_muting_log_archive records older than 7 days old + $stmtA = "DELETE FROM recording_dtmf_muting_log_archive WHERE dtmf_muting_end_time < \"$SDSQLdate\";"; $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; $sthArows = $sthA->rows; - $event_string = "$sthArows rows deleted from recording_live_log table"; + $event_string = "$sthArows old rows deleted from in recording_dtmf_muting_log_archive table ($SDSQLdate)"; if (!$Q) {print "$event_string \n";} if ($teodDB) {&teod_logger;} - $stmtA = "optimize table recording_live_log;"; + $stmtA = "optimize table recording_dtmf_muting_log_archive;"; $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; - ##### END recording_live_log end of day process removing records older than 7 days ##### + ##### START latency log summary log inserts @@ -3404,7 +3466,7 @@ {$Vext .= "exten => 8309,2,Monitor(wav,\${CALLERIDNAME})\n";} else { - if ($asterisk_version =~ /^2[1-9]|^3\d|^4\d/) + if ( ($asterisk_version =~ /^2[1-9]|^3\d|^4\d/) || ($SSrecording_dtmf_muting > 0) ) { # Deprecation of "Monitor" application after Asterisk 20 $Vext .= "exten => 8309,2,MixMonitor(,r($PATHmonitor/\${CALLERID(name)}-in.wav)t($PATHmonitor/\${CALLERID(name)}-out.wav))\n"; @@ -3422,7 +3484,7 @@ {$Vext .= "exten => 8310,2,Monitor(gsm,\${CALLERIDNAME})\n";} else { - if ($asterisk_version =~ /^2[1-9]|^3\d|^4\d/) + if ( ($asterisk_version =~ /^2[1-9]|^3\d|^4\d/) || ($SSrecording_dtmf_muting > 0) ) { # Deprecation of "Monitor" application after Asterisk 20 $Vext .= "exten => 8309,2,MixMonitor(,r($PATHmonitor/\${CALLERID(name)}-in.wav)t($PATHmonitor/\${CALLERID(name)}-out.wav))\n"; diff --git a/bin/AST_CRON_audio_1_move_mix.pl b/bin/AST_CRON_audio_1_move_mix.pl index 9557187fe..5d1c91cae 100644 --- a/bin/AST_CRON_audio_1_move_mix.pl +++ b/bin/AST_CRON_audio_1_move_mix.pl @@ -24,7 +24,7 @@ # This program assumes that recordings are saved by Asterisk as .wav # should be easy to change this code if you use .gsm instead # -# Copyright (C) 2023 Matt Florell LICENSE: AGPLv2 +# Copyright (C) 2025 Matt Florell LICENSE: AGPLv2 # # # 80302-1958 - First Build @@ -34,6 +34,7 @@ # 160501-1001 - Added --SPHINX options to check for SPHINX audio files # 160523-0650 - Added --HTTPS option to use https instead of http in local location # 231019-2203 - Changed sleep time between directory scans from 5 to 15 seconds +# 251006-1852 - Added update of recording_live table record # $MIX=0; @@ -294,6 +295,10 @@ if($DBX){print STDERR "\n|$stmtA|\n";} $affected_rows = $dbhA->do($stmtA); # or die "Couldn't execute query:|$stmtA|\n"; + $stmtA = "UPDATE recording_live set end_time=NOW(),recording_status='FINISHED FILE-MERGE' where recording_id='$recording_id' and recording_status='STARTED';"; + if($DBX){print STDERR "\n|$stmtA|\n";} + $affected_rows = $dbhA->do($stmtA); # or die "Couldn't execute query:|$stmtA|\n"; + if (!$T) { `mv -f "$dir1/$INfile" "$dir2/ORIG/$INfile"`; diff --git a/bin/AST_flush_DBqueue.pl b/bin/AST_flush_DBqueue.pl index e135e3601..9867b58dd 100644 --- a/bin/AST_flush_DBqueue.pl +++ b/bin/AST_flush_DBqueue.pl @@ -37,6 +37,7 @@ # 240219-0811 - Added optimizing of server_live_... tables # 240709-1300 - Added Validate XFER vicidial_auto_calls: "--check-xfers" flag # 250914-1537 - Added archiving of recording_live table +# 251003-0837 - Added --preserve-dtmf flag (DTMF logs would then be kept for 1-2 days) # $session_flush=0; @@ -44,6 +45,7 @@ $reset_stuck_leads=0; $stuck_lists=''; $stuck_listsSQL=''; +$preserve_dtmf=0; $check_xfers=0; $vicidial_recording_limit=60; @@ -68,6 +70,7 @@ print " [--session-flush] = flush the vicidial_sessions_recent table\n"; print " [--reset-stuck-leads] = reset status of ERI/INCALL leads to NEW if previewed but not called\n"; print " [--stuck-lists=X] = restrict stuck leads check to these lists: X-Y-Z multiple lists separated by a single dash\n"; + print " [--preserve-dtmf] = do not purge dtmf log\n"; print " [--check-xfers] = validates that XFER status vicidial_auto_calls records are live, if not, they are deleted\n"; print "\n"; @@ -106,6 +109,12 @@ if ($Q < 1) {print "\n----- RESET STUCK LEADS ----- $reset_stuck_leads \n\n";} } + if ($args =~ /--preserve-dtmf/i) + { + $preserve_dtmf=1; + if ($Q < 1) + {print "\n----- PRESERVE DTMF LOGS ----- $preserve_dtmf \n\n";} + } if ($args =~ /--check-xfers/i) { $check_xfers=1; @@ -344,10 +353,13 @@ if (!$T) { $affected_rows = $dbhA->do($stmtA);} if (!$Q) {print " - vicidial_manager flush: $affected_rows rows\n";} -$stmtA = "DELETE from vicidial_dtmf_log where dtmf_time < '$flush_time';"; -if($DB){print STDERR "\n|$stmtA|\n";} -if (!$T) { $affected_rows = $dbhA->do($stmtA);} -if (!$Q) {print " - vicidial_dtmf_log flush: $affected_rows rows\n";} +if ($preserve_dtmf < 1) + { + $stmtA = "DELETE from vicidial_dtmf_log where dtmf_time < '$flush_time';"; + if($DB){print STDERR "\n|$stmtA|\n";} + if (!$T) { $affected_rows = $dbhA->do($stmtA);} + if (!$Q) {print " - vicidial_dtmf_log flush: $affected_rows rows\n";} + } $stmtA = "DELETE from routing_initiated_recordings where launch_time < '$flush_time';"; if($DB){print STDERR "\n|$stmtA|\n";} @@ -392,19 +404,21 @@ if (!$Q) {print " - OPTIMIZE vicidial_manager \n";} -$stmtA = "OPTIMIZE table vicidial_dtmf_log;"; -if($DB){print STDERR "\n|$stmtA|\n";} -if (!$T) - { - $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; - $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; - $sthArows=$sthA->rows; - @aryA = $sthA->fetchrow_array; - if (!$Q) {print "|",$aryA[0],"|",$aryA[1],"|",$aryA[2],"|",$aryA[3],"|","\n";} - $sthA->finish(); - } -if (!$Q) {print " - OPTIMIZE vicidial_dtmf_log \n";} - +if ($preserve_dtmf < 1) + { + $stmtA = "OPTIMIZE table vicidial_dtmf_log;"; + if($DB){print STDERR "\n|$stmtA|\n";} + if (!$T) + { + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + @aryA = $sthA->fetchrow_array; + if (!$Q) {print "|",$aryA[0],"|",$aryA[1],"|",$aryA[2],"|",$aryA[3],"|","\n";} + $sthA->finish(); + } + if (!$Q) {print " - OPTIMIZE vicidial_dtmf_log \n";} + } $stmtA = "OPTIMIZE table routing_initiated_recordings;"; if($DB){print STDERR "\n|$stmtA|\n";} @@ -1099,7 +1113,7 @@ $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; $sthArows = $sthA->rows; - if (!$Q) {print "$sthArows rows delete from recording_live_log table: |$OR_recording_id[$orc]|$OR_user[$orc]|$OR_lead_id[$orc]|\n";} + if (!$Q) {print "$sthArows rows delete from recording_live table: |$OR_recording_id[$orc]|$OR_user[$orc]|$OR_lead_id[$orc]|\n";} } $orc++; } diff --git a/bin/AST_manager_listen_AMI2.pl b/bin/AST_manager_listen_AMI2.pl index e6790dd0a..bf6bd226c 100644 --- a/bin/AST_manager_listen_AMI2.pl +++ b/bin/AST_manager_listen_AMI2.pl @@ -17,7 +17,7 @@ # the ADMIN_keepalive_ALL.pl script, which makes sure it is always running in a # screen, provided that the astguiclient.conf keepalive setting "2" is set. # -# Copyright (C) 2021 Matt Florell LICENSE: AGPLv2 +# Copyright (C) 2025 Matt Florell LICENSE: AGPLv2 # # CHANGES # 170915-2106 - Initial version based off the orginal AST_manager_listen.pl script @@ -25,6 +25,8 @@ # 170930-0923 - Commented out handle_sip_event and handle_cpd_event functions, not needed anymore, to be deleted later # 190121-1505 - Added RA_USER_PHONE On-Hook CID to solve last RINGAGENT issues # 210407-2009 - Added Event handlers for new manager events +# 251007-2110 - Added code for recording_dtmf_detection and recording_dtmf_muting +# # constants $DB=0; # Debug flag, set to 0 for no debug messages, lots of output @@ -162,6 +164,20 @@ } $sthA->finish(); +### Grab System Settings values from the database +$stmtA = "SELECT recording_dtmf_detection,recording_dtmf_muting FROM system_settings;"; +$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; +$sthA->execute or die "executing: $stmtA ", $dbhA->errstr; +$sthArows=$sthA->rows; +if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $SSrecording_dtmf_detection = $aryA[0]; + $SSrecording_dtmf_muting = $aryA[1]; + } +$sthA->finish(); + + if (!$telnet_port) {$telnet_port = '5038';} $event_string='LOGGED INTO MYSQL SERVER ON 1 CONNECTION|'; @@ -866,6 +882,111 @@ sub handle_dtmf_begin_event $dtmf_string = "$HRnow_date|$s_hires|$usec|$event_hash{'Channel'}|$event_hash{'Uniqueid'}|$event_hash{'Digit'}|$event_hash{'Direction'}|Begin|$event_hash{'CallerIDName'}"; &dtmf_logger; + $temp_server_ip = $event_hash{'ServerIP'}; + $temp_channel = $event_hash{'Channel'}; + ##### BEGIN - if recording_dtmf_detection is enabled, check for recordings on this channel ##### + if ( ($SSrecording_dtmf_detection > 0) && ( ($temp_channel !~ /Local\/5\d\d\d\d\d\d\d@default/i) || ( ($temp_channel =~ /Local\/5\d\d\d\d\d\d\d@default/i) && ($temp_channel =~ /;1$/) ) ) ) + { + $channelSQL = "channel='$temp_channel'"; + if (($temp_channel =~ /Local\/5\d\d\d\d\d\d\d@default/i)) + { + $temp_rec_channel = $temp_channel; + $temp_rec_channel =~ s/-.*//gi; + $channelSQL = "channel='$temp_rec_channel'"; + } + $rec_live_match=0; + $stmtA = "SELECT count(*) FROM recording_live where $channelSQL and server_ip='$temp_server_ip' and recording_status='STARTED';"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArowsREC=$sthA->rows; + if ($sthArowsREC > 0) + { + @aryA = $sthA->fetchrow_array; + $rec_live_match = $aryA[0]; + } + $sthA->finish(); + if($DBX){print STDERR "$sthArowsREC|$rec_live_match|$stmtA|\n";} + + if ($rec_live_match > 0) + { + $temp_recording_id = ''; + $rec_channel = ''; + $dtmf_detected = 0; + $dtmf_muting = 0; + $dtmf_muting_seconds = 0; + $mute_state = ''; + $recording_type = ''; + $recording_filename = ''; + $rec_lead_id = 0; + $NEXTdtmf_muting = 0; + + $stmtA = "SELECT recording_id,channel,dtmf_detected,dtmf_muting,dtmf_muting_seconds,mute_state,recording_type,filename,lead_id FROM recording_live where $channelSQL and server_ip='$temp_server_ip' and recording_status='STARTED' order by recording_id limit 1;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArowsRECdetail=$sthA->rows; + if ($sthArowsRECdetail > 0) + { + @aryA = $sthA->fetchrow_array; + $temp_recording_id = $aryA[0]; + $rec_channel = $aryA[1]; + $dtmf_detected = $aryA[2]; + $dtmf_muting = $aryA[3]; + $dtmf_muting_seconds = $aryA[4]; + $mute_state = $aryA[5]; + $recording_type = $aryA[6]; + $recording_filename = $aryA[7]; + $rec_lead_id = $aryA[8]; + $NEXTdtmf_muting = ($dtmf_muting + 1); + } + $sthA->finish(); + + if ( ($SSrecording_dtmf_muting > 0) && ($dtmf_muting_seconds > 0) && ($sthArowsRECdetail > 0) ) + { + $mute_stateSQL=''; + if ($mute_state < 1) + {$mute_stateSQL="mute_state='1', dtmf_muting='$NEXTdtmf_muting',";} + # update recording_live record, trigger dtmf muting and increment dtmf_detected counter + $stmtA = "UPDATE recording_live SET $mute_stateSQL dtmf_detected='$NEXTdtmf_muting' where recording_id='$temp_recording_id';"; + my $affected_rows = $dbhA->do($stmtA); + if($DBX){print STDERR "$affected_rows|$stmtA|\n";} + + # if dtmf muting is triggered, then send the command to mute the channel and update the recording_live record + if (length($mute_stateSQL) > 10) + { + $mute_direction = 'both'; + if ( ($recording_type eq 'MONO_LEGACY') || ($recording_type eq 'MONO_LEGACY_RIR') ) + {$mute_direction = 'both';} + if ( ($recording_type !~ /PARALLEL/) && ($recording_type =~ /CUSTOMER_ONLY|SACCO|SACICO|SACRCO/) ) + {$mute_direction = 'read';} + if ( ($recording_type !~ /PARALLEL/) && ($recording_type =~ /CUSTOMER_MUTE|SACCM|SACICM|SACRCM/) ) + {$mute_direction = 'write';} + $vmgr_callerid = substr($recording_filename, -15) . 'DTMFM'; + $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$temp_server_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $temp_channel','Direction: $mute_direction','State: 1','','','','','','');"; + my $affected_rowsVM = $dbhA->do($stmtE); + if($DBX){print STDERR "$affected_rowsVM|$stmtE|\n";} + + $stmtC = "UPDATE recording_live SET mute_state='2', dtmf_muting_end_time=NOW() + INTERVAL $dtmf_muting_seconds SECOND where recording_id='$temp_recording_id';"; + my $affected_rowsRL = $dbhA->do($stmtC); + if($DBX){print STDERR "$affected_rowsRL|$stmtC|\n";} + + $stmtB="INSERT INTO recording_dtmf_muting_log SET recording_id='$temp_recording_id',recording_type='$recording_type',server_ip='$temp_server_ip',channel='$rec_channel',channel_to_mute='$temp_channel',filename='$recording_filename',lead_id='$rec_lead_id',campaign_id='',trigger_dtmf='$event_hash{'Digit'}',dtmf_muting='$NEXTdtmf_muting',dtmf_muting_start_time=NOW(),dtmf_muting_end_time=NOW() + INTERVAL $dtmf_muting_seconds SECOND,dtmf_muting_seconds='$dtmf_muting_seconds',mute_state='2';"; + my $affected_rowsML = $dbhA->do($stmtB); + if($DBX){print STDERR "$affected_rowsML|$stmtB|\n";} + } + } + else + { + if ($sthArowsRECdetail > 0) + { + # update recording_live record, increment dtmf_detected counter + $stmtA = "UPDATE recording_live SET dtmf_detected='$NEXTdtmf_muting' where recording_id='$temp_recording_id';"; + my $affected_rows = $dbhA->do($stmtA); + if($DBX){print STDERR "$affected_rows|$stmtA|\n";} + } + } + } + } + ##### END - if recording_dtmf_detection is enabled, check for recordings on this channel ##### return 1; } else diff --git a/bin/AST_update_AMI2.pl b/bin/AST_update_AMI2.pl index 6c15b632f..c28e60edc 100644 --- a/bin/AST_update_AMI2.pl +++ b/bin/AST_update_AMI2.pl @@ -5,7 +5,7 @@ # This script uses the Asterisk Manager interface to update the live_channels # tables and verify the parked_channels table in the asterisk MySQL database # -# Copyright (C) 2022 Matt Florell LICENSE: AGPLv2 +# Copyright (C) 2025 Matt Florell LICENSE: AGPLv2 # # CHANGES # 170915-2110 - Initial version for Asterisk 13, based upon AST_update.pl @@ -19,6 +19,7 @@ # 210315-1045 - Populate the CIDname in live_sip_channels/live_channels tables, Issue #1255 # 210827-0930 - Added PJSIP compatibility # 220310-1136 - Fix for issue dealing with bad carrier 'P-Asserted-Identity' input +# 251008-2114 - Added code for recording_dtmf_detection and recording_dtmf_muting # # constants @@ -38,6 +39,9 @@ # how often performance logging is triggered $performance_logging_interval = 5; +# dtmf-check last second +$dtmf_check_last_time = 999999; + ### begin parsing run-time options ### if (length($ARGV[0])>1) { @@ -192,6 +196,19 @@ if (!$telnet_port) {$telnet_port = '5038';} +### Grab System Settings values from the database +$stmtA = "SELECT recording_dtmf_detection,recording_dtmf_muting FROM system_settings;"; +$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; +$sthA->execute or die "executing: $stmtA ", $dbhA->errstr; +$sthArows=$sthA->rows; +if ($sthArows > 0) + { + @aryA = $sthA->fetchrow_array; + $SSrecording_dtmf_detection = $aryA[0]; + $SSrecording_dtmf_muting = $aryA[1]; + } +$sthA->finish(); + ##### Check for a server_updater record, and if not present, insert one $SUrec=0; @@ -642,7 +659,6 @@ } else { - # Process the channel list $counts = process_channels($dbhA,$chan_array_ref,$phones_ref,$db_trunks_ref,$db_clients_ref,$server_ip,$old_counts); @@ -663,6 +679,18 @@ $last_perf_log = time(); } + # check for if dtmf-muted recordings to stop, if recording_dtmf_detection and recording_dtmf_muting are active + if ( ($SSrecording_dtmf_detection > 0) && ($SSrecording_dtmf_muting > 0) ) + { + if ($dtmf_check_last_time != $current_time_sec) + { + # dtmf muting stop check hasn't run this second, so check for them + &dtmf_muting_stop_check; + + $dtmf_check_last_time = $current_time_sec; + } + } + # figure out how long that loop took. # get the current time ( $now_sec, $now_micro_sec ) = gettimeofday(); @@ -1462,8 +1490,102 @@ sub get_time_now #get the current date and time and epoch for logging call lengt $now_date_epoch = time(); $now_date = "$year-$mon-$mday $hour:$min:$sec"; $action_log_date = "$year-$mon-$mday"; + $current_time_sec = "$hour$min$sec"; + $current_time_sec = ($current_time_sec + 0); } +sub dtmf_muting_stop_check + { + $mute_to_stop_count=0; + ### Get count of dtmf muted recordings that should be un-muted + $stmtA = "SELECT count(*) FROM recording_live WHERE mute_state='2' and dtmf_muting_end_time <= '$now_date' and recording_status='STARTED' and server_ip='$server_ip';"; + $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; + $mute_to_stop_count = $aryA[0]; + } + $sthA->finish(); + + if ($DB) {print "DEBUG: DTMF Mute Stop Check: $mute_to_stop_count |$sthArows|$stmtA|\n";} + + if ($mute_to_stop_count > 0) + { + # gather details on all recordings that need to be un-muted + $stmtA = "SELECT recording_id,channel,dtmf_detected,dtmf_muting,dtmf_muting_seconds,mute_state,recording_type,filename,lead_id FROM recording_live where mute_state='2' and dtmf_muting_end_time <= '$now_date' and dtmf_muting_end_time != '2020-12-31 23:59:59' and recording_status='STARTED' and server_ip='$server_ip' order by recording_id limit 1;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArowsRECdetail=$sthA->rows; + $rl_ct=0; + while ($sthArowsRECdetail > $rl_ct) + { + @aryA = $sthA->fetchrow_array; + $temp_recording_id[$rl_ct] = $aryA[0]; + $rec_channel[$rl_ct] = $aryA[1]; + $dtmf_detected[$rl_ct] = $aryA[2]; + $dtmf_muting[$rl_ct] = $aryA[3]; + $dtmf_muting_seconds[$rl_ct] = $aryA[4]; + $mute_state[$rl_ct] = $aryA[5]; + $recording_type[$rl_ct] = $aryA[6]; + $recording_filename[$rl_ct] = $aryA[7]; + $rec_lead_id[$rl_ct] = $aryA[8]; + + $rl_ct++; + } + $sthA->finish(); + + # go through each recording and un-mute the recording + $rl_ct=0; + while ($sthArowsRECdetail > $rl_ct) + { + # update recording_live record, trigger dtmf muting and increment dtmf_detected counter + $stmtA = "UPDATE recording_live SET mute_state='3' where recording_id='$temp_recording_id[$rl_ct]';"; + my $affected_rows = $dbhA->do($stmtA); + if($DBX){print STDERR "$affected_rows|$stmtA|\n";} + + $channel_to_mute = $rec_channel[$rl_ct]; + $dtmf_mute_id=0; + ### Get channel name of channel that should be un-muted + $stmtA = "SELECT channel_to_mute,dtmf_mute_id FROM recording_dtmf_muting_log WHERE recording_id='$temp_recording_id[$rl_ct]' and mute_state='2' order by dtmf_mute_id desc limit 1;"; + $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; + $channel_to_mute = $aryA[0]; + $dtmf_mute_id = $aryA[1]; + } + $sthA->finish(); + + $mute_direction = 'both'; + if ( ($recording_type[$rl_ct] eq 'MONO_LEGACY') || ($recording_type[$rl_ct] eq 'MONO_LEGACY_RIR') ) + {$mute_direction = 'both';} + if ( ($recording_type[$rl_ct] !~ /PARALLEL/) && ($recording_type[$rl_ct] =~ /CUSTOMER_ONLY|SACCO|SACICO|SACRCO/) ) + {$mute_direction = 'read';} + if ( ($recording_type[$rl_ct] !~ /PARALLEL/) && ($recording_type[$rl_ct] =~ /CUSTOMER_MUTE|SACCM|SACICM|SACRCM/) ) + {$mute_direction = 'write';} + $vmgr_callerid = substr($recording_filename[$rl_ct], -15) . 'DTMFU'; + $stmtE="INSERT INTO vicidial_manager values('','','$now_date','NEW','N','$server_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel_to_mute','Direction: $mute_direction','State: 0','','','','','','');"; + my $affected_rowsVM = $dbhA->do($stmtE); + if($DBX){print STDERR "$affected_rowsVM|$stmtE|\n";} + + $stmtC = "UPDATE recording_live SET mute_state='0', dtmf_muting_end_time='$now_date' where recording_id='$temp_recording_id[$rl_ct]';"; + my $affected_rowsRL = $dbhA->do($stmtC); + if($DBX){print STDERR "$affected_rowsRL|$stmtC|\n";} + + $stmtB = "UPDATE recording_dtmf_muting_log SET mute_state='4',dtmf_muting_end_time='$now_date' WHERE dtmf_mute_id='$dtmf_mute_id';"; + my $affected_rowsML = $dbhA->do($stmtB); + if($DBX){print STDERR "$affected_rowsML|$stmtB|\n";} + + if ($DB) {print "DEBUG: DTMF Mute Stopped: $temp_recording_id[$rl_ct] $rl_ct\n";} + + $rl_ct++; + } + } + } # try to load a module sub try_load diff --git a/docs/STEREO_CALL_RECORDINGS.txt b/docs/STEREO_CALL_RECORDINGS.txt index c0ef3ce99..f742380ac 100644 --- a/docs/STEREO_CALL_RECORDINGS.txt +++ b/docs/STEREO_CALL_RECORDINGS.txt @@ -1,7 +1,7 @@ -VICIDIAL STEREO CALL RECORDINGS Started: 2025-06-18 Updated: 2025-10-01 +VICIDIAL STEREO CALL RECORDINGS Started: 2025-06-18 Updated: 2025-10-20 -TO USE THESE FEATURES, YOU WILL NEED TO HAVE ALL SERVERS IN YOUR CLUSTER USING SVN/TRUNK REVISION 3947(2025-10-01) CODE OR HIGHER!!! +TO USE THESE FEATURES, YOU WILL NEED TO HAVE ALL SERVERS IN YOUR CLUSTER USING SVN/TRUNK REVISION 3949(2025-10-20) CODE OR HIGHER!!! This project was designed to allow for additional stereo recording of phone calls at the agent and server levels directly on VICIdial Asterisk servers, with the customer always on one channel(the Right channel) and the agent and all other parties on the other channel(the Left channel). If you are looking for the VICI Gateway Recording Server documentation, please see the GATEWAY_RECORDING_SERVER.txt document. @@ -21,10 +21,9 @@ This project has been broken down into 4 phases of development, since it is so l ***COMPLETE*** 4) Live recording muting based on DTMF receipt and un-muting after x seconds of being muted(campaign setting), for both new customer-channel-stereo and legacy-mono agent session recordings. -***STILL-IN-DEVELOPMENT*** +***COMPLETE AS OF SVN/TRUNK REVISION 3949(2025-10-20)*** -While the above development phases will be worked-on in the order they are above, there are portions of the later phases that will be implemented as early as the first phase due to shared processes needed for the later phases. ------------------------------------------------------------------------------------------------- @@ -43,8 +42,13 @@ For In-groups, the "Stereo Recording" options do NOT default to inherit settings For all of Stereo Recording, the agent-controlled Mute Recordings feature will not be available. This is because of all of the complexity already included in the Customer-Only, Customer-Muted and Recording DTMF Muting features that are to be built into Stereo Recording. Also, in the existing default mono call recording, if the Recording DTMF Muting feature is enabled, then the agent-controlled Mute Recordings feature will not be available. -For Recording DTMF Muting (STILL BEING DEVELOPED), this is NOT designed to mute 100% of the DTMF audio in a recording, it is meant to trigger a fixed time period of muting of the channel sending the DTMF audio AFTER a DTMF digit is detected. As a note, on many VICIdial systems, audible DTMF is already muted and converted into out-of-band DTMF signalling in many channel types by default, so this feature may not be necessary for all organizations. This setting is a number of seconds to mute the channel, with '0' being disabled. the default is '0'. +For Recording DTMF Muting, this is NOT designed to mute 100% of the DTMF audio in a recording, it is meant to trigger a fixed time period of muting of the call recording AFTER a DTMF digit is detected. If Recording DTMF Muting is active for a campaign/in-group, it will affect both Mono Legacy and Stereo call recordings for those calls. As a note, on many VICIdial systems, audible DTMF is already muted and converted into out-of-band DTMF signalling in many channel types by default, so this feature may not be necessary for all organizations. This setting is a number of seconds to mute the channel, with '0' being disabled. the default is '0'. To use this feature, you will need to enable both "Allow Recording DTMF Detection" and "Allow Recording DTMF Muting" in System Settings. +IMPORTANT NOTE FOR RECORDING DTMF MUTING: Once enabled in the system settings, make sure you set the "Reload Dialplan On Servers" system settingss option to '1' and submit. This will make sure all of the call recording functions in the dialplan are using MixMonitor, which is what is required for Recording DTMF Muting to work properly. + +Also for Recording DTMF Muting, just like with Stereo Call Recording, each campaign and in-group that you want to have Recording DTMF Muting active for will need to have it enabled, there is no inheritance of that setting from campaign to in-groups. However, if you want to enable Recording DTMF Muting for all call recordings on a system with the same number of muting seconds on all calls, you can use the System Setting "Allow Recording DTMF Muting" setting set to a number 2 or greater to do this. + +When there is more than one recording on the same channel, Recording DTMF Muting logging will only log for one of the recordings on that channel, even though the muting will affect all recordings on that channel. @@ -171,6 +175,11 @@ List of recording_log.extension values with recording_log_stereo.recording_type MONO_LEGACY_RIR MONO_LEGACY_REMOTE MONO_LEGACY_SURVEY + MONO_LEGACY_NVA + MONO_LEGACY_DID + MONO_LEGACY_AMD + MONO_LEGACY_VERIF + MONO_LEGACY_3WAY STEREO_AGENT STEREO_DID SPACBC STEREO_PARALLEL AGENT-CONTROLLED BOTH_CHANNELS @@ -183,18 +192,21 @@ SPCO STEREO_PARALLEL CUSTOMER-ONLY SPCM STEREO_PARALLEL CUSTOMER-MUTED SPFR STEREO_PARALLEL FULL-RECORDING SPACI STEREO_PARALLEL AGENT-CONTROLLED RIR -SACI STEREO AGENT-CONTROLLED RIR +SACIBC STEREO AGENT-CONTROLLED RIR BOTH_CHANNELS +SACICO STEREO AGENT-CONTROLLED RIR CUSTOMER_ONLY +SACICM STEREO AGENT-CONTROLLED RIR CUSTOMER_MUTE SPCOR STEREO_PARALLEL CUSTOMER-ONLY REMOTE SPCMR STEREO_PARALLEL CUSTOMER-MUTED REMOTE SPFRR STEREO_PARALLEL FULL-RECORDING REMOTE SPACR STEREO_PARALLEL AGENT-CONTROLLED REMOTE -SACR STEREO AGENT-CONTROLLED REMOTE - +SACRBC STEREO AGENT-CONTROLLED REMOTE BOTH_CHANNELS +SACRCO STEREO AGENT-CONTROLLED REMOTE CUSTOMER_ONLY +SACRCM STEREO AGENT-CONTROLLED REMOTE CUSTOMER_MUTE ------------------------------------------------------------------------------------------------- -List of scripts modified/created for these new Stereo Call Recording features: +List of scripts modified/created for these new Stereo Call Recording and Recording DTMF Muting features: - agc/vicidial.php - agc/vdc_db_query.php - agc/manager_send.php @@ -204,12 +216,21 @@ List of scripts modified/created for these new Stereo Call Recording features: - install.pl - AST_CRON_audio_1_move_VDonly.pl - AST_CRON_audio_1_stereo.pl +- AST_CRON_audio_1_move_mix.pl - AST_CRON_audio_2_compress.pl - AST_flush_DBqueue.pl - ADMIN_keepalive_ALL.pl - ADMIN_archive_log_tables.pl +- AST_update_AMI2.pl +- AST_manager_listen_AMI2.pl - agi-VDAD_ALL_inbound.agi - agi-VDAD_ALL_outbound.agi +- VD_amd.agi +- agi-VDAD_RINGALL.agi +- agi-NVA_recording.agi +- agi-IVR_recording_verification.agi +- agi-DID_route.agi + @@ -346,23 +367,33 @@ index(recording_id), index(dtmf_muting_end_time) ) ENGINE=MyISAM; -CREATE TABLE recording_dtmf_log ( -recording_id INT(10) UNSIGNED PRIMARY KEY NOT NULL, +CREATE TABLE recording_log_parallel_archive LIKE recording_log_parallel; +CREATE TABLE recording_log_stereo_archive LIKE recording_log_stereo; + +CREATE TABLE recording_dtmf_muting_log ( +dtmf_mute_id INT(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL, +recording_id INT(10) UNSIGNED NOT NULL, recording_type VARCHAR(40) default 'MONO_LEGACY', server_ip VARCHAR(15), channel VARCHAR(255), +channel_to_mute VARCHAR(255), filename VARCHAR(100), lead_id INT(9) UNSIGNED, -dtmf_muting TINYINT(3) UNSIGNED default '0', +campaign_id VARCHAR(20) default '', +trigger_dtmf VARCHAR(100) default '', +dtmf_muting SMALLINT(3) UNSIGNED default '0', dtmf_muting_start_time DATETIME, dtmf_muting_end_time DATETIME, dtmf_muting_seconds TINYINT(3) UNSIGNED default '0', mute_state TINYINT(3) UNSIGNED default '0', index(filename), -index(lead_id), index(recording_id), index(dtmf_muting_end_time) ) ENGINE=MyISAM; -CREATE TABLE recording_log_parallel_archive LIKE recording_log_parallel; -CREATE TABLE recording_log_stereo_archive LIKE recording_log_stereo; +CREATE TABLE recording_dtmf_muting_log_archive LIKE recording_dtmf_muting_log; +ALTER TABLE recording_dtmf_muting_log_archive MODIFY dtmf_mute_id INT(10) UNSIGNED NOT NULL; +CREATE UNIQUE INDEX rdml_key on recording_dtmf_muting_log_archive(dtmf_mute_id, recording_id); + +CREATE INDEX rllst on recording_live_log(start_time); +CREATE TABLE recording_live_log_archive LIKE recording_live_log; diff --git a/extras/MySQL_AST_CREATE_tables.sql b/extras/MySQL_AST_CREATE_tables.sql index 035e96643..e01bf07a3 100644 --- a/extras/MySQL_AST_CREATE_tables.sql +++ b/extras/MySQL_AST_CREATE_tables.sql @@ -5428,20 +5428,23 @@ index(recording_id), index(dtmf_muting_end_time) ) ENGINE=MyISAM; -CREATE TABLE recording_dtmf_log ( -recording_id INT(10) UNSIGNED PRIMARY KEY NOT NULL, +CREATE TABLE recording_dtmf_muting_log ( +dtmf_mute_id INT(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL, +recording_id INT(10) UNSIGNED NOT NULL, recording_type VARCHAR(40) default 'MONO_LEGACY', server_ip VARCHAR(15), channel VARCHAR(255), +channel_to_mute VARCHAR(255), filename VARCHAR(100), lead_id INT(9) UNSIGNED, -dtmf_muting TINYINT(3) UNSIGNED default '0', +campaign_id VARCHAR(20) default '', +trigger_dtmf VARCHAR(100) default '', +dtmf_muting SMALLINT(3) UNSIGNED default '0', dtmf_muting_start_time DATETIME, dtmf_muting_end_time DATETIME, dtmf_muting_seconds TINYINT(3) UNSIGNED default '0', mute_state TINYINT(3) UNSIGNED default '0', index(filename), -index(lead_id), index(recording_id), index(dtmf_muting_end_time) ) ENGINE=MyISAM; @@ -5607,6 +5610,8 @@ CREATE INDEX vlecc on vicidial_log_extended (caller_code); CREATE UNIQUE INDEX vvmmcount on vicidial_vmm_counts (lead_id,call_date); CREATE UNIQUE INDEX vicidial_user_logins_daily_user on vicidial_user_logins_daily(login_day, user); +CREATE INDEX vdtmflt on vicidial_dtmf_log (dtmf_time); + CREATE INDEX vlali on vicidial_live_agents (lead_id); CREATE INDEX vlaus on vicidial_live_agents (user); @@ -5754,6 +5759,14 @@ CREATE UNIQUE INDEX vdpla on vicidial_3way_press_log_archive (call_date,caller_c CREATE TABLE vicidial_daily_rt_monitoring_log LIKE vicidial_rt_monitor_log; +CREATE TABLE recording_dtmf_muting_log_archive LIKE recording_dtmf_muting_log; +ALTER TABLE recording_dtmf_muting_log_archive MODIFY dtmf_mute_id INT(10) UNSIGNED NOT NULL; +CREATE UNIQUE INDEX rdml_key on recording_dtmf_muting_log_archive(dtmf_mute_id, recording_id); + +CREATE INDEX rllst on recording_live_log(start_time); +CREATE TABLE recording_live_log_archive LIKE recording_live_log; + + GRANT RELOAD ON *.* TO cron@'%'; GRANT RELOAD ON *.* TO cron@localhost; @@ -5854,4 +5867,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='1731',db_schema_update_date=NOW(),reload_timestamp=NOW(); +UPDATE system_settings SET db_schema_version='1732',db_schema_update_date=NOW(),reload_timestamp=NOW(); diff --git a/extras/upgrade_2.14.sql b/extras/upgrade_2.14.sql index f423fc07b..2a24e1779 100644 --- a/extras/upgrade_2.14.sql +++ b/extras/upgrade_2.14.sql @@ -2985,33 +2985,48 @@ index(recording_id), index(dtmf_muting_end_time) ) ENGINE=MyISAM; -CREATE TABLE recording_dtmf_log ( -recording_id INT(10) UNSIGNED PRIMARY KEY NOT NULL, +CREATE TABLE recording_log_parallel_archive LIKE recording_log_parallel; +CREATE TABLE recording_log_stereo_archive LIKE recording_log_stereo; + +UPDATE system_settings SET db_schema_version='1729',db_schema_update_date=NOW() where db_schema_version < 1729; + +ALTER TABLE vicidial_url_multi MODIFY url_type ENUM('dispo','start','addlead','noagent','apinewlead','talk','') default ''; + +UPDATE system_settings SET db_schema_version='1730',db_schema_update_date=NOW() where db_schema_version < 1730; + +ALTER TABLE vicidial_campaigns ADD call_count_limit_restrict VARCHAR(30) default 'DISABLED'; + +UPDATE system_settings SET db_schema_version='1731',db_schema_update_date=NOW() where db_schema_version < 1731; + +CREATE INDEX vdtmflt on vicidial_dtmf_log (dtmf_time); + +CREATE TABLE recording_dtmf_muting_log ( +dtmf_mute_id INT(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL, +recording_id INT(10) UNSIGNED NOT NULL, recording_type VARCHAR(40) default 'MONO_LEGACY', server_ip VARCHAR(15), channel VARCHAR(255), +channel_to_mute VARCHAR(255), filename VARCHAR(100), lead_id INT(9) UNSIGNED, -dtmf_muting TINYINT(3) UNSIGNED default '0', +campaign_id VARCHAR(20) default '', +trigger_dtmf VARCHAR(100) default '', +dtmf_muting SMALLINT(3) UNSIGNED default '0', dtmf_muting_start_time DATETIME, dtmf_muting_end_time DATETIME, dtmf_muting_seconds TINYINT(3) UNSIGNED default '0', mute_state TINYINT(3) UNSIGNED default '0', index(filename), -index(lead_id), index(recording_id), index(dtmf_muting_end_time) ) ENGINE=MyISAM; -CREATE TABLE recording_log_parallel_archive LIKE recording_log_parallel; -CREATE TABLE recording_log_stereo_archive LIKE recording_log_stereo; +CREATE TABLE recording_dtmf_muting_log_archive LIKE recording_dtmf_muting_log; +ALTER TABLE recording_dtmf_muting_log_archive MODIFY dtmf_mute_id INT(10) UNSIGNED NOT NULL; +CREATE UNIQUE INDEX rdml_key on recording_dtmf_muting_log_archive(dtmf_mute_id, recording_id); -UPDATE system_settings SET db_schema_version='1729',db_schema_update_date=NOW() where db_schema_version < 1729; +CREATE INDEX rllst on recording_live_log(start_time); -ALTER TABLE vicidial_url_multi MODIFY url_type ENUM('dispo','start','addlead','noagent','apinewlead','talk','') default ''; - -UPDATE system_settings SET db_schema_version='1730',db_schema_update_date=NOW() where db_schema_version < 1730; +CREATE TABLE recording_live_log_archive LIKE recording_live_log; -ALTER TABLE vicidial_campaigns ADD call_count_limit_restrict VARCHAR(30) default 'DISABLED'; - -UPDATE system_settings SET db_schema_version='1731',db_schema_update_date=NOW() where db_schema_version < 1731; +UPDATE system_settings SET db_schema_version='1732',db_schema_update_date=NOW() where db_schema_version < 1732; diff --git a/www/agc/manager_send.php b/www/agc/manager_send.php index 1b748d9bb..ef7468c97 100644 --- a/www/agc/manager_send.php +++ b/www/agc/manager_send.php @@ -159,10 +159,11 @@ # 240709-2010 - Changes to input variable filtering # 241122-1544 - Fix for DTMF issue #1525 # 250831-0839 - Added MonitorStereo/StopMonitorStereo functions +# 251005-0935 - Added code for recording_dtmf_muting # -$version = '2.14-106'; -$build = '250831-0839'; +$version = '2.14-107'; +$build = '251005-0935'; $php_script = 'manager_send.php'; $mel=1; # Mysql Error Log enabled = 1 $mysql_log_count=177; @@ -171,6 +172,7 @@ $startMS = microtime(); $dial_override_limit=6; $ip = getenv("REMOTE_ADDR"); +$recording_dtmf_muting=0; require_once("dbconnect_mysqli.php"); require_once("functions.php"); @@ -286,7 +288,7 @@ ############################################# ##### START SYSTEM_SETTINGS LOOKUP ##### -$stmt = "SELECT use_non_latin,allow_sipsak_messages,enable_languages,language_method,meetme_enter_login_filename,meetme_enter_leave3way_filename,agent_debug_logging,allow_web_debug,stereo_recording,stereo_parallel_recording FROM system_settings;"; +$stmt = "SELECT use_non_latin,allow_sipsak_messages,enable_languages,language_method,meetme_enter_login_filename,meetme_enter_leave3way_filename,agent_debug_logging,allow_web_debug,stereo_recording,stereo_parallel_recording,recording_dtmf_detection,recording_dtmf_muting FROM system_settings;"; $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02001',$user,$server_ip,$session_name,$one_mysql_log);} #if ($DB) {echo "$stmt\n";} @@ -304,6 +306,8 @@ $SSallow_web_debug = $row[7]; $SSstereo_recording = $row[8]; $SSstereo_parallel_recording = $row[9]; + $SSrecording_dtmf_detection = $row[10]; + $SSrecording_dtmf_muting = $row[11]; } if ($SSallow_web_debug < 1) {$DB=0;} ##### END SETTINGS LOOKUP ##### @@ -2706,6 +2710,53 @@ $recording_id = mysqli_insert_id($link); } } + + ### check for recording_dtmf_muting + $stmt="SELECT callerid FROM vicidial_live_agents where user='$user' and lead_id='$lead_id' limit 1;"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} + if ($DB) {echo "$stmt\n";} + $rec_count = mysqli_num_rows($rslt); + if ($rec_count>0) + { + $row=mysqli_fetch_row($rslt); + $USERcallerid = $row[0]; + + $stmt="SELECT campaign_id FROM vicidial_auto_calls where callerid='$USERcallerid' and lead_id='$lead_id' order by auto_call_id limit 1;"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} + if ($DB) {echo "$stmt\n";} + $vac_count = mysqli_num_rows($rslt); + if ($vac_count>0) + { + $row=mysqli_fetch_row($rslt); + $USERcampaign_id = $row[0]; + + $stmt = "SELECT recording_dtmf_muting FROM vicidial_campaigns where campaign_id='$USERcampaign_id';"; + if (preg_match("/^Y|^DC/",$USERcallerid)) + {$stmt = "SELECT recording_dtmf_muting FROM vicidial_inbound_groups where group_id='$USERcampaign_id';";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02XXX',$user,$server_ip,$session_name,$one_mysql_log);} + if ($DB) {echo "$stmt\n";} + $vic_count = mysqli_num_rows($rslt); + if ($vic_count>0) + { + $row=mysqli_fetch_row($rslt); + $recording_dtmf_muting = $row[0]; + if ( ($SSrecording_dtmf_detection < 1) or ($SSrecording_dtmf_muting < 1) ) + {$recording_dtmf_muting=0;} + } + } + } + + if ( ($SSrecording_dtmf_detection > 0) and ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + ### insert record into recording_live table ### + $stmt = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','MONO_LEGACY','$server_ip','$NOW_TIME','$channel','$filename','$lead_id','$user','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; + if ($format=='debug') {echo "\n";} + $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 ($FROMvdc=='YES') { ##### update vla record with recording_id @@ -2945,11 +2996,11 @@ ##### gather stereo recording settings for this specific campaign/in-group if ($VLA_inOUT == 'INBOUND') { - $stmt="SELECT stereo_recording,stereo_parallel_recording,stereo_rec_filename,stereo_recording_agent FROM vicidial_inbound_groups where group_id='$VDcampaign_id';"; + $stmt="SELECT stereo_recording,stereo_parallel_recording,stereo_rec_filename,stereo_recording_agent,recording_dtmf_muting FROM vicidial_inbound_groups where group_id='$VDcampaign_id';"; } else { - $stmt="SELECT stereo_recording,stereo_parallel_recording,stereo_rec_filename,stereo_recording_agent FROM vicidial_campaigns where campaign_id='$VDcampaign_id';"; + $stmt="SELECT stereo_recording,stereo_parallel_recording,stereo_rec_filename,stereo_recording_agent,recording_dtmf_muting FROM vicidial_campaigns where campaign_id='$VDcampaign_id';"; } $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02075',$user,$server_ip,$session_name,$one_mysql_log);} @@ -2962,6 +3013,9 @@ $stereo_parallel_recording = $row[1]; $stereo_rec_filename = $row[2]; $stereo_recording_agent = $row[3]; + $recording_dtmf_muting = $row[4]; + if ( ($SSrecording_dtmf_detection < 1) or ($SSrecording_dtmf_muting < 1) ) + {$recording_dtmf_muting=0;} } } @@ -3020,7 +3074,7 @@ if (preg_match("/RECID/",$filename) ) { - $stmt = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$server_ip','$stereo_exten','$NOW_TIME','$StarTtime','$stereo_rec_filename','$lead_id','$user','$VDvicidial_id')"; + $stmt = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$call_server_ip','$stereo_exten','$NOW_TIME','$StarTtime','$stereo_rec_filename','$lead_id','$user','$VDvicidial_id')"; if ($format=='debug') {echo "\n";} $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02133',$user,$server_ip,$session_name,$one_mysql_log);} @@ -3039,7 +3093,7 @@ } else { - $stmt = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$server_ip','$stereo_exten','$NOW_TIME','$StarTtime','$stereo_rec_filename','$lead_id','$user','$VDvicidial_id')"; + $stmt = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$call_server_ip','$stereo_exten','$NOW_TIME','$StarTtime','$stereo_rec_filename','$lead_id','$user','$VDvicidial_id')"; if ($format=='debug') {echo "\n";} $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02073',$user,$server_ip,$session_name,$one_mysql_log);} @@ -3068,12 +3122,14 @@ } # stereo_parallel_recording is enabled, only insert DB records, don't initiate recording - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,recording_status,parallel_recording_id) values('$recording_id','$server_ip','$NOW_TIME','0','$stereo_rec_filename','$lead_id','$VDcampaign_id STEREO_PARALLEL AGENT-CONTROLLED $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $VDvicidial_id|user: $user|channel: $channel|','STEREO START','$parallel_recording_id');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,recording_status,parallel_recording_id) values('$recording_id','$call_server_ip','$NOW_TIME','0','$stereo_rec_filename','$lead_id','$VDcampaign_id STEREO_PARALLEL AGENT-CONTROLLED $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $VDvicidial_id|user: $user|channel: $channel|','STEREO START','$parallel_recording_id');"; if ($format=='debug') {echo "\n";} $rslt=mysql_to_mysqli($stmtA, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmtA,'02166',$user,$server_ip,$session_name,$one_mysql_log);} - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL AGENT-CONTROLLED','$server_ip','$NOW_TIME','$channel','$stereo_rec_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) and ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO_PARALLEL AGENT-CONTROLLED $stereo_exten','$call_server_ip','$NOW_TIME','$channel','$stereo_rec_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; if ($format=='debug') {echo "\n";} $rslt=mysql_to_mysqli($stmtD, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmtD,'02167',$user,$server_ip,$session_name,$one_mysql_log);} @@ -3084,17 +3140,19 @@ $PATHmonitorT = '/var/spool/asterisk/monitorS'; $stereo_recording_options = "r($PATHmonitorT/$stereo_rec_filename-out.wav)t($PATHmonitorT/$stereo_rec_filename-in.wav)"; $vmgr_callerid = substr($stereo_rec_filename, 0, 17) . '...'; - $stmt="INSERT INTO vicidial_manager values('','','$NOW_TIME','NEW','N','$server_ip','','MixMonitor','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Options: $stereo_recording_options','','','','','','','');"; + $stmt="INSERT INTO vicidial_manager values('','','$NOW_TIME','NEW','N','$call_server_ip','','MixMonitor','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Options: $stereo_recording_options','','','','','','','');"; if ($format=='debug') {echo "\n";} $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02135',$user,$server_ip,$session_name,$one_mysql_log);} - $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,recording_status) values('$recording_id','$server_ip','$NOW_TIME','0','$stereo_rec_filename','$lead_id','$VDcampaign_id STEREO AGENT-CONTROLLED $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $VDvicidial_id|user: $user|channel: $channel|','STEREO START');"; + $stmtA = "INSERT INTO recording_log_stereo (recording_id,server_ip,start_time,length_in_sec,filename,lead_id,options,processing_log,recording_status) values('$recording_id','$call_server_ip','$NOW_TIME','0','$stereo_rec_filename','$lead_id','$VDcampaign_id STEREO AGENT-CONTROLLED $stereo_recording $stereo_recording_agent','start: $now_date|vicidial_id: $VDvicidial_id|user: $user|channel: $channel|','STEREO START');"; if ($format=='debug') {echo "\n";} $rslt=mysql_to_mysqli($stmtA, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmtA,'02168',$user,$server_ip,$session_name,$one_mysql_log);} - $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO AGENT-CONTROLLED','$server_ip','$NOW_TIME','$channel','$stereo_rec_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED');"; + if ( ($SSrecording_dtmf_detection > 0) and ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + $stmtD = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO AGENT-CONTROLLED $stereo_exten','$call_server_ip','$NOW_TIME','$channel','$stereo_rec_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; if ($format=='debug') {echo "\n";} $rslt=mysql_to_mysqli($stmtD, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmtD,'02169',$user,$server_ip,$session_name,$one_mysql_log);} @@ -3102,7 +3160,7 @@ if (preg_match("/CUSTOMER_ONLY/",$stereo_recording) ) { $vmgr_callerid = substr($stereo_rec_filename, 0, 16) . 'M...'; - $stmt="INSERT INTO vicidial_manager values('','','$NOW_TIME','NEW','N','$server_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: write','State: 1','','','','','','');"; + $stmt="INSERT INTO vicidial_manager values('','','$NOW_TIME','NEW','N','$call_server_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: write','State: 1','','','','','','');"; if ($format=='debug') {echo "\n";} $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02170',$user,$server_ip,$session_name,$one_mysql_log);} @@ -3110,7 +3168,7 @@ if (preg_match("/CUSTOMER_MUTE/",$stereo_recording) ) { $vmgr_callerid = substr($stereo_rec_filename, 0, 16) . 'M...'; - $stmt="INSERT INTO vicidial_manager values('','','$NOW_TIME','NEW','N','$server_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: read','State: 1','','','','','','');"; + $stmt="INSERT INTO vicidial_manager values('','','$NOW_TIME','NEW','N','$call_server_ip','','MixMonitorMute','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','Direction: read','State: 1','','','','','','');"; if ($format=='debug') {echo "\n";} $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02171',$user,$server_ip,$session_name,$one_mysql_log);} @@ -3210,14 +3268,14 @@ if (!preg_match("/PARALLEL/",$recording_type)) { # stop all stereo recordings on the customer channel - $stmt="INSERT INTO vicidial_manager values('','','$NOW_TIME','NEW','N','$server_ip','','StopMixMonitor','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','','','','','','','','');"; + $stmt="INSERT INTO vicidial_manager values('','','$NOW_TIME','NEW','N','$call_server_ip','','StopMixMonitor','$vmgr_callerid','ActionID: $vmgr_callerid','Channel: $channel','','','','','','','','');"; if ($format=='debug') {echo "\n";} $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'02177',$user,$server_ip,$session_name,$one_mysql_log);} } } ##### END StopMonitorStereo steps ##### - echo _QXZ("%1s command sent for Channel %2s on %3s",0,'',$ACTION,$channel,$server_ip)."\nFilename: $filename\nRecorDing_ID: $recording_id\n RECORDING WILL LAST UP TO 60 MINUTES\n"; + echo _QXZ("%1s command sent for Channel %2s on %3s",0,'',$ACTION,$channel,$call_server_ip)."\nFilename: $filename\nRecorDing_ID: $recording_id\n RECORDING WILL LAST UP TO 60 MINUTES\n"; } } diff --git a/www/agc/vdc_db_query.php b/www/agc/vdc_db_query.php index afca9ffa6..bd1294086 100644 --- a/www/agc/vdc_db_query.php +++ b/www/agc/vdc_db_query.php @@ -553,7 +553,7 @@ # 240612-0206 - Fix for extension_appended_cidname newer options # 240801-1140 - Code updates for PHP8 compatibility # 240830-1618 - Added manual_minimum_ring_seconds SIP action lookup code -# 240906-1646 - Added testing for stereo_recording campaign option for manual dial calls *NOT PRODUCTION READY* +# 240906-1646 - Added testing for stereo_recording campaign option for manual dial calls # 250129-0900 - Fix for PHP8 TypeError # 250224-1642 - Fix for drop_lockout_time issue with NULL last_local_call_time DROP leads # 250311-1420 - Fix for start_call_url on inbound calls where blank and campaign set to ALT @@ -563,10 +563,11 @@ # 250916-1918 - Added stereo recording features # 250923-1755 - Added talk_sec_url features # 251002-1352 - Added call_count_limit_restrict campaign option +# 251005-0931 - Added code for recording_dtmf_muting # -$version = '2.14-456'; -$build = '251002-1352'; +$version = '2.14-457'; +$build = '251005-0931'; $php_script = 'vdc_db_query.php'; $mel=1; # Mysql Error Log enabled = 1 $mysql_log_count=995; @@ -575,6 +576,7 @@ $VD_login=0; $SSagent_debug_logging=0; $pause_to_code_jump=0; +$recording_dtmf_muting=0; $startMS = microtime(); require_once("dbconnect_mysqli.php"); @@ -1094,7 +1096,7 @@ ############################################# ##### START SYSTEM_SETTINGS LOOKUP ##### -$stmt = "SELECT use_non_latin,timeclock_end_of_day,agentonly_callback_campaign_lock,alt_log_server_ip,alt_log_dbname,alt_log_login,alt_log_pass,tables_use_alt_log_db,qc_features_active,allow_emails,callback_time_24hour,enable_languages,language_method,agent_debug_logging,default_language,active_modules,allow_chats,default_phone_code,user_new_lead_limit,sip_event_logging,call_quota_lead_ranking,daily_call_count_limit,call_limit_24hour,allow_web_debug,abandon_check_queue,inbound_credits,stereo_recording,stereo_parallel_recording FROM system_settings;"; +$stmt = "SELECT use_non_latin,timeclock_end_of_day,agentonly_callback_campaign_lock,alt_log_server_ip,alt_log_dbname,alt_log_login,alt_log_pass,tables_use_alt_log_db,qc_features_active,allow_emails,callback_time_24hour,enable_languages,language_method,agent_debug_logging,default_language,active_modules,allow_chats,default_phone_code,user_new_lead_limit,sip_event_logging,call_quota_lead_ranking,daily_call_count_limit,call_limit_24hour,allow_web_debug,abandon_check_queue,inbound_credits,stereo_recording,stereo_parallel_recording,recording_dtmf_detection,recording_dtmf_muting FROM system_settings;"; $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00001',$user,$server_ip,$session_name,$one_mysql_log);} #if ($DB) {echo "$stmt\n";} @@ -1130,6 +1132,8 @@ $SSinbound_credits = $row[25]; $SSstereo_recording = $row[26]; $SSstereo_parallel_recording = $row[27]; + $SSrecording_dtmf_detection = $row[28]; + $SSrecording_dtmf_muting = $row[29]; } if ($SSallow_web_debug < 1) {$DB=0; $format='text';} ##### END SETTINGS LOOKUP ##### @@ -2433,7 +2437,7 @@ $local_call_time='24hours'; ##### gather local call time, user_group_script settings from campaign - $stmt="SELECT local_call_time,user_group_script,custom_one,custom_two,custom_three,custom_four,custom_five,state_descriptions FROM vicidial_campaigns where campaign_id='$campaign';"; + $stmt="SELECT local_call_time,user_group_script,custom_one,custom_two,custom_three,custom_four,custom_five,state_descriptions,recording_dtmf_muting FROM vicidial_campaigns where campaign_id='$campaign';"; $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00353',$user,$server_ip,$session_name,$one_mysql_log);} if ($DB) {echo "$stmt\n";} @@ -2449,6 +2453,9 @@ $camp_custom_four = $row[5]; $camp_custom_five = $row[6]; $state_descriptions = $row[7]; + $recording_dtmf_muting = $row[8]; + if ( ($SSrecording_dtmf_detection < 1) or ($SSrecording_dtmf_muting < 1) ) + {$recording_dtmf_muting=0;} } $stmt="SELECT user_group,territory FROM vicidial_users where user='$user';"; @@ -5394,6 +5401,14 @@ $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00733',$user,$server_ip,$session_name,$one_mysql_log);} + if ( ($SSrecording_dtmf_detection > 0) and ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + ### insert record into recording_live table ### + $stmt = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','MONO_LEGACY_RIR','$server_ip','$NOW_TIME','$channel','$recording_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; + if ($format=='debug') {echo "\n";} + $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);} + ##### update vla record with recording_id $stmt = "UPDATE vicidial_live_agents SET external_recording='$recording_id' where user='$user';"; if ($format=='debug') {echo "\n";} @@ -6441,7 +6456,7 @@ ### check for manual dial filter and extension append settings in campaign $use_eac=0; $use_custom_cid='N'; - $stmt = "SELECT manual_dial_filter,use_internal_dnc,use_campaign_dnc,use_other_campaign_dnc,extension_appended_cidname,start_call_url,scheduled_callbacks_auto_reschedule,dial_timeout_lead_container,daily_call_count_limit,daily_limit_manual,call_limit_24hour_method,call_limit_24hour_scope,call_limit_24hour,call_limit_24hour_override,custom_one,custom_two,custom_three,custom_four,custom_five,daily_phone_number_call_limit,state_descriptions,call_count_limit_restrict,call_count_limit FROM vicidial_campaigns where campaign_id='$campaign';"; + $stmt = "SELECT manual_dial_filter,use_internal_dnc,use_campaign_dnc,use_other_campaign_dnc,extension_appended_cidname,start_call_url,scheduled_callbacks_auto_reschedule,dial_timeout_lead_container,daily_call_count_limit,daily_limit_manual,call_limit_24hour_method,call_limit_24hour_scope,call_limit_24hour,call_limit_24hour_override,custom_one,custom_two,custom_three,custom_four,custom_five,daily_phone_number_call_limit,state_descriptions,call_count_limit_restrict,call_count_limit,recording_dtmf_muting FROM vicidial_campaigns where campaign_id='$campaign';"; $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00325',$user,$server_ip,$session_name,$one_mysql_log);} if ($DB) {echo "$stmt\n";} @@ -6472,6 +6487,9 @@ $state_descriptions = $row[20]; $call_count_limit_restrict = $row[21]; $call_count_limit = $row[22]; + $recording_dtmf_muting = $row[23]; + if ( ($SSrecording_dtmf_detection < 1) or ($SSrecording_dtmf_muting < 1) ) + {$recording_dtmf_muting=0;} } # check for user overrides @@ -7441,6 +7459,14 @@ $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00740',$user,$server_ip,$session_name,$one_mysql_log);} + if ( ($SSrecording_dtmf_detection > 0) and ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + ### insert record into recording_live table ### + $stmt = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','MONO_LEGACY_RIR','$server_ip','$NOW_TIME','$channel','$recording_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; + if ($format=='debug') {echo "\n";} + $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);} + ##### update vla record with recording_id $stmt = "UPDATE vicidial_live_agents SET external_recording='$recording_id' where user='$user';"; if ($format=='debug') {echo "\n";} @@ -8184,7 +8210,7 @@ $row=mysqli_fetch_row($rslt); if ( $row[0] == 'CONFBRIDGE' ) { - $stmt="SELECT stereo_recording,stereo_parallel_recording,stereo_rec_filename,stereo_recording_agent,parallel_rec_co_filename,parallel_rec_cm_filename,parallel_rec_fr_filename FROM vicidial_campaigns where campaign_id='$campaign';"; + $stmt="SELECT stereo_recording,stereo_parallel_recording,stereo_rec_filename,stereo_recording_agent,parallel_rec_co_filename,parallel_rec_cm_filename,parallel_rec_fr_filename,recording_dtmf_muting FROM vicidial_campaigns where campaign_id='$campaign';"; $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00921',$user,$server_ip,$session_name,$one_mysql_log);} if ($DB) {echo "$stmt\n";} @@ -8199,6 +8225,9 @@ $parallel_rec_co_filename = $row[4]; $parallel_rec_cm_filename = $row[5]; $parallel_rec_fr_filename = $row[6]; + $recording_dtmf_muting = $row[7]; + if ( ($SSrecording_dtmf_detection < 1) or ($SSrecording_dtmf_muting < 1) ) + {$recording_dtmf_muting=0;} } if ( (preg_match("/CUSTOMER|BOTH/",$stereo_recording) ) and (strlen($stereo_rec_filename) > 5) ) @@ -8302,8 +8331,10 @@ $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00927',$user,$server_ip,$session_name,$one_mysql_log);} + if ( ($SSrecording_dtmf_detection > 0) and ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } ### insert record into recording_live table ### - $stmt = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL CUSTOMER-ONLY','$server_ip','$NOW_TIME','$channel','$temp_parallel_rec_co_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED');"; + $stmt = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO_PARALLEL CUSTOMER-ONLY','$server_ip','$NOW_TIME','$channel','$temp_parallel_rec_co_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; if ($format=='debug') {echo "\n";} $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00928',$user,$server_ip,$session_name,$one_mysql_log);} @@ -8353,8 +8384,10 @@ $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00931',$user,$server_ip,$session_name,$one_mysql_log);} + if ( ($SSrecording_dtmf_detection > 0) and ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } ### insert record into recording_live table ### - $stmt = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL CUSTOMER-MUTED','$server_ip','$NOW_TIME','$channel','$temp_parallel_rec_cm_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED');"; + $stmt = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO_PARALLEL CUSTOMER-MUTED','$server_ip','$NOW_TIME','$channel','$temp_parallel_rec_cm_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; if ($format=='debug') {echo "\n";} $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00932',$user,$server_ip,$session_name,$one_mysql_log);} @@ -8404,8 +8437,10 @@ $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00935',$user,$server_ip,$session_name,$one_mysql_log);} + if ( ($SSrecording_dtmf_detection > 0) and ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } ### insert record into recording_live table ### - $stmt = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL FULL-RECORDING','$server_ip','$NOW_TIME','$channel','$temp_parallel_rec_fr_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED');"; + $stmt = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO_PARALLEL FULL-RECORDING','$server_ip','$NOW_TIME','$channel','$temp_parallel_rec_fr_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; if ($format=='debug') {echo "\n";} $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00936',$user,$server_ip,$session_name,$one_mysql_log);} @@ -8449,8 +8484,10 @@ $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00939',$user,$server_ip,$session_name,$one_mysql_log);} + if ( ($SSrecording_dtmf_detection > 0) and ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } ### insert record into recording_live table ### - $stmt = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO_PARALLEL AGENT-CONTROLLED','$server_ip','$NOW_TIME','$channel','$temp_parallel_rec_ag_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED');"; + $stmt = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO_PARALLEL AGENT-CONTROLLED','$server_ip','$NOW_TIME','$channel','$temp_parallel_rec_ag_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; if ($format=='debug') {echo "\n";} $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00940',$user,$server_ip,$session_name,$one_mysql_log);} @@ -8465,9 +8502,15 @@ if ((preg_match("/ALLCALLS|ALLFORCE/",$stereo_recording_agent))) { $stereo_ac='SAC-'.$stereo_recording_agent."\n"; + $rl_exten='SACBC'; + if (preg_match("/CUSTOMER_ONLY/",$stereo_recording) ) + {$rl_exten='SACCO';} + if (preg_match("/CUSTOMER_MUTE/",$stereo_recording) ) + {$rl_exten='SACCM';} + ## Start NON-parallel stereo call recording ## # insert a record into the recording_log table - $stmt = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$server_ip','SAC','$NOW_TIME','$StarTtime','$stereo_rec_filename','$lead_id','$user','$uniqueid')"; + $stmt = "INSERT INTO recording_log (channel,server_ip,extension,start_time,start_epoch,filename,lead_id,user,vicidial_id) values('$channel','$server_ip','$rl_exten','$NOW_TIME','$StarTtime','$stereo_rec_filename','$lead_id','$user','$uniqueid')"; if ($format=='debug') {echo "\n";} $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00941',$user,$server_ip,$session_name,$one_mysql_log);} @@ -8498,8 +8541,10 @@ $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00944',$user,$server_ip,$session_name,$one_mysql_log);} + if ( ($SSrecording_dtmf_detection > 0) and ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } ### insert record into recording_live table ### - $stmt = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status) values('$recording_id','STEREO AGENT-CONTROLLED','$server_ip','$NOW_TIME','$channel','$stereo_rec_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED');"; + $stmt = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','STEREO AGENT-CONTROLLED $rl_exten','$server_ip','$NOW_TIME','$channel','$stereo_rec_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; if ($format=='debug') {echo "\n";} $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00945',$user,$server_ip,$session_name,$one_mysql_log);} @@ -9064,7 +9109,7 @@ if ($auto_dial_level > 0) { ### check to see if campaign has alt_dial enabled - $stmt="SELECT auto_alt_dial,use_internal_dnc,use_campaign_dnc,use_other_campaign_dnc,daily_call_count_limit,daily_limit_manual,call_limit_24hour_method,call_limit_24hour_scope,call_limit_24hour,call_limit_24hour_override,auto_alt_threshold,daily_phone_number_call_limit,call_count_limit_restrict,call_count_limit FROM vicidial_campaigns where campaign_id='$campaign';"; + $stmt="SELECT auto_alt_dial,use_internal_dnc,use_campaign_dnc,use_other_campaign_dnc,daily_call_count_limit,daily_limit_manual,call_limit_24hour_method,call_limit_24hour_scope,call_limit_24hour,call_limit_24hour_override,auto_alt_threshold,daily_phone_number_call_limit,call_count_limit_restrict,call_count_limit,recording_dtmf_muting FROM vicidial_campaigns where campaign_id='$campaign';"; $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00064',$user,$server_ip,$session_name,$one_mysql_log);} if ($DB) {echo "$stmt\n";} @@ -9086,6 +9131,9 @@ $daily_phone_number_call_limit = $row[11]; $call_count_limit_restrict = $row[12]; $call_count_limit = $row[13]; + $recording_dtmf_muting = $row[14]; + if ( ($SSrecording_dtmf_detection < 1) or ($SSrecording_dtmf_muting < 1) ) + {$recording_dtmf_muting=0;} } else {$auto_alt_dial = 'NONE';} $alt_lead_done=0; @@ -10306,6 +10354,14 @@ $recording_id = mysqli_insert_id($link); } } + + if ( ($SSrecording_dtmf_detection > 0) and ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } + ### insert record into recording_live table ### + $stmt = "INSERT INTO recording_live (recording_id,recording_type,server_ip,start_time,channel,filename,lead_id,user,dtmf_muting_end_time,recording_status,dtmf_muting_seconds) values('$recording_id','MONO_LEGACY_3WAY','$server_ip','$NOW_TIME','$channel','$leave_3way_start_recording_filename','$lead_id','$user','2020-12-31 23:59:59','STARTED','$recording_dtmf_muting');"; + if ($format=='debug') {echo "\n";} + $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);} } ##### END leave_3way_start_recording if triggered ##### @@ -10457,6 +10513,7 @@ # default to $fronter=$user, closer blank $fronter = $user; $closer=''; + $recording_dtmf_muting=0; if ( (strlen($campaign)<1) || (strlen($server_ip)<1) ) { @@ -11092,7 +11149,7 @@ $ig_custom_five=''; $ig_state_descriptions=''; - $stmt = "SELECT group_name,group_color,web_form_address,fronter_display,ingroup_script,get_call_launch,xferconf_a_dtmf,xferconf_a_number,xferconf_b_dtmf,xferconf_b_number,default_xfer_group,ingroup_recording_override,ingroup_rec_filename,default_group_alias,web_form_address_two,timer_action,timer_action_message,timer_action_seconds,start_call_url,dispo_call_url,xferconf_c_number,xferconf_d_number,xferconf_e_number,uniqueid_status_display,uniqueid_status_prefix,timer_action_destination,web_form_address_three,status_group_id,inbound_survey,ingroup_script_two,browser_alert_sound,browser_alert_volume,custom_one,custom_two,custom_three,custom_four,custom_five,state_descriptions,stereo_recording,stereo_recording_agent from vicidial_inbound_groups where group_id='$VDADchannel_group';"; + $stmt = "SELECT group_name,group_color,web_form_address,fronter_display,ingroup_script,get_call_launch,xferconf_a_dtmf,xferconf_a_number,xferconf_b_dtmf,xferconf_b_number,default_xfer_group,ingroup_recording_override,ingroup_rec_filename,default_group_alias,web_form_address_two,timer_action,timer_action_message,timer_action_seconds,start_call_url,dispo_call_url,xferconf_c_number,xferconf_d_number,xferconf_e_number,uniqueid_status_display,uniqueid_status_prefix,timer_action_destination,web_form_address_three,status_group_id,inbound_survey,ingroup_script_two,browser_alert_sound,browser_alert_volume,custom_one,custom_two,custom_three,custom_four,custom_five,state_descriptions,stereo_recording,stereo_recording_agent,recording_dtmf_muting from vicidial_inbound_groups where group_id='$VDADchannel_group';"; if ($DB) {echo "$stmt\n";} $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00119',$user,$server_ip,$session_name,$one_mysql_log);} @@ -11139,6 +11196,9 @@ $ig_state_descriptions = $row[37]; $stereo_recording = $row[38]; $stereo_recording_agent = $row[39]; + $recording_dtmf_muting = $row[40]; + if ( ($SSrecording_dtmf_detection < 1) or ($SSrecording_dtmf_muting < 1) ) + {$recording_dtmf_muting=0;} $status_group_gather_data = status_group_gather($row[27],'INGROUP'); @@ -11524,9 +11584,11 @@ } } + if ( ($SSrecording_dtmf_detection > 0) and ($SSrecording_dtmf_muting > 0) ) + {if ($SSrecording_dtmf_muting > 1) {$recording_dtmf_muting = $SSrecording_dtmf_muting;} } ### if web form is set then send on to vicidial.php for override of WEB_FORM address - if ( (strlen($VDCL_group_web)>5) or (strlen($VDCL_group_name)>0) ) {echo "$VDCL_group_web|$VDCL_group_name|$VDCL_group_color|$VDCL_fronter_display|$VDADchannel_group|$VDCL_ingroup_script|$VDCL_get_call_launch|$VDCL_xferconf_a_dtmf|$VDCL_xferconf_a_number|$VDCL_xferconf_b_dtmf|$VDCL_xferconf_b_number|$VDCL_default_xfer_group|$VDCL_ingroup_recording_override|$VDCL_ingroup_rec_filename|$VDCL_default_group_alias|$VDCL_caller_id_number|$VDCL_group_web_vars|$VDCL_group_web_two|$VDCL_timer_action|$VDCL_timer_action_message|$VDCL_timer_action_seconds|$VDCL_xferconf_c_number|$VDCL_xferconf_d_number|$VDCL_xferconf_e_number|$VDCL_uniqueid_status_display|$custom_call_id|$VDCL_uniqueid_status_prefix|$VDCL_timer_action_destination|$DID_id|$DID_extension|$DID_pattern|$DID_description|$INclosecallid|$INxfercallid|$VDCL_group_web_three|$VDCL_ingroup_script_color|$VDCL_inbound_survey|$VDCL_survey_participate|$VDCL_ingroup_script_two|$VDCL_ingroup_script_color_two|$VDCL_browser_alert_sound|$VDCL_browser_alert_volume|$stereo_recording|$stereo_recording_agent|$talk_sec_urls_secs|\n";} - else {echo "X|$VDCL_group_name|$VDCL_group_color|$VDCL_fronter_display|$VDADchannel_group|$VDCL_ingroup_script|$VDCL_get_call_launch|$VDCL_xferconf_a_dtmf|$VDCL_xferconf_a_number|$VDCL_xferconf_b_dtmf|$VDCL_xferconf_b_number|$VDCL_default_xfer_group|$VDCL_ingroup_recording_override|$VDCL_ingroup_rec_filename|$VDCL_default_group_alias|$VDCL_caller_id_number|$VDCL_group_web_vars|$VDCL_group_web_two|$VDCL_timer_action|$VDCL_timer_action_message|$VDCL_timer_action_seconds|$VDCL_xferconf_c_number|$VDCL_xferconf_d_number|$VDCL_xferconf_e_number|$VDCL_uniqueid_status_display|$custom_call_id|$VDCL_uniqueid_status_prefix|$VDCL_timer_action_destination|$DID_id|$DID_extension|$DID_pattern|$DID_description|$INclosecallid|$INxfercallid|$VDCL_group_web_three|$VDCL_ingroup_script_color|$VDCL_inbound_survey|$VDCL_survey_participate|$VDCL_ingroup_script_two|$VDCL_ingroup_script_color_two|$VDCL_browser_alert_sound|$VDCL_browser_alert_volume|$stereo_recording|$stereo_recording_agent|$talk_sec_urls_secs|\n";} + if ( (strlen($VDCL_group_web)>5) or (strlen($VDCL_group_name)>0) ) {echo "$VDCL_group_web|$VDCL_group_name|$VDCL_group_color|$VDCL_fronter_display|$VDADchannel_group|$VDCL_ingroup_script|$VDCL_get_call_launch|$VDCL_xferconf_a_dtmf|$VDCL_xferconf_a_number|$VDCL_xferconf_b_dtmf|$VDCL_xferconf_b_number|$VDCL_default_xfer_group|$VDCL_ingroup_recording_override|$VDCL_ingroup_rec_filename|$VDCL_default_group_alias|$VDCL_caller_id_number|$VDCL_group_web_vars|$VDCL_group_web_two|$VDCL_timer_action|$VDCL_timer_action_message|$VDCL_timer_action_seconds|$VDCL_xferconf_c_number|$VDCL_xferconf_d_number|$VDCL_xferconf_e_number|$VDCL_uniqueid_status_display|$custom_call_id|$VDCL_uniqueid_status_prefix|$VDCL_timer_action_destination|$DID_id|$DID_extension|$DID_pattern|$DID_description|$INclosecallid|$INxfercallid|$VDCL_group_web_three|$VDCL_ingroup_script_color|$VDCL_inbound_survey|$VDCL_survey_participate|$VDCL_ingroup_script_two|$VDCL_ingroup_script_color_two|$VDCL_browser_alert_sound|$VDCL_browser_alert_volume|$stereo_recording|$stereo_recording_agent|$talk_sec_urls_secs|$recording_dtmf_muting|\n";} + else {echo "X|$VDCL_group_name|$VDCL_group_color|$VDCL_fronter_display|$VDADchannel_group|$VDCL_ingroup_script|$VDCL_get_call_launch|$VDCL_xferconf_a_dtmf|$VDCL_xferconf_a_number|$VDCL_xferconf_b_dtmf|$VDCL_xferconf_b_number|$VDCL_default_xfer_group|$VDCL_ingroup_recording_override|$VDCL_ingroup_rec_filename|$VDCL_default_group_alias|$VDCL_caller_id_number|$VDCL_group_web_vars|$VDCL_group_web_two|$VDCL_timer_action|$VDCL_timer_action_message|$VDCL_timer_action_seconds|$VDCL_xferconf_c_number|$VDCL_xferconf_d_number|$VDCL_xferconf_e_number|$VDCL_uniqueid_status_display|$custom_call_id|$VDCL_uniqueid_status_prefix|$VDCL_timer_action_destination|$DID_id|$DID_extension|$DID_pattern|$DID_description|$INclosecallid|$INxfercallid|$VDCL_group_web_three|$VDCL_ingroup_script_color|$VDCL_inbound_survey|$VDCL_survey_participate|$VDCL_ingroup_script_two|$VDCL_ingroup_script_color_two|$VDCL_browser_alert_sound|$VDCL_browser_alert_volume|$stereo_recording|$stereo_recording_agent|$talk_sec_urls_secs|$recording_dtmf_muting|\n";} if (strlen($fronter) < 2) {$fronter = $tsr;} $stmt = "SELECT full_name from vicidial_users where user='$fronter';"; diff --git a/www/agc/vicidial.php b/www/agc/vicidial.php index 3165b847b..d26eeb71b 100644 --- a/www/agc/vicidial.php +++ b/www/agc/vicidial.php @@ -751,10 +751,11 @@ # 250916-2055 - Added stereo recording features # 250924-0953 - Added Talk Seconds URLs features # 251002-1353 - Added call_count_limit_restrict campaign option +# 251020-0849 - Added code for recording_dtmf_muting, fix for Stereo Call Recording # -$version = '2.14-717c'; -$build = '251002-1353'; +$version = '2.14-718c'; +$build = '251020-0849'; $php_script = 'vicidial.php'; $mel=1; # Mysql Error Log enabled = 1 $mysql_log_count=108; @@ -864,7 +865,7 @@ ############################################# ##### START SYSTEM_SETTINGS AND USER LANGUAGE LOOKUP ##### -$stmt = "SELECT use_non_latin,vdc_header_date_format,vdc_customer_date_format,vdc_header_phone_format,webroot_writable,timeclock_end_of_day,vtiger_url,enable_vtiger_integration,outbound_autodial_active,enable_second_webform,user_territories_active,static_agent_url,custom_fields_enabled,pllb_grouping_limit,qc_features_active,allow_emails,callback_time_24hour,enable_languages,language_method,meetme_enter_login_filename,meetme_enter_leave3way_filename,enable_third_webform,default_language,active_modules,allow_chats,chat_url,default_phone_code,agent_screen_colors,manual_auto_next,agent_xfer_park_3way,admin_web_directory,agent_script,agent_push_events,agent_push_url,agent_logout_link,agentonly_callback_campaign_lock,manual_dial_validation,mute_recordings,enable_second_script,enable_first_webform,recording_buttons,outbound_cid_any,browser_call_alerts,manual_dial_phone_strip,require_password_length,pass_hash_enabled,agent_hidden_sound_seconds,agent_hidden_sound,agent_hidden_sound_volume,agent_screen_timer,agent_hide_hangup,allow_web_debug,max_logged_in_agents,login_kickall,agent_notifications,inbound_credits,two_factor_auth_agent_hours,two_factor_container,sip_event_logging,stereo_recording,agent_hide_dial_fail,agent_man_dial_filter,agent_3way_dial_filter FROM system_settings;"; +$stmt = "SELECT use_non_latin,vdc_header_date_format,vdc_customer_date_format,vdc_header_phone_format,webroot_writable,timeclock_end_of_day,vtiger_url,enable_vtiger_integration,outbound_autodial_active,enable_second_webform,user_territories_active,static_agent_url,custom_fields_enabled,pllb_grouping_limit,qc_features_active,allow_emails,callback_time_24hour,enable_languages,language_method,meetme_enter_login_filename,meetme_enter_leave3way_filename,enable_third_webform,default_language,active_modules,allow_chats,chat_url,default_phone_code,agent_screen_colors,manual_auto_next,agent_xfer_park_3way,admin_web_directory,agent_script,agent_push_events,agent_push_url,agent_logout_link,agentonly_callback_campaign_lock,manual_dial_validation,mute_recordings,enable_second_script,enable_first_webform,recording_buttons,outbound_cid_any,browser_call_alerts,manual_dial_phone_strip,require_password_length,pass_hash_enabled,agent_hidden_sound_seconds,agent_hidden_sound,agent_hidden_sound_volume,agent_screen_timer,agent_hide_hangup,allow_web_debug,max_logged_in_agents,login_kickall,agent_notifications,inbound_credits,two_factor_auth_agent_hours,two_factor_container,sip_event_logging,stereo_recording,agent_hide_dial_fail,agent_man_dial_filter,agent_3way_dial_filter,recording_dtmf_detection,recording_dtmf_muting FROM system_settings;"; $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'01001',$VD_login,$server_ip,$session_name,$one_mysql_log);} #if ($DB) {echo "$stmt\n";} @@ -935,6 +936,8 @@ $SSagent_hide_dial_fail = $row[60]; $SSagent_man_dial_filter = $row[61]; $SSagent_3way_dial_filter = $row[62]; + $SSrecording_dtmf_detection = $row[63]; + $SSrecording_dtmf_muting = $row[64]; if ( ($SSagent_hidden_sound == '---NONE---') or ($SSagent_hidden_sound == '') ) {$SSagent_hidden_sound_seconds=0;} } else @@ -3157,7 +3160,7 @@ function login_submit() $HKstatusnames = substr("$HKstatusnames", 0, -1); ##### grab the campaign settings - $stmt="SELECT park_ext,park_file_name,web_form_address,allow_closers,auto_dial_level,dial_timeout,dial_prefix,campaign_cid,campaign_vdad_exten,campaign_rec_exten,campaign_recording,campaign_rec_filename,campaign_script,get_call_launch,am_message_exten,xferconf_a_dtmf,xferconf_a_number,xferconf_b_dtmf,xferconf_b_number,alt_number_dialing,scheduled_callbacks,wrapup_seconds,wrapup_message,closer_campaigns,use_internal_dnc,allcalls_delay,omit_phone_code,agent_pause_codes_active,no_hopper_leads_logins,campaign_allow_inbound,manual_dial_list_id,default_xfer_group,xfer_groups,disable_alter_custphone,display_queue_count,manual_dial_filter,agent_clipboard_copy,use_campaign_dnc,three_way_call_cid,dial_method,three_way_dial_prefix,web_form_target,vtiger_screen_login,agent_allow_group_alias,default_group_alias,quick_transfer_button,prepopulate_transfer_preset,view_calls_in_queue,view_calls_in_queue_launch,call_requeue_button,pause_after_each_call,no_hopper_dialing,agent_dial_owner_only,agent_display_dialable_leads,web_form_address_two,agent_select_territories,crm_popup_login,crm_login_address,timer_action,timer_action_message,timer_action_seconds,start_call_url,dispo_call_url,xferconf_c_number,xferconf_d_number,xferconf_e_number,use_custom_cid,scheduled_callbacks_alert,scheduled_callbacks_count,manual_dial_override,blind_monitor_warning,blind_monitor_message,blind_monitor_filename,timer_action_destination,enable_xfer_presets,hide_xfer_number_to_dial,manual_dial_prefix,customer_3way_hangup_logging,customer_3way_hangup_seconds,customer_3way_hangup_action,ivr_park_call,manual_preview_dial,api_manual_dial,manual_dial_call_time_check,my_callback_option,per_call_notes,agent_lead_search,agent_lead_search_method,queuemetrics_phone_environment,auto_pause_precall,auto_pause_precall_code,auto_resume_precall,manual_dial_cid,custom_3way_button_transfer,callback_days_limit,disable_dispo_screen,disable_dispo_status,screen_labels,status_display_fields,pllb_grouping,pllb_grouping_limit,in_group_dial,in_group_dial_select,pause_after_next_call,owner_populate,manual_dial_lead_id,dead_max,dispo_max,pause_max,dead_max_dispo,dispo_max_dispo,max_inbound_calls,manual_dial_search_checkbox,hide_call_log_info,timer_alt_seconds,wrapup_bypass,wrapup_after_hotkey,callback_active_limit,callback_active_limit_override,comments_all_tabs,comments_dispo_screen,comments_callback_screen,qc_comment_history,show_previous_callback,clear_script,manual_dial_search_filter,web_form_address_three,manual_dial_override_field,status_display_ingroup,customer_gone_seconds,agent_display_fields,manual_dial_timeout,manual_auto_next,manual_auto_show,allow_required_fields,dead_to_dispo,agent_xfer_validation,ready_max_logout,callback_display_days,three_way_record_stop,hangup_xfer_record_start,max_inbound_calls_outcome,manual_auto_next_options,agent_screen_time_display,pause_max_dispo,script_top_dispo,routing_initiated_recordings,dead_trigger_seconds,dead_trigger_action,dead_trigger_repeat,dead_trigger_filename,scheduled_callbacks_force_dial,callback_hours_block,callback_display_days,scheduled_callbacks_timezones_container,three_way_volume_buttons,manual_dial_validation,mute_recordings,leave_vm_no_dispo,leave_vm_message_group_id,campaign_script_two,browser_alert_sound,browser_alert_volume,three_way_record_stop_exception,pause_max_exceptions,transfer_button_launch,leave_3way_start_recording,leave_3way_start_recording_exception,calls_waiting_vl_one,calls_waiting_vl_two,in_man_dial_next_ready_seconds,in_man_dial_next_ready_seconds_override,transfer_no_dispo,local_call_time,pause_max_url,agent_hide_hangup,ig_xfer_list_sort,script_tab_frame_size,user_group_script,agent_hangup_route,agent_hangup_value,agent_hangup_ig_override,show_confetti,custom_one,custom_two,custom_three,custom_four,custom_five,allow_chats,dead_stop_recording,force_per_call_notes,state_descriptions,script_tab_height,leave_3way_stop_recording,manual_minimum_ring_seconds,manual_minimum_attempt_seconds,manual_minimum_answer_seconds,sip_event_logging,stereo_recording,stereo_recording_agent FROM vicidial_campaigns where campaign_id = '$VD_campaign';"; + $stmt="SELECT park_ext,park_file_name,web_form_address,allow_closers,auto_dial_level,dial_timeout,dial_prefix,campaign_cid,campaign_vdad_exten,campaign_rec_exten,campaign_recording,campaign_rec_filename,campaign_script,get_call_launch,am_message_exten,xferconf_a_dtmf,xferconf_a_number,xferconf_b_dtmf,xferconf_b_number,alt_number_dialing,scheduled_callbacks,wrapup_seconds,wrapup_message,closer_campaigns,use_internal_dnc,allcalls_delay,omit_phone_code,agent_pause_codes_active,no_hopper_leads_logins,campaign_allow_inbound,manual_dial_list_id,default_xfer_group,xfer_groups,disable_alter_custphone,display_queue_count,manual_dial_filter,agent_clipboard_copy,use_campaign_dnc,three_way_call_cid,dial_method,three_way_dial_prefix,web_form_target,vtiger_screen_login,agent_allow_group_alias,default_group_alias,quick_transfer_button,prepopulate_transfer_preset,view_calls_in_queue,view_calls_in_queue_launch,call_requeue_button,pause_after_each_call,no_hopper_dialing,agent_dial_owner_only,agent_display_dialable_leads,web_form_address_two,agent_select_territories,crm_popup_login,crm_login_address,timer_action,timer_action_message,timer_action_seconds,start_call_url,dispo_call_url,xferconf_c_number,xferconf_d_number,xferconf_e_number,use_custom_cid,scheduled_callbacks_alert,scheduled_callbacks_count,manual_dial_override,blind_monitor_warning,blind_monitor_message,blind_monitor_filename,timer_action_destination,enable_xfer_presets,hide_xfer_number_to_dial,manual_dial_prefix,customer_3way_hangup_logging,customer_3way_hangup_seconds,customer_3way_hangup_action,ivr_park_call,manual_preview_dial,api_manual_dial,manual_dial_call_time_check,my_callback_option,per_call_notes,agent_lead_search,agent_lead_search_method,queuemetrics_phone_environment,auto_pause_precall,auto_pause_precall_code,auto_resume_precall,manual_dial_cid,custom_3way_button_transfer,callback_days_limit,disable_dispo_screen,disable_dispo_status,screen_labels,status_display_fields,pllb_grouping,pllb_grouping_limit,in_group_dial,in_group_dial_select,pause_after_next_call,owner_populate,manual_dial_lead_id,dead_max,dispo_max,pause_max,dead_max_dispo,dispo_max_dispo,max_inbound_calls,manual_dial_search_checkbox,hide_call_log_info,timer_alt_seconds,wrapup_bypass,wrapup_after_hotkey,callback_active_limit,callback_active_limit_override,comments_all_tabs,comments_dispo_screen,comments_callback_screen,qc_comment_history,show_previous_callback,clear_script,manual_dial_search_filter,web_form_address_three,manual_dial_override_field,status_display_ingroup,customer_gone_seconds,agent_display_fields,manual_dial_timeout,manual_auto_next,manual_auto_show,allow_required_fields,dead_to_dispo,agent_xfer_validation,ready_max_logout,callback_display_days,three_way_record_stop,hangup_xfer_record_start,max_inbound_calls_outcome,manual_auto_next_options,agent_screen_time_display,pause_max_dispo,script_top_dispo,routing_initiated_recordings,dead_trigger_seconds,dead_trigger_action,dead_trigger_repeat,dead_trigger_filename,scheduled_callbacks_force_dial,callback_hours_block,callback_display_days,scheduled_callbacks_timezones_container,three_way_volume_buttons,manual_dial_validation,mute_recordings,leave_vm_no_dispo,leave_vm_message_group_id,campaign_script_two,browser_alert_sound,browser_alert_volume,three_way_record_stop_exception,pause_max_exceptions,transfer_button_launch,leave_3way_start_recording,leave_3way_start_recording_exception,calls_waiting_vl_one,calls_waiting_vl_two,in_man_dial_next_ready_seconds,in_man_dial_next_ready_seconds_override,transfer_no_dispo,local_call_time,pause_max_url,agent_hide_hangup,ig_xfer_list_sort,script_tab_frame_size,user_group_script,agent_hangup_route,agent_hangup_value,agent_hangup_ig_override,show_confetti,custom_one,custom_two,custom_three,custom_four,custom_five,allow_chats,dead_stop_recording,force_per_call_notes,state_descriptions,script_tab_height,leave_3way_stop_recording,manual_minimum_ring_seconds,manual_minimum_attempt_seconds,manual_minimum_answer_seconds,sip_event_logging,stereo_recording,stereo_recording_agent,recording_dtmf_muting FROM vicidial_campaigns where campaign_id = '$VD_campaign';"; $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'01013',$VD_login,$server_ip,$session_name,$one_mysql_log);} if ($DB) {echo "$stmt\n";} @@ -3362,6 +3365,7 @@ function login_submit() $CAMPsip_event_logging = $row[197]; $stereo_recording = $row[198]; $stereo_recording_agent = $row[199]; + $recording_dtmf_muting = $row[200]; if ( (!preg_match("/DISABLED/",$VU_manual_dial_lead_id)) and (strlen($VU_manual_dial_lead_id) > 0) ) { @@ -3504,7 +3508,7 @@ function login_submit() if (preg_match("/EXTERNAL/",$transfer_no_dispo)) {$transfer_no_dispoEXTERNAL=1;} if (preg_match("/LEAVE3WAY/",$transfer_no_dispo)) {$transfer_no_dispoLEAVE3WAY=1;} - if ($SSmute_recordings < 1) + if ( ($SSmute_recordings < 1) or ( ($SSrecording_dtmf_detection > 0) and ($SSrecording_dtmf_muting > 0) and ($recording_dtmf_muting > 0) ) ) {$mute_recordings='N';} else { @@ -6796,6 +6800,7 @@ function login_submit() var MDOalt=''; var manual_entry_dial=0; var mute_recordings=''; + var recording_dtmf_muting=''; var leave_vm_no_dispo=''; var leave_vm_message_group_id=''; var leave_vm_message_group_exists=''; @@ -6866,6 +6871,7 @@ function login_submit() var agent_hide_dial_fail=''; var agent_hide_dial_fail_MESSAGE=""; var talk_sec_url_secs=''; + var redirectserverip=''; var DiaLControl_auto_HTML = "\" border=\"0\" alt=\"You are paused\" />"; var DiaLControl_auto_HTML_ready = "\" border=\"0\" alt=\"You are active\" />"; var DiaLControl_auto_HTML_OFF = "\" border=\"0\" alt=\"pause button disabled\" />"; @@ -9139,7 +9145,7 @@ function conf_send_recording(taskconfrectype,taskconfrec,taskconffile,taskfromap { document.getElementById("RecorDControl").innerHTML = conf_rec_start_html; } - if (mute_recordings == 'Y') + if ( (mute_recordings == 'Y') && (recording_dtmf_muting < 1) ) { document.getElementById("RecorDMute").innerHTML = conf_rec_mute_html; } @@ -9219,7 +9225,7 @@ function conf_send_recording(taskconfrectype,taskconfrec,taskconffile,taskfromap { document.getElementById("RecorDControl").innerHTML = conf_rec_start_html; } - if (mute_recordings == 'Y') + if ( (mute_recordings == 'Y') && (recording_dtmf_muting < 1) ) { document.getElementById("RecorDMute").innerHTML = conf_rec_mute_html; } @@ -9305,7 +9311,7 @@ function conf_send_stereo_recording(taskconfrectype,taskconfrec,taskconffile,tas document.getElementById("StRecorDControl").innerHTML = conf_rec_start_html; } } - confmonitor_query = "server_ip=" + server_ip + "&session_name=" + session_name + "&campaign=" + campaign + "&user=" + user + "&pass=" + pass + "&ACTION=" + taskconfrectype + "&format=text&channel=" + lastcustchannel + "&filename=NOfilenameNEEDED&exten=" + query_recording_exten + "&ext_context=" + ext_context + "&lead_id=" + document.vicidial_form.lead_id.value + "&CalLCID=" + LasTCID + "&phone_number=" + lead_dial_number + "&ext_priority=1&FROMvdc=YES&uniqueid=" + tmp_vicidial_id + "&FROMapi=" + taskfromapi; + confmonitor_query = "server_ip=" + server_ip + "&call_server_ip=" + lastcustserverip + "&session_name=" + session_name + "&campaign=" + campaign + "&user=" + user + "&pass=" + pass + "&ACTION=" + taskconfrectype + "&format=text&channel=" + lastcustchannel + "&filename=NOfilenameNEEDED&exten=" + query_recording_exten + "&ext_context=" + ext_context + "&lead_id=" + document.vicidial_form.lead_id.value + "&CalLCID=" + LasTCID + "&phone_number=" + lead_dial_number + "&ext_priority=1&FROMvdc=YES&uniqueid=" + tmp_vicidial_id + "&FROMapi=" + taskfromapi; xmlhttp.open('POST', 'manager_send.php'); xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8'); xmlhttp.send(confmonitor_query); @@ -9401,7 +9407,7 @@ function mainxfer_send_redirect(taskvar,taskxferconf,taskserverip,taskdebugnote, if (xmlhttpXF) { var redirectvalue = MDchannel; - var redirectserverip = lastcustserverip; + redirectserverip = lastcustserverip; if (redirectvalue.length < 2) {redirectvalue = lastcustchannel} if ( (taskvar == 'XfeRBLIND') || (taskvar == 'XfeRVMAIL') ) @@ -9822,7 +9828,7 @@ function transfer_email(EMAILtaskvar, EMAILlead_id, EMAILuniqueid, email_row_id) if (xmlhttpXF) { var redirectvalue = MDchannel; - var redirectserverip = lastcustserverip; + redirectserverip = lastcustserverip; var queryCID=''; var exten=''; var ext_context=''; @@ -14315,6 +14321,7 @@ function check_for_auto_incoming() VDICstereo_recording = VDIC_data_VDIG[42]; VDICstereo_recording_agent = VDIC_data_VDIG[43]; talk_sec_url_secs = VDIC_data_VDIG[44]; + recording_dtmf_muting = VDIC_data_VDIG[45]; // alert("talk_sec_url_secs: |" + talk_sec_url_secs + "|"); var VDIC_data_VDFR=check_VDIC_array[3].split("|"); if ( (VDIC_data_VDFR[1].length > 1) && (VDCL_fronter_display == 'Y') ) diff --git a/www/vicidial/admin.php b/www/vicidial/admin.php index 91e706a2d..398d131c2 100644 --- a/www/vicidial/admin.php +++ b/www/vicidial/admin.php @@ -6290,12 +6290,13 @@ # 250822-2056 - Added system/campaign/ingroup settings for stereo_recording # 250922-0841 - Added Talk Seconds URL links to multi-url admin page in campaigns and in-groups # 251002-1428 - Added call_count_limit_restrict campaign setting +# 251019-2024 - Added Recording DTMF Muting # # 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-945a'; -$build = '251002-1428'; +$admin_version = '2.14-946a'; +$build = '251019-2024'; $STARTtime = date("U"); $SQLdate = date("Y-m-d H:i:s"); @@ -28184,9 +28185,11 @@ function ajax_logout_now() { echo "\n"; } - if ( ( ($SSrecording_dtmf_muting =='1') or ($SSrecording_dtmf_muting =='2') or ($SSrecording_dtmf_muting =='3') ) and ($SSrecording_dtmf_detection == '1') ) + if ( ( ($SSrecording_dtmf_muting =='1') or ($SSrecording_dtmf_muting >= 2) ) and ($SSrecording_dtmf_detection == '1') ) { - echo "\n"; + $SYSTEM_DTMF_MUTING_OVERRIDE=''; + if ($SSrecording_dtmf_muting >= 2) {$SYSTEM_DTMF_MUTING_OVERRIDE = ""._QXZ("SYSTEM OVERRIDE ENABLED").": $SSrecording_dtmf_muting "._QXZ("SECONDS")."";} + echo "\n"; } else { @@ -31464,22 +31467,61 @@ function ajax_logout_now() echo "
\n"; echo ""; echo "
"._QXZ("Alternate URL Form"); echo "
\n"; echo ""; - echo ""; + echo ""; echo ""; echo ""; echo ""; @@ -555,7 +573,7 @@ $ENDtime = date("U"); $RUNtime = ($ENDtime - $STARTtime); -echo "\n\n\n


\n "._QXZ("runtime").": $RUNtime "._QXZ("seconds")."         "._QXZ("Version").": $admin_version     "._QXZ("Build").": $build"; +echo "\n\n\n


\n   "._QXZ("runtime").": $RUNtime "._QXZ("seconds")."         "._QXZ("Version").": $admin_version     "._QXZ("Build").": $build"; ?> diff --git a/www/vicidial/help_documentation.txt b/www/vicidial/help_documentation.txt index efc304816..308f8ee33 100644 --- a/www/vicidial/help_documentation.txt +++ b/www/vicidial/help_documentation.txt @@ -1,4 +1,4 @@ -# version: 20250917172301 +# version: 20250920221701 users-user User ID 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-. users-pass Password This field is where you put the users password. Must be at least 2 characters in length, unless the User Password Minimum Length system setting is enabled, which will require a longer password. 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. users-force_change_password Force Change Password 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. @@ -432,6 +432,7 @@ campaigns-crm_login_address CRM Popup Address The web address of a CRM logi campaigns-start_call_url Start Call URL This web URL address is not seen by the agent, but it is called every time a call is sent to an agent if it is populated. Uses the same variables as the web form fields and scripts. This URL can NOT be a relative path. For Manual dial calls, the Start Call URL will be sent when the call is placed. Default is blank. If you put ALT into this field and submit this form, you will be able to go to a separate page where you can define multiple URLs for this action. campaigns-dispo_call_url Dispo Call URL This web URL address is not seen by the agent, but it is called every time a call is dispositioned by an agent if it is populated. Uses the same variables as the web form fields and scripts. dispo, callback_lead_status, talk_time and term_reason are the variables you can use to retrieve the agent-defined disposition for the call and the actual talk time in seconds of the call as well as how the call was ended. This URL can NOT be a relative path. Default is blank. If you put ALT into this field and submit this form, you will be able to go to a separate page where you can define multiple URLs for this action as well as specific statuses that will trigger them. campaigns-na_call_url No Agent Call URL This web URL address is not seen by the agent, but if it is populated it is called every time a call that is not handled by an agent is hung up or transferred. Uses the same variables as the web form fields and scripts. --A--dispo--B-- can be used to retrieve the system-defined disposition for the call. This URL can NOT be a relative path. Default is blank. Custom Fields are not available with this feature. If you put ALT into this field and submit this form, you will be able to go to a separate page where you can define multiple URLs for this action as well as specific statuses that will trigger them. +campaigns-talk_sec_url Talk Seconds URLs This feature allows you to define URLs that can be triggered by the Agent Screen when the agent is talking to the customer based upon how many seconds they have been talking. If the customer hangs up, then no more Talk Seconds URLs will be triggered. To define these Talk Seconds URLs, just click on the link to the right. campaigns-agent_allow_group_alias Group Alias Allowed If you want to allow your agents to use group aliases then you need to set this to Y. Group Aliases are explained more in the Admin section, they allow agents to select different callerIDs for outbound manual calls that they may place. Default is N. campaigns-default_group_alias Default Group Alias If you have allowed Group Aliases then this is the group alias that is selected first by default when the agent chooses to use a Group Alias for an outbound manual call. Default is NONE or empty. campaigns-calls_inqueue_count Calls In Queue Count Display This setting, if set to a valid CALLS_IN_QUEUE_COUNT type Settings Container, will change the display at the top of the agent screen to a specific filtered count of the calls in queue, replacing the default display of the count of every call waiting in queue that the agent has permissions to handle. If both of these settings are enabled, the first one will display before the second one. If you use an EXCEPT option, the exception container cannot also use an EXCEPT option. Default is ---DISABLED---. The CALLS_IN_QUEUE_COUNT type Settings Container should have -HEADING=>Display Name- as its first line, without the dashes, and then either a list of In-Groups and Campaigns, or one of the following special options,
--ALL-IN-GROUP-CALLS--
--ALL-CAMPAIGN-CALLS--
--ALL-CALLS--
--ALL-IN-GROUP-CALLS-EXCEPT=container_id
--ALL-CAMPAIGN-CALLS-EXCEPT=container_id
--ALL-CALLS-EXCEPT=container_id
@@ -691,6 +692,7 @@ inbound_groups-enter_ingroup_url Enter In-Group URL This web URL address is inbound_groups-start_call_url Start Call URL This web URL address is not seen by the agent, but it is called every time a call is sent to an agent if it is populated. Uses the same variables as the web form fields and scripts. Default is blank. If you put ALT into this field and submit this form, you will be able to go to a separate page where you can define multiple URLs for this action. inbound_groups-dispo_call_url Dispo Call URL This web URL address is not seen by the agent, but it is called every time a call is dispositioned by an agent if it is populated. Uses the same variables as the web form fields and scripts. dispo, talk_time and term_reason are the variables you can use to retrieve the agent-defined disposition for the call and the actual talk time in seconds of the call as well as how the call was ended. Default is blank. If you put ALT into this field and submit this form, you will be able to go to a separate page where you can define multiple URLs for this action as well as specific statuses that will trigger them. If you want the campaign Dispo Call URL to be used for inbound calls, then put CAMP into this field. inbound_groups-na_call_url No Agent Call URL This web URL address is not seen by the agent, but if it is populated it is called every time a call that is not handled by an agent is hung up or transferred. Uses the same variables as the web form fields and scripts. --A--dispo--B-- can be used to retrieve the system-defined disposition for the call. This URL can NOT be a relative path. Default is blank. Custom Fields are not available with this feature. If the Wait time, On-Hold Prompt or other settings are not set properly in this In-Group, then this feature may not function properly. If you put ALT into this field and submit this form, you will be able to go to a separate page where you can define multiple URLs for this action as well as specific statuses that will trigger them. +inbound_groups-talk_sec_url Talk Seconds URLs This feature allows you to define URLs that can be triggered by the Agent Screen when the agent is talking to the customer based upon how many seconds they have been talking. If the customer hangs up, then no more Talk Seconds URLs will be triggered. To define these Talk Seconds URLs, just click on the link to the right. If there are no active Talk Seconds URLs defined for an In-Group, then the Campaign Talk Seconds URLs for the campaign the agent is logged into will be used for those In-Group calls. If you want to ensure that the Campaign Talk Seconds URLs are not used for this In-Group, then you can create a Talk Seconds URLs entry for the In-Group that has Active set to -N- and the URL set to -FORCEDISABLE-. inbound_groups-waiting_call_url_on Waiting Call URL On This feature allows you to trigger a URL when there are calls waiting in this In-Group. The -On- URL will be sent the first time a call is waiting, and no more will be sent as long as there are still calls from this In-Group waiting in the queue. The -Off- URL will be sent as soon as there are no calls waiting for this In-Group anymore. This feature was created to allow for a remote power switch to be triggered to light up a flashing light to notify agents in a call center room that there were calls waiting for them. For this feature to work, both the -On- and -Off- URLs must be filled in. Default is -empty- for disabled. inbound_groups-add_lead_url Add Lead URL This web URL address is not seen by the agent, but it is called every time a lead is added to the system through the inbound process. Default is blank. You must begin this URL with VAR if you want to use variables, and of course --A-- and --B-- around the actual variable in the URL where you want to use it. Here is the list of variables that are available for this function. lead_id, vendor_lead_code, list_id, phone_number, phone_code, did_id, did_extension, did_pattern, did_description, uniqueid inbound_groups-add_lead_timezone Add Lead Timezone This is the method that the system will use to determine the current timezone when a lead is created when a call is being routed through this in-group. SERVER will use the current timezone of the server. PHONE_CODE_AREACODE will look up the timezone based on the phone code set in the lead and the areacode of the phone number. Default is SERVER. @@ -1484,7 +1486,7 @@ cb-bulk-newlist Transfer to List ID The list ID to which all callbacks will cb-bulk-newstatus New Status The new vicidial_list status the selected callbacks will be updated to. This affects the vicidial_list table ONLY. cb-export Callbacks export This page is used to view and download a list of all scheduled callbacks based on the campaigns selected and the dates the callbacks are scheduled to be contacted. cb-export-cb-dates Scheduled callback dates The date the leads are scheduled to be called back. -alt_multi_urls Alternate Multi URLs This page allows you to define Alternate URLs with conditions in place of the simple URL option for Dispo, Start, Add Lead or No Agent URLs. The RANK field will define the order in which the URLs are requested, this is important because if you have a URL that may take a few seconds to run ranked as 1, that will mean that any URLs ranked after it will have to wait to be run until that first URL request receives a response. The ACTIVE field will determine whether the specific URL is run. The STATUSES field only works for the Dispo URLs and will determine which disposition statuses will trigger the URL being run, if you want to run the entry for all statuses just fill in ---ALL--- in this field, if you want only a few statuses, separate them by spaces. If populated, the LISTS field will limit the calls that the URL is run from to only the list IDs listed in this field. To have it run for all lists, leave the field blank, if you want only a few lists, separate them by spaces. The MIN LENGTH field will limit the calls that the URL is run for to only calls that are this minimum length in seconds and higher, default is 0. The min length option does not work for No Agent Call URLs. The URL field works the same as it would in the URL option in campaigns, in-groups and lists, and it is also limited to 2000 characters in length. If you want to delete a URL, it must first be set to not active, then you can click on the DELETE link below the SUBMIT button for that URL entry. +alt_multi_urls Alternate Multi URLs This page allows you to define Alternate URLs with conditions in place of the simple URL option for Dispo, Start, Add Lead, No Agent or Talk Seconds URLs. The RANK field will define the order in which the URLs are requested, this is important because if you have a URL that may take a few seconds to run ranked as 1, that will mean that any URLs ranked after it will have to wait to be run until that first URL request receives a response. The ACTIVE field will determine whether the specific URL is run. The STATUSES field only works for the Dispo URLs and will determine which disposition statuses will trigger the URL being run, if you want to run the entry for all statuses just fill in ---ALL--- in this field, if you want only a few statuses, separate them by spaces. If populated, the LISTS field will limit the calls that the URL is run from to only the list IDs listed in this field. To have it run for all lists, leave the field blank, if you want only a few lists, separate them by spaces. The MIN LENGTH field will limit the calls that the URL is run for to only calls that are this minimum length in seconds and higher, default is 0. The min length option does not work for No Agent, Start or Add Lead URLs. For Talk Seconds URLS, the MIN LENGTH field is the trigger time during talk time with the customer when each URL is triggered, if it is set to 0 for a Talk Seconds URL, then that URL will never trigger. The URL field works the same as it would in the URL option in campaigns, in-groups and lists, and it is also limited to 2000 characters in length. If you want to delete a URL, it must first be set to not active, then you can click on the DELETE link below the SUBMIT button for that URL entry. amm_multi AM Message Wildcards This page allows you to define Am Message Wildcards that will check lead data from the defined lead fields for matches in the defined order specified on this page. For example, if you add a wildcard with the word -vacation- tied to the vendor_lead_code field, and the lead being played a message has -vacation- in that field, then it will hear the message defined in that AM Message Wildcard record. If you want to delete a wildcard, it must first be set to not active, then you can click on the DELETE link below the SUBMIT button for that wildcard entry user_list_new_limits User List New Lead Limits If the system setting for New Leads Per List Limit is enabled, then this page allows for the setting of per-user per-list new lead limit overrides to those List limits. This feature will only work properly if the campaign is set to either the MANUAL or INBOUND_MAN Dial Method and No Hopper dialing is enabled. user_inbound_calls_today User Inbound Calls Today This page will show you the User Inbound Calls Today, the Max Limits and the Call Credits for all users in the system. If one of the limits is reached, you will see notes showing you which one was reached. From c58745ff77b4031cc26a29178cb80c12b21bf6f4 Mon Sep 17 00:00:00 2001 From: Mattf Date: Sun, 28 Sep 2025 20:13:38 +0000 Subject: [PATCH 06/12] Added hosted_settings dialplan variable to FastAGI_log.pl script git-svn-id: svn://svn.eflo.net/agc_2-X/trunk@3946 3d104415-ff17-0410-8863-d5cf3c621b8a --- bin/FastAGI_log.pl | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/bin/FastAGI_log.pl b/bin/FastAGI_log.pl index e51dc1325..7e03fea32 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) 2024 Matt Florell LICENSE: AGPLv2 +# Copyright (C) 2025 Matt Florell LICENSE: AGPLv2 # # CHANGELOG: # 61010-1007 - First test build @@ -102,7 +102,8 @@ # 240225-0957 - Added AUTONEXT hopper_hold_inserts campaign option # 241001-2224 - Fixes for Khomp call processing # 241020-1929 - Added khomp campaign settings options -# 281028-0958 - Added vicidial_khomp_log logging of container used +# 241028-0958 - Added vicidial_khomp_log logging of container used +# 250928-1556 - Added hosted_settings dialplan variable # # defaults for PreFork @@ -770,9 +771,9 @@ sub process_request if ($AGILOG) {$agi_string = "|CAMPDTO: $dial_timeout|$callerid|"; &agi_output;} } - ### BEGIN OpenSIPs CallerIDname code ### - ### get system_settings - $stmtA = "SELECT opensips_cid_name FROM system_settings"; + ### BEGIN OpenSIPs CallerIDname and Hosted Settings code ### + ### get system_settings and hosted_settings + $stmtA = "SELECT opensips_cid_name,hosted_settings FROM system_settings"; $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; $sthArows=$sthA->rows; @@ -780,9 +781,10 @@ sub process_request { @aryA = $sthA->fetchrow_array; $opensips_cid_name = $aryA[0]; + $hosted_settings = $aryA[1]; } $sthA->finish(); - if ($AGILOG) {$agi_string = "$stmtA|$opensips_cid_name"; &agi_output;} + if ($AGILOG) {$agi_string = "$stmtA|$opensips_cid_name|$hosted_settings"; &agi_output;} ### opensips_cid_name is active if ( $opensips_cid_name == 1) @@ -808,7 +810,15 @@ sub process_request $AGI->exec("EXEC SIPAddHeader(\"$header\")"); } } - ### END OpenSIPs CallerIDname code ### + + ### if hosted_settings has a value, set a dialplan variable + if ( length($hosted_settings) > 0 ) + { + $AGI->exec("EXEC Set(_HOSTEDSETTINGS=$hosted_settings)"); + if ($AGILOG) {$agi_string = "|HOSTEDSETTINGS: $hosted_settings|$callerid|"; &agi_output;} + } + + ### END OpenSIPs CallerIDname and Hosted Settings code ### if ($AGILOG) {$agi_string = "|KHOMP $amd_type|$HVcauses|$extension|$campaign_vdad_exten"; &agi_output;} From a97d873d011954d9e877890523f9a04201eaeaff Mon Sep 17 00:00:00 2001 From: Mattf Date: Thu, 2 Oct 2025 01:57:46 +0000 Subject: [PATCH 07/12] Switched Server Performance report to Graph.js from ploticus, converted to HTML Rare bug fix for Stereo Recordings Changed install.pl to use Asterisk 18.X as default git-svn-id: svn://svn.eflo.net/agc_2-X/trunk@3947 3d104415-ff17-0410-8863-d5cf3c621b8a --- agi/agi-VDAD_ALL_inbound.agi | 55 +- agi/agi-VDAD_ALL_outbound.agi | 105 +-- docs/STEREO_CALL_RECORDINGS.txt | 4 +- extras/MySQL_AST_CREATE_tables.sql | 2 +- install.pl | 3 +- www/vicidial/AST_server_performance.php | 1143 +++++++++++------------ 6 files changed, 615 insertions(+), 697 deletions(-) diff --git a/agi/agi-VDAD_ALL_inbound.agi b/agi/agi-VDAD_ALL_inbound.agi index d07a2eb2e..8baef744d 100644 --- a/agi/agi-VDAD_ALL_inbound.agi +++ b/agi/agi-VDAD_ALL_inbound.agi @@ -267,6 +267,7 @@ # 250325-1724 - Fix for possible daily_limit issue # 250825-1824 - Added stereo_recording code # 250924-2147 - Added code for deprecation of "Monitor" application after Asterisk 20 +# 251001-1836 - Fix for rare Stereo recording filename issue # $script = 'agi-VDAD_ALL_inbound.agi'; @@ -3404,21 +3405,7 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override $sthA->finish(); # get date/time - ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); - $year = ($year + 1900); - $Tyear = ($year - 2000); - $mon++; - if ($mon < 10) {$mon = "0$mon";} - if ($mday < 10) {$mday = "0$mday";} - if ($hour < 10) {$hour = "0$hour";} - if ($min < 10) {$min = "0$min";} - if ($sec < 10) {$sec = "0$sec";} - - $now_date_epoch = time(); - $now_date = "$year-$mon-$mday $hour:$min:$sec"; - $recdate = "$year$mon$mday-$hour$min$sec"; - $tinydate = "$Tyear$mon$mday$hour$min$sec"; - + &get_date_time; $campaign_rec_filename =~ s/CAMPAIGN/$log_campaign/gi; $campaign_rec_filename =~ s/INGROUP/$channel_group/gi; $campaign_rec_filename =~ s/CUSTPHONE/$phone_number/gi; @@ -3483,6 +3470,7 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override ### BEGIN stereo call recording for ALLCALLS/ALLFORCE and for all parallel stereo recording in-groups ### if ( ($stereo_recording =~ /CUSTOMER|BOTH/i) && ($conf_engine eq "CONFBRIDGE") && ($SSstereo_recording > 0) ) { + &get_date_time; $stereo_rec_filename =~ s/CAMPAIGN/$log_campaign/gi; $stereo_rec_filename =~ s/INGROUP/$channel_group/gi; $stereo_rec_filename =~ s/CUSTPHONE/$phone_number/gi; @@ -5003,21 +4991,7 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override $sthA->finish(); # get date/time - ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); - $year = ($year + 1900); - $Tyear = ($year - 2000); - $mon++; - if ($mon < 10) {$mon = "0$mon";} - if ($mday < 10) {$mday = "0$mday";} - if ($hour < 10) {$hour = "0$hour";} - if ($min < 10) {$min = "0$min";} - if ($sec < 10) {$sec = "0$sec";} - - $now_date_epoch = time(); - $now_date = "$year-$mon-$mday $hour:$min:$sec"; - $recdate = "$year$mon$mday-$hour$min$sec"; - $tinydate = "$Tyear$mon$mday$hour$min$sec"; - + &get_date_time; $campaign_rec_filename =~ s/CAMPAIGN/$log_campaign/gi; $campaign_rec_filename =~ s/INGROUP/$channel_group/gi; $campaign_rec_filename =~ s/CUSTPHONE/$phone_number/gi; @@ -5089,6 +5063,7 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override ### BEGIN stereo call recording for ALLCALLS/ALLFORCE and for all parallel stereo recording in-groups ### if ( ($stereo_recording =~ /CUSTOMER|BOTH/i) && ($conf_engine eq "CONFBRIDGE") && ($SSstereo_recording > 0) ) { + &get_date_time; $stereo_rec_filename =~ s/CAMPAIGN/$log_campaign/gi; $stereo_rec_filename =~ s/INGROUP/$channel_group/gi; $stereo_rec_filename =~ s/CUSTPHONE/$phone_number/gi; @@ -10405,6 +10380,26 @@ sub parse_asterisk_version } +sub get_date_time + { + # get date/time, for recording filenames + ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); + $year = ($year + 1900); + $Tyear = ($year - 2000); + $mon++; + if ($mon < 10) {$mon = "0$mon";} + if ($mday < 10) {$mday = "0$mday";} + if ($hour < 10) {$hour = "0$hour";} + if ($min < 10) {$min = "0$min";} + if ($sec < 10) {$sec = "0$sec";} + + $now_date_epoch = time(); + $now_date = "$year-$mon-$mday $hour:$min:$sec"; + $recdate = "$year$mon$mday-$hour$min$sec"; + $tinydate = "$Tyear$mon$mday$hour$min$sec"; + } + + sub trigger_transfer_process { # $DS='--'; diff --git a/agi/agi-VDAD_ALL_outbound.agi b/agi/agi-VDAD_ALL_outbound.agi index b796786f3..ec87a3761 100644 --- a/agi/agi-VDAD_ALL_outbound.agi +++ b/agi/agi-VDAD_ALL_outbound.agi @@ -134,6 +134,7 @@ # 241020-1928 - Added khomp campaign settings options # 250827-1556 - Added stereo_recording code # 250924-2150 - Added code for deprecation of "Monitor" application after Asterisk 20 +# 251001-1837 - Fix for rare Stereo recording filename issue # $script = 'agi-VDAD_ALL_outbound.agi'; @@ -1178,21 +1179,7 @@ if ($VDACaffected_rows > 0) $sthA->finish(); # get date/time - ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); - $year = ($year + 1900); - $Tyear = ($year - 2000); - $mon++; - if ($mon < 10) {$mon = "0$mon";} - if ($mday < 10) {$mday = "0$mday";} - if ($hour < 10) {$hour = "0$hour";} - if ($min < 10) {$min = "0$min";} - if ($sec < 10) {$sec = "0$sec";} - - $now_date_epoch = time(); - $now_date = "$year-$mon-$mday $hour:$min:$sec"; - $recdate = "$year$mon$mday-$hour$min$sec"; - $tinydate = "$Tyear$mon$mday$hour$min$sec"; - + &get_date_time; $campaign_rec_filename =~ s/CAMPAIGN/$VDADcampaign/gi; $campaign_rec_filename =~ s/INGROUP/$VDADcampaign/gi; $campaign_rec_filename =~ s/CUSTPHONE/$VDADphone/gi; @@ -3197,21 +3184,7 @@ while ($drop_timer <= $DROP_TIME) $sthA->finish(); # get date/time - ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); - $year = ($year + 1900); - $Tyear = ($year - 2000); - $mon++; - if ($mon < 10) {$mon = "0$mon";} - if ($mday < 10) {$mday = "0$mday";} - if ($hour < 10) {$hour = "0$hour";} - if ($min < 10) {$min = "0$min";} - if ($sec < 10) {$sec = "0$sec";} - - $now_date_epoch = time(); - $now_date = "$year-$mon-$mday $hour:$min:$sec"; - $recdate = "$year$mon$mday-$hour$min$sec"; - $tinydate = "$Tyear$mon$mday$hour$min$sec"; - + &get_date_time; $campaign_rec_filename =~ s/CAMPAIGN/$VDADcampaign/gi; $campaign_rec_filename =~ s/CUSTPHONE/$VDADphone/gi; $campaign_rec_filename =~ s/FULLDATE/$recdate/gi; @@ -3286,6 +3259,7 @@ while ($drop_timer <= $DROP_TIME) ### BEGIN stereo call recording for ALLCALLS/ALLFORCE and for all parallel stereo recording campaigns for remote agents ### if ( ($stereo_recording =~ /CUSTOMER|BOTH/i) && ($conf_engine eq "CONFBRIDGE") && ($SSstereo_recording > 0) ) { + &get_date_time; $stereo_rec_filename =~ s/CAMPAIGN/$VDADcampaign/gi; $stereo_rec_filename =~ s/INGROUP/$VDADcampaign/gi; $stereo_rec_filename =~ s/CUSTPHONE/$VDADphone/gi; @@ -3637,21 +3611,7 @@ while ($drop_timer <= $DROP_TIME) $sthA->finish(); # get date/time - ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); - $year = ($year + 1900); - $Tyear = ($year - 2000); - $mon++; - if ($mon < 10) {$mon = "0$mon";} - if ($mday < 10) {$mday = "0$mday";} - if ($hour < 10) {$hour = "0$hour";} - if ($min < 10) {$min = "0$min";} - if ($sec < 10) {$sec = "0$sec";} - - $now_date_epoch = time(); - $now_date = "$year-$mon-$mday $hour:$min:$sec"; - $recdate = "$year$mon$mday-$hour$min$sec"; - $tinydate = "$Tyear$mon$mday$hour$min$sec"; - + &get_date_time; $campaign_rec_filename =~ s/CAMPAIGN/$VDADcampaign/gi; $campaign_rec_filename =~ s/CUSTPHONE/$VDADphone/gi; $campaign_rec_filename =~ s/FULLDATE/$recdate/gi; @@ -3717,6 +3677,7 @@ while ($drop_timer <= $DROP_TIME) ### BEGIN stereo call recording for ALLCALLS/ALLFORCE and for all parallel stereo recording campaigns ### if ( ($stereo_recording =~ /CUSTOMER|BOTH/i) && ($conf_engine eq "CONFBRIDGE") && ($SSstereo_recording > 0) ) { + &get_date_time; $stereo_rec_filename =~ s/CAMPAIGN/$VDADcampaign/gi; $stereo_rec_filename =~ s/INGROUP/$VDADcampaign/gi; $stereo_rec_filename =~ s/CUSTPHONE/$VDADphone/gi; @@ -4619,21 +4580,7 @@ while ($drop_timer <= $DROP_TIME) $sthA->finish(); # get date/time - ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); - $year = ($year + 1900); - $Tyear = ($year - 2000); - $mon++; - if ($mon < 10) {$mon = "0$mon";} - if ($mday < 10) {$mday = "0$mday";} - if ($hour < 10) {$hour = "0$hour";} - if ($min < 10) {$min = "0$min";} - if ($sec < 10) {$sec = "0$sec";} - - $now_date_epoch = time(); - $now_date = "$year-$mon-$mday $hour:$min:$sec"; - $recdate = "$year$mon$mday-$hour$min$sec"; - $tinydate = "$Tyear$mon$mday$hour$min$sec"; - + &get_date_time; $campaign_rec_filename =~ s/CAMPAIGN/$VDADcampaign/gi; $campaign_rec_filename =~ s/CUSTPHONE/$VDADphone/gi; $campaign_rec_filename =~ s/FULLDATE/$recdate/gi; @@ -4707,6 +4654,7 @@ while ($drop_timer <= $DROP_TIME) ### BEGIN stereo call recording for ALLCALLS/ALLFORCE and for all parallel stereo recording campaigns for remote agents ### if ( ($stereo_recording =~ /CUSTOMER|BOTH/i) && ($conf_engine eq "CONFBRIDGE") && ($SSstereo_recording > 0) ) { + &get_date_time; $stereo_rec_filename =~ s/CAMPAIGN/$VDADcampaign/gi; $stereo_rec_filename =~ s/INGROUP/$VDADcampaign/gi; $stereo_rec_filename =~ s/CUSTPHONE/$VDADphone/gi; @@ -5058,21 +5006,7 @@ while ($drop_timer <= $DROP_TIME) $sthA->finish(); # get date/time - ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); - $year = ($year + 1900); - $Tyear = ($year - 2000); - $mon++; - if ($mon < 10) {$mon = "0$mon";} - if ($mday < 10) {$mday = "0$mday";} - if ($hour < 10) {$hour = "0$hour";} - if ($min < 10) {$min = "0$min";} - if ($sec < 10) {$sec = "0$sec";} - - $now_date_epoch = time(); - $now_date = "$year-$mon-$mday $hour:$min:$sec"; - $recdate = "$year$mon$mday-$hour$min$sec"; - $tinydate = "$Tyear$mon$mday$hour$min$sec"; - + &get_date_time; $campaign_rec_filename =~ s/CAMPAIGN/$VDADcampaign/gi; $campaign_rec_filename =~ s/CUSTPHONE/$VDADphone/gi; $campaign_rec_filename =~ s/FULLDATE/$recdate/gi; @@ -5136,6 +5070,7 @@ while ($drop_timer <= $DROP_TIME) ### BEGIN stereo call recording for ALLCALLS/ALLFORCE and for all parallel stereo recording campaigns ### if ( ($stereo_recording =~ /CUSTOMER|BOTH/i) && ($conf_engine eq "CONFBRIDGE") && ($SSstereo_recording > 0) ) { + &get_date_time; $stereo_rec_filename =~ s/CAMPAIGN/$VDADcampaign/gi; $stereo_rec_filename =~ s/INGROUP/$VDADcampaign/gi; $stereo_rec_filename =~ s/CUSTPHONE/$VDADphone/gi; @@ -6632,6 +6567,26 @@ sub tts_num_var_test } +sub get_date_time + { + # get date/time, for recording filenames + ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); + $year = ($year + 1900); + $Tyear = ($year - 2000); + $mon++; + if ($mon < 10) {$mon = "0$mon";} + if ($mday < 10) {$mday = "0$mday";} + if ($hour < 10) {$hour = "0$hour";} + if ($min < 10) {$min = "0$min";} + if ($sec < 10) {$sec = "0$sec";} + + $now_date_epoch = time(); + $now_date = "$year-$mon-$mday $hour:$min:$sec"; + $recdate = "$year$mon$mday-$hour$min$sec"; + $tinydate = "$Tyear$mon$mday$hour$min$sec"; + } + + sub trigger_transfer_process { # $DS='--'; diff --git a/docs/STEREO_CALL_RECORDINGS.txt b/docs/STEREO_CALL_RECORDINGS.txt index 15f840559..c0ef3ce99 100644 --- a/docs/STEREO_CALL_RECORDINGS.txt +++ b/docs/STEREO_CALL_RECORDINGS.txt @@ -1,7 +1,7 @@ -VICIDIAL STEREO CALL RECORDINGS Started: 2025-06-18 Updated: 2025-09-25 +VICIDIAL STEREO CALL RECORDINGS Started: 2025-06-18 Updated: 2025-10-01 -TO USE THESE FEATURES, YOU WILL NEED TO HAVE ALL SERVERS IN YOUR CLUSTER USING SVN/TRUNK REVISION 3945(2025-09-25) CODE OR HIGHER!!! +TO USE THESE FEATURES, YOU WILL NEED TO HAVE ALL SERVERS IN YOUR CLUSTER USING SVN/TRUNK REVISION 3947(2025-10-01) CODE OR HIGHER!!! This project was designed to allow for additional stereo recording of phone calls at the agent and server levels directly on VICIdial Asterisk servers, with the customer always on one channel(the Right channel) and the agent and all other parties on the other channel(the Left channel). If you are looking for the VICI Gateway Recording Server documentation, please see the GATEWAY_RECORDING_SERVER.txt document. diff --git a/extras/MySQL_AST_CREATE_tables.sql b/extras/MySQL_AST_CREATE_tables.sql index 22bfb3025..b7ad14d5e 100644 --- a/extras/MySQL_AST_CREATE_tables.sql +++ b/extras/MySQL_AST_CREATE_tables.sql @@ -944,7 +944,7 @@ realtime_agent_time_stats ENUM('DISABLED','WAIT_CUST_ACW','WAIT_CUST_ACW_PAUSE', use_auto_hopper ENUM('Y','N') default 'Y', auto_hopper_multi VARCHAR(6) default '1', auto_hopper_level MEDIUMINT(8) UNSIGNED default '0', -auto_trim_hopper ENUM('Y','N') default 'Y', +auto_trim_hopper ENUM('Y','N') default 'N', api_manual_dial ENUM('STANDARD','QUEUE','QUEUE_AND_AUTOCALL') default 'STANDARD', manual_dial_call_time_check ENUM('DISABLED','ENABLED') default 'DISABLED', display_leads_count ENUM('Y','N') default 'N', diff --git a/install.pl b/install.pl index d4a67b2f8..b9a65e372 100644 --- a/install.pl +++ b/install.pl @@ -97,7 +97,7 @@ # default keepalive processes: $VARactive_keepalives = '1234568'; # default Asterisk version: -$VARasterisk_version = '16.X'; +$VARasterisk_version = '18.X'; # default recording FTP archive variables: $VARFTP_host = '10.0.0.4'; $VARFTP_user = 'cron'; @@ -2099,6 +2099,7 @@ print " 11.X\n"; print " 13.X\n"; print " 16.X\n"; + print " 18.X\n"; print "Enter asterisk version or press enter for default: [$VARasterisk_version] "; $PROMPTasterisk_version = ; chomp($PROMPTasterisk_version); diff --git a/www/vicidial/AST_server_performance.php b/www/vicidial/AST_server_performance.php index 6c5a26ab6..5dceb93c8 100644 --- a/www/vicidial/AST_server_performance.php +++ b/www/vicidial/AST_server_performance.php @@ -1,588 +1,555 @@ - LICENSE: AGPLv2 -# -# CHANGES -# -# 60619-1732 - Added variable filtering to eliminate SQL injection attack threat -# - Added required user/pass to gain access to this page -# 70417-1106 - Changed time frame to be definable per time range on a single day -# - Fixed vertical scaling issues -# 80118-1508 - Fixed horizontal scale marking issues -# 90310-2151 - Added admin header -# 90508-0644 - Changed to PHP long tags -# 100214-1421 - Sort menu alphabetically -# 100712-1324 - Added system setting slave server option -# 100802-2347 - Added User Group Allowed Reports option validation -# 100914-1326 - Added lookup for user_level 7 users to set to reports only which will remove other admin links -# 130414-0157 - Added report logging -# 130610-0959 - Finalized changing of all ereg instances to preg -# 130621-0726 - Added filtering of input to prevent SQL injection attacks and new user auth -# 130901-2012 - Changed to mysqli PHP functions -# 130926-0658 - Added check for several different ploticus bin paths -# 140108-0716 - Added webserver and hostname to report logging -# 140328-0005 - Converted division calculations to use MathZDC function -# 141114-0730 - Finalized adding QXZ translation to all admin files -# 141230-1440 - Added code for on-the-fly language translations display -# 170409-1550 - Added IP List validation code -# 170422-0750 - Added input variable filtering -# 180223-1541 - Fixed blank default date/time ranges -# 191013-0842 - Fixes for PHP7 -# 220302-0841 - Added allow_web_debug system setting -# - -$startMS = microtime(); - -require("dbconnect_mysqli.php"); -require("functions.php"); - -$PHP_AUTH_USER=$_SERVER['PHP_AUTH_USER']; -$PHP_AUTH_PW=$_SERVER['PHP_AUTH_PW']; -$PHP_SELF=$_SERVER['PHP_SELF']; -$PHP_SELF = preg_replace('/\.php.*/i','.php',$PHP_SELF); -if (isset($_GET["begin_query_time"])) {$begin_query_time=$_GET["begin_query_time"];} - elseif (isset($_POST["begin_query_time"])) {$begin_query_time=$_POST["begin_query_time"];} -if (isset($_GET["end_query_time"])) {$end_query_time=$_GET["end_query_time"];} - elseif (isset($_POST["end_query_time"])) {$end_query_time=$_POST["end_query_time"];} -if (isset($_GET["group"])) {$group=$_GET["group"];} - elseif (isset($_POST["group"])) {$group=$_POST["group"];} -if (isset($_GET["DB"])) {$DB=$_GET["DB"];} - elseif (isset($_POST["DB"])) {$DB=$_POST["DB"];} -if (isset($_GET["submit"])) {$submit=$_GET["submit"];} - elseif (isset($_POST["submit"])) {$submit=$_POST["submit"];} -if (isset($_GET["SUBMIT"])) {$SUBMIT=$_GET["SUBMIT"];} - elseif (isset($_POST["SUBMIT"])) {$SUBMIT=$_POST["SUBMIT"];} - -$DB=preg_replace("/[^0-9a-zA-Z]/","",$DB); - -$NOW_DATE = date("Y-m-d"); -$NOW_TIME = date("Y-m-d H:i:s"); -$STARTtime = date("U"); -if (strlen($begin_query_time) < 10) {$begin_query_time = "$NOW_DATE 09:00:00";} -if (strlen($end_query_time) < 10) {$end_query_time = "$NOW_DATE 15:30:00";} -if (!isset($group)) {$group = '';} - -$report_name = 'Server Performance Report'; -$db_source = 'M'; - -############################################# -##### START SYSTEM_SETTINGS LOOKUP ##### -$stmt = "SELECT use_non_latin,outbound_autodial_active,slave_db_server,reports_use_slave_db,enable_languages,language_method,allow_web_debug FROM system_settings;"; -$rslt=mysql_to_mysqli($stmt, $link); -#if ($DB) {echo "$stmt\n";} -$qm_conf_ct = mysqli_num_rows($rslt); -if ($qm_conf_ct > 0) - { - $row=mysqli_fetch_row($rslt); - $non_latin = $row[0]; - $outbound_autodial_active = $row[1]; - $slave_db_server = $row[2]; - $reports_use_slave_db = $row[3]; - $SSenable_languages = $row[4]; - $SSlanguage_method = $row[5]; - $SSallow_web_debug = $row[6]; - } -if ($SSallow_web_debug < 1) {$DB=0;} -##### END SETTINGS LOOKUP ##### -########################################### - -$begin_query_time = preg_replace('/[^- \:_0-9a-zA-Z]/', '', $begin_query_time); -$end_query_time = preg_replace('/[^- \:_0-9a-zA-Z]/', '', $end_query_time); -$group = preg_replace('/[^- \.\:\_0-9a-zA-Z]/', '', $group); -$submit = preg_replace('/[^-_0-9a-zA-Z]/', '', $submit); -$SUBMIT = preg_replace('/[^-_0-9a-zA-Z]/', '', $SUBMIT); - -if ($non_latin < 1) - { - $PHP_AUTH_USER = preg_replace('/[^-_0-9a-zA-Z]/', '', $PHP_AUTH_USER); - $PHP_AUTH_PW = preg_replace('/[^-_0-9a-zA-Z]/', '', $PHP_AUTH_PW); - } -else - { - $PHP_AUTH_USER = preg_replace('/[^-_0-9\p{L}]/u', '', $PHP_AUTH_USER); - $PHP_AUTH_PW = preg_replace('/[^-_0-9\p{L}]/u', '', $PHP_AUTH_PW); - } - -$stmt="SELECT selected_language from vicidial_users where user='$PHP_AUTH_USER';"; -if ($DB) {echo "|$stmt|\n";} -$rslt=mysql_to_mysqli($stmt, $link); -$sl_ct = mysqli_num_rows($rslt); -if ($sl_ct > 0) - { - $row=mysqli_fetch_row($rslt); - $VUselected_language = $row[0]; - } - -$auth=0; -$reports_auth=0; -$admin_auth=0; -$auth_message = user_authorization($PHP_AUTH_USER,$PHP_AUTH_PW,'REPORTS',1,0); -if ($auth_message == 'GOOD') - {$auth=1;} - -if ($auth > 0) - { - $stmt="SELECT count(*) from vicidial_users where user='$PHP_AUTH_USER' and user_level > 7 and view_reports='1';"; - if ($DB) {echo "|$stmt|\n";} - $rslt=mysql_to_mysqli($stmt, $link); - $row=mysqli_fetch_row($rslt); - $admin_auth=$row[0]; - - $stmt="SELECT count(*) from vicidial_users where user='$PHP_AUTH_USER' and user_level > 6 and view_reports='1';"; - if ($DB) {echo "|$stmt|\n";} - $rslt=mysql_to_mysqli($stmt, $link); - $row=mysqli_fetch_row($rslt); - $reports_auth=$row[0]; - - if ($reports_auth < 1) - { - $VDdisplayMESSAGE = _QXZ("You are not allowed to view reports"); - Header ("Content-type: text/html; charset=utf-8"); - echo "$VDdisplayMESSAGE: |$PHP_AUTH_USER|$auth_message|\n"; - exit; - } - if ( ($reports_auth > 0) and ($admin_auth < 1) ) - { - $ADD=999999; - $reports_only_user=1; - } - } -else - { - $VDdisplayMESSAGE = _QXZ("Login incorrect, please try again"); - if ($auth_message == 'LOCK') - { - $VDdisplayMESSAGE = _QXZ("Too many login attempts, try again in 15 minutes"); - Header ("Content-type: text/html; charset=utf-8"); - echo "$VDdisplayMESSAGE: |$PHP_AUTH_USER|$auth_message|\n"; - exit; - } - if ($auth_message == 'IPBLOCK') - { - $VDdisplayMESSAGE = _QXZ("Your IP Address is not allowed") . ": $ip"; - Header ("Content-type: text/html; charset=utf-8"); - echo "$VDdisplayMESSAGE: |$PHP_AUTH_USER|$auth_message|\n"; - exit; - } - Header("WWW-Authenticate: Basic realm=\"CONTACT-CENTER-ADMIN\""); - Header("HTTP/1.0 401 Unauthorized"); - echo "$VDdisplayMESSAGE: |$PHP_AUTH_USER|$PHP_AUTH_PW|$auth_message|\n"; - exit; - } - -##### BEGIN log visit to the vicidial_report_log table ##### -$LOGip = getenv("REMOTE_ADDR"); -$LOGbrowser = getenv("HTTP_USER_AGENT"); -$LOGscript_name = getenv("SCRIPT_NAME"); -$LOGserver_name = getenv("SERVER_NAME"); -$LOGserver_port = getenv("SERVER_PORT"); -$LOGrequest_uri = getenv("REQUEST_URI"); -$LOGhttp_referer = getenv("HTTP_REFERER"); -$LOGbrowser=preg_replace("/<|>|\'|\"|\\\\/","",$LOGbrowser); -$LOGrequest_uri=preg_replace("/<|>|\'|\"|\\\\/","",$LOGrequest_uri); -$LOGhttp_referer=preg_replace("/<|>|\'|\"|\\\\/","",$LOGhttp_referer); -if (preg_match("/443/i",$LOGserver_port)) - {$HTTPprotocol = 'https://';} -else - {$HTTPprotocol = 'http://';} -if (($LOGserver_port == '80') or ($LOGserver_port == '443') ) - {$LOGserver_port='';} -else - {$LOGserver_port = ":$LOGserver_port";} -$LOGfull_url = "$HTTPprotocol$LOGserver_name$LOGserver_port$LOGrequest_uri"; - -$LOGhostname = php_uname('n'); -if (strlen($LOGhostname)<1) {$LOGhostname='X';} -if (strlen($LOGserver_name)<1) {$LOGserver_name='X';} - -$stmt="SELECT webserver_id FROM vicidial_webservers where webserver='$LOGserver_name' and hostname='$LOGhostname' LIMIT 1;"; -$rslt=mysql_to_mysqli($stmt, $link); -if ($DB) {echo "$stmt\n";} -$webserver_id_ct = mysqli_num_rows($rslt); -if ($webserver_id_ct > 0) - { - $row=mysqli_fetch_row($rslt); - $webserver_id = $row[0]; - } -else - { - ##### insert webserver entry - $stmt="INSERT INTO vicidial_webservers (webserver,hostname) values('$LOGserver_name','$LOGhostname');"; - if ($DB) {echo "$stmt\n";} - $rslt=mysql_to_mysqli($stmt, $link); - $affected_rows = mysqli_affected_rows($link); - $webserver_id = mysqli_insert_id($link); - } - -$stmt="INSERT INTO vicidial_report_log set event_date=NOW(), user='$PHP_AUTH_USER', ip_address='$LOGip', report_name='$report_name', browser='$LOGbrowser', referer='$LOGhttp_referer', notes='$LOGserver_name:$LOGserver_port $LOGscript_name |$group, $query_date, $end_date, $shift, $file_download, $report_display_type|', url='$LOGfull_url', webserver='$webserver_id';"; -if ($DB) {echo "|$stmt|\n";} -$rslt=mysql_to_mysqli($stmt, $link); -$report_log_id = mysqli_insert_id($link); -##### END log visit to the vicidial_report_log table ##### - -if ( (strlen($slave_db_server)>5) and (preg_match("/$report_name/",$reports_use_slave_db)) ) - { - mysqli_close($link); - $use_slave_server=1; - $db_source = 'S'; - require("dbconnect_mysqli.php"); - echo "\n"; - } - -$stmt="SELECT user_group from vicidial_users where user='$PHP_AUTH_USER';"; -if ($DB) {echo "|$stmt|\n";} -$rslt=mysql_to_mysqli($stmt, $link); -$row=mysqli_fetch_row($rslt); -$LOGuser_group = $row[0]; - -$stmt="SELECT allowed_campaigns,allowed_reports from vicidial_user_groups where user_group='$LOGuser_group';"; -if ($DB) {echo "|$stmt|\n";} -$rslt=mysql_to_mysqli($stmt, $link); -$row=mysqli_fetch_row($rslt); -$LOGallowed_campaigns = $row[0]; -$LOGallowed_reports = $row[1]; - -if ( (!preg_match("/$report_name/",$LOGallowed_reports)) and (!preg_match("/ALL REPORTS/",$LOGallowed_reports)) ) - { - Header("WWW-Authenticate: Basic realm=\"CONTACT-CENTER-ADMIN\""); - Header("HTTP/1.0 401 Unauthorized"); - echo _QXZ("You are not allowed to view this report").": |$PHP_AUTH_USER|$report_name|\n"; - exit; - } - -# path from root to where ploticus files will be stored -$PLOTroot = "vicidial/ploticus"; -$DOCroot = "$WeBServeRRooT/$PLOTroot/"; - -$stmt="select server_ip from servers order by server_ip;"; -$rslt=mysql_to_mysqli($stmt, $link); -if ($DB) {echo "$stmt\n";} -$servers_to_print = mysqli_num_rows($rslt); -$i=0; -$groups=array(); -while ($i < $servers_to_print) - { - $row=mysqli_fetch_row($rslt); - $groups[$i] =$row[0]; - $i++; - } - -$NWB = "\"HELP\""; - -?> - - - - - -\n"; -echo ""._QXZ("$report_name")."\n"; -echo "\n"; -echo "\n"; - -echo ""; -echo ""; - - $short_header=1; - - require("admin_header.php"); - -echo ""._QXZ("$report_name")." $NWB#serverperformance$NWE\n"; - -echo "
\n"; - echo "
"._QXZ("Alternate %1s URLs for %2s",0,'',$url_type_text,$entry_type).": $campaign_id   $NWB#alt_multi_urls$NWE\n"; + echo "
"; + if (!preg_match("/talk/",$url_type)) + {echo _QXZ("Alternate");} + echo _QXZ(" %1s URLs for %2s",0,'',$url_type_text,$entry_type).": $campaign_id   $NWB#alt_multi_urls$NWE\n"; echo "\n"; - echo "\n"; + echo "\n"; $stmt="SELECT url_id,active,url_rank,url_statuses,url_description,url_address,url_lists,url_call_length from vicidial_url_multi where campaign_id='$campaign_id' and entry_type='$entry_type' and url_type='$url_type' order by url_rank limit 1000;"; if ($DB) {echo "$stmt\n";} @@ -521,6 +537,8 @@ echo "\n"; echo "\n"; } + if ($types_to_print < 1) + {echo "";} echo "
#URL ID"._QXZ("ACTIVE").""._QXZ("RANK").""._QXZ("STATUSES").""._QXZ("LISTS").""._QXZ("MIN LENGTH").""._QXZ("DESCRIPTION").""._QXZ("SUBMIT")."
#URL ID"._QXZ("ACTIVE").""._QXZ("RANK").""._QXZ("$statuses_text").""._QXZ("LISTS").""._QXZ("$min_length_text").""._QXZ("DESCRIPTION").""._QXZ("SUBMIT")."
  "._QXZ("No URLs added here yet")."

\n"; @@ -537,7 +555,7 @@ echo "\n"; echo "\n"; echo "
"._QXZ("RANK").": "._QXZ("STATUSES").": "._QXZ("STATUSES").": "._QXZ("DESCRIPTION").":
"; - - -echo "
\n"; -echo _QXZ("Date/Time Range").": \n"; -echo _QXZ("to")." \n"; -echo _QXZ("Server").": \n"; -echo "             "._QXZ("REPORTS")." \n"; -echo "
\n\n"; - -echo "
\n";
-
-
-if (!$group)
-	{
-	echo "\n";
-	echo _QXZ("PLEASE SELECT A SERVER AND DATE/TIME RANGE ABOVE AND CLICK SUBMIT")."\n";
-	}
-
-else
-	{
-	$query_date_BEGIN = $begin_query_time;   
-	$query_date_END = $end_query_time;
-
-
-	echo _QXZ("Server Performance Report",53)." $NOW_TIME\n";
-
-	echo _QXZ("Time range").": $query_date_BEGIN "._QXZ("to")." $query_date_END\n\n";
-	echo "---------- "._QXZ("TOTALS, PEAKS and AVERAGES")."\n";
-
-	$stmt="select AVG(sysload),AVG(channels_total),MAX(sysload),MAX(channels_total),MAX(processes) from server_performance where start_time <= '" . mysqli_real_escape_string($link, $query_date_END) . "' and start_time >= '" . mysqli_real_escape_string($link, $query_date_BEGIN) . "' and server_ip='" . mysqli_real_escape_string($link, $group) . "';";
-	$rslt=mysql_to_mysqli($stmt, $link);
-	if ($DB) {echo "$stmt\n";}
-	$row=mysqli_fetch_row($rslt);
-	$AVGload =	sprintf("%10s", $row[0]);
-	$AVGchannels =	sprintf("%10s", $row[1]);
-	$HIGHload =	$row[2];
-		$HIGHmulti = intval(MathZDC($HIGHload, 100));
-	$HIGHchannels =	$row[3];
-	$HIGHprocesses =$row[4];
-	if ($row[2] > $row[3]) {$HIGHlimit = $row[2];}
-	else {$HIGHlimit = $row[3];}
-	if ($HIGHlimit < $row[4]) {$HIGHlimit = $row[4];}
-
-	$stmt="select AVG(cpu_user_percent),AVG(cpu_system_percent),AVG(cpu_idle_percent) from server_performance where start_time <= '" . mysqli_real_escape_string($link, $query_date_END) . "' and start_time >= '" . mysqli_real_escape_string($link, $query_date_BEGIN) . "' and server_ip='" . mysqli_real_escape_string($link, $group) . "';";
-	$rslt=mysql_to_mysqli($stmt, $link);
-	if ($DB) {echo "$stmt\n";}
-	$row=mysqli_fetch_row($rslt);
-	$AVGcpuUSER =	sprintf("%10s", $row[0]);
-	$AVGcpuSYSTEM =	sprintf("%10s", $row[1]);
-	$AVGcpuIDLE =	sprintf("%10s", $row[2]);
-
-	$stmt="select count(*),SUM(length_in_min) from call_log where extension NOT IN('8365','8366','8367') and  start_time <= '" . mysqli_real_escape_string($link, $query_date_END) . "' and start_time >= '" . mysqli_real_escape_string($link, $query_date_BEGIN) . "' and server_ip='" . mysqli_real_escape_string($link, $group) . "';";
-	$rslt=mysql_to_mysqli($stmt, $link);
-	if ($DB) {echo "$stmt\n";}
-	$row=mysqli_fetch_row($rslt);
-	$TOTALcalls =	sprintf("%10s", $row[0]);
-	$OFFHOOKtime =	sprintf("%10s", $row[1]);
-
-
-	echo _QXZ("Total Calls in/out on this server:",42)."  $TOTALcalls\n";
-	echo _QXZ("Total Off-Hook time on this server (min):",42)." $OFFHOOKtime\n";
-	echo _QXZ("Average/Peak channels in use for server:",42)." $AVGchannels / $HIGHchannels\n";
-	echo _QXZ("Average/Peak load for server:",42)." $AVGload / $HIGHload\n";
-	echo _QXZ("Average USER process cpu percentage:",42)." $AVGcpuUSER %\n";
-	echo _QXZ("Average SYSTEM process cpu percentage:",42)." $AVGcpuSYSTEM %\n";
-	echo _QXZ("Average IDLE process cpu percentage:",42)." $AVGcpuIDLE %\n";
-
-	echo "\n";
-	echo "---------- "._QXZ("LINE GRAPH").":\n";
-
-
-
-	##############################
-	#########  Graph stats
-
-	$DAT = '.dat';
-	$HTM = '.htm';
-	$PNG = '.png';
-	$filedate = date("Y-m-d_His");
-	$DATfile = "$group$query_date$shift$filedate$DAT";
-	$HTMfile = "$group$query_date$shift$filedate$HTM";
-	$PNGfile = "$group$query_date$shift$filedate$PNG";
-
-	$HTMfp = fopen ("$DOCroot/$HTMfile", "a");
-	$DATfp = fopen ("$DOCroot/$DATfile", "a");
-
-	$stmt="select DATE_FORMAT(start_time,'%Y-%m-%d.%H:%i:%s') as timex,sysload,processes,channels_total,live_recordings,cpu_user_percent,cpu_system_percent from server_performance where server_ip='" . mysqli_real_escape_string($link, $group) . "' and start_time <= '" . mysqli_real_escape_string($link, $query_date_END) . "' and start_time >= '" . mysqli_real_escape_string($link, $query_date_BEGIN) . "' order by timex limit 99999;";
-	$rslt=mysql_to_mysqli($stmt, $link);
-	if ($DB) {echo "$stmt\n";}
-	$rows_to_print = mysqli_num_rows($rslt);
-	$i=0;
-	while ($i < $rows_to_print)
-		{
-		$row=mysqli_fetch_row($rslt);
-		if ($i<1) {$time_BEGIN = $row[0];}
-		$time_END = $row[0];
-		$row[5] = intval(($row[5] + $row[6]) * $HIGHmulti);
-		$row[6] = intval($row[6] * $HIGHmulti);
-		if ($rows_to_print > 9999)
-			{
-			if ($rows_to_print <= 19999)
-				{
-				if (preg_match("/0$|2$|4$|6$|8$/",$i))
-					{
-					fwrite ($DATfp, "$row[5]\t$row[6]\t$row[0]\t$row[1]\t$row[2]\t$row[3]\n");
-					}
-				}
-			if ( ($rows_to_print > 19999) and ($rows_to_print <= 49999) )
-				{
-				if (preg_match("/0$|5$/",$i))
-					{
-					fwrite ($DATfp, "$row[5]\t$row[6]\t$row[0]\t$row[1]\t$row[2]\t$row[3]\n");
-					}
-				}
-			if ( ($rows_to_print > 49999) and ($rows_to_print <= 99999) )
-				{
-				if (preg_match("/0$/",$i))
-					{
-					fwrite ($DATfp, "$row[5]\t$row[6]\t$row[0]\t$row[1]\t$row[2]\t$row[3]\n");
-					}
-				}
-			}
-		else
-			{
-			fwrite ($DATfp, "$row[5]\t$row[6]\t$row[0]\t$row[1]\t$row[2]\t$row[3]\n");
-			}
-		$i++;
-		}
-	fclose($DATfp);
-
-	$rows_to_max = ($rows_to_print + 100);
-
-	$time_scale_abb = '5 '._QXZ("minutes");
-	$time_scale_tick = '1 minute';
-	if ($i > 1000) {$time_scale_abb = '10 '._QXZ("minutes");   $time_scale_tick = '2 '._QXZ("minutes");}
-	if ($i > 1500) {$time_scale_abb = '15 '._QXZ("minutes");   $time_scale_tick = '3 '._QXZ("minutes");}
-	if ($i > 2000) {$time_scale_abb = '20 '._QXZ("minutes");   $time_scale_tick = '4 '._QXZ("minutes");}
-	if ($i > 3000) {$time_scale_abb = '30 '._QXZ("minutes");   $time_scale_tick = '5 '._QXZ("minutes");}
-	if ($i > 4000) {$time_scale_abb = '40 '._QXZ("minutes");   $time_scale_tick = '10 '._QXZ("minutes");}
-	if ($i > 5000) {$time_scale_abb = '60 '._QXZ("minutes");   $time_scale_tick = '15 '._QXZ("minutes");}
-	if ($i > 6000) {$time_scale_abb = '90 '._QXZ("minutes");   $time_scale_tick = '15 '._QXZ("minutes");}
-	if ($i > 7000) {$time_scale_abb = '120 '._QXZ("minutes");   $time_scale_tick = '30 '._QXZ("minutes");}
-
-	print _QXZ("rows").": $i   "._QXZ("tick").": $time_scale_abb   "._QXZ("scale").": $time_scale_tick\n";
-
-	$HTMcontent  = '';
-	$HTMcontent .= "#proc page\n";
-	$HTMcontent .= "#if @DEVICE in png,gif\n";
-	$HTMcontent .= "   scale: 0.6\n";
-	$HTMcontent .= "\n";
-	$HTMcontent .= "#endif\n";
-	$HTMcontent .= "#proc getdata\n";
-	$HTMcontent .= "file: $DOCroot/$DATfile\n";
-	$HTMcontent .= "fieldnames: userproc sysproc datetime load processes channels\n";
-	$HTMcontent .= "\n";
-	$HTMcontent .= "#proc areadef\n";
-	$HTMcontent .= "title: Server $group   $query_date_BEGIN to $query_date_END\n";
-	$HTMcontent .= "titledetails: size=14  align=C\n";
-	$HTMcontent .= "rectangle: 1 1 12 7\n";
-	$HTMcontent .= "xscaletype: datetime yyyy-mm-dd.hh:mm:ss\n";
-	$HTMcontent .= "xrange: $time_BEGIN $time_END\n";
-	$HTMcontent .= "yrange: 0 $HIGHlimit\n";
-	$HTMcontent .= "\n";
-	$HTMcontent .= "#proc xaxis\n";
-	$HTMcontent .= "stubs: inc $time_scale_abb\n";
-	$HTMcontent .= "minorticinc: $time_scale_tick\n";
-	$HTMcontent .= "stubformat: hh:mma\n";
-	$HTMcontent .= "\n";
-	$HTMcontent .= "#proc yaxis\n";
-	$HTMcontent .= "stubs: inc 50\n";
-	$HTMcontent .= "grid: color=yellow\n";
-	$HTMcontent .= "gridskip: min\n";
-	$HTMcontent .= "ticincrement: 100 1000\n";
-	$HTMcontent .= "\n";
-	$HTMcontent .= "#proc lineplot\n";
-	$HTMcontent .= "xfield: datetime\n";
-	$HTMcontent .= "yfield: userproc\n";
-	$HTMcontent .= "linedetails: color=purple width=.5\n";
-	$HTMcontent .= "fill: lavender\n";
-	$HTMcontent .= "legendlabel: user proc%\n";
-	$HTMcontent .= "maxinpoints: $rows_to_max\n";
-	$HTMcontent .= "\n";
-	$HTMcontent .= "#proc lineplot\n";
-	$HTMcontent .= "xfield: datetime\n";
-	$HTMcontent .= "yfield: sysproc\n";
-	$HTMcontent .= "linedetails: color=yelloworange width=.5\n";
-	$HTMcontent .= "fill: dullyellow\n";
-	$HTMcontent .= "legendlabel: system proc%\n";
-	$HTMcontent .= "maxinpoints: $rows_to_max\n";
-	$HTMcontent .= "\n";
-	$HTMcontent .= "#proc curvefit\n";
-	$HTMcontent .= "xfield: datetime\n";
-	$HTMcontent .= "yfield: load\n";
-	$HTMcontent .= "linedetails: color=blue width=.5\n";
-	$HTMcontent .= "legendlabel: load\n";
-	$HTMcontent .= "maxinpoints: $rows_to_max\n";
-	$HTMcontent .= "\n";
-	$HTMcontent .= "#proc curvefit\n";
-	$HTMcontent .= "xfield: datetime\n";
-	$HTMcontent .= "yfield: processes\n";
-	$HTMcontent .= "linedetails: color=red width=.5\n";
-	$HTMcontent .= "legendlabel: processes\n";
-	$HTMcontent .= "maxinpoints: $rows_to_max\n";
-	$HTMcontent .= "\n";
-	$HTMcontent .= "#proc curvefit\n";
-	$HTMcontent .= "xfield: datetime\n";
-	$HTMcontent .= "yfield: channels\n";
-	$HTMcontent .= "linedetails: color=green width=.5\n";
-	$HTMcontent .= "legendlabel: channels\n";
-	$HTMcontent .= "maxinpoints: $rows_to_max\n";
-	$HTMcontent .= "\n";
-	$HTMcontent .= "#proc legend\n";
-	$HTMcontent .= "location: max-1 max\n";
-	$HTMcontent .= "seglen: 0.2\n";
-	$HTMcontent .= "\n";
-
-	fwrite ($HTMfp, "$HTMcontent");
-	fclose($HTMfp);
-
-	if (file_exists("/usr/local/bin/pl"))
-		{
-		passthru("/usr/local/bin/pl -png $DOCroot/$HTMfile -o $DOCroot/$PNGfile");
-		}
-	else
-		{
-		if (file_exists("/usr/bin/pl"))
-			{
-			passthru("/usr/bin/pl -png $DOCroot/$HTMfile -o $DOCroot/$PNGfile");
-			}
-		else
-			{
-			if (file_exists("/usr/bin/ploticus"))
-				{
-				passthru("/usr/bin/ploticus -png $DOCroot/$HTMfile -o $DOCroot/$PNGfile");
-				}
-			else
-				{
-				echo "ERROR: ploticus not found\n";
-				}
-			}
-		}
-	sleep(1);
-
-	echo "
"; - echo "\n"; - echo "\n"; - - #echo ""; - } - -if ($db_source == 'S') - { - mysqli_close($link); - $use_slave_server=0; - $db_source = 'M'; - require("dbconnect_mysqli.php"); - } - -$endMS = microtime(); -$startMSary = explode(" ",$startMS); -$endMSary = explode(" ",$endMS); -$runS = ($endMSary[0] - $startMSary[0]); -$runM = ($endMSary[1] - $startMSary[1]); -$TOTALrun = ($runS + $runM); - -$stmt="UPDATE vicidial_report_log set run_time='$TOTALrun' where report_log_id='$report_log_id';"; -if ($DB) {echo "|$stmt|\n";} -$rslt=mysql_to_mysqli($stmt, $link); - -?> - -
-
- - + LICENSE: AGPLv2 +# +# CHANGES +# +# 60619-1732 - Added variable filtering to eliminate SQL injection attack threat +# - Added required user/pass to gain access to this page +# 70417-1106 - Changed time frame to be definable per time range on a single day +# - Fixed vertical scaling issues +# 80118-1508 - Fixed horizontal scale marking issues +# 90310-2151 - Added admin header +# 90508-0644 - Changed to PHP long tags +# 100214-1421 - Sort menu alphabetically +# 100712-1324 - Added system setting slave server option +# 100802-2347 - Added User Group Allowed Reports option validation +# 100914-1326 - Added lookup for user_level 7 users to set to reports only which will remove other admin links +# 130414-0157 - Added report logging +# 130610-0959 - Finalized changing of all ereg instances to preg +# 130621-0726 - Added filtering of input to prevent SQL injection attacks and new user auth +# 130901-2012 - Changed to mysqli PHP functions +# 130926-0658 - Added check for several different ploticus bin paths +# 140108-0716 - Added webserver and hostname to report logging +# 140328-0005 - Converted division calculations to use MathZDC function +# 141114-0730 - Finalized adding QXZ translation to all admin files +# 141230-1440 - Added code for on-the-fly language translations display +# 170409-1550 - Added IP List validation code +# 170422-0750 - Added input variable filtering +# 180223-1541 - Fixed blank default date/time ranges +# 191013-0842 - Fixes for PHP7 +# 220302-0841 - Added allow_web_debug system setting +# 251001-1700 - Switched graph to Graph.js from ploticus, converted to HTML +# + +$startMS = microtime(); + +require("dbconnect_mysqli.php"); +require("functions.php"); + +$PHP_AUTH_USER=$_SERVER['PHP_AUTH_USER']; +$PHP_AUTH_PW=$_SERVER['PHP_AUTH_PW']; +$PHP_SELF=$_SERVER['PHP_SELF']; +$PHP_SELF = preg_replace('/\.php.*/i','.php',$PHP_SELF); +if (isset($_GET["begin_query_time"])) {$begin_query_time=$_GET["begin_query_time"];} + elseif (isset($_POST["begin_query_time"])) {$begin_query_time=$_POST["begin_query_time"];} +if (isset($_GET["end_query_time"])) {$end_query_time=$_GET["end_query_time"];} + elseif (isset($_POST["end_query_time"])) {$end_query_time=$_POST["end_query_time"];} +if (isset($_GET["group"])) {$group=$_GET["group"];} + elseif (isset($_POST["group"])) {$group=$_POST["group"];} +if (isset($_GET["DB"])) {$DB=$_GET["DB"];} + elseif (isset($_POST["DB"])) {$DB=$_POST["DB"];} +if (isset($_GET["submit"])) {$submit=$_GET["submit"];} + elseif (isset($_POST["submit"])) {$submit=$_POST["submit"];} +if (isset($_GET["SUBMIT"])) {$SUBMIT=$_GET["SUBMIT"];} + elseif (isset($_POST["SUBMIT"])) {$SUBMIT=$_POST["SUBMIT"];} + +$DB=preg_replace("/[^0-9a-zA-Z]/","",$DB); + +$NOW_DATE = date("Y-m-d"); +$NOW_TIME = date("Y-m-d H:i:s"); +$STARTtime = date("U"); +if (strlen($begin_query_time) < 10) {$begin_query_time = "$NOW_DATE 09:00:00";} +if (strlen($end_query_time) < 10) {$end_query_time = "$NOW_DATE 15:30:00";} +if (!isset($group)) {$group = '';} + +$report_name = 'Server Performance Report'; +$db_source = 'M'; + +############################################# +##### START SYSTEM_SETTINGS LOOKUP ##### +$stmt = "SELECT use_non_latin,outbound_autodial_active,slave_db_server,reports_use_slave_db,enable_languages,language_method,allow_web_debug FROM system_settings;"; +$rslt=mysql_to_mysqli($stmt, $link); +#if ($DB) {echo "$stmt\n";} +$qm_conf_ct = mysqli_num_rows($rslt); +if ($qm_conf_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $non_latin = $row[0]; + $outbound_autodial_active = $row[1]; + $slave_db_server = $row[2]; + $reports_use_slave_db = $row[3]; + $SSenable_languages = $row[4]; + $SSlanguage_method = $row[5]; + $SSallow_web_debug = $row[6]; + } +if ($SSallow_web_debug < 1) {$DB=0;} +##### END SETTINGS LOOKUP ##### +########################################### + +$begin_query_time = preg_replace('/[^- \:_0-9a-zA-Z]/', '', $begin_query_time); +$end_query_time = preg_replace('/[^- \:_0-9a-zA-Z]/', '', $end_query_time); +$group = preg_replace('/[^- \.\:\_0-9a-zA-Z]/', '', $group); +$submit = preg_replace('/[^-_0-9a-zA-Z]/', '', $submit); +$SUBMIT = preg_replace('/[^-_0-9a-zA-Z]/', '', $SUBMIT); + +if ($non_latin < 1) + { + $PHP_AUTH_USER = preg_replace('/[^-_0-9a-zA-Z]/', '', $PHP_AUTH_USER); + $PHP_AUTH_PW = preg_replace('/[^-_0-9a-zA-Z]/', '', $PHP_AUTH_PW); + } +else + { + $PHP_AUTH_USER = preg_replace('/[^-_0-9\p{L}]/u', '', $PHP_AUTH_USER); + $PHP_AUTH_PW = preg_replace('/[^-_0-9\p{L}]/u', '', $PHP_AUTH_PW); + } + +$stmt="SELECT selected_language from vicidial_users where user='$PHP_AUTH_USER';"; +if ($DB) {echo "|$stmt|\n";} +$rslt=mysql_to_mysqli($stmt, $link); +$sl_ct = mysqli_num_rows($rslt); +if ($sl_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $VUselected_language = $row[0]; + } + +$auth=0; +$reports_auth=0; +$admin_auth=0; +$auth_message = user_authorization($PHP_AUTH_USER,$PHP_AUTH_PW,'REPORTS',1,0); +if ($auth_message == 'GOOD') + {$auth=1;} + +if ($auth > 0) + { + $stmt="SELECT count(*) from vicidial_users where user='$PHP_AUTH_USER' and user_level > 7 and view_reports='1';"; + if ($DB) {echo "|$stmt|\n";} + $rslt=mysql_to_mysqli($stmt, $link); + $row=mysqli_fetch_row($rslt); + $admin_auth=$row[0]; + + $stmt="SELECT count(*) from vicidial_users where user='$PHP_AUTH_USER' and user_level > 6 and view_reports='1';"; + if ($DB) {echo "|$stmt|\n";} + $rslt=mysql_to_mysqli($stmt, $link); + $row=mysqli_fetch_row($rslt); + $reports_auth=$row[0]; + + if ($reports_auth < 1) + { + $VDdisplayMESSAGE = _QXZ("You are not allowed to view reports"); + Header ("Content-type: text/html; charset=utf-8"); + echo "$VDdisplayMESSAGE: |$PHP_AUTH_USER|$auth_message|\n"; + exit; + } + if ( ($reports_auth > 0) and ($admin_auth < 1) ) + { + $ADD=999999; + $reports_only_user=1; + } + } +else + { + $VDdisplayMESSAGE = _QXZ("Login incorrect, please try again"); + if ($auth_message == 'LOCK') + { + $VDdisplayMESSAGE = _QXZ("Too many login attempts, try again in 15 minutes"); + Header ("Content-type: text/html; charset=utf-8"); + echo "$VDdisplayMESSAGE: |$PHP_AUTH_USER|$auth_message|\n"; + exit; + } + if ($auth_message == 'IPBLOCK') + { + $VDdisplayMESSAGE = _QXZ("Your IP Address is not allowed") . ": $ip"; + Header ("Content-type: text/html; charset=utf-8"); + echo "$VDdisplayMESSAGE: |$PHP_AUTH_USER|$auth_message|\n"; + exit; + } + Header("WWW-Authenticate: Basic realm=\"CONTACT-CENTER-ADMIN\""); + Header("HTTP/1.0 401 Unauthorized"); + echo "$VDdisplayMESSAGE: |$PHP_AUTH_USER|$PHP_AUTH_PW|$auth_message|\n"; + exit; + } + +##### BEGIN log visit to the vicidial_report_log table ##### +$LOGip = getenv("REMOTE_ADDR"); +$LOGbrowser = getenv("HTTP_USER_AGENT"); +$LOGscript_name = getenv("SCRIPT_NAME"); +$LOGserver_name = getenv("SERVER_NAME"); +$LOGserver_port = getenv("SERVER_PORT"); +$LOGrequest_uri = getenv("REQUEST_URI"); +$LOGhttp_referer = getenv("HTTP_REFERER"); +$LOGbrowser=preg_replace("/<|>|\'|\"|\\\\/","",$LOGbrowser); +$LOGrequest_uri=preg_replace("/<|>|\'|\"|\\\\/","",$LOGrequest_uri); +$LOGhttp_referer=preg_replace("/<|>|\'|\"|\\\\/","",$LOGhttp_referer); +if (preg_match("/443/i",$LOGserver_port)) + {$HTTPprotocol = 'https://';} +else + {$HTTPprotocol = 'http://';} +if (($LOGserver_port == '80') or ($LOGserver_port == '443') ) + {$LOGserver_port='';} +else + {$LOGserver_port = ":$LOGserver_port";} +$LOGfull_url = "$HTTPprotocol$LOGserver_name$LOGserver_port$LOGrequest_uri"; + +$LOGhostname = php_uname('n'); +if (strlen($LOGhostname)<1) {$LOGhostname='X';} +if (strlen($LOGserver_name)<1) {$LOGserver_name='X';} + +$stmt="SELECT webserver_id FROM vicidial_webservers where webserver='$LOGserver_name' and hostname='$LOGhostname' LIMIT 1;"; +$rslt=mysql_to_mysqli($stmt, $link); +if ($DB) {echo "$stmt\n";} +$webserver_id_ct = mysqli_num_rows($rslt); +if ($webserver_id_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $webserver_id = $row[0]; + } +else + { + ##### insert webserver entry + $stmt="INSERT INTO vicidial_webservers (webserver,hostname) values('$LOGserver_name','$LOGhostname');"; + if ($DB) {echo "$stmt\n";} + $rslt=mysql_to_mysqli($stmt, $link); + $affected_rows = mysqli_affected_rows($link); + $webserver_id = mysqli_insert_id($link); + } + +$stmt="INSERT INTO vicidial_report_log set event_date=NOW(), user='$PHP_AUTH_USER', ip_address='$LOGip', report_name='$report_name', browser='$LOGbrowser', referer='$LOGhttp_referer', notes='$LOGserver_name:$LOGserver_port $LOGscript_name |$group, $query_date, $end_date, $shift, $file_download, $report_display_type|', url='$LOGfull_url', webserver='$webserver_id';"; +if ($DB) {echo "|$stmt|\n";} +$rslt=mysql_to_mysqli($stmt, $link); +$report_log_id = mysqli_insert_id($link); +##### END log visit to the vicidial_report_log table ##### + +if ( (strlen($slave_db_server)>5) and (preg_match("/$report_name/",$reports_use_slave_db)) ) + { + mysqli_close($link); + $use_slave_server=1; + $db_source = 'S'; + require("dbconnect_mysqli.php"); + echo "\n"; + } + +$stmt="SELECT user_group from vicidial_users where user='$PHP_AUTH_USER';"; +if ($DB) {echo "|$stmt|\n";} +$rslt=mysql_to_mysqli($stmt, $link); +$row=mysqli_fetch_row($rslt); +$LOGuser_group = $row[0]; + +$stmt="SELECT allowed_campaigns,allowed_reports from vicidial_user_groups where user_group='$LOGuser_group';"; +if ($DB) {echo "|$stmt|\n";} +$rslt=mysql_to_mysqli($stmt, $link); +$row=mysqli_fetch_row($rslt); +$LOGallowed_campaigns = $row[0]; +$LOGallowed_reports = $row[1]; + +if ( (!preg_match("/$report_name/",$LOGallowed_reports)) and (!preg_match("/ALL REPORTS/",$LOGallowed_reports)) ) + { + Header("WWW-Authenticate: Basic realm=\"CONTACT-CENTER-ADMIN\""); + Header("HTTP/1.0 401 Unauthorized"); + echo _QXZ("You are not allowed to view this report").": |$PHP_AUTH_USER|$report_name|\n"; + exit; + } + +# path from root to where ploticus files will be stored +$PLOTroot = "vicidial/ploticus"; +$DOCroot = "$WeBServeRRooT/$PLOTroot/"; + +$stmt="select server_ip from servers order by server_ip;"; +$rslt=mysql_to_mysqli($stmt, $link); +if ($DB) {echo "$stmt\n";} +$servers_to_print = mysqli_num_rows($rslt); +$i=0; +$groups=array(); +while ($i < $servers_to_print) + { + $row=mysqli_fetch_row($rslt); + $groups[$i] =$row[0]; + $i++; + } + +$NWB = "\"HELP\""; + +require("screen_colors.php"); + +?> + + + + + +\n"; +echo ""._QXZ("$report_name")."\n"; + +require("chart_button.php"); +# echo "\n"; +echo ""; +echo ""; +echo ""; +echo ""; +echo "\n"; +echo "\n"; + +echo "\n"; +echo ""; + + $short_header=1; + + require("admin_header.php"); + +echo ""._QXZ("$report_name")." $NWB#serverperformance$NWE\n"; + +echo ""; + +if (!$group) + { + echo "\n"; + } + +else + { + $query_date_BEGIN = $begin_query_time; + $query_date_END = $end_query_time; + + echo "\n"; + + echo "\n\n"; + echo "\n"; + + $stmt="select AVG(sysload),AVG(channels_total),MAX(sysload),MAX(channels_total),MAX(processes) from server_performance where start_time <= '" . mysqli_real_escape_string($link, $query_date_END) . "' and start_time >= '" . mysqli_real_escape_string($link, $query_date_BEGIN) . "' and server_ip='" . mysqli_real_escape_string($link, $group) . "';"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($DB) {echo "$stmt\n";} + $row=mysqli_fetch_row($rslt); + $AVGload = sprintf("%10s", $row[0]); + $AVGchannels = sprintf("%10s", $row[1]); + $HIGHload = $row[2]; + $HIGHmulti = intval(MathZDC($HIGHload, 100)); + $HIGHchannels = $row[3]; + $HIGHprocesses =$row[4]; + if ($row[2] > $row[3]) {$HIGHlimit = $row[2];} + else {$HIGHlimit = $row[3];} + if ($HIGHlimit < $row[4]) {$HIGHlimit = $row[4];} + + $stmt="select AVG(cpu_user_percent),AVG(cpu_system_percent),AVG(cpu_idle_percent) from server_performance where start_time <= '" . mysqli_real_escape_string($link, $query_date_END) . "' and start_time >= '" . mysqli_real_escape_string($link, $query_date_BEGIN) . "' and server_ip='" . mysqli_real_escape_string($link, $group) . "';"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($DB) {echo "$stmt\n";} + $row=mysqli_fetch_row($rslt); + $AVGcpuUSER = sprintf("%10s", $row[0]); + $AVGcpuSYSTEM = sprintf("%10s", $row[1]); + $AVGcpuIDLE = sprintf("%10s", $row[2]); + + $stmt="select count(*),if(SUM(length_in_min) is null, 0, SUM(length_in_min)) from call_log where extension NOT IN('8365','8366','8367') and start_time <= '" . mysqli_real_escape_string($link, $query_date_END) . "' and start_time >= '" . mysqli_real_escape_string($link, $query_date_BEGIN) . "' and server_ip='" . mysqli_real_escape_string($link, $group) . "';"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($DB) {echo "$stmt\n";} + $row=mysqli_fetch_row($rslt); + $TOTALcalls = sprintf("%10s", $row[0]); + $OFFHOOKtime = sprintf("%10s", $row[1]); + + + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + + $stmt="select DATE_FORMAT(start_time,'%Y-%m-%d %H:%i:%s') as timex,sysload,processes,channels_total,live_recordings,cpu_user_percent,cpu_system_percent, start_time from server_performance where server_ip='" . mysqli_real_escape_string($link, $group) . "' and start_time <= '" . mysqli_real_escape_string($link, $query_date_END) . "' and start_time >= '" . mysqli_real_escape_string($link, $query_date_BEGIN) . "' order by timex limit 99999;"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($DB) {echo "$stmt\n";} + $rows_to_print = mysqli_num_rows($rslt); + $i=0; + + $linewidth=1; $radius=1; $mod=1; + switch (true) + { + case ($rows_to_print <= 50): + $linewidth=3; + $radius=3; + case ($rows_to_print <= 100): + $linewidth=2; + $radius=2; + case ($rows_to_print <= 9999): + $mod=1; + break; + case ($rows_to_print <= 19999): + $mod=2; + break; + case ($rows_to_print <= 49999): + $mod=5; + break; + case ($rows_to_print <= 99999): + $mod=10; + break; + } + + $labels="\t\tlabels: ["; + $datasets="\t\tdatasets: [\n"; + + $SYSLOAD_dataset.="\t\t\t{\n"; + $SYSLOAD_dataset.="\t\t\t\tlabel: \"System load\",\n"; + $SYSLOAD_dataset.="\t\t\t\tradius: $radius,\n"; + $SYSLOAD_dataset.="\t\t\t\tborderWidth: \"$linewidth\",\n"; + $SYSLOAD_dataset.="\t\t\t\tborderColor: \"#FF0000\",\n"; + $SYSLOAD_dataset.="\t\t\t\tbackgroundColor: \"#FF0000\",\n"; + $SYSLOAD_dataset.="\t\t\t\tfill: false,\n"; + $SYSLOAD_dataset.="\t\t\t\tdata: ["; + + $PROCESSES_dataset.="\t\t\t{\n"; + $PROCESSES_dataset.="\t\t\t\tlabel: \"Processes\",\n"; + $PROCESSES_dataset.="\t\t\t\tradius: $radius,\n"; + $PROCESSES_dataset.="\t\t\t\tborderWidth: \"$linewidth\",\n"; + $PROCESSES_dataset.="\t\t\t\tfill: false,\n"; + $PROCESSES_dataset.="\t\t\t\tborderColor: \"#0000FF\",\n"; + $PROCESSES_dataset.="\t\t\t\tbackgroundColor: \"#0000FF\",\n"; + $PROCESSES_dataset.="\t\t\t\tdata: ["; + + $CHANNELS_dataset.="\t\t\t{\n"; + $CHANNELS_dataset.="\t\t\t\tlabel: \"Channels\",\n"; + $CHANNELS_dataset.="\t\t\t\tradius: $radius,\n"; + $CHANNELS_dataset.="\t\t\t\tborderWidth: \"$linewidth\",\n"; + $CHANNELS_dataset.="\t\t\t\tfill: false,\n"; + $CHANNELS_dataset.="\t\t\t\tborderColor: \"#FF9900\",\n"; + $CHANNELS_dataset.="\t\t\t\tbackgroundColor: \"#FF9900\",\n"; + $CHANNELS_dataset.="\t\t\t\tdata: ["; + + $CPU_USER_dataset.="\t\t\t{\n"; + $CPU_USER_dataset.="\t\t\t\tlabel: \"CPU - User\",\n"; + $CPU_USER_dataset.="\t\t\t\tradius: $radius,\n"; + $CPU_USER_dataset.="\t\t\t\tborderWidth: \"$linewidth\",\n"; + $CPU_USER_dataset.="\t\t\t\tfill: false,\n"; + $CPU_USER_dataset.="\t\t\t\tborderColor: \"#00FF00\",\n"; + $CPU_USER_dataset.="\t\t\t\tbackgroundColor: \"#00FF00\",\n"; + $CPU_USER_dataset.="\t\t\t\tdata: [\n"; + + $CPU_SYS_dataset.="\t\t\t{\n"; + $CPU_SYS_dataset.="\t\t\t\tlabel: \"CPU - System\",\n"; + $CPU_SYS_dataset.="\t\t\t\tradius: $radius,\n"; + $CPU_SYS_dataset.="\t\t\t\tborderWidth: \"$linewidth\",\n"; + $CPU_SYS_dataset.="\t\t\t\tfill: false,\n"; + $CPU_SYS_dataset.="\t\t\t\tborderColor: \"#FF00FF\",\n"; + $CPU_SYS_dataset.="\t\t\t\tbackgroundColor: \"#FF00FF\",\n"; + $CPU_SYS_dataset.="\t\t\t\tdata: ["; + + while ($i < $rows_to_print) + { + $row=mysqli_fetch_row($rslt); + if ($i<1) {$time_BEGIN = $row[0];} + $time_END = $row[0]; + $row[5] = intval(($row[5] + $row[6]) * $HIGHmulti); + $row[6] = intval($row[6] * $HIGHmulti); + + if ($i%$mod==0) + { + $labels.="\"$row[0]\","; + $SYSLOAD_dataset.="\"$row[1]\","; + $PROCESSES_dataset.="\"$row[2]\","; + $CHANNELS_dataset.="\"$row[3]\","; + $CPU_USER_dataset.="\"$row[5]\","; + $CPU_SYS_dataset.="\"$row[6]\","; + } + $i++; + } + + $labels=preg_replace('/,$/', "", $labels)."],\n"; + $SYSLOAD_dataset=preg_replace('/,$/', "", $SYSLOAD_dataset)."]\n"; + $PROCESSES_dataset=preg_replace('/,$/', "", $PROCESSES_dataset)."]\n"; + $CHANNELS_dataset=preg_replace('/,$/', "", $CHANNELS_dataset)."]\n"; + $CPU_USER_dataset=preg_replace('/,$/', "", $CPU_USER_dataset)."]\n"; + $CPU_SYS_dataset=preg_replace('/,$/', "", $CPU_SYS_dataset)."]\n"; + + $SYSLOAD_dataset.="\t\t\t}\n"; + $PROCESSES_dataset.="\t\t\t}\n"; + $CHANNELS_dataset.="\t\t\t}\n"; + $CPU_USER_dataset.="\t\t\t}\n"; + $CPU_SYS_dataset.="\t\t\t}\n"; +?> + + + +
"; + + +echo "
\n"; +echo _QXZ("Date/Time Range").": \n"; +echo _QXZ("to")." \n"; +echo _QXZ("Server").": \n"; +echo "\n"; +echo "             "._QXZ("REPORTS")."\n"; +echo "
\n\n"; +echo "
"._QXZ("PLEASE SELECT A SERVER AND DATE/TIME RANGE ABOVE AND CLICK SUBMIT")."
"._QXZ("Server Performance Report").": $NOW_TIME
"._QXZ("Time range").": $query_date_BEGIN "._QXZ("to")." $query_date_END
"._QXZ("TOTALS, PEAKS and AVERAGES")."
"._QXZ("Total Calls in/out on this server:")."$TOTALcalls
"._QXZ("Total Off-Hook time on this server (min):")."$OFFHOOKtime
"._QXZ("Average/Peak channels in use for server:")."$AVGchannels / $HIGHchannels
"._QXZ("Average/Peak load for server:")."$AVGload / $HIGHload
"._QXZ("Average USER process cpu percentage:")."$AVGcpuUSER %
"._QXZ("Average SYSTEM process cpu percentage:")."$AVGcpuSYSTEM %
"._QXZ("Average IDLE process cpu percentage:")."$AVGcpuIDLE %

+ + +
+ +
Total run time: $TOTALrun seconds"; + +$stmt="UPDATE vicidial_report_log set run_time='$TOTALrun' where report_log_id='$report_log_id';"; +if ($DB) {echo "|$stmt|\n";} +$rslt=mysql_to_mysqli($stmt, $link); + +?> + +
+
$db_source"; +} +?> + + From cc3d84bf73e2781ecfa369c49058df671dd765fb Mon Sep 17 00:00:00 2001 From: Mattf Date: Thu, 2 Oct 2025 22:54:27 +0000 Subject: [PATCH 08/12] Added call_count_limit_restrict campaign option git-svn-id: svn://svn.eflo.net/agc_2-X/trunk@3948 3d104415-ff17-0410-8863-d5cf3c621b8a --- extras/MySQL_AST_CREATE_tables.sql | 5 +- extras/upgrade_2.14.sql | 4 ++ www/agc/vdc_db_query.php | 94 ++++++++++++++++++++++++----- www/agc/vicidial.php | 14 ++++- www/vicidial/admin.php | 20 ++++-- www/vicidial/help_documentation.txt | 3 +- 6 files changed, 113 insertions(+), 27 deletions(-) diff --git a/extras/MySQL_AST_CREATE_tables.sql b/extras/MySQL_AST_CREATE_tables.sql index b7ad14d5e..035e96643 100644 --- a/extras/MySQL_AST_CREATE_tables.sql +++ b/extras/MySQL_AST_CREATE_tables.sql @@ -1142,7 +1142,8 @@ parallel_rec_co_filename VARCHAR(50) default '', parallel_rec_cm_filename VARCHAR(50) default '', parallel_rec_fr_filename VARCHAR(50) default '', recording_dtmf_muting SMALLINT(3) UNSIGNED default '0', -stereo_recording_agent ENUM('NEVER','ONDEMAND','ALLCALLS','ALLFORCE') default 'ALLFORCE' +stereo_recording_agent ENUM('NEVER','ONDEMAND','ALLCALLS','ALLFORCE') default 'ALLFORCE', +call_count_limit_restrict VARCHAR(30) default 'DISABLED' ) ENGINE=MyISAM; CREATE TABLE vicidial_lists ( @@ -5853,4 +5854,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='1730',db_schema_update_date=NOW(),reload_timestamp=NOW(); +UPDATE system_settings SET db_schema_version='1731',db_schema_update_date=NOW(),reload_timestamp=NOW(); diff --git a/extras/upgrade_2.14.sql b/extras/upgrade_2.14.sql index 14bcd2798..f423fc07b 100644 --- a/extras/upgrade_2.14.sql +++ b/extras/upgrade_2.14.sql @@ -3011,3 +3011,7 @@ UPDATE system_settings SET db_schema_version='1729',db_schema_update_date=NOW() ALTER TABLE vicidial_url_multi MODIFY url_type ENUM('dispo','start','addlead','noagent','apinewlead','talk','') default ''; UPDATE system_settings SET db_schema_version='1730',db_schema_update_date=NOW() where db_schema_version < 1730; + +ALTER TABLE vicidial_campaigns ADD call_count_limit_restrict VARCHAR(30) default 'DISABLED'; + +UPDATE system_settings SET db_schema_version='1731',db_schema_update_date=NOW() where db_schema_version < 1731; diff --git a/www/agc/vdc_db_query.php b/www/agc/vdc_db_query.php index 9ff366e18..afca9ffa6 100644 --- a/www/agc/vdc_db_query.php +++ b/www/agc/vdc_db_query.php @@ -562,13 +562,14 @@ # 250723-2002 - Fix for issue #1548 # 250916-1918 - Added stereo recording features # 250923-1755 - Added talk_sec_url features +# 251002-1352 - Added call_count_limit_restrict campaign option # -$version = '2.14-455'; -$build = '250923-1755'; +$version = '2.14-456'; +$build = '251002-1352'; $php_script = 'vdc_db_query.php'; $mel=1; # Mysql Error Log enabled = 1 -$mysql_log_count=989; +$mysql_log_count=995; $one_mysql_log=0; $DB=0; $VD_login=0; @@ -2909,7 +2910,7 @@ if ($lead_id_defined < 1) { ##### gather no hopper dialing settings from campaign - $stmt="SELECT no_hopper_dialing,agent_dial_owner_only,local_call_time,dial_statuses,drop_lockout_time,lead_filter_id,lead_order,lead_order_randomize,lead_order_secondary,call_count_limit,next_dial_my_callbacks,callback_list_calltime,callback_hours_block,daily_call_count_limit,daily_limit_manual,daily_phone_number_call_limit FROM vicidial_campaigns where campaign_id='$campaign';"; + $stmt="SELECT no_hopper_dialing,agent_dial_owner_only,local_call_time,dial_statuses,drop_lockout_time,lead_filter_id,lead_order,lead_order_randomize,lead_order_secondary,call_count_limit,next_dial_my_callbacks,callback_list_calltime,callback_hours_block,daily_call_count_limit,daily_limit_manual,daily_phone_number_call_limit,call_count_limit_restrict FROM vicidial_campaigns where campaign_id='$campaign';"; $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00236',$user,$server_ip,$session_name,$one_mysql_log);} if ($DB) {echo "$stmt\n";} @@ -2933,6 +2934,7 @@ $daily_call_count_limit = $row[13]; $daily_limit_manual = $row[14]; $daily_phone_number_call_limit = $row[15]; + $call_count_limit_restrict = $row[16]; } if (preg_match("/N/i",$no_hopper_dialing)) { @@ -4327,7 +4329,7 @@ ##### BEGIN check for postal_code and phone time zones if alert enabled $post_phone_time_diff_alert_message=''; - $stmt="SELECT post_phone_time_diff_alert,local_call_time,owner_populate,default_xfer_group,daily_call_count_limit,daily_limit_manual,call_limit_24hour_method,call_limit_24hour_scope,call_limit_24hour,call_limit_24hour_override,daily_phone_number_call_limit FROM vicidial_campaigns where campaign_id='$campaign';"; + $stmt="SELECT post_phone_time_diff_alert,local_call_time,owner_populate,default_xfer_group,daily_call_count_limit,daily_limit_manual,call_limit_24hour_method,call_limit_24hour_scope,call_limit_24hour,call_limit_24hour_override,daily_phone_number_call_limit,call_count_limit_restrict,call_count_limit FROM vicidial_campaigns where campaign_id='$campaign';"; $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00414',$user,$server_ip,$session_name,$one_mysql_log);} if ($DB) {echo "$stmt\n";} @@ -4346,6 +4348,8 @@ $call_limit_24hour = $row[8]; $call_limit_24hour_override = $row[9]; $daily_phone_number_call_limit = $row[10]; + $call_count_limit_restrict = $row[11]; + $call_count_limit = $row[12]; } if ( ($post_phone_time_diff_alert == 'ENABLED') or (preg_match("/OUTSIDE_CALLTIME/",$post_phone_time_diff_alert)) ) { @@ -4431,7 +4435,7 @@ } ##### END check for postal_code and phone time zones if alert enabled - ### Daily call count limit check ### + ### Total and Daily call count limit check ### manual_dccl_check($lead_id, $no_hopper_dialing_used, 0, $agent_dialed_number); #### BEGIN check for 24-hour call count limit #### @@ -4629,7 +4633,7 @@ if ( (strlen($preview)<1) or ($preview == 'NO') or (strlen($dial_ingroup) > 1) ) { $use_custom_cid='N'; - $stmt = "SELECT use_custom_cid,manual_dial_hopper_check,start_call_url,manual_dial_filter,use_internal_dnc,use_campaign_dnc,use_other_campaign_dnc,cid_group_id,scheduled_callbacks_auto_reschedule,dial_timeout_lead_container,manual_dial_cid,daily_call_count_limit,daily_limit_manual,call_limit_24hour_method,call_limit_24hour_scope,call_limit_24hour,call_limit_24hour_override,cid_group_id_two,daily_phone_number_call_limit,state_descriptions FROM vicidial_campaigns where campaign_id='$campaign';"; + $stmt = "SELECT use_custom_cid,manual_dial_hopper_check,start_call_url,manual_dial_filter,use_internal_dnc,use_campaign_dnc,use_other_campaign_dnc,cid_group_id,scheduled_callbacks_auto_reschedule,dial_timeout_lead_container,manual_dial_cid,daily_call_count_limit,daily_limit_manual,call_limit_24hour_method,call_limit_24hour_scope,call_limit_24hour,call_limit_24hour_override,cid_group_id_two,daily_phone_number_call_limit,state_descriptions,call_count_limit_restrict,call_count_limit FROM vicidial_campaigns where campaign_id='$campaign';"; $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00313',$user,$server_ip,$session_name,$one_mysql_log);} if ($DB) {echo "$stmt\n";} @@ -4657,6 +4661,8 @@ $cid_group_id_two = $row[17]; $daily_phone_number_call_limit = $row[18]; $state_descriptions = $row[19]; + $call_count_limit_restrict = $row[20]; + $call_count_limit = $row[21]; } ### BEGIN check for Dial Timeout Lead Override ### @@ -6435,7 +6441,7 @@ ### check for manual dial filter and extension append settings in campaign $use_eac=0; $use_custom_cid='N'; - $stmt = "SELECT manual_dial_filter,use_internal_dnc,use_campaign_dnc,use_other_campaign_dnc,extension_appended_cidname,start_call_url,scheduled_callbacks_auto_reschedule,dial_timeout_lead_container,daily_call_count_limit,daily_limit_manual,call_limit_24hour_method,call_limit_24hour_scope,call_limit_24hour,call_limit_24hour_override,custom_one,custom_two,custom_three,custom_four,custom_five,daily_phone_number_call_limit,state_descriptions FROM vicidial_campaigns where campaign_id='$campaign';"; + $stmt = "SELECT manual_dial_filter,use_internal_dnc,use_campaign_dnc,use_other_campaign_dnc,extension_appended_cidname,start_call_url,scheduled_callbacks_auto_reschedule,dial_timeout_lead_container,daily_call_count_limit,daily_limit_manual,call_limit_24hour_method,call_limit_24hour_scope,call_limit_24hour,call_limit_24hour_override,custom_one,custom_two,custom_three,custom_four,custom_five,daily_phone_number_call_limit,state_descriptions,call_count_limit_restrict,call_count_limit FROM vicidial_campaigns where campaign_id='$campaign';"; $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00325',$user,$server_ip,$session_name,$one_mysql_log);} if ($DB) {echo "$stmt\n";} @@ -6464,6 +6470,8 @@ $camp_custom_five = $row[18]; $daily_phone_number_call_limit = $row[19]; $state_descriptions = $row[20]; + $call_count_limit_restrict = $row[21]; + $call_count_limit = $row[22]; } # check for user overrides @@ -9056,7 +9064,7 @@ if ($auto_dial_level > 0) { ### check to see if campaign has alt_dial enabled - $stmt="SELECT auto_alt_dial,use_internal_dnc,use_campaign_dnc,use_other_campaign_dnc,daily_call_count_limit,daily_limit_manual,call_limit_24hour_method,call_limit_24hour_scope,call_limit_24hour,call_limit_24hour_override,auto_alt_threshold,daily_phone_number_call_limit FROM vicidial_campaigns where campaign_id='$campaign';"; + $stmt="SELECT auto_alt_dial,use_internal_dnc,use_campaign_dnc,use_other_campaign_dnc,daily_call_count_limit,daily_limit_manual,call_limit_24hour_method,call_limit_24hour_scope,call_limit_24hour,call_limit_24hour_override,auto_alt_threshold,daily_phone_number_call_limit,call_count_limit_restrict,call_count_limit FROM vicidial_campaigns where campaign_id='$campaign';"; $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00064',$user,$server_ip,$session_name,$one_mysql_log);} if ($DB) {echo "$stmt\n";} @@ -9076,6 +9084,8 @@ $call_limit_24hour_override = $row[9]; $auto_alt_threshold = $row[10]; $daily_phone_number_call_limit = $row[11]; + $call_count_limit_restrict = $row[12]; + $call_count_limit = $row[13]; } else {$auto_alt_dial = 'NONE';} $alt_lead_done=0; @@ -11152,7 +11162,7 @@ $force_disable=0; $stmt = "SELECT count(*) from vicidial_url_multi where campaign_id='$VDADchannel_group' and entry_type='ingroup' and url_type='talk' and active='N' and url_address LIKE \"%FORCEDISABLE%\";"; $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00990',$user,$server_ip,$session_name,$one_mysql_log);} if ($DB) {echo "$stmt\n";} $fdtu_field_ct = mysqli_num_rows($rslt); if ($fdtu_field_ct > 0) @@ -13009,7 +13019,7 @@ $force_disable=0; $stmt = "SELECT count(*) from vicidial_url_multi where campaign_id='$VDADchannel_group' and entry_type='ingroup' and url_type='talk' and active='N' and url_address LIKE \"%FORCEDISABLE%\";"; $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00991',$user,$server_ip,$session_name,$one_mysql_log);} if ($DB) {echo "$stmt\n";} $fdtu_field_ct = mysqli_num_rows($rslt); if ($fdtu_field_ct > 0) @@ -15375,7 +15385,7 @@ } ### END Call Notes Logging ### - $stmt="SELECT auto_alt_dial_statuses,use_internal_dnc,use_campaign_dnc,api_manual_dial,use_other_campaign_dnc,call_quota_lead_ranking,daily_call_count_limit,daily_limit_manual,daily_phone_number_call_limit from vicidial_campaigns where campaign_id='$campaign';"; + $stmt="SELECT auto_alt_dial_statuses,use_internal_dnc,use_campaign_dnc,api_manual_dial,use_other_campaign_dnc,call_quota_lead_ranking,daily_call_count_limit,daily_limit_manual,daily_phone_number_call_limit,call_count_limit_restrict,call_count_limit from vicidial_campaigns where campaign_id='$campaign';"; $rslt=mysql_to_mysqli($stmt, $link); if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00155',$user,$server_ip,$session_name,$one_mysql_log);} $row=mysqli_fetch_row($rslt); @@ -15388,6 +15398,8 @@ $daily_call_count_limit = $row[6]; $daily_limit_manual = $row[7]; $daily_phone_number_call_limit = $row[8]; + $call_count_limit_restrict = $row[9]; + $call_count_limit = $row[10]; ### BEGIN Call Quota Lead Renking logging ### @@ -17648,7 +17660,7 @@ # check if this In-Group has talk seconds urls set to -FORCEDISABLE- $stmt = "SELECT count(*) from vicidial_url_multi where campaign_id='$VDADchannel_group' and entry_type='$DUentry_type' and url_type='talk' and active='N' and url_address LIKE \"%FORCEDISABLE%\";"; $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 ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00992',$user,$server_ip,$session_name,$one_mysql_log);} if ($DB) {echo "$stmt\n";} $fdtu_field_ct = mysqli_num_rows($rslt); if ($fdtu_field_ct > 0) @@ -23311,13 +23323,13 @@ function manual_dnc_check($temp_phone_number, $temp_no_hopper, $temp_dial_only) } -##### Daily call count limit check ##### +##### Total and Daily call count limit check ##### function manual_dccl_check($temp_lead_id, $temp_no_hopper, $temp_dial_only, $temp_phone_number) { - global $manual_dial_filter, $use_internal_dnc, $use_campaign_dnc, $campaign, $user, $link, $NOW_TIME, $mel, $server_ip, $session_name, $one_mysql_log, $SSagent_debug_logging, $startMS, $ACTION, $php_script, $stage, $lead_id, $daily_call_count_limit, $daily_limit_manual, $SSdaily_call_count_limit, $daily_phone_number_call_limit; + global $manual_dial_filter, $use_internal_dnc, $use_campaign_dnc, $campaign, $user, $link, $NOW_TIME, $mel, $server_ip, $session_name, $one_mysql_log, $SSagent_debug_logging, $startMS, $ACTION, $php_script, $stage, $lead_id, $daily_call_count_limit, $daily_limit_manual, $SSdaily_call_count_limit, $daily_phone_number_call_limit, $call_count_limit, $call_count_limit_restrict; # $fp = fopen ("./DCCLdebug_log.txt", "a"); -# fwrite ($fp, "$NOW_TIME|1 |$lead_id|$SSdaily_call_count_limit|$daily_call_count_limit|$daily_limit_manual|\n"); +# fwrite ($fp, "$NOW_TIME|1 |$lead_id|$SSdaily_call_count_limit|$daily_call_count_limit|$daily_limit_manual|$call_count_limit|$call_count_limit_restrict|\n"); # fclose($fp); ### BEGIN Daily call count limit filtering ### @@ -23421,6 +23433,56 @@ function manual_dccl_check($temp_lead_id, $temp_no_hopper, $temp_dial_only, $tem } } ### END Daily phone_number call count limit filtering ### + + ### BEGIN Total call_count_limit_restrict filtering ### + if ( ($call_count_limit > 0) and (preg_match("/RESTRICT_ALL/",$call_count_limit_restrict)) ) + { + $temp_daily_call_count_limit = $daily_phone_number_call_limit; + if ($temp_dial_only > 0) {$temp_daily_call_count_limit = ($daily_phone_number_call_limit + 1);} + $stmt="SELECT called_count FROM vicidial_list where lead_id='$temp_lead_id';"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00993',$user,$server_ip,$session_name,$one_mysql_log);} + if ($DB) {echo "$stmt\n";} + $vlcdc_ct = mysqli_num_rows($rslt); + if ($vlcdc_ct > 0) + { + $row=mysqli_fetch_row($rslt); + if ($row[0] >= $call_count_limit) + { + ### flag the lead as called + $stmt = "UPDATE vicidial_list set called_since_last_reset='Y' where lead_id='$lead_id';"; + if ($DB) {echo "$stmt\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00994',$user,$server_ip,$session_name,$one_mysql_log);} + + if ($temp_no_hopper > 0) + { + ### reset agent log record + $stmt="UPDATE vicidial_agent_log set lead_id=NULL,comments='' where agent_log_id='$agent_log_id';"; + if ($format=='debug') {echo "\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00995',$user,$server_ip,$session_name,$one_mysql_log);} + + echo " NO-HOPPER TOTAL CALL LIMIT\nTRY AGAIN\n"; + $stage .= "|$agent_log_id|$vla_status|$agent_dialed_type|$agent_dialed_number|"; + } + else + { + if ($temp_dial_only) + { + echo " CALL NOT PLACED\nTOTAL CALL LIMIT\n"; + } + else + { + echo "TOTAL CALL LIMIT\n"; + } + } + if ($SSagent_debug_logging > 0) {vicidial_ajax_log($NOW_TIME,$startMS,$link,$ACTION,$php_script,$user,$stage,$lead_id,$session_name,$stmt);} + exit; + } + } + } + ### END Total call_count_limit_restrict filtering ### } diff --git a/www/agc/vicidial.php b/www/agc/vicidial.php index 08143b4d2..3165b847b 100644 --- a/www/agc/vicidial.php +++ b/www/agc/vicidial.php @@ -750,10 +750,11 @@ # 250808-1322 - Added agent_man_dial_filter & agent_3way_dial_filter system settings # 250916-2055 - Added stereo recording features # 250924-0953 - Added Talk Seconds URLs features +# 251002-1353 - Added call_count_limit_restrict campaign option # -$version = '2.14-716c'; -$build = '250924-0953'; +$version = '2.14-717c'; +$build = '251002-1353'; $php_script = 'vicidial.php'; $mel=1; # Mysql Error Log enabled = 1 $mysql_log_count=108; @@ -12564,6 +12565,7 @@ function ManualDialNext(mdnCBid,mdnBDleadid,mdnDiaLCodE,mdnPhonENumbeR,mdnStagE, var regMNCvar = new RegExp("HOPPER EMPTY","ig"); var regMDFvarDNC = new RegExp("DNC","ig"); + var regMDFvarTCCL = new RegExp("TOTAL CALL LIMIT","ig"); var regMDFvarDCCL = new RegExp("DAILY CALL LIMIT","ig"); var regMDFvarDCCLP = new RegExp("DAILY PHONE NUMBER CALL LIMIT","ig"); var regMNHDNCvar = new RegExp("NO-HOPPER DNC","ig"); @@ -12575,7 +12577,7 @@ function ManualDialNext(mdnCBid,mdnBDleadid,mdnDiaLCodE,mdnPhonENumbeR,mdnStagE, var regMDFvarTIME = new RegExp("OUTSIDE","ig"); var regMDFvarTFH = new RegExp("24-HOUR CALL LIMIT","ig"); var regMDFvarERR = new RegExp("ERROR","ig"); - if ( (MDnextCID.match(regMNCvar)) || (MDnextCID.match(regMDFvarDNC)) || (MDnextCID.match(regMDFvarDCCL)) || (MDnextCID.match(regMDFvarCAMP)) || (MDnextCID.match(regMDFvarSYS)) ||(MDnextCID.match(regMDFvarCB)) || (MDnextCID.match(regMDFvarTIME)) || (MDnextCID.match(regMDFvarTFH)) || (MDnextCID.match(regMDFvarERR)) || (MDnextCID.match(regMDFvarDCCLP)) || (MDnextCID.match(regMNHDCCLPvar)) ) + if ( (MDnextCID.match(regMNCvar)) || (MDnextCID.match(regMDFvarDNC)) || (MDnextCID.match(regMDFvarTCCL)) || (MDnextCID.match(regMDFvarDCCL)) || (MDnextCID.match(regMDFvarCAMP)) || (MDnextCID.match(regMDFvarSYS)) ||(MDnextCID.match(regMDFvarCB)) || (MDnextCID.match(regMDFvarTIME)) || (MDnextCID.match(regMDFvarTFH)) || (MDnextCID.match(regMDFvarERR)) || (MDnextCID.match(regMDFvarDCCLP)) || (MDnextCID.match(regMNHDCCLPvar)) ) { button_click_log = button_click_log + "" + SQLdate + "-----DialNextFailed---" + MDnextCID + " " + "|"; @@ -12600,6 +12602,12 @@ function ManualDialNext(mdnCBid,mdnBDleadid,mdnDiaLCodE,mdnPhonENumbeR,mdnStagE, alert_displayed=1; in_lead_preview_state=0; } + if (MDnextCID.match(regMDFvarTCCL)) + { + alert_box("\n" + mdnPhonENumbeR); + alert_displayed=1; + in_lead_preview_state=0; + } if (MDnextCID.match(regMDFvarDCCL)) { alert_box("\n" + mdnPhonENumbeR); diff --git a/www/vicidial/admin.php b/www/vicidial/admin.php index 8ee59f1a2..91e706a2d 100644 --- a/www/vicidial/admin.php +++ b/www/vicidial/admin.php @@ -2868,6 +2868,8 @@ elseif (isset($_POST["parallel_rec_cm_filename"])) {$parallel_rec_cm_filename=$_POST["parallel_rec_cm_filename"];} if (isset($_GET["parallel_rec_fr_filename"])) {$parallel_rec_fr_filename=$_GET["parallel_rec_fr_filename"];} elseif (isset($_POST["parallel_rec_fr_filename"])) {$parallel_rec_fr_filename=$_POST["parallel_rec_fr_filename"];} +if (isset($_GET["call_count_limit_restrict"])) {$call_count_limit_restrict=$_GET["call_count_limit_restrict"];} + elseif (isset($_POST["call_count_limit_restrict"])) {$call_count_limit_restrict=$_POST["call_count_limit_restrict"];} $DB=preg_replace("/[^0-9a-zA-Z]/","",$DB); @@ -3650,6 +3652,7 @@ $stereo_recording = preg_replace('/[^-_0-9a-zA-Z]/','',$stereo_recording); $stereo_parallel_recording = preg_replace('/[^-_0-9a-zA-Z]/','',$stereo_parallel_recording); $stereo_recording_agent = preg_replace('/[^-_0-9a-zA-Z]/','',$stereo_recording_agent); +$call_count_limit_restrict = preg_replace('/[^-_0-9a-zA-Z]/','',$call_count_limit_restrict); if ($non_latin < 1) { @@ -6286,12 +6289,13 @@ # 250808-1120 - Added agent_man_dial_filter & agent_3way_dial_filter system settings # 250822-2056 - Added system/campaign/ingroup settings for stereo_recording # 250922-0841 - Added Talk Seconds URL links to multi-url admin page in campaigns and in-groups +# 251002-1428 - Added call_count_limit_restrict campaign setting # # 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-944a'; -$build = '250922-0841'; +$admin_version = '2.14-945a'; +$build = '251002-1428'; $STARTtime = date("U"); $SQLdate = date("Y-m-d H:i:s"); @@ -12731,7 +12735,7 @@ function ajax_logout_now() $rslt=mysql_to_mysqli($stmtX, $link); } - $stmt="INSERT INTO vicidial_campaigns (campaign_name,campaign_id,active,dial_status_a,dial_status_b,dial_status_c,dial_status_d,dial_status_e,lead_order,park_ext,park_file_name,web_form_address,allow_closers,hopper_level,auto_dial_level,next_agent_call,local_call_time,voicemail_ext,dial_timeout,dial_prefix,campaign_cid,campaign_vdad_exten,campaign_rec_exten,campaign_recording,campaign_rec_filename,campaign_script,get_call_launch,am_message_exten,amd_send_to_vmx,xferconf_a_dtmf,xferconf_a_number,xferconf_b_dtmf,xferconf_b_number,alt_number_dialing,scheduled_callbacks,lead_filter_id,drop_call_seconds,drop_action,safe_harbor_exten,display_dialable_count,wrapup_seconds,wrapup_message,closer_campaigns,use_internal_dnc,allcalls_delay,omit_phone_code,dial_method,available_only_ratio_tally,adaptive_dropped_percentage,adaptive_maximum_level,adaptive_latest_server_time,adaptive_intensity,adaptive_dl_diff_target,concurrent_transfers,auto_alt_dial,auto_alt_dial_statuses,agent_pause_codes_active,campaign_description,campaign_changedate,campaign_stats_refresh,campaign_logindate,dial_statuses,disable_alter_custdata,no_hopper_leads_logins,list_order_mix,campaign_allow_inbound,manual_dial_list_id,default_xfer_group,queue_priority,drop_inbound_group,qc_enabled,qc_statuses,qc_lists,qc_web_form_address,qc_script,survey_first_audio_file,survey_dtmf_digits,survey_ni_digit,survey_opt_in_audio_file,survey_ni_audio_file,survey_method,survey_no_response_action,survey_ni_status,survey_response_digit_map,survey_xfer_exten,survey_camp_record_dir,disable_alter_custphone,display_queue_count,qc_get_record_launch,qc_show_recording,qc_shift_id,manual_dial_filter,agent_clipboard_copy,agent_extended_alt_dial,use_campaign_dnc,three_way_call_cid,three_way_dial_prefix,web_form_target,vtiger_search_category,vtiger_create_call_record,vtiger_create_lead_record,vtiger_screen_login,cpd_amd_action,agent_allow_group_alias,default_group_alias,vtiger_search_dead,vtiger_status_call,survey_third_digit,survey_fourth_digit,survey_third_audio_file,survey_fourth_audio_file,survey_third_status,survey_fourth_status,survey_third_exten,survey_fourth_exten,drop_lockout_time,quick_transfer_button,prepopulate_transfer_preset,drop_rate_group,view_calls_in_queue,view_calls_in_queue_launch,grab_calls_in_queue,call_requeue_button,pause_after_each_call,no_hopper_dialing,agent_dial_owner_only,agent_display_dialable_leads,web_form_address_two,waitforsilence_options,agent_select_territories,crm_popup_login,crm_login_address,timer_action,timer_action_message,timer_action_seconds,start_call_url,dispo_call_url,xferconf_c_number,xferconf_d_number,xferconf_e_number,use_custom_cid,scheduled_callbacks_alert,queuemetrics_callstatus_override,extension_appended_cidname,scheduled_callbacks_count,manual_dial_override,blind_monitor_warning,blind_monitor_message,blind_monitor_filename,inbound_queue_no_dial,timer_action_destination,enable_xfer_presets,hide_xfer_number_to_dial,manual_dial_prefix,customer_3way_hangup_logging,customer_3way_hangup_seconds,customer_3way_hangup_action,ivr_park_call,ivr_park_call_agi,manual_preview_dial,realtime_agent_time_stats,use_auto_hopper,auto_hopper_multi,auto_trim_hopper,api_manual_dial,manual_dial_call_time_check,display_leads_count,lead_order_randomize,lead_order_secondary,per_call_notes,my_callback_option,agent_lead_search,agent_lead_search_method,queuemetrics_phone_environment,auto_pause_precall,auto_resume_precall,auto_pause_precall_code,manual_dial_cid,post_phone_time_diff_alert,custom_3way_button_transfer,available_only_tally_threshold,available_only_tally_threshold_agents,dial_level_threshold,dial_level_threshold_agents,safe_harbor_audio,safe_harbor_menu_id,survey_menu_id,callback_days_limit,dl_diff_target_method,disable_dispo_screen,disable_dispo_status,screen_labels,status_display_fields,na_call_url,survey_recording,pllb_grouping,pllb_grouping_limit,call_count_limit,call_count_target,callback_hours_block,callback_list_calltime,user_group,hopper_vlc_dup_check,safe_harbor_audio_field,pause_after_next_call,owner_populate,use_other_campaign_dnc,allow_emails,allow_chats,amd_inbound_group,amd_callmenu,survey_wait_sec,manual_dial_lead_id,dead_max,dispo_max,pause_max,dead_max_dispo,dispo_max_dispo,max_inbound_calls,manual_dial_search_checkbox,hide_call_log_info,timer_alt_seconds,wrapup_bypass,wrapup_after_hotkey,callback_active_limit,callback_active_limit_override,comments_all_tabs,comments_dispo_screen,comments_callback_screen,qc_comment_history,show_previous_callback,clear_script,cpd_unknown_action,manual_dial_search_filter,web_form_address_three,manual_dial_override_field,status_display_ingroup,customer_gone_seconds,agent_display_fields,am_message_wildcards,manual_dial_timeout,routing_initiated_recordings,manual_dial_hopper_check,callback_useronly_move_minutes,ofcom_uk_drop_calc,manual_auto_next,manual_auto_show,allow_required_fields,dead_to_dispo,agent_xfer_validation,ready_max_logout,callback_display_days,three_way_record_stop,hangup_xfer_record_start,scheduled_callbacks_email_alert,max_inbound_calls_outcome,manual_auto_next_options,agent_screen_time_display,next_dial_my_callbacks,inbound_no_agents_no_dial_container,inbound_no_agents_no_dial_threshold,cid_group_id,pause_max_dispo,script_top_dispo,dead_trigger_seconds,dead_trigger_action,dead_trigger_repeat,dead_trigger_filename,dead_trigger_url,scheduled_callbacks_force_dial,scheduled_callbacks_auto_reschedule,scheduled_callbacks_timezones_container,three_way_volume_buttons,callback_dnc,manual_dial_validation,mute_recordings,auto_active_list_new,call_quota_lead_ranking,sip_event_logging,campaign_script_two,leave_vm_no_dispo,leave_vm_message_group_id,dial_timeout_lead_container,amd_type,vmm_daily_limit,opensips_cid_name,amd_agent_route_options,browser_alert_sound,browser_alert_volume,three_way_record_stop_exception,in_group_dial,pause_max_exceptions,hopper_drop_run_trigger,daily_call_count_limit,daily_limit_manual,transfer_button_launch,shared_dial_rank,agent_search_method,qc_scorecard_id,qc_statuses_id,clear_form,leave_3way_start_recording,leave_3way_start_recording_exception,calls_waiting_vl_one,calls_waiting_vl_two,calls_inqueue_count_one,calls_inqueue_count_two,in_man_dial_next_ready_seconds,in_man_dial_next_ready_seconds_override,transfer_no_dispo,call_limit_24hour_method,call_limit_24hour_scope,call_limit_24hour,call_limit_24hour_override,cid_group_id_two,incall_tally_threshold_seconds,auto_alt_threshold,pause_max_url,agent_hide_hangup,ig_xfer_list_sort,script_tab_frame_size,max_logged_in_agents,user_group_script,agent_hangup_route,agent_hangup_value,agent_hangup_ig_override,show_confetti,demographic_quotas,demographic_quotas_container,demographic_quotas_rerank,demographic_quotas_list_resets,custom_one,custom_two,custom_three,custom_four,custom_five,dead_stop_recording,manual_vm_status_updates,force_per_call_notes,agent_search_ingroup_list,hopper_hold_inserts,daily_phone_number_call_limit,state_descriptions,script_tab_height,call_log_days,leave_3way_stop_recording,manual_minimum_ring_seconds,manual_minimum_attempt_seconds,manual_minimum_answer_seconds,khomp_settings_container,stereo_recording,stereo_rec_filename,stereo_parallel_recording,recording_dtmf_muting,stereo_recording_agent,parallel_rec_co_filename,parallel_rec_cm_filename,parallel_rec_fr_filename) SELECT \"$campaign_name\",\"$campaign_id\",\"N\",dial_status_a,dial_status_b,dial_status_c,dial_status_d,dial_status_e,lead_order,park_ext,park_file_name,web_form_address,allow_closers,hopper_level,auto_dial_level,next_agent_call,local_call_time,voicemail_ext,dial_timeout,dial_prefix,campaign_cid,campaign_vdad_exten,campaign_rec_exten,campaign_recording,campaign_rec_filename,campaign_script,get_call_launch,am_message_exten,amd_send_to_vmx,xferconf_a_dtmf,xferconf_a_number,xferconf_b_dtmf,xferconf_b_number,alt_number_dialing,scheduled_callbacks,lead_filter_id,drop_call_seconds,drop_action,safe_harbor_exten,display_dialable_count,wrapup_seconds,wrapup_message,closer_campaigns,use_internal_dnc,allcalls_delay,omit_phone_code,dial_method,available_only_ratio_tally,adaptive_dropped_percentage,adaptive_maximum_level,adaptive_latest_server_time,adaptive_intensity,adaptive_dl_diff_target,concurrent_transfers,auto_alt_dial,auto_alt_dial_statuses,agent_pause_codes_active,campaign_description,campaign_changedate,campaign_stats_refresh,campaign_logindate,dial_statuses,disable_alter_custdata,no_hopper_leads_logins,\"DISABLED\",campaign_allow_inbound,manual_dial_list_id,default_xfer_group,queue_priority,drop_inbound_group,qc_enabled,qc_statuses,qc_lists,qc_web_form_address,qc_script,survey_first_audio_file,survey_dtmf_digits,survey_ni_digit,survey_opt_in_audio_file,survey_ni_audio_file,survey_method,survey_no_response_action,survey_ni_status,survey_response_digit_map,survey_xfer_exten,survey_camp_record_dir,disable_alter_custphone,display_queue_count,qc_get_record_launch,qc_show_recording,qc_shift_id,manual_dial_filter,agent_clipboard_copy,agent_extended_alt_dial,use_campaign_dnc,three_way_call_cid,three_way_dial_prefix,web_form_target,vtiger_search_category,vtiger_create_call_record,vtiger_create_lead_record,vtiger_screen_login,cpd_amd_action,agent_allow_group_alias,default_group_alias,vtiger_search_dead,vtiger_status_call,survey_third_digit,survey_fourth_digit,survey_third_audio_file,survey_fourth_audio_file,survey_third_status,survey_fourth_status,survey_third_exten,survey_fourth_exten,drop_lockout_time,quick_transfer_button,prepopulate_transfer_preset,drop_rate_group,view_calls_in_queue,view_calls_in_queue_launch,grab_calls_in_queue,call_requeue_button,pause_after_each_call,no_hopper_dialing,agent_dial_owner_only,agent_display_dialable_leads,web_form_address_two,waitforsilence_options,agent_select_territories,crm_popup_login,crm_login_address,timer_action,timer_action_message,timer_action_seconds,start_call_url,dispo_call_url,xferconf_c_number,xferconf_d_number,xferconf_e_number,use_custom_cid,scheduled_callbacks_alert,queuemetrics_callstatus_override,extension_appended_cidname,scheduled_callbacks_count,manual_dial_override,blind_monitor_warning,blind_monitor_message,blind_monitor_filename,inbound_queue_no_dial,timer_action_destination,enable_xfer_presets,hide_xfer_number_to_dial,manual_dial_prefix,customer_3way_hangup_logging,customer_3way_hangup_seconds,customer_3way_hangup_action,ivr_park_call,ivr_park_call_agi,manual_preview_dial,realtime_agent_time_stats,use_auto_hopper,auto_hopper_multi,auto_trim_hopper,api_manual_dial,manual_dial_call_time_check,display_leads_count,lead_order_randomize,lead_order_secondary,per_call_notes,my_callback_option,agent_lead_search,agent_lead_search_method,queuemetrics_phone_environment,auto_pause_precall,auto_resume_precall,auto_pause_precall_code,manual_dial_cid,post_phone_time_diff_alert,custom_3way_button_transfer,available_only_tally_threshold,available_only_tally_threshold_agents,dial_level_threshold,dial_level_threshold_agents,safe_harbor_audio,safe_harbor_menu_id,survey_menu_id,callback_days_limit,dl_diff_target_method,disable_dispo_screen,disable_dispo_status,screen_labels,status_display_fields,na_call_url,survey_recording,pllb_grouping,pllb_grouping_limit,call_count_limit,call_count_target,callback_hours_block,callback_list_calltime,user_group,hopper_vlc_dup_check,safe_harbor_audio_field,pause_after_next_call,owner_populate,use_other_campaign_dnc,allow_emails,allow_chats,amd_inbound_group,amd_callmenu,survey_wait_sec,manual_dial_lead_id,dead_max,dispo_max,pause_max,dead_max_dispo,dispo_max_dispo,max_inbound_calls,manual_dial_search_checkbox,hide_call_log_info,timer_alt_seconds,wrapup_bypass,wrapup_after_hotkey,callback_active_limit,callback_active_limit_override,comments_all_tabs,comments_dispo_screen,comments_callback_screen,qc_comment_history,show_previous_callback,clear_script,cpd_unknown_action,manual_dial_search_filter,web_form_address_three,manual_dial_override_field,status_display_ingroup,customer_gone_seconds,agent_display_fields,am_message_wildcards,manual_dial_timeout,routing_initiated_recordings,manual_dial_hopper_check,callback_useronly_move_minutes,ofcom_uk_drop_calc,manual_auto_next,manual_auto_show,allow_required_fields,dead_to_dispo,agent_xfer_validation,ready_max_logout,callback_display_days,three_way_record_stop,hangup_xfer_record_start,scheduled_callbacks_email_alert,max_inbound_calls_outcome,manual_auto_next_options,agent_screen_time_display,next_dial_my_callbacks,inbound_no_agents_no_dial_container,inbound_no_agents_no_dial_threshold,cid_group_id,pause_max_dispo,script_top_dispo,dead_trigger_seconds,dead_trigger_action,dead_trigger_repeat,dead_trigger_filename,dead_trigger_url,scheduled_callbacks_force_dial,scheduled_callbacks_auto_reschedule,scheduled_callbacks_timezones_container,three_way_volume_buttons,callback_dnc,manual_dial_validation,mute_recordings,auto_active_list_new,call_quota_lead_ranking,sip_event_logging,campaign_script_two,leave_vm_no_dispo,leave_vm_message_group_id,dial_timeout_lead_container,amd_type,vmm_daily_limit,opensips_cid_name,amd_agent_route_options,browser_alert_sound,browser_alert_volume,three_way_record_stop_exception,in_group_dial,pause_max_exceptions,hopper_drop_run_trigger,daily_call_count_limit,daily_limit_manual,transfer_button_launch,shared_dial_rank,agent_search_method,qc_scorecard_id,qc_statuses_id,clear_form,leave_3way_start_recording,leave_3way_start_recording_exception,calls_waiting_vl_one,calls_waiting_vl_two,calls_inqueue_count_one,calls_inqueue_count_two,in_man_dial_next_ready_seconds,in_man_dial_next_ready_seconds_override,transfer_no_dispo,call_limit_24hour_method,call_limit_24hour_scope,call_limit_24hour,call_limit_24hour_override,cid_group_id_two,incall_tally_threshold_seconds,auto_alt_threshold,pause_max_url,agent_hide_hangup,ig_xfer_list_sort,script_tab_frame_size,max_logged_in_agents,user_group_script,agent_hangup_route,agent_hangup_value,agent_hangup_ig_override,show_confetti,demographic_quotas,demographic_quotas_container,demographic_quotas_rerank,demographic_quotas_list_resets,custom_one,custom_two,custom_three,custom_four,custom_five,dead_stop_recording,manual_vm_status_updates,force_per_call_notes,agent_search_ingroup_list,hopper_hold_inserts,daily_phone_number_call_limit,state_descriptions,script_tab_height,call_log_days,leave_3way_stop_recording,manual_minimum_ring_seconds,manual_minimum_attempt_seconds,manual_minimum_answer_seconds,khomp_settings_container,stereo_recording,stereo_rec_filename,stereo_parallel_recording,recording_dtmf_muting,stereo_recording_agent,parallel_rec_co_filename,parallel_rec_cm_filename,parallel_rec_fr_filename from vicidial_campaigns where campaign_id='$source_campaign_id';"; + $stmt="INSERT INTO vicidial_campaigns (campaign_name,campaign_id,active,dial_status_a,dial_status_b,dial_status_c,dial_status_d,dial_status_e,lead_order,park_ext,park_file_name,web_form_address,allow_closers,hopper_level,auto_dial_level,next_agent_call,local_call_time,voicemail_ext,dial_timeout,dial_prefix,campaign_cid,campaign_vdad_exten,campaign_rec_exten,campaign_recording,campaign_rec_filename,campaign_script,get_call_launch,am_message_exten,amd_send_to_vmx,xferconf_a_dtmf,xferconf_a_number,xferconf_b_dtmf,xferconf_b_number,alt_number_dialing,scheduled_callbacks,lead_filter_id,drop_call_seconds,drop_action,safe_harbor_exten,display_dialable_count,wrapup_seconds,wrapup_message,closer_campaigns,use_internal_dnc,allcalls_delay,omit_phone_code,dial_method,available_only_ratio_tally,adaptive_dropped_percentage,adaptive_maximum_level,adaptive_latest_server_time,adaptive_intensity,adaptive_dl_diff_target,concurrent_transfers,auto_alt_dial,auto_alt_dial_statuses,agent_pause_codes_active,campaign_description,campaign_changedate,campaign_stats_refresh,campaign_logindate,dial_statuses,disable_alter_custdata,no_hopper_leads_logins,list_order_mix,campaign_allow_inbound,manual_dial_list_id,default_xfer_group,queue_priority,drop_inbound_group,qc_enabled,qc_statuses,qc_lists,qc_web_form_address,qc_script,survey_first_audio_file,survey_dtmf_digits,survey_ni_digit,survey_opt_in_audio_file,survey_ni_audio_file,survey_method,survey_no_response_action,survey_ni_status,survey_response_digit_map,survey_xfer_exten,survey_camp_record_dir,disable_alter_custphone,display_queue_count,qc_get_record_launch,qc_show_recording,qc_shift_id,manual_dial_filter,agent_clipboard_copy,agent_extended_alt_dial,use_campaign_dnc,three_way_call_cid,three_way_dial_prefix,web_form_target,vtiger_search_category,vtiger_create_call_record,vtiger_create_lead_record,vtiger_screen_login,cpd_amd_action,agent_allow_group_alias,default_group_alias,vtiger_search_dead,vtiger_status_call,survey_third_digit,survey_fourth_digit,survey_third_audio_file,survey_fourth_audio_file,survey_third_status,survey_fourth_status,survey_third_exten,survey_fourth_exten,drop_lockout_time,quick_transfer_button,prepopulate_transfer_preset,drop_rate_group,view_calls_in_queue,view_calls_in_queue_launch,grab_calls_in_queue,call_requeue_button,pause_after_each_call,no_hopper_dialing,agent_dial_owner_only,agent_display_dialable_leads,web_form_address_two,waitforsilence_options,agent_select_territories,crm_popup_login,crm_login_address,timer_action,timer_action_message,timer_action_seconds,start_call_url,dispo_call_url,xferconf_c_number,xferconf_d_number,xferconf_e_number,use_custom_cid,scheduled_callbacks_alert,queuemetrics_callstatus_override,extension_appended_cidname,scheduled_callbacks_count,manual_dial_override,blind_monitor_warning,blind_monitor_message,blind_monitor_filename,inbound_queue_no_dial,timer_action_destination,enable_xfer_presets,hide_xfer_number_to_dial,manual_dial_prefix,customer_3way_hangup_logging,customer_3way_hangup_seconds,customer_3way_hangup_action,ivr_park_call,ivr_park_call_agi,manual_preview_dial,realtime_agent_time_stats,use_auto_hopper,auto_hopper_multi,auto_trim_hopper,api_manual_dial,manual_dial_call_time_check,display_leads_count,lead_order_randomize,lead_order_secondary,per_call_notes,my_callback_option,agent_lead_search,agent_lead_search_method,queuemetrics_phone_environment,auto_pause_precall,auto_resume_precall,auto_pause_precall_code,manual_dial_cid,post_phone_time_diff_alert,custom_3way_button_transfer,available_only_tally_threshold,available_only_tally_threshold_agents,dial_level_threshold,dial_level_threshold_agents,safe_harbor_audio,safe_harbor_menu_id,survey_menu_id,callback_days_limit,dl_diff_target_method,disable_dispo_screen,disable_dispo_status,screen_labels,status_display_fields,na_call_url,survey_recording,pllb_grouping,pllb_grouping_limit,call_count_limit,call_count_target,callback_hours_block,callback_list_calltime,user_group,hopper_vlc_dup_check,safe_harbor_audio_field,pause_after_next_call,owner_populate,use_other_campaign_dnc,allow_emails,allow_chats,amd_inbound_group,amd_callmenu,survey_wait_sec,manual_dial_lead_id,dead_max,dispo_max,pause_max,dead_max_dispo,dispo_max_dispo,max_inbound_calls,manual_dial_search_checkbox,hide_call_log_info,timer_alt_seconds,wrapup_bypass,wrapup_after_hotkey,callback_active_limit,callback_active_limit_override,comments_all_tabs,comments_dispo_screen,comments_callback_screen,qc_comment_history,show_previous_callback,clear_script,cpd_unknown_action,manual_dial_search_filter,web_form_address_three,manual_dial_override_field,status_display_ingroup,customer_gone_seconds,agent_display_fields,am_message_wildcards,manual_dial_timeout,routing_initiated_recordings,manual_dial_hopper_check,callback_useronly_move_minutes,ofcom_uk_drop_calc,manual_auto_next,manual_auto_show,allow_required_fields,dead_to_dispo,agent_xfer_validation,ready_max_logout,callback_display_days,three_way_record_stop,hangup_xfer_record_start,scheduled_callbacks_email_alert,max_inbound_calls_outcome,manual_auto_next_options,agent_screen_time_display,next_dial_my_callbacks,inbound_no_agents_no_dial_container,inbound_no_agents_no_dial_threshold,cid_group_id,pause_max_dispo,script_top_dispo,dead_trigger_seconds,dead_trigger_action,dead_trigger_repeat,dead_trigger_filename,dead_trigger_url,scheduled_callbacks_force_dial,scheduled_callbacks_auto_reschedule,scheduled_callbacks_timezones_container,three_way_volume_buttons,callback_dnc,manual_dial_validation,mute_recordings,auto_active_list_new,call_quota_lead_ranking,sip_event_logging,campaign_script_two,leave_vm_no_dispo,leave_vm_message_group_id,dial_timeout_lead_container,amd_type,vmm_daily_limit,opensips_cid_name,amd_agent_route_options,browser_alert_sound,browser_alert_volume,three_way_record_stop_exception,in_group_dial,pause_max_exceptions,hopper_drop_run_trigger,daily_call_count_limit,daily_limit_manual,transfer_button_launch,shared_dial_rank,agent_search_method,qc_scorecard_id,qc_statuses_id,clear_form,leave_3way_start_recording,leave_3way_start_recording_exception,calls_waiting_vl_one,calls_waiting_vl_two,calls_inqueue_count_one,calls_inqueue_count_two,in_man_dial_next_ready_seconds,in_man_dial_next_ready_seconds_override,transfer_no_dispo,call_limit_24hour_method,call_limit_24hour_scope,call_limit_24hour,call_limit_24hour_override,cid_group_id_two,incall_tally_threshold_seconds,auto_alt_threshold,pause_max_url,agent_hide_hangup,ig_xfer_list_sort,script_tab_frame_size,max_logged_in_agents,user_group_script,agent_hangup_route,agent_hangup_value,agent_hangup_ig_override,show_confetti,demographic_quotas,demographic_quotas_container,demographic_quotas_rerank,demographic_quotas_list_resets,custom_one,custom_two,custom_three,custom_four,custom_five,dead_stop_recording,manual_vm_status_updates,force_per_call_notes,agent_search_ingroup_list,hopper_hold_inserts,daily_phone_number_call_limit,state_descriptions,script_tab_height,call_log_days,leave_3way_stop_recording,manual_minimum_ring_seconds,manual_minimum_attempt_seconds,manual_minimum_answer_seconds,khomp_settings_container,stereo_recording,stereo_rec_filename,stereo_parallel_recording,recording_dtmf_muting,stereo_recording_agent,parallel_rec_co_filename,parallel_rec_cm_filename,parallel_rec_fr_filename,call_count_limit_restrict) SELECT \"$campaign_name\",\"$campaign_id\",\"N\",dial_status_a,dial_status_b,dial_status_c,dial_status_d,dial_status_e,lead_order,park_ext,park_file_name,web_form_address,allow_closers,hopper_level,auto_dial_level,next_agent_call,local_call_time,voicemail_ext,dial_timeout,dial_prefix,campaign_cid,campaign_vdad_exten,campaign_rec_exten,campaign_recording,campaign_rec_filename,campaign_script,get_call_launch,am_message_exten,amd_send_to_vmx,xferconf_a_dtmf,xferconf_a_number,xferconf_b_dtmf,xferconf_b_number,alt_number_dialing,scheduled_callbacks,lead_filter_id,drop_call_seconds,drop_action,safe_harbor_exten,display_dialable_count,wrapup_seconds,wrapup_message,closer_campaigns,use_internal_dnc,allcalls_delay,omit_phone_code,dial_method,available_only_ratio_tally,adaptive_dropped_percentage,adaptive_maximum_level,adaptive_latest_server_time,adaptive_intensity,adaptive_dl_diff_target,concurrent_transfers,auto_alt_dial,auto_alt_dial_statuses,agent_pause_codes_active,campaign_description,campaign_changedate,campaign_stats_refresh,campaign_logindate,dial_statuses,disable_alter_custdata,no_hopper_leads_logins,\"DISABLED\",campaign_allow_inbound,manual_dial_list_id,default_xfer_group,queue_priority,drop_inbound_group,qc_enabled,qc_statuses,qc_lists,qc_web_form_address,qc_script,survey_first_audio_file,survey_dtmf_digits,survey_ni_digit,survey_opt_in_audio_file,survey_ni_audio_file,survey_method,survey_no_response_action,survey_ni_status,survey_response_digit_map,survey_xfer_exten,survey_camp_record_dir,disable_alter_custphone,display_queue_count,qc_get_record_launch,qc_show_recording,qc_shift_id,manual_dial_filter,agent_clipboard_copy,agent_extended_alt_dial,use_campaign_dnc,three_way_call_cid,three_way_dial_prefix,web_form_target,vtiger_search_category,vtiger_create_call_record,vtiger_create_lead_record,vtiger_screen_login,cpd_amd_action,agent_allow_group_alias,default_group_alias,vtiger_search_dead,vtiger_status_call,survey_third_digit,survey_fourth_digit,survey_third_audio_file,survey_fourth_audio_file,survey_third_status,survey_fourth_status,survey_third_exten,survey_fourth_exten,drop_lockout_time,quick_transfer_button,prepopulate_transfer_preset,drop_rate_group,view_calls_in_queue,view_calls_in_queue_launch,grab_calls_in_queue,call_requeue_button,pause_after_each_call,no_hopper_dialing,agent_dial_owner_only,agent_display_dialable_leads,web_form_address_two,waitforsilence_options,agent_select_territories,crm_popup_login,crm_login_address,timer_action,timer_action_message,timer_action_seconds,start_call_url,dispo_call_url,xferconf_c_number,xferconf_d_number,xferconf_e_number,use_custom_cid,scheduled_callbacks_alert,queuemetrics_callstatus_override,extension_appended_cidname,scheduled_callbacks_count,manual_dial_override,blind_monitor_warning,blind_monitor_message,blind_monitor_filename,inbound_queue_no_dial,timer_action_destination,enable_xfer_presets,hide_xfer_number_to_dial,manual_dial_prefix,customer_3way_hangup_logging,customer_3way_hangup_seconds,customer_3way_hangup_action,ivr_park_call,ivr_park_call_agi,manual_preview_dial,realtime_agent_time_stats,use_auto_hopper,auto_hopper_multi,auto_trim_hopper,api_manual_dial,manual_dial_call_time_check,display_leads_count,lead_order_randomize,lead_order_secondary,per_call_notes,my_callback_option,agent_lead_search,agent_lead_search_method,queuemetrics_phone_environment,auto_pause_precall,auto_resume_precall,auto_pause_precall_code,manual_dial_cid,post_phone_time_diff_alert,custom_3way_button_transfer,available_only_tally_threshold,available_only_tally_threshold_agents,dial_level_threshold,dial_level_threshold_agents,safe_harbor_audio,safe_harbor_menu_id,survey_menu_id,callback_days_limit,dl_diff_target_method,disable_dispo_screen,disable_dispo_status,screen_labels,status_display_fields,na_call_url,survey_recording,pllb_grouping,pllb_grouping_limit,call_count_limit,call_count_target,callback_hours_block,callback_list_calltime,user_group,hopper_vlc_dup_check,safe_harbor_audio_field,pause_after_next_call,owner_populate,use_other_campaign_dnc,allow_emails,allow_chats,amd_inbound_group,amd_callmenu,survey_wait_sec,manual_dial_lead_id,dead_max,dispo_max,pause_max,dead_max_dispo,dispo_max_dispo,max_inbound_calls,manual_dial_search_checkbox,hide_call_log_info,timer_alt_seconds,wrapup_bypass,wrapup_after_hotkey,callback_active_limit,callback_active_limit_override,comments_all_tabs,comments_dispo_screen,comments_callback_screen,qc_comment_history,show_previous_callback,clear_script,cpd_unknown_action,manual_dial_search_filter,web_form_address_three,manual_dial_override_field,status_display_ingroup,customer_gone_seconds,agent_display_fields,am_message_wildcards,manual_dial_timeout,routing_initiated_recordings,manual_dial_hopper_check,callback_useronly_move_minutes,ofcom_uk_drop_calc,manual_auto_next,manual_auto_show,allow_required_fields,dead_to_dispo,agent_xfer_validation,ready_max_logout,callback_display_days,three_way_record_stop,hangup_xfer_record_start,scheduled_callbacks_email_alert,max_inbound_calls_outcome,manual_auto_next_options,agent_screen_time_display,next_dial_my_callbacks,inbound_no_agents_no_dial_container,inbound_no_agents_no_dial_threshold,cid_group_id,pause_max_dispo,script_top_dispo,dead_trigger_seconds,dead_trigger_action,dead_trigger_repeat,dead_trigger_filename,dead_trigger_url,scheduled_callbacks_force_dial,scheduled_callbacks_auto_reschedule,scheduled_callbacks_timezones_container,three_way_volume_buttons,callback_dnc,manual_dial_validation,mute_recordings,auto_active_list_new,call_quota_lead_ranking,sip_event_logging,campaign_script_two,leave_vm_no_dispo,leave_vm_message_group_id,dial_timeout_lead_container,amd_type,vmm_daily_limit,opensips_cid_name,amd_agent_route_options,browser_alert_sound,browser_alert_volume,three_way_record_stop_exception,in_group_dial,pause_max_exceptions,hopper_drop_run_trigger,daily_call_count_limit,daily_limit_manual,transfer_button_launch,shared_dial_rank,agent_search_method,qc_scorecard_id,qc_statuses_id,clear_form,leave_3way_start_recording,leave_3way_start_recording_exception,calls_waiting_vl_one,calls_waiting_vl_two,calls_inqueue_count_one,calls_inqueue_count_two,in_man_dial_next_ready_seconds,in_man_dial_next_ready_seconds_override,transfer_no_dispo,call_limit_24hour_method,call_limit_24hour_scope,call_limit_24hour,call_limit_24hour_override,cid_group_id_two,incall_tally_threshold_seconds,auto_alt_threshold,pause_max_url,agent_hide_hangup,ig_xfer_list_sort,script_tab_frame_size,max_logged_in_agents,user_group_script,agent_hangup_route,agent_hangup_value,agent_hangup_ig_override,show_confetti,demographic_quotas,demographic_quotas_container,demographic_quotas_rerank,demographic_quotas_list_resets,custom_one,custom_two,custom_three,custom_four,custom_five,dead_stop_recording,manual_vm_status_updates,force_per_call_notes,agent_search_ingroup_list,hopper_hold_inserts,daily_phone_number_call_limit,state_descriptions,script_tab_height,call_log_days,leave_3way_stop_recording,manual_minimum_ring_seconds,manual_minimum_attempt_seconds,manual_minimum_answer_seconds,khomp_settings_container,stereo_recording,stereo_rec_filename,stereo_parallel_recording,recording_dtmf_muting,stereo_recording_agent,parallel_rec_co_filename,parallel_rec_cm_filename,parallel_rec_fr_filename,call_count_limit_restrict from vicidial_campaigns where campaign_id='$source_campaign_id';"; $rslt=mysql_to_mysqli($stmt, $link); $affected_rows = mysqli_affected_rows($link); @@ -17544,7 +17548,7 @@ function ajax_logout_now() if ($LOGmodify_dial_prefix > 0) {$prefixSQL = ",dial_prefix='$dial_prefix',manual_dial_prefix='$manual_dial_prefix',three_way_dial_prefix='$three_way_dial_prefix'";} - $stmtA="UPDATE vicidial_campaigns set campaign_name='$campaign_name',active='$active',dial_status_a='$dial_status_a',dial_status_b='$dial_status_b',dial_status_c='$dial_status_c',dial_status_d='$dial_status_d',dial_status_e='$dial_status_e',lead_order='$lead_order',allow_closers='$allow_closers',hopper_level='$hopper_level', auto_trim_hopper='$auto_trim_hopper', use_auto_hopper='$use_auto_hopper', auto_hopper_multi='$auto_hopper_multi', $adlSQL next_agent_call='$next_agent_call', local_call_time='$local_call_time', voicemail_ext='$voicemail_ext', dial_timeout='$dial_timeout', campaign_cid='$campaign_cid', campaign_vdad_exten='$campaign_vdad_exten', web_form_address='" . mysqli_real_escape_string($link, $web_form_address) . "', park_ext='$park_ext', park_file_name='$park_file_name', campaign_rec_exten='$campaign_rec_exten', campaign_recording='$campaign_recording', campaign_rec_filename='$campaign_rec_filename', campaign_script='$script_id', get_call_launch='$get_call_launch', am_message_exten='$am_message_exten', amd_send_to_vmx='$amd_send_to_vmx', xferconf_a_dtmf='$xferconf_a_dtmf',xferconf_a_number='$xferconf_a_number',xferconf_b_dtmf='$xferconf_b_dtmf',xferconf_b_number='$xferconf_b_number',lead_filter_id='$lead_filter_id',alt_number_dialing='$alt_number_dialing',scheduled_callbacks='$scheduled_callbacks',drop_action='$drop_action',drop_call_seconds='$drop_call_seconds',safe_harbor_exten='$safe_harbor_exten',wrapup_seconds='$wrapup_seconds',wrapup_message='$wrapup_message',closer_campaigns=$closer_campaignsSQL,use_internal_dnc='$use_internal_dnc',allcalls_delay='$allcalls_delay',omit_phone_code='$omit_phone_code',dial_method='$dial_method',available_only_ratio_tally='$available_only_ratio_tally',adaptive_dropped_percentage='$adaptive_dropped_percentage',adaptive_maximum_level='$adaptive_maximum_level',adaptive_latest_server_time='$adaptive_latest_server_time',adaptive_intensity='$adaptive_intensity',adaptive_dl_diff_target='$adaptive_dl_diff_target',concurrent_transfers='$concurrent_transfers',auto_alt_dial='$auto_alt_dial',agent_pause_codes_active='$agent_pause_codes_active',campaign_description='$campaign_description',campaign_changedate='$SQLdate',campaign_stats_refresh='$campaign_stats_refresh',disable_alter_custdata='$disable_alter_custdata',no_hopper_leads_logins='$no_hopper_leads_logins',list_order_mix='$list_order_mix',campaign_allow_inbound='$campaign_allow_inbound',manual_dial_list_id='$manual_dial_list_id',default_xfer_group='$default_xfer_group',xfer_groups='$XFERgroups_value',queue_priority='$queue_priority',drop_inbound_group='$drop_inbound_group',disable_alter_custphone='$disable_alter_custphone',display_queue_count='$display_queue_count',manual_dial_filter='$manual_dial_filter',agent_clipboard_copy='$agent_clipboard_copy',agent_extended_alt_dial='$agent_extended_alt_dial',use_campaign_dnc='$use_campaign_dnc',three_way_call_cid='$three_way_call_cid',web_form_target='$web_form_target',vtiger_search_category='$vtiger_search_category',vtiger_create_call_record='$vtiger_create_call_record',vtiger_create_lead_record='$vtiger_create_lead_record',vtiger_screen_login='$vtiger_screen_login',cpd_amd_action='$cpd_amd_action',agent_allow_group_alias='$agent_allow_group_alias',default_group_alias='$default_group_alias',vtiger_search_dead='$vtiger_search_dead',vtiger_status_call='$vtiger_status_call',drop_lockout_time='$drop_lockout_time',quick_transfer_button='$quick_transfer_button',prepopulate_transfer_preset='$prepopulate_transfer_preset',drop_rate_group='$drop_rate_group',view_calls_in_queue='$view_calls_in_queue',view_calls_in_queue_launch='$view_calls_in_queue_launch',grab_calls_in_queue='$grab_calls_in_queue',call_requeue_button='$call_requeue_button',pause_after_each_call='$pause_after_each_call',no_hopper_dialing='$no_hopper_dialing',agent_dial_owner_only='$agent_dial_owner_only',agent_display_dialable_leads='$agent_display_dialable_leads',web_form_address_two='" . mysqli_real_escape_string($link, $web_form_address_two) . "',waitforsilence_options='$waitforsilence_options',agent_select_territories='$agent_select_territories',crm_popup_login='$crm_popup_login',crm_login_address='" . mysqli_real_escape_string($link, $crm_login_address) . "',timer_action='$timer_action',timer_action_message='$timer_action_message',timer_action_seconds='$timer_action_seconds',start_call_url='" . mysqli_real_escape_string($link, $start_call_url) . "',dispo_call_url='" . mysqli_real_escape_string($link, $dispo_call_url) . "',xferconf_c_number='$xferconf_c_number',xferconf_d_number='$xferconf_d_number',xferconf_e_number='$xferconf_e_number',use_custom_cid='$use_custom_cid',scheduled_callbacks_alert='$scheduled_callbacks_alert',queuemetrics_callstatus_override='$queuemetrics_callstatus',extension_appended_cidname='$extension_appended_cidname',scheduled_callbacks_count='$scheduled_callbacks_count',manual_dial_override='$manual_dial_override',blind_monitor_warning='$blind_monitor_warning',blind_monitor_message='" . mysqli_real_escape_string($link, $blind_monitor_message) . "',blind_monitor_filename='$blind_monitor_filename',inbound_queue_no_dial='$inbound_queue_no_dial',timer_action_destination='$timer_action_destination',enable_xfer_presets='$enable_xfer_presets',hide_xfer_number_to_dial='$hide_xfer_number_to_dial',customer_3way_hangup_logging='$customer_3way_hangup_logging',customer_3way_hangup_seconds='$customer_3way_hangup_seconds',customer_3way_hangup_action='$customer_3way_hangup_action',ivr_park_call='$ivr_park_call',ivr_park_call_agi='$ivr_park_call_agi',manual_preview_dial='$manual_preview_dial',realtime_agent_time_stats='$realtime_agent_time_stats',api_manual_dial='$api_manual_dial',manual_dial_call_time_check='$manual_dial_call_time_check',lead_order_randomize='$lead_order_randomize',lead_order_secondary='$lead_order_secondary',per_call_notes='$per_call_notes',my_callback_option='$my_callback_option',agent_lead_search='$agent_lead_search',agent_lead_search_method='$agent_lead_search_method',queuemetrics_phone_environment='$queuemetrics_phone_environment',auto_pause_precall='$auto_pause_precall',auto_resume_precall='$auto_resume_precall',auto_pause_precall_code='$auto_pause_precall_code',manual_dial_cid='$manual_dial_cid',post_phone_time_diff_alert='$post_phone_time_diff_alert',custom_3way_button_transfer='$custom_3way_button_transfer',available_only_tally_threshold='$available_only_tally_threshold',available_only_tally_threshold_agents='$available_only_tally_threshold_agents',dial_level_threshold='$dial_level_threshold',dial_level_threshold_agents='$dial_level_threshold_agents',safe_harbor_audio='$safe_harbor_audio',safe_harbor_menu_id='$safe_harbor_menu_id',callback_days_limit='$callback_days_limit',dl_diff_target_method='$dl_diff_target_method',disable_dispo_screen='$disable_dispo_screen',disable_dispo_status='$disable_dispo_status',screen_labels='$screen_labels',status_display_fields='$status_display_fields',na_call_url='" . mysqli_real_escape_string($link, $na_call_url) . "',pllb_grouping='$pllb_grouping',pllb_grouping_limit='$pllb_grouping_limit',call_count_limit='$call_count_limit',call_count_target='$call_count_target',callback_hours_block='$callback_hours_block',callback_list_calltime='$callback_list_calltime',user_group='$user_group',hopper_vlc_dup_check='$hopper_vlc_dup_check',in_group_dial='$in_group_dial',in_group_dial_select='$in_group_dial_select',safe_harbor_audio_field='$safe_harbor_audio_field',pause_after_next_call='$pause_after_next_call',owner_populate='$owner_populate',use_other_campaign_dnc='$use_other_campaign_dnc',allow_emails='$allow_emails',allow_chats='$allow_chats',amd_inbound_group='$amd_inbound_group',amd_callmenu='$amd_callmenu',manual_dial_lead_id='$manual_dial_lead_id',dead_max='$dead_max',dispo_max='$dispo_max',pause_max='$pause_max',dead_max_dispo='$dead_max_dispo',dispo_max_dispo='$dispo_max_dispo',max_inbound_calls='$max_inbound_calls',manual_dial_search_checkbox='$manual_dial_search_checkbox',hide_call_log_info='$hide_call_log_info',timer_alt_seconds='$timer_alt_seconds',wrapup_bypass='$wrapup_bypass',wrapup_after_hotkey='$wrapup_after_hotkey',callback_active_limit='$callback_active_limit',callback_active_limit_override='$callback_active_limit_override',comments_all_tabs='$comments_all_tabs',comments_dispo_screen='$comments_dispo_screen',comments_callback_screen='$comments_callback_screen',qc_comment_history='$qc_comment_history',show_previous_callback='$show_previous_callback',clear_script='$clear_script',cpd_unknown_action='$cpd_unknown_action',manual_dial_search_filter='$manual_dial_search_filter',web_form_address_three='" . mysqli_real_escape_string($link, $web_form_address_three) . "',manual_dial_override_field='$manual_dial_override_field',status_display_ingroup='$status_display_ingroup',customer_gone_seconds='$customer_gone_seconds',agent_display_fields='$agent_display_fields',am_message_wildcards='$am_message_wildcards',manual_dial_timeout='$manual_dial_timeout',routing_initiated_recordings='$routing_initiated_recordings',manual_dial_hopper_check='$manual_dial_hopper_check',callback_useronly_move_minutes='$callback_useronly_move_minutes',ofcom_uk_drop_calc='$ofcom_uk_drop_calc',manual_auto_next='$manual_auto_next',manual_auto_show='$manual_auto_show',allow_required_fields='$allow_required_fields',dead_to_dispo='$dead_to_dispo',agent_xfer_validation='$agent_xfer_validation',ready_max_logout='$ready_max_logout',callback_display_days='$callback_display_days',three_way_record_stop='$three_way_record_stop',hangup_xfer_record_start='$hangup_xfer_record_start',scheduled_callbacks_email_alert='$scheduled_callbacks_email_alert',max_inbound_calls_outcome='$max_inbound_calls_outcome',manual_auto_next_options='$manual_auto_next_options',agent_screen_time_display='$agent_screen_time_display',next_dial_my_callbacks='$next_dial_my_callbacks',inbound_no_agents_no_dial_container='$inbound_no_agents_no_dial_container',inbound_no_agents_no_dial_threshold='$inbound_no_agents_no_dial_threshold',cid_group_id='$cid_group_id',pause_max_dispo='$pause_max_dispo',script_top_dispo='$script_top_dispo',dead_trigger_seconds='$dead_trigger_seconds',dead_trigger_action='$dead_trigger_action',dead_trigger_repeat='$dead_trigger_repeat',dead_trigger_filename='$dead_trigger_filename',dead_trigger_url='" . mysqli_real_escape_string($link, $dead_trigger_url) . "',scheduled_callbacks_force_dial='$scheduled_callbacks_force_dial',scheduled_callbacks_auto_reschedule='$scheduled_callbacks_auto_reschedule',scheduled_callbacks_timezones_container='$scheduled_callbacks_timezones_container',three_way_volume_buttons='$three_way_volume_buttons',callback_dnc='$callback_dnc',manual_dial_validation='$manual_dial_validation',mute_recordings='$mute_recordings',auto_active_list_new='$auto_active_list_new',call_quota_lead_ranking='$call_quota_lead_ranking',sip_event_logging='$sip_event_logging',campaign_script_two='$campaign_script_two',leave_vm_no_dispo='$leave_vm_no_dispo',leave_vm_message_group_id='$leave_vm_message_group_id',dial_timeout_lead_container='$dial_timeout_lead_container',amd_type='$amd_type',vmm_daily_limit='$vmm_daily_limit',opensips_cid_name='$opensips_cid_name',amd_agent_route_options='$amd_agent_route_options',browser_alert_sound='$browser_alert_sound',browser_alert_volume='$browser_alert_volume',three_way_record_stop_exception='$three_way_record_stop_exception',pause_max_exceptions='$pause_max_exceptions',daily_call_count_limit='$daily_call_count_limit',daily_limit_manual='$daily_limit_manual',transfer_button_launch='$transfer_button_launch',shared_dial_rank='$shared_dial_rank',agent_search_method='$agent_search_method',clear_form='$clear_form',leave_3way_start_recording='$leave_3way_start_recording',leave_3way_start_recording_exception='$leave_3way_start_recording_exception',calls_waiting_vl_one='$calls_waiting_vl_one',calls_waiting_vl_two='$calls_waiting_vl_two',calls_inqueue_count_one='$calls_inqueue_count_one',calls_inqueue_count_two='$calls_inqueue_count_two',in_man_dial_next_ready_seconds='$in_man_dial_next_ready_seconds',in_man_dial_next_ready_seconds_override='$in_man_dial_next_ready_seconds_override',transfer_no_dispo='$transfer_no_dispo',call_limit_24hour_method='$call_limit_24hour_method',call_limit_24hour_scope='$call_limit_24hour_scope',call_limit_24hour='$call_limit_24hour',call_limit_24hour_override='$call_limit_24hour_override',cid_group_id_two='$cid_group_id_two',incall_tally_threshold_seconds='$incall_tally_threshold_seconds',auto_alt_threshold='$auto_alt_threshold',pause_max_url='$pause_max_url',agent_hide_hangup='$agent_hide_hangup',ig_xfer_list_sort='$ig_xfer_list_sort',script_tab_frame_size='$script_tab_frame_size',max_logged_in_agents='$max_logged_in_agents',user_group_script='$user_group_script',agent_hangup_route='$agent_hangup_route',agent_hangup_value='$agent_hangup_value',agent_hangup_ig_override='$agent_hangup_ig_override',show_confetti='$show_confetti',demographic_quotas='$demographic_quotas',demographic_quotas_container='$demographic_quotas_container',demographic_quotas_rerank='$demographic_quotas_rerank',demographic_quotas_list_resets='$demographic_quotas_list_resets',custom_one='$custom_one',custom_two='$custom_two',custom_three='$custom_three',custom_four='$custom_four',custom_five='$custom_five',dead_stop_recording='$dead_stop_recording',manual_vm_status_updates='$manual_vm_status_updates',force_per_call_notes='$force_per_call_notes',agent_search_ingroup_list='$agent_search_ingroup_list',hopper_hold_inserts='$hopper_hold_inserts',daily_phone_number_call_limit='$daily_phone_number_call_limit',state_descriptions='$state_descriptions',script_tab_height='$script_tab_height',call_log_days='$call_log_days',leave_3way_stop_recording='$leave_3way_stop_recording',manual_minimum_ring_seconds='$manual_minimum_ring_seconds',manual_minimum_attempt_seconds='$manual_minimum_attempt_seconds',manual_minimum_answer_seconds='$manual_minimum_answer_seconds',khomp_settings_container='$khomp_settings_container',stereo_recording='$stereo_recording',stereo_rec_filename='$stereo_rec_filename',stereo_parallel_recording='$stereo_parallel_recording',recording_dtmf_muting='$recording_dtmf_muting',stereo_recording_agent='$stereo_recording_agent',parallel_rec_co_filename='$parallel_rec_co_filename',parallel_rec_cm_filename='$parallel_rec_cm_filename',parallel_rec_fr_filename='$parallel_rec_fr_filename' $prefixSQL $hdrtSQL where campaign_id='$campaign_id';"; + $stmtA="UPDATE vicidial_campaigns set campaign_name='$campaign_name',active='$active',dial_status_a='$dial_status_a',dial_status_b='$dial_status_b',dial_status_c='$dial_status_c',dial_status_d='$dial_status_d',dial_status_e='$dial_status_e',lead_order='$lead_order',allow_closers='$allow_closers',hopper_level='$hopper_level', auto_trim_hopper='$auto_trim_hopper', use_auto_hopper='$use_auto_hopper', auto_hopper_multi='$auto_hopper_multi', $adlSQL next_agent_call='$next_agent_call', local_call_time='$local_call_time', voicemail_ext='$voicemail_ext', dial_timeout='$dial_timeout', campaign_cid='$campaign_cid', campaign_vdad_exten='$campaign_vdad_exten', web_form_address='" . mysqli_real_escape_string($link, $web_form_address) . "', park_ext='$park_ext', park_file_name='$park_file_name', campaign_rec_exten='$campaign_rec_exten', campaign_recording='$campaign_recording', campaign_rec_filename='$campaign_rec_filename', campaign_script='$script_id', get_call_launch='$get_call_launch', am_message_exten='$am_message_exten', amd_send_to_vmx='$amd_send_to_vmx', xferconf_a_dtmf='$xferconf_a_dtmf',xferconf_a_number='$xferconf_a_number',xferconf_b_dtmf='$xferconf_b_dtmf',xferconf_b_number='$xferconf_b_number',lead_filter_id='$lead_filter_id',alt_number_dialing='$alt_number_dialing',scheduled_callbacks='$scheduled_callbacks',drop_action='$drop_action',drop_call_seconds='$drop_call_seconds',safe_harbor_exten='$safe_harbor_exten',wrapup_seconds='$wrapup_seconds',wrapup_message='$wrapup_message',closer_campaigns=$closer_campaignsSQL,use_internal_dnc='$use_internal_dnc',allcalls_delay='$allcalls_delay',omit_phone_code='$omit_phone_code',dial_method='$dial_method',available_only_ratio_tally='$available_only_ratio_tally',adaptive_dropped_percentage='$adaptive_dropped_percentage',adaptive_maximum_level='$adaptive_maximum_level',adaptive_latest_server_time='$adaptive_latest_server_time',adaptive_intensity='$adaptive_intensity',adaptive_dl_diff_target='$adaptive_dl_diff_target',concurrent_transfers='$concurrent_transfers',auto_alt_dial='$auto_alt_dial',agent_pause_codes_active='$agent_pause_codes_active',campaign_description='$campaign_description',campaign_changedate='$SQLdate',campaign_stats_refresh='$campaign_stats_refresh',disable_alter_custdata='$disable_alter_custdata',no_hopper_leads_logins='$no_hopper_leads_logins',list_order_mix='$list_order_mix',campaign_allow_inbound='$campaign_allow_inbound',manual_dial_list_id='$manual_dial_list_id',default_xfer_group='$default_xfer_group',xfer_groups='$XFERgroups_value',queue_priority='$queue_priority',drop_inbound_group='$drop_inbound_group',disable_alter_custphone='$disable_alter_custphone',display_queue_count='$display_queue_count',manual_dial_filter='$manual_dial_filter',agent_clipboard_copy='$agent_clipboard_copy',agent_extended_alt_dial='$agent_extended_alt_dial',use_campaign_dnc='$use_campaign_dnc',three_way_call_cid='$three_way_call_cid',web_form_target='$web_form_target',vtiger_search_category='$vtiger_search_category',vtiger_create_call_record='$vtiger_create_call_record',vtiger_create_lead_record='$vtiger_create_lead_record',vtiger_screen_login='$vtiger_screen_login',cpd_amd_action='$cpd_amd_action',agent_allow_group_alias='$agent_allow_group_alias',default_group_alias='$default_group_alias',vtiger_search_dead='$vtiger_search_dead',vtiger_status_call='$vtiger_status_call',drop_lockout_time='$drop_lockout_time',quick_transfer_button='$quick_transfer_button',prepopulate_transfer_preset='$prepopulate_transfer_preset',drop_rate_group='$drop_rate_group',view_calls_in_queue='$view_calls_in_queue',view_calls_in_queue_launch='$view_calls_in_queue_launch',grab_calls_in_queue='$grab_calls_in_queue',call_requeue_button='$call_requeue_button',pause_after_each_call='$pause_after_each_call',no_hopper_dialing='$no_hopper_dialing',agent_dial_owner_only='$agent_dial_owner_only',agent_display_dialable_leads='$agent_display_dialable_leads',web_form_address_two='" . mysqli_real_escape_string($link, $web_form_address_two) . "',waitforsilence_options='$waitforsilence_options',agent_select_territories='$agent_select_territories',crm_popup_login='$crm_popup_login',crm_login_address='" . mysqli_real_escape_string($link, $crm_login_address) . "',timer_action='$timer_action',timer_action_message='$timer_action_message',timer_action_seconds='$timer_action_seconds',start_call_url='" . mysqli_real_escape_string($link, $start_call_url) . "',dispo_call_url='" . mysqli_real_escape_string($link, $dispo_call_url) . "',xferconf_c_number='$xferconf_c_number',xferconf_d_number='$xferconf_d_number',xferconf_e_number='$xferconf_e_number',use_custom_cid='$use_custom_cid',scheduled_callbacks_alert='$scheduled_callbacks_alert',queuemetrics_callstatus_override='$queuemetrics_callstatus',extension_appended_cidname='$extension_appended_cidname',scheduled_callbacks_count='$scheduled_callbacks_count',manual_dial_override='$manual_dial_override',blind_monitor_warning='$blind_monitor_warning',blind_monitor_message='" . mysqli_real_escape_string($link, $blind_monitor_message) . "',blind_monitor_filename='$blind_monitor_filename',inbound_queue_no_dial='$inbound_queue_no_dial',timer_action_destination='$timer_action_destination',enable_xfer_presets='$enable_xfer_presets',hide_xfer_number_to_dial='$hide_xfer_number_to_dial',customer_3way_hangup_logging='$customer_3way_hangup_logging',customer_3way_hangup_seconds='$customer_3way_hangup_seconds',customer_3way_hangup_action='$customer_3way_hangup_action',ivr_park_call='$ivr_park_call',ivr_park_call_agi='$ivr_park_call_agi',manual_preview_dial='$manual_preview_dial',realtime_agent_time_stats='$realtime_agent_time_stats',api_manual_dial='$api_manual_dial',manual_dial_call_time_check='$manual_dial_call_time_check',lead_order_randomize='$lead_order_randomize',lead_order_secondary='$lead_order_secondary',per_call_notes='$per_call_notes',my_callback_option='$my_callback_option',agent_lead_search='$agent_lead_search',agent_lead_search_method='$agent_lead_search_method',queuemetrics_phone_environment='$queuemetrics_phone_environment',auto_pause_precall='$auto_pause_precall',auto_resume_precall='$auto_resume_precall',auto_pause_precall_code='$auto_pause_precall_code',manual_dial_cid='$manual_dial_cid',post_phone_time_diff_alert='$post_phone_time_diff_alert',custom_3way_button_transfer='$custom_3way_button_transfer',available_only_tally_threshold='$available_only_tally_threshold',available_only_tally_threshold_agents='$available_only_tally_threshold_agents',dial_level_threshold='$dial_level_threshold',dial_level_threshold_agents='$dial_level_threshold_agents',safe_harbor_audio='$safe_harbor_audio',safe_harbor_menu_id='$safe_harbor_menu_id',callback_days_limit='$callback_days_limit',dl_diff_target_method='$dl_diff_target_method',disable_dispo_screen='$disable_dispo_screen',disable_dispo_status='$disable_dispo_status',screen_labels='$screen_labels',status_display_fields='$status_display_fields',na_call_url='" . mysqli_real_escape_string($link, $na_call_url) . "',pllb_grouping='$pllb_grouping',pllb_grouping_limit='$pllb_grouping_limit',call_count_limit='$call_count_limit',call_count_target='$call_count_target',callback_hours_block='$callback_hours_block',callback_list_calltime='$callback_list_calltime',user_group='$user_group',hopper_vlc_dup_check='$hopper_vlc_dup_check',in_group_dial='$in_group_dial',in_group_dial_select='$in_group_dial_select',safe_harbor_audio_field='$safe_harbor_audio_field',pause_after_next_call='$pause_after_next_call',owner_populate='$owner_populate',use_other_campaign_dnc='$use_other_campaign_dnc',allow_emails='$allow_emails',allow_chats='$allow_chats',amd_inbound_group='$amd_inbound_group',amd_callmenu='$amd_callmenu',manual_dial_lead_id='$manual_dial_lead_id',dead_max='$dead_max',dispo_max='$dispo_max',pause_max='$pause_max',dead_max_dispo='$dead_max_dispo',dispo_max_dispo='$dispo_max_dispo',max_inbound_calls='$max_inbound_calls',manual_dial_search_checkbox='$manual_dial_search_checkbox',hide_call_log_info='$hide_call_log_info',timer_alt_seconds='$timer_alt_seconds',wrapup_bypass='$wrapup_bypass',wrapup_after_hotkey='$wrapup_after_hotkey',callback_active_limit='$callback_active_limit',callback_active_limit_override='$callback_active_limit_override',comments_all_tabs='$comments_all_tabs',comments_dispo_screen='$comments_dispo_screen',comments_callback_screen='$comments_callback_screen',qc_comment_history='$qc_comment_history',show_previous_callback='$show_previous_callback',clear_script='$clear_script',cpd_unknown_action='$cpd_unknown_action',manual_dial_search_filter='$manual_dial_search_filter',web_form_address_three='" . mysqli_real_escape_string($link, $web_form_address_three) . "',manual_dial_override_field='$manual_dial_override_field',status_display_ingroup='$status_display_ingroup',customer_gone_seconds='$customer_gone_seconds',agent_display_fields='$agent_display_fields',am_message_wildcards='$am_message_wildcards',manual_dial_timeout='$manual_dial_timeout',routing_initiated_recordings='$routing_initiated_recordings',manual_dial_hopper_check='$manual_dial_hopper_check',callback_useronly_move_minutes='$callback_useronly_move_minutes',ofcom_uk_drop_calc='$ofcom_uk_drop_calc',manual_auto_next='$manual_auto_next',manual_auto_show='$manual_auto_show',allow_required_fields='$allow_required_fields',dead_to_dispo='$dead_to_dispo',agent_xfer_validation='$agent_xfer_validation',ready_max_logout='$ready_max_logout',callback_display_days='$callback_display_days',three_way_record_stop='$three_way_record_stop',hangup_xfer_record_start='$hangup_xfer_record_start',scheduled_callbacks_email_alert='$scheduled_callbacks_email_alert',max_inbound_calls_outcome='$max_inbound_calls_outcome',manual_auto_next_options='$manual_auto_next_options',agent_screen_time_display='$agent_screen_time_display',next_dial_my_callbacks='$next_dial_my_callbacks',inbound_no_agents_no_dial_container='$inbound_no_agents_no_dial_container',inbound_no_agents_no_dial_threshold='$inbound_no_agents_no_dial_threshold',cid_group_id='$cid_group_id',pause_max_dispo='$pause_max_dispo',script_top_dispo='$script_top_dispo',dead_trigger_seconds='$dead_trigger_seconds',dead_trigger_action='$dead_trigger_action',dead_trigger_repeat='$dead_trigger_repeat',dead_trigger_filename='$dead_trigger_filename',dead_trigger_url='" . mysqli_real_escape_string($link, $dead_trigger_url) . "',scheduled_callbacks_force_dial='$scheduled_callbacks_force_dial',scheduled_callbacks_auto_reschedule='$scheduled_callbacks_auto_reschedule',scheduled_callbacks_timezones_container='$scheduled_callbacks_timezones_container',three_way_volume_buttons='$three_way_volume_buttons',callback_dnc='$callback_dnc',manual_dial_validation='$manual_dial_validation',mute_recordings='$mute_recordings',auto_active_list_new='$auto_active_list_new',call_quota_lead_ranking='$call_quota_lead_ranking',sip_event_logging='$sip_event_logging',campaign_script_two='$campaign_script_two',leave_vm_no_dispo='$leave_vm_no_dispo',leave_vm_message_group_id='$leave_vm_message_group_id',dial_timeout_lead_container='$dial_timeout_lead_container',amd_type='$amd_type',vmm_daily_limit='$vmm_daily_limit',opensips_cid_name='$opensips_cid_name',amd_agent_route_options='$amd_agent_route_options',browser_alert_sound='$browser_alert_sound',browser_alert_volume='$browser_alert_volume',three_way_record_stop_exception='$three_way_record_stop_exception',pause_max_exceptions='$pause_max_exceptions',daily_call_count_limit='$daily_call_count_limit',daily_limit_manual='$daily_limit_manual',transfer_button_launch='$transfer_button_launch',shared_dial_rank='$shared_dial_rank',agent_search_method='$agent_search_method',clear_form='$clear_form',leave_3way_start_recording='$leave_3way_start_recording',leave_3way_start_recording_exception='$leave_3way_start_recording_exception',calls_waiting_vl_one='$calls_waiting_vl_one',calls_waiting_vl_two='$calls_waiting_vl_two',calls_inqueue_count_one='$calls_inqueue_count_one',calls_inqueue_count_two='$calls_inqueue_count_two',in_man_dial_next_ready_seconds='$in_man_dial_next_ready_seconds',in_man_dial_next_ready_seconds_override='$in_man_dial_next_ready_seconds_override',transfer_no_dispo='$transfer_no_dispo',call_limit_24hour_method='$call_limit_24hour_method',call_limit_24hour_scope='$call_limit_24hour_scope',call_limit_24hour='$call_limit_24hour',call_limit_24hour_override='$call_limit_24hour_override',cid_group_id_two='$cid_group_id_two',incall_tally_threshold_seconds='$incall_tally_threshold_seconds',auto_alt_threshold='$auto_alt_threshold',pause_max_url='$pause_max_url',agent_hide_hangup='$agent_hide_hangup',ig_xfer_list_sort='$ig_xfer_list_sort',script_tab_frame_size='$script_tab_frame_size',max_logged_in_agents='$max_logged_in_agents',user_group_script='$user_group_script',agent_hangup_route='$agent_hangup_route',agent_hangup_value='$agent_hangup_value',agent_hangup_ig_override='$agent_hangup_ig_override',show_confetti='$show_confetti',demographic_quotas='$demographic_quotas',demographic_quotas_container='$demographic_quotas_container',demographic_quotas_rerank='$demographic_quotas_rerank',demographic_quotas_list_resets='$demographic_quotas_list_resets',custom_one='$custom_one',custom_two='$custom_two',custom_three='$custom_three',custom_four='$custom_four',custom_five='$custom_five',dead_stop_recording='$dead_stop_recording',manual_vm_status_updates='$manual_vm_status_updates',force_per_call_notes='$force_per_call_notes',agent_search_ingroup_list='$agent_search_ingroup_list',hopper_hold_inserts='$hopper_hold_inserts',daily_phone_number_call_limit='$daily_phone_number_call_limit',state_descriptions='$state_descriptions',script_tab_height='$script_tab_height',call_log_days='$call_log_days',leave_3way_stop_recording='$leave_3way_stop_recording',manual_minimum_ring_seconds='$manual_minimum_ring_seconds',manual_minimum_attempt_seconds='$manual_minimum_attempt_seconds',manual_minimum_answer_seconds='$manual_minimum_answer_seconds',khomp_settings_container='$khomp_settings_container',stereo_recording='$stereo_recording',stereo_rec_filename='$stereo_rec_filename',stereo_parallel_recording='$stereo_parallel_recording',recording_dtmf_muting='$recording_dtmf_muting',stereo_recording_agent='$stereo_recording_agent',parallel_rec_co_filename='$parallel_rec_co_filename',parallel_rec_cm_filename='$parallel_rec_cm_filename',parallel_rec_fr_filename='$parallel_rec_fr_filename',call_count_limit_restrict='$call_count_limit_restrict' $prefixSQL $hdrtSQL where campaign_id='$campaign_id';"; if ($DB) {echo "|$stmt|\n";} $rslt=mysql_to_mysqli($stmtA, $link); @@ -26403,7 +26407,7 @@ function ajax_logout_now() $enable_vtiger_integration_LU = $row[0]; $vtiger_url_LU = $row[1]; - $stmt="SELECT campaign_id,campaign_name,active,dial_status_a,dial_status_b,dial_status_c,dial_status_d,dial_status_e,lead_order,park_ext,park_file_name,web_form_address,allow_closers,hopper_level,auto_dial_level,next_agent_call,local_call_time,voicemail_ext,dial_timeout,dial_prefix,campaign_cid,campaign_vdad_exten,campaign_rec_exten,campaign_recording,campaign_rec_filename,campaign_script,get_call_launch,am_message_exten,amd_send_to_vmx,xferconf_a_dtmf,xferconf_a_number,xferconf_b_dtmf,xferconf_b_number,alt_number_dialing,scheduled_callbacks,lead_filter_id,drop_call_seconds,drop_action,safe_harbor_exten,display_dialable_count,wrapup_seconds,wrapup_message,closer_campaigns,use_internal_dnc,allcalls_delay,omit_phone_code,dial_method,available_only_ratio_tally,adaptive_dropped_percentage,adaptive_maximum_level,adaptive_latest_server_time,adaptive_intensity,adaptive_dl_diff_target,concurrent_transfers,auto_alt_dial,auto_alt_dial_statuses,agent_pause_codes_active,campaign_description,campaign_changedate,campaign_stats_refresh,campaign_logindate,dial_statuses,disable_alter_custdata,no_hopper_leads_logins,list_order_mix,campaign_allow_inbound,manual_dial_list_id,default_xfer_group,xfer_groups,queue_priority,drop_inbound_group,qc_enabled,qc_statuses,qc_lists,qc_shift_id,qc_get_record_launch,qc_show_recording,qc_web_form_address,qc_script,survey_first_audio_file,survey_dtmf_digits,survey_ni_digit,survey_opt_in_audio_file,survey_ni_audio_file,survey_method,survey_no_response_action,survey_ni_status,survey_response_digit_map,survey_xfer_exten,survey_camp_record_dir,disable_alter_custphone,display_queue_count,manual_dial_filter,agent_clipboard_copy,agent_extended_alt_dial,use_campaign_dnc,three_way_call_cid,three_way_dial_prefix,web_form_target,vtiger_search_category,vtiger_create_call_record,vtiger_create_lead_record,vtiger_screen_login,cpd_amd_action,agent_allow_group_alias,default_group_alias,vtiger_search_dead,vtiger_status_call,survey_third_digit,survey_third_audio_file,survey_third_status,survey_third_exten,survey_fourth_digit,survey_fourth_audio_file,survey_fourth_status,survey_fourth_exten,drop_lockout_time,quick_transfer_button,prepopulate_transfer_preset,drop_rate_group,view_calls_in_queue,view_calls_in_queue_launch,grab_calls_in_queue,call_requeue_button,pause_after_each_call,no_hopper_dialing,agent_dial_owner_only,agent_display_dialable_leads,web_form_address_two,waitforsilence_options,agent_select_territories,campaign_calldate,crm_popup_login,crm_login_address,timer_action,timer_action_message,timer_action_seconds,start_call_url,dispo_call_url,xferconf_c_number,xferconf_d_number,xferconf_e_number,use_custom_cid,scheduled_callbacks_alert,queuemetrics_callstatus_override,extension_appended_cidname,scheduled_callbacks_count,manual_dial_override,blind_monitor_warning,blind_monitor_message,blind_monitor_filename,inbound_queue_no_dial,timer_action_destination,enable_xfer_presets,hide_xfer_number_to_dial,manual_dial_prefix,customer_3way_hangup_logging,customer_3way_hangup_seconds,customer_3way_hangup_action,ivr_park_call,ivr_park_call_agi,manual_preview_dial,realtime_agent_time_stats,use_auto_hopper,auto_hopper_multi,auto_trim_hopper,api_manual_dial,manual_dial_call_time_check,display_leads_count,lead_order_randomize,lead_order_secondary,per_call_notes,my_callback_option,agent_lead_search,agent_lead_search_method,queuemetrics_phone_environment,auto_pause_precall,auto_resume_precall,auto_pause_precall_code,manual_dial_cid,post_phone_time_diff_alert,custom_3way_button_transfer,available_only_tally_threshold,available_only_tally_threshold_agents,dial_level_threshold,dial_level_threshold_agents,safe_harbor_audio,safe_harbor_menu_id,survey_menu_id,callback_days_limit,dl_diff_target_method,disable_dispo_screen,disable_dispo_status,screen_labels,status_display_fields,na_call_url,survey_recording,pllb_grouping,pllb_grouping_limit,call_count_limit,call_count_target,callback_hours_block,callback_list_calltime,user_group,hopper_vlc_dup_check,in_group_dial,in_group_dial_select,safe_harbor_audio_field,pause_after_next_call,owner_populate,use_other_campaign_dnc,allow_emails,amd_inbound_group,amd_callmenu,survey_wait_sec,manual_dial_lead_id,dead_max,dispo_max,pause_max,dead_max_dispo,dispo_max_dispo,max_inbound_calls,manual_dial_search_checkbox,hide_call_log_info,timer_alt_seconds,wrapup_bypass,wrapup_after_hotkey,callback_active_limit,callback_active_limit_override,allow_chats,comments_all_tabs,comments_dispo_screen,comments_callback_screen,qc_comment_history,show_previous_callback,clear_script,cpd_unknown_action,manual_dial_search_filter,web_form_address_three,manual_dial_override_field,status_display_ingroup,customer_gone_seconds,agent_display_fields,am_message_wildcards,manual_dial_timeout,routing_initiated_recordings,manual_dial_hopper_check,callback_useronly_move_minutes,ofcom_uk_drop_calc,manual_auto_next,manual_auto_show,allow_required_fields,dead_to_dispo,agent_xfer_validation,ready_max_logout,callback_display_days,three_way_record_stop,hangup_xfer_record_start,scheduled_callbacks_email_alert,max_inbound_calls_outcome,manual_auto_next_options,agent_screen_time_display,next_dial_my_callbacks,inbound_no_agents_no_dial_container,inbound_no_agents_no_dial_threshold,cid_group_id,pause_max_dispo,script_top_dispo,dead_trigger_seconds,dead_trigger_action,dead_trigger_repeat,dead_trigger_filename,dead_trigger_url,scheduled_callbacks_force_dial,scheduled_callbacks_auto_reschedule,scheduled_callbacks_timezones_container,three_way_volume_buttons,callback_dnc,manual_dial_validation,mute_recordings,auto_active_list_new,call_quota_lead_ranking,call_quota_process_running,sip_event_logging,campaign_script_two,leave_vm_no_dispo,leave_vm_message_group_id,dial_timeout_lead_container,amd_type,vmm_daily_limit,opensips_cid_name,amd_agent_route_options,browser_alert_sound,browser_alert_volume,three_way_record_stop_exception,pause_max_exceptions,hopper_drop_run_trigger,daily_call_count_limit,daily_limit_manual,transfer_button_launch,shared_dial_rank,agent_search_method,qc_scorecard_id,qc_statuses_id,clear_form,leave_3way_start_recording,leave_3way_start_recording_exception,calls_waiting_vl_one,calls_waiting_vl_two,calls_inqueue_count_one,calls_inqueue_count_two,in_man_dial_next_ready_seconds,in_man_dial_next_ready_seconds_override,transfer_no_dispo,call_limit_24hour_method,call_limit_24hour_scope,call_limit_24hour,call_limit_24hour_override,cid_group_id_two,incall_tally_threshold_seconds,auto_alt_threshold,pause_max_url,agent_hide_hangup,ig_xfer_list_sort,script_tab_frame_size,max_logged_in_agents,user_group_script,agent_hangup_route,agent_hangup_value,agent_hangup_ig_override,show_confetti,demographic_quotas,demographic_quotas_container,demographic_quotas_rerank,demographic_quotas_list_resets,demographic_quotas_last_rerank,custom_one,custom_two,custom_three,custom_four,custom_five,dead_stop_recording,manual_vm_status_updates,force_per_call_notes,agent_search_ingroup_list,hopper_hold_inserts,daily_phone_number_call_limit,state_descriptions,script_tab_height,call_log_days,leave_3way_stop_recording,manual_minimum_ring_seconds,manual_minimum_attempt_seconds,manual_minimum_answer_seconds,khomp_settings_container,stereo_recording,stereo_rec_filename,stereo_parallel_recording,recording_dtmf_muting,stereo_recording_agent,parallel_rec_co_filename,parallel_rec_cm_filename,parallel_rec_fr_filename from vicidial_campaigns where campaign_id='$campaign_id' $LOGallowed_campaignsSQL;"; + $stmt="SELECT campaign_id,campaign_name,active,dial_status_a,dial_status_b,dial_status_c,dial_status_d,dial_status_e,lead_order,park_ext,park_file_name,web_form_address,allow_closers,hopper_level,auto_dial_level,next_agent_call,local_call_time,voicemail_ext,dial_timeout,dial_prefix,campaign_cid,campaign_vdad_exten,campaign_rec_exten,campaign_recording,campaign_rec_filename,campaign_script,get_call_launch,am_message_exten,amd_send_to_vmx,xferconf_a_dtmf,xferconf_a_number,xferconf_b_dtmf,xferconf_b_number,alt_number_dialing,scheduled_callbacks,lead_filter_id,drop_call_seconds,drop_action,safe_harbor_exten,display_dialable_count,wrapup_seconds,wrapup_message,closer_campaigns,use_internal_dnc,allcalls_delay,omit_phone_code,dial_method,available_only_ratio_tally,adaptive_dropped_percentage,adaptive_maximum_level,adaptive_latest_server_time,adaptive_intensity,adaptive_dl_diff_target,concurrent_transfers,auto_alt_dial,auto_alt_dial_statuses,agent_pause_codes_active,campaign_description,campaign_changedate,campaign_stats_refresh,campaign_logindate,dial_statuses,disable_alter_custdata,no_hopper_leads_logins,list_order_mix,campaign_allow_inbound,manual_dial_list_id,default_xfer_group,xfer_groups,queue_priority,drop_inbound_group,qc_enabled,qc_statuses,qc_lists,qc_shift_id,qc_get_record_launch,qc_show_recording,qc_web_form_address,qc_script,survey_first_audio_file,survey_dtmf_digits,survey_ni_digit,survey_opt_in_audio_file,survey_ni_audio_file,survey_method,survey_no_response_action,survey_ni_status,survey_response_digit_map,survey_xfer_exten,survey_camp_record_dir,disable_alter_custphone,display_queue_count,manual_dial_filter,agent_clipboard_copy,agent_extended_alt_dial,use_campaign_dnc,three_way_call_cid,three_way_dial_prefix,web_form_target,vtiger_search_category,vtiger_create_call_record,vtiger_create_lead_record,vtiger_screen_login,cpd_amd_action,agent_allow_group_alias,default_group_alias,vtiger_search_dead,vtiger_status_call,survey_third_digit,survey_third_audio_file,survey_third_status,survey_third_exten,survey_fourth_digit,survey_fourth_audio_file,survey_fourth_status,survey_fourth_exten,drop_lockout_time,quick_transfer_button,prepopulate_transfer_preset,drop_rate_group,view_calls_in_queue,view_calls_in_queue_launch,grab_calls_in_queue,call_requeue_button,pause_after_each_call,no_hopper_dialing,agent_dial_owner_only,agent_display_dialable_leads,web_form_address_two,waitforsilence_options,agent_select_territories,campaign_calldate,crm_popup_login,crm_login_address,timer_action,timer_action_message,timer_action_seconds,start_call_url,dispo_call_url,xferconf_c_number,xferconf_d_number,xferconf_e_number,use_custom_cid,scheduled_callbacks_alert,queuemetrics_callstatus_override,extension_appended_cidname,scheduled_callbacks_count,manual_dial_override,blind_monitor_warning,blind_monitor_message,blind_monitor_filename,inbound_queue_no_dial,timer_action_destination,enable_xfer_presets,hide_xfer_number_to_dial,manual_dial_prefix,customer_3way_hangup_logging,customer_3way_hangup_seconds,customer_3way_hangup_action,ivr_park_call,ivr_park_call_agi,manual_preview_dial,realtime_agent_time_stats,use_auto_hopper,auto_hopper_multi,auto_trim_hopper,api_manual_dial,manual_dial_call_time_check,display_leads_count,lead_order_randomize,lead_order_secondary,per_call_notes,my_callback_option,agent_lead_search,agent_lead_search_method,queuemetrics_phone_environment,auto_pause_precall,auto_resume_precall,auto_pause_precall_code,manual_dial_cid,post_phone_time_diff_alert,custom_3way_button_transfer,available_only_tally_threshold,available_only_tally_threshold_agents,dial_level_threshold,dial_level_threshold_agents,safe_harbor_audio,safe_harbor_menu_id,survey_menu_id,callback_days_limit,dl_diff_target_method,disable_dispo_screen,disable_dispo_status,screen_labels,status_display_fields,na_call_url,survey_recording,pllb_grouping,pllb_grouping_limit,call_count_limit,call_count_target,callback_hours_block,callback_list_calltime,user_group,hopper_vlc_dup_check,in_group_dial,in_group_dial_select,safe_harbor_audio_field,pause_after_next_call,owner_populate,use_other_campaign_dnc,allow_emails,amd_inbound_group,amd_callmenu,survey_wait_sec,manual_dial_lead_id,dead_max,dispo_max,pause_max,dead_max_dispo,dispo_max_dispo,max_inbound_calls,manual_dial_search_checkbox,hide_call_log_info,timer_alt_seconds,wrapup_bypass,wrapup_after_hotkey,callback_active_limit,callback_active_limit_override,allow_chats,comments_all_tabs,comments_dispo_screen,comments_callback_screen,qc_comment_history,show_previous_callback,clear_script,cpd_unknown_action,manual_dial_search_filter,web_form_address_three,manual_dial_override_field,status_display_ingroup,customer_gone_seconds,agent_display_fields,am_message_wildcards,manual_dial_timeout,routing_initiated_recordings,manual_dial_hopper_check,callback_useronly_move_minutes,ofcom_uk_drop_calc,manual_auto_next,manual_auto_show,allow_required_fields,dead_to_dispo,agent_xfer_validation,ready_max_logout,callback_display_days,three_way_record_stop,hangup_xfer_record_start,scheduled_callbacks_email_alert,max_inbound_calls_outcome,manual_auto_next_options,agent_screen_time_display,next_dial_my_callbacks,inbound_no_agents_no_dial_container,inbound_no_agents_no_dial_threshold,cid_group_id,pause_max_dispo,script_top_dispo,dead_trigger_seconds,dead_trigger_action,dead_trigger_repeat,dead_trigger_filename,dead_trigger_url,scheduled_callbacks_force_dial,scheduled_callbacks_auto_reschedule,scheduled_callbacks_timezones_container,three_way_volume_buttons,callback_dnc,manual_dial_validation,mute_recordings,auto_active_list_new,call_quota_lead_ranking,call_quota_process_running,sip_event_logging,campaign_script_two,leave_vm_no_dispo,leave_vm_message_group_id,dial_timeout_lead_container,amd_type,vmm_daily_limit,opensips_cid_name,amd_agent_route_options,browser_alert_sound,browser_alert_volume,three_way_record_stop_exception,pause_max_exceptions,hopper_drop_run_trigger,daily_call_count_limit,daily_limit_manual,transfer_button_launch,shared_dial_rank,agent_search_method,qc_scorecard_id,qc_statuses_id,clear_form,leave_3way_start_recording,leave_3way_start_recording_exception,calls_waiting_vl_one,calls_waiting_vl_two,calls_inqueue_count_one,calls_inqueue_count_two,in_man_dial_next_ready_seconds,in_man_dial_next_ready_seconds_override,transfer_no_dispo,call_limit_24hour_method,call_limit_24hour_scope,call_limit_24hour,call_limit_24hour_override,cid_group_id_two,incall_tally_threshold_seconds,auto_alt_threshold,pause_max_url,agent_hide_hangup,ig_xfer_list_sort,script_tab_frame_size,max_logged_in_agents,user_group_script,agent_hangup_route,agent_hangup_value,agent_hangup_ig_override,show_confetti,demographic_quotas,demographic_quotas_container,demographic_quotas_rerank,demographic_quotas_list_resets,demographic_quotas_last_rerank,custom_one,custom_two,custom_three,custom_four,custom_five,dead_stop_recording,manual_vm_status_updates,force_per_call_notes,agent_search_ingroup_list,hopper_hold_inserts,daily_phone_number_call_limit,state_descriptions,script_tab_height,call_log_days,leave_3way_stop_recording,manual_minimum_ring_seconds,manual_minimum_attempt_seconds,manual_minimum_answer_seconds,khomp_settings_container,stereo_recording,stereo_rec_filename,stereo_parallel_recording,recording_dtmf_muting,stereo_recording_agent,parallel_rec_co_filename,parallel_rec_cm_filename,parallel_rec_fr_filename,call_count_limit_restrict from vicidial_campaigns where campaign_id='$campaign_id' $LOGallowed_campaignsSQL;"; $rslt=mysql_to_mysqli($stmt, $link); $row=mysqli_fetch_row($rslt); $campaign_name = $row[1]; @@ -26768,6 +26772,7 @@ function ajax_logout_now() $parallel_rec_co_filename = $row[360]; $parallel_rec_cm_filename = $row[361]; $parallel_rec_fr_filename = $row[362]; + $call_count_limit_restrict = $row[363]; if (preg_match('/DISABLED/', $list_order_mix)) {$DEFlistDISABLE = ''; $DEFstatusDISABLED=0;} @@ -27605,6 +27610,11 @@ function ajax_logout_now() echo "
"._QXZ("Call Count Target").": $NWB#campaigns-call_count_target$NWE
"._QXZ("Call Count Limit Manual Restrict").": $NWB#campaigns-call_count_limit_restrict$NWE
"._QXZ("Daily Call Count Limit").": $NWB#campaigns-daily_call_count_limit$NWE
"._QXZ("Recording DTMF Muting").": $NWB#campaigns-recording_dtmf_muting$NWE
"._QXZ("Recording DTMF Muting").": $NWB#campaigns-recording_dtmf_muting$NWE $SYSTEM_DTMF_MUTING_OVERRIDE
\n"; echo "\n"; - $stmt="SELECT vu.user,vca.campaign_rank,vca.calls_today,full_name,vca.campaign_grade from vicidial_campaign_agents vca, vicidial_users vu where campaign_id='$campaign_id' and active='Y' and vu.user=vca.user $LOGadmin_viewable_groupsSQL order by vu.user;"; - $rsltx=mysql_to_mysqli($stmt, $link); - $users_to_print = mysqli_num_rows($rsltx); + $stmt="SELECT user_group from vicidial_user_groups where ( (allowed_campaigns LIKE \"%-ALL-CAMPAIGNS-%\") or (allowed_campaigns LIKE \"% $campaign_id %\") ) $LOGadmin_viewable_groupsSQL;"; + $rslt=mysql_to_mysqli($stmt, $link); + $USERgroups_to_print = mysqli_num_rows($rslt); + if ($DB) {echo "$USERgroups_to_print|$stmt\n";} + $USERgroupsSQL="''"; + $i=0; + while ($i < $USERgroups_to_print) + { + $row=mysqli_fetch_row($rslt); + $USERgroupsSQL .= ",'$row[0]'"; + $i++; + } + + $stmt="SELECT user,full_name from vicidial_users where user_group IN($USERgroupsSQL) and active='Y' order by user;"; + $rslt=mysql_to_mysqli($stmt, $link); + $users_to_print = mysqli_num_rows($rslt); + if ($DB) {echo "$users_to_print|$stmt\n";} + $U_user=array(); + $U_full_name=array(); + $i=0; + while ($i < $users_to_print) + { + $row=mysqli_fetch_row($rslt); + $U_user[$i] = $row[0]; + $U_full_name[$i] = $row[1]; + $i++; + } $o=0; while ($users_to_print > $o) { - $rowx=mysqli_fetch_row($rsltx); - $o++; + $temp_user = $U_user[$o]; + $temp_name = $U_full_name[$o]; + $campaign_rank='n/a'; + $calls_today='n/a'; + $campaign_grade='n/a'; if (preg_match('/1$|3$|5$|7$|9$/i', $o)) {$bgcolor='bgcolor="#'. $SSstd_row2_background .'"';} else {$bgcolor='bgcolor="#'. $SSstd_row1_background .'"';} - echo "\n"; + $stmt="SELECT campaign_rank,calls_today,campaign_grade from vicidial_campaign_agents where user='$U_user[$o]' and campaign_id='$campaign_id';"; + $rslt=mysql_to_mysqli($stmt, $link); + $USERdetails_to_print = mysqli_num_rows($rslt); + if ($USERdetails_to_print > 0) + { + $row=mysqli_fetch_row($rslt); + $campaign_rank = $row[0]; + $calls_today = $row[1]; + $campaign_grade = $row[2]; + } + $o++; + + echo "\n"; } echo "
"._QXZ("USER")."     "._QXZ("RANK")."     "._QXZ("GRADE")."     "._QXZ("CALLS TODAY")."
$rowx[0] - $rowx[3]$rowx[1]$rowx[4]$rowx[2]
$temp_user - $temp_name$campaign_rank$campaign_grade$calls_today

\n"; @@ -35236,9 +35278,11 @@ function ajax_logout_now() { echo "\n"; } - if ( ( ($SSrecording_dtmf_muting =='1') or ($SSrecording_dtmf_muting =='2') or ($SSrecording_dtmf_muting =='3') ) and ($SSrecording_dtmf_detection == '1') ) + if ( ( ($SSrecording_dtmf_muting =='1') or ($SSrecording_dtmf_muting >= 2) ) and ($SSrecording_dtmf_detection == '1') ) { - echo ""._QXZ("Recording DTMF Muting").": $NWB#inbound_groups-recording_dtmf_muting$NWE\n"; + $SYSTEM_DTMF_MUTING_OVERRIDE=''; + if ($SSrecording_dtmf_muting >= 2) {$SYSTEM_DTMF_MUTING_OVERRIDE = ""._QXZ("SYSTEM OVERRIDE ENABLED").": $SSrecording_dtmf_muting "._QXZ("SECONDS")."";} + echo ""._QXZ("Recording DTMF Muting").": $NWB#inbound_groups-recording_dtmf_muting$NWE $SYSTEM_DTMF_MUTING_OVERRIDE \n"; } else { @@ -45271,7 +45315,7 @@ function ajax_logout_now() echo ""._QXZ("Allow Stereo Recordings").": $NWB#settings-stereo_recording$NWE\n"; echo ""._QXZ("Enable Stereo Parallel Recordings").": $NWB#settings-stereo_parallel_recording$NWE\n"; echo ""._QXZ("Allow Recording DTMF Detection").": $NWB#settings-recording_dtmf_detection$NWE\n"; - echo ""._QXZ("Allow Recording DTMF Muting").": $NWB#settings-recording_dtmf_muting$NWE\n"; + echo ""._QXZ("Allow Recording DTMF Muting").": $NWB#settings-recording_dtmf_muting$NWE\n"; } else { diff --git a/www/vicidial/admin_modify_lead.php b/www/vicidial/admin_modify_lead.php index e04214dfc..27495eebd 100644 --- a/www/vicidial/admin_modify_lead.php +++ b/www/vicidial/admin_modify_lead.php @@ -121,6 +121,7 @@ # 241002-0936 - Fix for displaying CID info on outbound calls that were blind transferred # 250129-0921 - Fix for closer call notes display, Issue #1534 # 250913-0837 - Added Stereo Call Recording indicator +# 251010-1140 - Added DTMF count and muting recording log indicator columns # require("dbconnect_mysqli.php"); @@ -282,7 +283,7 @@ ############################################# ##### START SYSTEM_SETTINGS LOOKUP ##### -$stmt = "SELECT use_non_latin,custom_fields_enabled,webroot_writable,allow_emails,enable_languages,language_method,active_modules,log_recording_access,admin_screen_colors,enable_gdpr_download_deletion,source_id_display,mute_recordings,sip_event_logging,allow_web_debug,hopper_hold_inserts,coldstorage_server_ip,coldstorage_dbname,coldstorage_login,coldstorage_pass,coldstorage_port,stereo_recording FROM system_settings;"; +$stmt = "SELECT use_non_latin,custom_fields_enabled,webroot_writable,allow_emails,enable_languages,language_method,active_modules,log_recording_access,admin_screen_colors,enable_gdpr_download_deletion,source_id_display,mute_recordings,sip_event_logging,allow_web_debug,hopper_hold_inserts,coldstorage_server_ip,coldstorage_dbname,coldstorage_login,coldstorage_pass,coldstorage_port,stereo_recording,recording_dtmf_detection,recording_dtmf_muting FROM system_settings;"; $rslt=mysql_to_mysqli($stmt, $link); #if ($DB) {echo "$stmt\n";} $qm_conf_ct = mysqli_num_rows($rslt); @@ -310,6 +311,8 @@ $SScoldstorage_pass = $row[18]; $SScoldstorage_port = $row[19]; $SSstereo_recording = $row[20]; + $SSrecording_dtmf_detection = $row[21]; + $SSrecording_dtmf_muting = $row[22]; } if ($SSallow_web_debug < 1) {$DB=0;} ##### END SETTINGS LOOKUP ##### @@ -4012,10 +4015,21 @@ function getMousePos(event) {mouseY=event.pageY;} { $stereo_column = ""._QXZ("STEREO").""; } + $dtmf_detect_column=''; + if ($SSrecording_dtmf_detection > 0) + { + $dtmf_detect_column = ""._QXZ("DTMF GRP")."   "; + } + $dtmf_mute_column=''; + if ( ($SSrecording_dtmf_detection > 0) and ($SSrecording_dtmf_muting > 0) ) + { + $dtmf_mute_column = ""._QXZ("D-MUTE")."   "; + } + echo ""._QXZ("RECORDINGS FOR THIS LEAD").":\n"; echo "\n"; - echo "$mute_column$stereo_column\n"; + echo "$mute_column$stereo_column$dtmf_detect_column$dtmf_mute_column\n"; $stmt="SELECT recording_id,channel,server_ip,extension,start_time,start_epoch,end_time,end_epoch,length_in_sec,length_in_min,filename,location,lead_id,user,vicidial_id from recording_log where lead_id='" . mysqli_real_escape_string($link, $lead_id) . "' order by recording_id desc limit 500;"; $rslt=mysql_to_mysqli($stmt, $link); @@ -4113,6 +4127,38 @@ function getMousePos(event) {mouseY=event.pageY;} if (!preg_match("/^S/",$stereo_flag)) {$stereo_flag='';} echo "\n"; } + if ($SSrecording_dtmf_detection > 0) + { + $dtmf_detected=''; + $dtmf_muting=''; + $dtmf_muting_seconds=''; + + $stmtDTMF="SELECT dtmf_detected,dtmf_muting,dtmf_muting_seconds from recording_live_log where recording_id='$row[0]' limit 1;"; + $rsltDTMF=mysql_to_mysqli($stmtDTMF, $link); + $DTMF_to_print = mysqli_num_rows($rsltDTMF); + if ($DB) {echo "$DTMF_to_print|$stmtDTMF|\n";} + if ($DTMF_to_print > 0) + { + $DTMFrow=mysqli_fetch_row($rsltDTMF); + $dtmf_detected = $DTMFrow[0]; + $dtmf_muting = $DTMFrow[1]; + $dtmf_muting_seconds = $DTMFrow[2]; + + if ($dtmf_detected < 1) + {$dtmf_detected='';} + if ($SSrecording_dtmf_muting > 0) + { + if ($dtmf_muting > 0) + {$dtmf_muting = "$dtmf_muting - $dtmf_muting_seconds";} + else + {$dtmf_muting='';} + } + } + echo "\n"; + if ($SSrecording_dtmf_muting > 0) + {echo "\n";} + } + echo "$play_audio"; echo "\n"; $rec_ids .= ",'$row[0]'"; diff --git a/www/vicidial/help_documentation.txt b/www/vicidial/help_documentation.txt index 254138447..5da6db243 100644 --- a/www/vicidial/help_documentation.txt +++ b/www/vicidial/help_documentation.txt @@ -1,4 +1,4 @@ -# version: 20251002142401 +# version: 20251017123601 users-user User ID 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-. users-pass Password This field is where you put the users password. Must be at least 2 characters in length, unless the User Password Minimum Length system setting is enabled, which will require a longer password. 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. users-force_change_password Force Change Password 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. @@ -275,7 +275,7 @@ campaigns-stereo_recording_agent Stereo Recording Agent Control If Stereo C campaigns-stereo_rec_filename Stereo Rec Filename If Stereo Call Recordings is enabled, this will be the recording filename of the Stereo call recordings. This cannot be set the same as the Campaign Rec Filename. This field is required to be populated for Stereo Call Recording to work for calls placed from this campaign. The dynamic fields that can be used are the same as can be used in the Campaign Rec Filename. Default is S_FULLDATE_CUSTPHONE. campaigns-stereo_parallel_recording Parallel Stereo Recordings if enabled, then every call will be recorded in its entirety, from when the agent receives it until it leaves the agent session. The options include: CUSTOMER-ONLY, CUSTOMER-MUTED and FULL-RECORDING. If Stereo Recording Agent Control is also enabled, that can itself also result in multiple recordings on a single call. Default is DISABLED. campaigns-parallel_rec_xx_filename Parallel Rec Filenames If Parallel Stereo Recordings are enabled, then these optional fields can be used to customize the call recording filenames for each type of Parallel Stereo Call Recording. If these fields are not populated, then the system will default to use the Stereo Rec Filename with a prefix at the beginning of each filename for the type of Parallel Stereo Call Recording that has been used: CO for Customer-Only, CM for Customer-Muted and FR for Full-Recording. Default is blank for all 3 of these fields. -campaigns-recording_dtmf_muting Recording DTMF Muting NOT FUNCTIONAL, STILL IN DEVELOPMENT. If enabled, and Allow Recording DTMF Detection is also enabled, call recordings will be muted for this number of seconds after the first DTMF signal is detected while recording is active. Default is 0 for disabled. +campaigns-recording_dtmf_muting Recording DTMF Muting If enabled, and the Allow Recording DTMF Detection system setting is also enabled, call recordings will be muted for this number of seconds after the first DTMF signal is detected while recording is active. This setting will only effect on calls placed from this campaign, if you also want DTMF Muting to be active for inbound calls, then each In-Group will also need to have this feature enabled. If this is enabled for a campaign, then Mute Recordings will be disabled automatically. Default is 0 for disabled. campaigns-per_call_notes Call Notes Per Call Setting this option to ENABLED will allow agents to enter in notes for every call they handle in the agent interface. The notes entry field will appear below the Comments field in the agent interface. Also, if the Agent User Group is allowed to view Call Logs then the agent will be able to view past call notes for a lead at any time. Default is DISABLED. campaigns-force_per_call_notes Per Call Notes Required If enabled, the agent will have to enter text into the Call Notes field on their agent screen in order to Hangup the Customer phone call. The CHARACTERS options will also enable this feature, but they will require a minimum number of characters to be entered to allow hangup. Default is DISABLED. campaigns-comments_all_tabs Comments All Tabs Setting this option to ENABLED will display the Comments field on all tabs in the main agent screen. Default is DISABLED. @@ -676,7 +676,7 @@ inbound_groups-stereo_recording_agent Stereo Recording Agent Control If Ste inbound_groups-stereo_rec_filename Stereo Rec Filename If Stereo Call Recordings is enabled, this will be the recording filename of the Stereo call recordings for calls handled through this In-Group. This cannot be set the same as the Campaign Rec Filename. This field is required to be populated for Stereo Call Recording to work for calls handled through this In-Group. The dynamic fields that can be used are the same as can be used in the In-Group Recording Filename. Default is S_FULLDATE_CUSTPHONE. inbound_groups-stereo_parallel_recording Parallel Stereo Recordings if enabled, then every call will be recorded in its entirety for calls handled through this In-Group, from when the agent receives it until it leaves the agent session. The options include: CUSTOMER-ONLY, CUSTOMER-MUTED and FULL-RECORDING. If Stereo Recording Agent Control is also enabled, that can itself also result in multiple recordings on a single call. Default is DISABLED. inbound_groups-parallel_rec_xx_filename Parallel Rec Filenames If Parallel Stereo Recordings are enabled, then these optional fields can be used to customize the call recording filenames for each type of Parallel Stereo Call Recording. If these fields are not populated, then the system will default to use the Stereo Rec Filename with a prefix at the beginning of each filename for the type of Parallel Stereo Call Recording that has been used: CO for Customer-Only, CM for Customer-Muted and FR for Full-Recording. Default is blank for all 3 of these fields. -inbound_groups-recording_dtmf_muting Recording DTMF Muting NOT FUNCTIONAL, STILL IN DEVELOPMENT. If enabled, and Allow Recording DTMF Detection is also enabled, call recordings for calls handled through this In-Group will be muted for this number of seconds after the first DTMF signal is detected while recording is active. Default is 0 for disabled. +inbound_groups-recording_dtmf_muting Recording DTMF Muting If enabled, and the Allow Recording DTMF Detection system setting is also enabled, call recordings from this In-Group will be muted for this number of seconds after the first DTMF signal is detected while recording is active. This setting will only effect on calls handled through this In-Group, if you also want DTMF Muting to be active for outbound calls, then each Campaign will also need to have this feature enabled. Default is 0 for disabled. inbound_groups-qc_enabled QC Enabled Setting this field to Y allows for the agent Quality Control features to work. Default is N. inbound_groups-qc_statuses QC Statuses This area is where you select which statuses of leads should be gone over by the QC system. Place a check next to the status that you want QC to review. inbound_groups-qc_statuses_id QC Statuses ID This area is where you select which "QC_TEMPLATE" settings container will be used to determine the call statuses that are eligible for QC evaluation in this ingroup. This will override both campaign and list "QC Statuses ID" settings. @@ -1252,8 +1252,8 @@ settings-recording_buttons Recording Buttons Type This option allows you to settings-mute_recordings Allow Mute Recordings This option if enabled allows you to enable the MUTE RECORDING button on the agent screen by campaign and-or user. This feature is only tested with systems running Asterisk 13. You should not mute recordings for more than 15 minutes at a time. Default is 0 for disabled. settings-stereo_recording Allow Stereo Recordings If enabled, allows for additional call recordings in stereo, with the customer on one side and the agent on the other. Must also be enabled at the campaign level. Enabling this setting may require additional system resources if standard mono recordings are also still enabled. Default is 0 for disabled. settings-stereo_parallel_recording Enable Stereo Parallel Recordings If enabled, and Allow Stereo Recordings is also enabled, allows for multiple parallel stereo call recordings for every call. Enabling this setting will require additional system resources, since every call will be recorded in its entirety, and post-call processing will be required to facilitate all of this settings features. Must also be enabled at the campaign level. Default is 0 for disabled. -settings-recording_dtmf_detection Allow Recording DTMF Detection NOT FUNCTIONAL, STILL IN DEVELOPMENT. If enabled, recordings will be flagged if any DTMF signals are detected during the recording duration. Default is 0 for disabled. -settings-recording_dtmf_muting Allow Recording DTMF Muting NOT FUNCTIONAL, STILL IN DEVELOPMENT. If enabled, and Allow Recording DTMF Detection is also enabled, call recordings will be muted for X seconds after the first DTMF signal is detected while recording is active. Must also be enabled at the campaign level. Default is 0 for disabled. +settings-recording_dtmf_detection Allow Recording DTMF Detection If enabled, recording logs will be flagged if any DTMF signals are detected during the recording duration. Default is 0 for disabled. +settings-recording_dtmf_muting Allow Recording DTMF Muting If enabled, and Allow Recording DTMF Detection is also enabled, then you will be allowed to enable this feature for specific Campaigns and In-Groups. If set to -1- this setting will only effect on calls handled through the Campaigns and In-Groups that have this feature enabled. If this is enabled for a campaign, then Mute Recordings will be disabled automatically for that campaign. If this setting is set to 2 or higher, then this will force-enable DTMF Muting on all calls on this cluster and will override any Campaign or In-Group settings with this number of seconds of DTMF muting. Default is 0 for disabled. settings-enable_auto_reports Enable Automated Reports This option if enabled allows you access to the Automated Reports section where you can set up reports to run at scheduled times and be delivered by email or FTP. Default is 0 for disabled. settings-first_login_trigger First Login Trigger This setting allows for the initial configuration of the server screen to be shown to the administrator when they first log into the system. settings-require_password_length User Password Minimum Length If set above 0, this setting will require that user passwords, phone and server passwords, and system settings default passwords be at least this minimum length of characters when those records settings are modified on the Modify pages. The most important factor in password security is the length of the password, and user passwords in this system can be up to 100 characters in length. Default is 0 for disabled. From 31184628c9385f4e1be5b58b24056dc156e9334b Mon Sep 17 00:00:00 2001 From: Mattf Date: Sun, 26 Oct 2025 12:39:52 +0000 Subject: [PATCH 10/12] Added crashed DB table display to admin web screens Added --vicidial-dial-log-only flag to log archive script git-svn-id: svn://svn.eflo.net/agc_2-X/trunk@3950 3d104415-ff17-0410-8863-d5cf3c621b8a --- UPGRADE | 4 + bin/ADMIN_archive_log_tables.pl | 88 ++++++++++++- bin/ADMIN_keepalive_ALL.pl | 71 ++++++++++- bin/AST_table_status.pl | 191 ++++++++++++++++++++++++++++ extras/MySQL_AST_CREATE_tables.sql | 11 +- extras/upgrade_2.14.sql | 10 ++ www/vicidial/admin.php | 67 +++++++++- www/vicidial/admin_header.php | 19 ++- www/vicidial/help_documentation.txt | 3 +- 9 files changed, 448 insertions(+), 16 deletions(-) create mode 100644 bin/AST_table_status.pl diff --git a/UPGRADE b/UPGRADE index e3b256769..4df56648b 100644 --- a/UPGRADE +++ b/UPGRADE @@ -890,6 +890,10 @@ OTHER CHANGES: for X seconds if any DTMF signal is detected on the call. Configurable in Campaigns, In-Groups and system-wide. +254. Added Database crashed table auto-check, with display on Admin Web screens + for level 9 users if crashed tables are found. Enabled by default, + configurable in the System Settings. + diff --git a/bin/ADMIN_archive_log_tables.pl b/bin/ADMIN_archive_log_tables.pl index 8b60414b0..83c71ae05 100644 --- a/bin/ADMIN_archive_log_tables.pl +++ b/bin/ADMIN_archive_log_tables.pl @@ -75,6 +75,7 @@ # 240924-2041 - Added --vicidial-log-only # 250914-1537 - Added archiving of recording_log_stereo and recording_log_parallel tables # 251011-2048 - Added archiving of recording_live_log table +# 251024-1518 - Added --vicidial-dial-log-only flag # $CALC_TEST=0; @@ -122,6 +123,8 @@ print " [--api-log-days=XX] = REQUIRED FOR --api-only, number of days to archive vicidial_api_log table only past\n"; print " [--vicidial-log-only] = OPTIONAL, only archive vicidial_log table then exit\n"; print " [--vicidial-log-days=XX] = REQUIRED FOR --vicidial-log-only, number of days to archive vicidial_log table only past\n"; + print " [--vicidial-dial-log-only] = OPTIONAL, only archive vicidial_dial_log table then exit\n"; + print " [--vicidial-dial-log-days=XX] = REQUIRED FOR --vicidial-dial-log-only, number of days to archive vicidial_dial_log table only past\n"; print " [--extended-log-only] = OPTIONAL, only archive vicidial_log_extended table then exit\n"; print " [--extended-log-days=XX] = REQUIRED FOR --extended-log-only, number of days to archive vicidial_log_extended table only past\n"; print " [--api-archive-only] = OPTIONAL, only purge vicidial_api_log_archive table then exit\n"; @@ -294,7 +297,6 @@ if ($Q < 1) {print "\n----- VICIDIAL LOG ARCHIVE ONLY $vicidial_log_only -----\n\n";} } - if ($args =~ /--vicidial-log-days=/i) { $vicidial_log_only++; @@ -308,13 +310,31 @@ {print "\n----- VICIDIAL LOG ARCHIVE ACTIVE, DAYS: $extendeddays -----\n\n";} } + if ($args =~ /--vicidial-dial-log-only/i) + { + $vicidial_dial_log_only++; + if ($Q < 1) + {print "\n----- VICIDIAL DIAL LOG ARCHIVE ONLY $vicidial_dial_log_only -----\n\n";} + } + if ($args =~ /--vicidial-dial-log-days=/i) + { + $vicidial_dial_log_only++; + @data_in = split(/--vicidial-dial-log-days=/,$args); + $extendeddays = $data_in[1]; + $extendeddays =~ s/ .*$//gi; + $extendeddays =~ s/\D//gi; + if ($extendeddays > 999999) + {$extendeddays=1825;} + if ($Q < 1) + {print "\n----- VICIDIAL DIAL LOG ARCHIVE ACTIVE, DAYS: $extendeddays -----\n\n";} + } + if ($args =~ /--extended-log-only/i) { $extended_log_only++; if ($Q < 1) {print "\n----- EXTENDED LOG ARCHIVE ONLY $extended_log_only -----\n\n";} } - if ($args =~ /--extended-log-days=/i) { $extended_log_only++; @@ -334,7 +354,6 @@ if ($Q < 1) {print "\n----- API ARCHIVE PURGE ONLY -----\n\n";} } - if ($args =~ /--api-archive-days=/i) { $api_log_archive_purge++; @@ -354,7 +373,6 @@ if ($Q < 1) {print "\n----- URL LOG PURGE ONLY -----\n\n";} } - if ($args =~ /--url-log-days=/i) { $url_log_only++; @@ -505,7 +523,7 @@ if ($URLsec < 10) {$URLsec = "0$URLsec";} $URLdel_time = "$URLyear-$URLmon-$URLmday $URLhour:$URLmin:$URLsec"; } -if ( ($extended_log_only > 0) || ($vicidial_log_only > 0) ) +if ( ($extended_log_only > 0) || ($vicidial_log_only > 0) || ($vicidial_dial_log_only > 0) ) { $EXTENDEDdel_epoch = ($secX - (86400 * $extendeddays)); # X days ago ($EXTENDEDsec,$EXTENDEDmin,$EXTENDEDhour,$EXTENDEDmday,$EXTENDEDmon,$EXTENDEDyear,$EXTENDEDwday,$EXTENDEDyday,$EXTENDEDisdst) = localtime($EXTENDEDdel_epoch); @@ -2083,6 +2101,66 @@ ########## END --vicidial-log-only flag processing ########## + + + ########## BEGIN --vicidial-dial-log-only flag processing ########## + if ($vicidial_dial_log_only > 0) + { + ##### vicidial_dial_log + $stmtA = "SELECT count(*) from vicidial_dial_log;"; + $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; + $vicidial_dial_log_count = $aryA[0]; + } + $sthA->finish(); + + $stmtA = "SELECT count(*) from vicidial_dial_log_archive;"; + $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; + $vicidial_dial_log_archive_count = $aryA[0]; + } + $sthA->finish(); + + if (!$Q) {print "\nProcessing vicidial_dial_log table... ($vicidial_dial_log_count|$vicidial_dial_log_archive_count)\n";} + $stmtA = "INSERT IGNORE INTO vicidial_dial_log_archive SELECT * from vicidial_dial_log;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + + $sthArows = $sthA->rows; + if (!$Q) {print "$sthArows rows inserted into vicidial_dial_log_archive table \n";} + + $rv = $sthA->err(); + if (!$rv) + { + if ($wipe_all > 0) + {$stmtA = "DELETE FROM vicidial_dial_log;";} + else + {$stmtA = "DELETE FROM vicidial_dial_log WHERE call_date < '$EXTENDEDdel_time';";} + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows = $sthA->rows; + if (!$Q) {print "$sthArows rows deleted from vicidial_dial_log table \n";} + + $stmtA = "optimize table vicidial_dial_log;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + } + + if (!$Q) {print "\nProcessing vicidial_dial_log table finished: ($sthArows rows deleted) \n";} + + exit; + } + ########## END --vicidial-dial-log-only flag processing ########## + + if ($queue_log > 0) { ############################################# diff --git a/bin/ADMIN_keepalive_ALL.pl b/bin/ADMIN_keepalive_ALL.pl index b97a8b3e3..6bb8d3240 100644 --- a/bin/ADMIN_keepalive_ALL.pl +++ b/bin/ADMIN_keepalive_ALL.pl @@ -177,9 +177,10 @@ # 250924-2212 - Added code for deprecation of "Monitor" application after Asterisk 20 # 251006-0832 - Added truncating of vicidial_dtmf_log older than 24 hours & If recording_dtmf_muting enabled, force use of MixMonitor for recording # 251011-1000 - Added archiving of recording_dtmf_muting_log, disabled purging of recording_live_log after 7 days +# 251024-2222 - Added crashed table detection # -$build = '251011-1000'; +$build = '251024-2222'; $DB=0; # Debug flag $teodDB=0; # flag to log Timeclock End of Day processes to log file @@ -502,7 +503,7 @@ ##### Get the settings from system_settings ##### -$stmtA = "SELECT sounds_central_control_active,active_voicemail_server,custom_dialplan_entry,default_codecs,generate_cross_server_exten,voicemail_timezones,default_voicemail_timezone,call_menu_qualify_enabled,allow_voicemail_greeting,reload_timestamp,meetme_enter_login_filename,meetme_enter_leave3way_filename,allow_chats,enable_auto_reports,enable_drop_lists,expired_lists_inactive,sip_event_logging,call_quota_lead_ranking,inbound_answer_config,log_latency_gaps,demographic_quotas,weekday_resets,highest_lead_id,hopper_hold_inserts,stereo_recording,stereo_parallel_recording,recording_dtmf_muting FROM system_settings;"; +$stmtA = "SELECT sounds_central_control_active,active_voicemail_server,custom_dialplan_entry,default_codecs,generate_cross_server_exten,voicemail_timezones,default_voicemail_timezone,call_menu_qualify_enabled,allow_voicemail_greeting,reload_timestamp,meetme_enter_login_filename,meetme_enter_leave3way_filename,allow_chats,enable_auto_reports,enable_drop_lists,expired_lists_inactive,sip_event_logging,call_quota_lead_ranking,inbound_answer_config,log_latency_gaps,demographic_quotas,weekday_resets,highest_lead_id,hopper_hold_inserts,stereo_recording,stereo_parallel_recording,recording_dtmf_muting,db_crashed_tables_check FROM system_settings;"; # print "$stmtA\n"; $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; @@ -537,6 +538,7 @@ $SSstereo_recording = $aryA[24]; $SSstereo_parallel_recording = $aryA[25]; $SSrecording_dtmf_muting = $aryA[26]; + $SSdb_crashed_tables_check = $aryA[27]; } $sthA->finish(); if ($DBXXX > 0) {print "SYSTEM SETTINGS: $sounds_central_control_active|$active_voicemail_server|$SScustom_dialplan_entry|$SSdefault_codecs\n";} @@ -604,6 +606,7 @@ $runningASTERISK=0; $runningsip_logger=0; $runningconf_updater=0; + $runningcrash_test=0; $AST_conf_3way=0; $AST_rec_monitor=0; @@ -780,6 +783,11 @@ $runningAST_rec_monitor++; if ($DB) {print "AST_rec_monitor RUNNING: |$psline[1]|\n";} } + if ($psline[1] =~ /$REGhome\/AST_table_status\.pl/) + { + $runningcrash_test++; + if ($DB) {print "AST_table_status RUNNING: |$psline[1]|\n";} + } $i++; } @@ -953,6 +961,11 @@ $runningAST_rec_monitor++; if ($DB) {print "AST_rec_monitor RUNNING: |$psline[1]|\n";} } + if ($psline[1] =~ /$REGhome\/AST_table_status\.pl/) + { + $runningcrash_test++; + if ($DB) {print "AST_table_status RUNNING: |$psline[1]|\n";} + } $i++; } @@ -1522,6 +1535,15 @@ if ($DB) {print "|",$aryA[0],"|",$aryA[1],"|",$aryA[2],"|",$aryA[3],"|","\n";} $sthA->finish(); + $stmtA = "optimize table crashed_tables;"; + if($DBX){print STDERR "\n|$stmtA|\n";} + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArows=$sthA->rows; + @aryA = $sthA->fetchrow_array; + if ($DB) {print "|",$aryA[0],"|",$aryA[1],"|",$aryA[2],"|",$aryA[3],"|","\n";} + $sthA->finish(); + if ($agents_calls_reset > 0) { $stmtA = "delete from vicidial_live_inbound_agents where last_call_finish < \"$TDSQLdate\";"; @@ -2318,7 +2340,7 @@ ##### BEGIN vicidial_dtmf_log end of day process removing records older than 24 hours ##### - $stmtA = "DELETE from vicidial_dtmf_log where vicidial_dtmf_log < \"$RMSQLdate\";"; + $stmtA = "DELETE from vicidial_dtmf_log where dtmf_time < \"$RMSQLdate\";"; if($DBX){print STDERR "\n|$stmtA|\n";} $affected_rows = $dbhA->do($stmtA); if($DB){print STDERR "\n|$affected_rows vicidial_dtmf_log records older than 1 day purged|\n";} @@ -6812,6 +6834,49 @@ +################################################################################ +##### BEGIN check for crashed tables +################################################################################ +if ( ($THISserver_voicemail > 0) && ($SSdb_crashed_tables_check > 0) ) + { + if ($DB) {print "Begin check for crashed table... |db_crashed_tables_check setting: $SSdb_crashed_tables_check| \n";} + + if ($runningcrash_test > 0) + { + if ($DB) {print "Previous crash test already running, do not start another one.\n";} + } + else + { + $start_crash_check_now=0; + if ($SSdb_crashed_tables_check >= 4) + {$start_crash_check_now++;} + if ( ($SSdb_crashed_tables_check >= 3) && ($reset_test =~ /0$/) ) + {$start_crash_check_now++;} + if ( ($SSdb_crashed_tables_check >= 2) && ($reset_test =~ /00$/) ) + {$start_crash_check_now++;} + if ( ($SSdb_crashed_tables_check >= 1) && ($timeclock_end_of_day_NOW > 0) ) + {$start_crash_check_now++;} + + if ($start_crash_check_now > 0) + { + if ($DB) {print "starting AST_table_status... |$start_crash_check_now| \n";} + # add a '-L' to the command below to activate logging + `/usr/bin/screen -d -m -S ASTcrash $PATHhome/AST_table_status.pl --debugX`; + if ($megaDB) + { + `/usr/bin/screen -S ASTcrash -X logfile $PATHlogs/ASTcrash-screenlog.0`; + `/usr/bin/screen -S ASTcrash -X log`; + } + } + } + } +################################################################################ +##### END check for crashed tables +################################################################################ + + + + if ($DB) {print "DONE\n";} diff --git a/bin/AST_table_status.pl b/bin/AST_table_status.pl new file mode 100644 index 000000000..b1ddc35dd --- /dev/null +++ b/bin/AST_table_status.pl @@ -0,0 +1,191 @@ +#!/usr/bin/perl +# +# AST_table_status.pl version 2.12 +# +# DESCRIPTION: +# - gathers MySQL "SHOW TABLE STATUS" info to check for crashed tables +# +# +# Copyright (C) 2025 Matt Florell LICENSE: AGPLv2 +# +# CHANGES +# 251025-1618 - First build +# + +### begin parsing run-time options ### +if (length($ARGV[0])>1) + { + $i=0; + while ($#ARGV >= $i) + { + $args = "$args $ARGV[$i]"; + $i++; + } + + if ($args =~ /--help/i) + { + print "allowed run time options:\n"; + print " [-q] = quiet\n"; + print " [-t] = test\n"; + print " [--debug] = debugging messages\n"; + print " [--debugX] = Extra debugging messages\n"; + print "\n"; + + exit; + } + else + { + if ($args =~ /-q/i) + { + $q=1; $Q=1; + } + if ($args =~ /--debug/i) + { + $DB=1; + print "\n----- DEBUGGING -----\n\n"; + } + if ($args =~ /--debugX/i) + { + $DBX=1; + print "\n----- EXTRA DEBUGGING -----\n\n"; + } + if ($args =~ /-t|--test/i) + { + $T=1; $TEST=1; + print "\n----- TESTING -----\n\n"; + } + } + } +else + { + print "no command line options set Exiting...\n"; + } +### end parsing run-time options ### + +$secX = time(); +($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); +$year = ($year + 1900); +$yy = $year; $yy =~ s/^..//gi; +$mon++; +if ($mon < 10) {$mon = "0$mon";} +if ($mday < 10) {$mday = "0$mday";} +if ($hour < 10) {$hour = "0$hour";} +if ($min < 10) {$min = "0$min";} +if ($sec < 10) {$sec = "0$sec";} +$now_date="$year-$mon-$mday $hour:$min:$sec"; + +if (!$Q) {print "NOW DATETIME: $now_date \n";} + +# default path to astguiclient configuration file: +$PATHconf = '/etc/astguiclient.conf'; + +open(conf, "$PATHconf") || die "can't open $PATHconf: $!\n"; +@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++; + } + +# Customized Variables +$server_ip = $VARserver_ip; # Asterisk server IP + +if (!$VARDB_port) {$VARDB_port='3306';} + +use DBI; + +$dbhA = DBI->connect("DBI:mysql:$VARDB_database:$VARDB_server:$VARDB_port", "$VARDB_user", "$VARDB_pass") + or die "Couldn't connect to database: " . DBI->errstr; + + +if ($DB) {print "Begin check for crashed table...\n";} +# gather crashed table records +$stmtA = "SHOW TABLE STATUS WHERE Comment LIKE \"%crash%\";"; +$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; +$sthA->execute or die "executing: $stmtA ", $dbhA->errstr; +$sthArowsCRASH=$sthA->rows; +$i=0; +while ($sthArowsCRASH > $i) + { + @aryA = $sthA->fetchrow_array; + $CRASHEDtables[$i] = $aryA[0]; + + if($DBX){print STDERR "\nCRASHED TABLE: |$i|$CRASHEDtables[$i]| \n";} + + $i++; + } +$sthA->finish(); + +if ($i > 0) + { + $keep_tables="''"; + $i=0; + while ($sthArowsCRASH > $i) + { + $keep_tables .= ",'$CRASHEDtables[$i]'"; + $stmtA = "INSERT INTO crashed_tables SET table_name='$CRASHEDtables[$i]',crashed_datetime='$now_date',last_check_datetime='$now_date' ON DUPLICATE KEY UPDATE last_check_datetime='$now_date';"; + $Iaffected_rows = $dbhA->do($stmtA); + if ($DB) {print "Crashed table update: |$Iaffected_rows|$stmtA";} + $i++; + } + $stmtA = "DELETE FROM crashed_tables where table_name NOT IN($keep_tables);"; + $Iaffected_rows = $dbhA->do($stmtA); + if ($DB) {print "Crashed table old entries cleared: |$Iaffected_rows|$stmtA";} + } +else + { + if($DBX){print STDERR "\nNO CRASHED TABLES FOUND.\n";} + $CRASHEDtable_ct=0; + # gather crashed table records count + $stmtA = "SELECT count(*) FROM crashed_tables;"; + $sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr; + $sthA->execute or die "executing: $stmtA ", $dbhA->errstr; + $sthArowsCRASHct=$sthA->rows; + if ($sthArowsCRASHct > 0) + { + @aryA = $sthA->fetchrow_array; + $CRASHEDtable_ct = $aryA[0]; + } + $sthA->finish(); + + if ($CRASHEDtable_ct > 0) + { + $stmtA = "DELETE FROM crashed_tables;"; + $Iaffected_rows = $dbhA->do($stmtA); + if ($DB) {print "Crashed table cleared: |$Iaffected_rows|$stmtA";} + } + } + + +$dbhA->disconnect(); + +if (!$Q) {print "Script exiting\n";} + +exit; diff --git a/extras/MySQL_AST_CREATE_tables.sql b/extras/MySQL_AST_CREATE_tables.sql index e01bf07a3..1629139b7 100644 --- a/extras/MySQL_AST_CREATE_tables.sql +++ b/extras/MySQL_AST_CREATE_tables.sql @@ -2074,7 +2074,8 @@ agent_man_dial_filter VARCHAR(20) default '', agent_3way_dial_filter VARCHAR(20) default '', recording_dtmf_detection TINYINT(3) UNSIGNED default '0', recording_dtmf_muting TINYINT(3) UNSIGNED default '0', -stereo_parallel_recording ENUM('0','1','2','3','4','5','6') default '0' +stereo_parallel_recording ENUM('0','1','2','3','4','5','6') default '0', +db_crashed_tables_check ENUM('0','1','2','3','4','5','6') default '1' ) ENGINE=MyISAM; CREATE TABLE vicidial_campaigns_list_mix ( @@ -5449,6 +5450,12 @@ index(recording_id), index(dtmf_muting_end_time) ) ENGINE=MyISAM; +CREATE TABLE crashed_tables ( +table_name VARCHAR(100) PRIMARY KEY NOT NULL, +crashed_datetime DATETIME, +last_check_datetime DATETIME +) ENGINE=MyISAM; + ALTER TABLE vicidial_email_list MODIFY message text character set utf8; @@ -5867,4 +5874,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='1732',db_schema_update_date=NOW(),reload_timestamp=NOW(); +UPDATE system_settings SET db_schema_version='1733',db_schema_update_date=NOW(),reload_timestamp=NOW(); diff --git a/extras/upgrade_2.14.sql b/extras/upgrade_2.14.sql index 2a24e1779..9247a88b0 100644 --- a/extras/upgrade_2.14.sql +++ b/extras/upgrade_2.14.sql @@ -3030,3 +3030,13 @@ CREATE INDEX rllst on recording_live_log(start_time); CREATE TABLE recording_live_log_archive LIKE recording_live_log; UPDATE system_settings SET db_schema_version='1732',db_schema_update_date=NOW() where db_schema_version < 1732; + +CREATE TABLE crashed_tables ( +table_name VARCHAR(100) PRIMARY KEY NOT NULL, +crashed_datetime DATETIME, +last_check_datetime DATETIME +) ENGINE=MyISAM; + +ALTER TABLE system_settings ADD db_crashed_tables_check ENUM('0','1','2','3','4','5','6') default '1'; + +UPDATE system_settings SET db_schema_version='1733',db_schema_update_date=NOW() where db_schema_version < 1733; diff --git a/www/vicidial/admin.php b/www/vicidial/admin.php index 398d131c2..c5c6c0391 100644 --- a/www/vicidial/admin.php +++ b/www/vicidial/admin.php @@ -2870,6 +2870,8 @@ elseif (isset($_POST["parallel_rec_fr_filename"])) {$parallel_rec_fr_filename=$_POST["parallel_rec_fr_filename"];} if (isset($_GET["call_count_limit_restrict"])) {$call_count_limit_restrict=$_GET["call_count_limit_restrict"];} elseif (isset($_POST["call_count_limit_restrict"])) {$call_count_limit_restrict=$_POST["call_count_limit_restrict"];} +if (isset($_GET["db_crashed_tables_check"])) {$db_crashed_tables_check=$_GET["db_crashed_tables_check"];} + elseif (isset($_POST["db_crashed_tables_check"])) {$db_crashed_tables_check=$_POST["db_crashed_tables_check"];} $DB=preg_replace("/[^0-9a-zA-Z]/","",$DB); @@ -3416,6 +3418,7 @@ $agent_hide_dial_fail = preg_replace('/[^0-9]/','',$agent_hide_dial_fail); $recording_dtmf_detection = preg_replace('/[^0-9]/','',$recording_dtmf_detection); $recording_dtmf_muting = preg_replace('/[^0-9]/','',$recording_dtmf_muting); +$db_crashed_tables_check = preg_replace('/[^0-9]/','',$db_crashed_tables_check); $user_new_lead_limit = preg_replace('/[^-0-9]/','',$user_new_lead_limit); $drop_call_seconds = preg_replace('/[^-0-9]/','',$drop_call_seconds); @@ -6291,12 +6294,13 @@ # 250922-0841 - Added Talk Seconds URL links to multi-url admin page in campaigns and in-groups # 251002-1428 - Added call_count_limit_restrict campaign setting # 251019-2024 - Added Recording DTMF Muting +# 251025-1924 - Added CRASHED DATABASE TABLES display page, db_crashed_tables_check system settings 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-946a'; -$build = '251019-2024'; +$admin_version = '2.14-947a'; +$build = '251025-1924'; $STARTtime = date("U"); $SQLdate = date("Y-m-d H:i:s"); @@ -7372,6 +7376,7 @@ function ajax_logout_now() if ($ADD==999987) {$hh='reports'; echo _QXZ("PHONE CODES");} if ($ADD==999986) {$hh='reports'; echo _QXZ("POSTAL CODES");} if ($ADD==999985) {$hh='reports'; echo _QXZ("POSTAL CODES CITIES");} +if ($ADD==999984) {$hh='reports'; echo _QXZ("CRASHED DATABASE TABLES");} echo "\n"; @@ -21413,7 +21418,7 @@ function ajax_logout_now() $update_apinewlead_rows=mysqli_affected_rows($link); # update the system settings - $stmt="UPDATE system_settings set use_non_latin='$use_non_latin',webroot_writable='$webroot_writable',enable_queuemetrics_logging='$enable_queuemetrics_logging',queuemetrics_server_ip='$queuemetrics_server_ip',queuemetrics_dbname='$queuemetrics_dbname',queuemetrics_login='$queuemetrics_login',queuemetrics_pass='$queuemetrics_pass',queuemetrics_url='" . mysqli_real_escape_string($link, $queuemetrics_url) . "',queuemetrics_log_id='$queuemetrics_log_id',queuemetrics_eq_prepend='$queuemetrics_eq_prepend',vicidial_agent_disable='$vicidial_agent_disable',allow_sipsak_messages='$allow_sipsak_messages',admin_home_url='" . mysqli_real_escape_string($link, $admin_home_url) . "',enable_agc_xfer_log='$enable_agc_xfer_log',timeclock_end_of_day='$timeclock_end_of_day',vdc_header_date_format='$vdc_header_date_format',vdc_customer_date_format='$vdc_customer_date_format',vdc_header_phone_format='$vdc_header_phone_format',vdc_agent_api_active='$vdc_agent_api_active',enable_vtiger_integration='$enable_vtiger_integration',vtiger_server_ip='$vtiger_server_ip',vtiger_dbname='$vtiger_dbname',vtiger_login='$vtiger_login',vtiger_pass='$vtiger_pass',vtiger_url='" . mysqli_real_escape_string($link, $vtiger_url) . "',qc_features_active='$qc_features_active',outbound_autodial_active='$outbound_autodial_active',outbound_calls_per_second='$outbound_calls_per_second',enable_tts_integration='$enable_tts_integration',agentonly_callback_campaign_lock='$agentonly_callback_campaign_lock',sounds_central_control_active='$sounds_central_control_active',sounds_web_server='$sounds_web_server',sounds_web_directory='$sounds_web_directory',active_voicemail_server='$active_voicemail_server',auto_dial_limit='$auto_dial_limit',user_territories_active='$user_territories_active',allow_custom_dialplan='$allow_custom_dialplan',enable_second_webform='$enable_second_webform',default_webphone='$default_webphone',default_external_server_ip='$default_external_server_ip',webphone_url='" . mysqli_real_escape_string($link, $webphone_url) . "',enable_agc_dispo_log='$enable_agc_dispo_log',queuemetrics_loginout='$queuemetrics_loginout',callcard_enabled='$callcard_enabled',queuemetrics_callstatus='$queuemetrics_callstatus',default_codecs='$default_codecs',admin_web_directory='$admin_web_directory',label_title='$label_title',label_first_name='$label_first_name',label_middle_initial='$label_middle_initial',label_last_name='$label_last_name',label_address1='$label_address1',label_address2='$label_address2',label_address3='$label_address3',label_city='$label_city',label_state='$label_state',label_province='$label_province',label_postal_code='$label_postal_code',label_vendor_lead_code='$label_vendor_lead_code',label_gender='$label_gender',label_phone_number='$label_phone_number',label_phone_code='$label_phone_code',label_alt_phone='$label_alt_phone',label_security_phrase='$label_security_phrase',label_email='$label_email',label_comments='$label_comments',label_lead_id='$label_lead_id',label_list_id='$label_list_id',label_entry_date='$label_entry_date',label_gmt_offset_now='$label_gmt_offset_now',label_source_id='$label_source_id',label_called_since_last_reset='$label_called_since_last_reset',label_status='$label_status',label_user='$label_user',label_date_of_birth='$label_date_of_birth',label_country_code='$label_country_code',label_last_local_call_time='$label_last_local_call_time',label_called_count='$label_called_count',label_rank='$label_rank',label_owner='$label_owner',label_entry_list_id='$label_entry_list_id',custom_fields_enabled='$custom_fields_enabled',slave_db_server='$slave_db_server',reports_use_slave_db='$reports_use_slave_db'$custom_reports_slave_SQL,webphone_systemkey='$webphone_systemkey',first_login_trigger='$first_login_trigger',default_phone_registration_password='$default_phone_registration_password',default_phone_login_password='$default_phone_login_password',default_server_password='$default_server_password',admin_modify_refresh='$admin_modify_refresh',nocache_admin='$nocache_admin',generate_cross_server_exten='$generate_cross_server_exten',queuemetrics_addmember_enabled='$queuemetrics_addmember_enabled',queuemetrics_dispo_pause='$queuemetrics_dispo_pause',label_hide_field_logs='$label_hide_field_logs',queuemetrics_pe_phone_append='$queuemetrics_pe_phone_append',test_campaign_calls='$test_campaign_calls',agents_calls_reset='$agents_calls_reset',default_voicemail_timezone='$default_voicemail_timezone',default_local_gmt='$default_local_gmt',noanswer_log='$noanswer_log',alt_log_server_ip='$alt_log_server_ip',alt_log_dbname='$alt_log_dbname',alt_log_login='$alt_log_login',alt_log_pass='$alt_log_pass',tables_use_alt_log_db='$tables_use_alt_log_db',did_agent_log='$did_agent_log',campaign_cid_areacodes_enabled='$campaign_cid_areacodes_enabled',pllb_grouping_limit='$pllb_grouping_limit',did_ra_extensions_enabled='$did_ra_extensions_enabled',expanded_list_stats='$expanded_list_stats',contacts_enabled='$contacts_enabled',call_menu_qualify_enabled='$call_menu_qualify_enabled',admin_list_counts='$admin_list_counts',allow_voicemail_greeting='$allow_voicemail_greeting',queuemetrics_socket='$queuemetrics_socket',queuemetrics_socket_url='$queuemetrics_socket_url',enhanced_disconnect_logging='$enhanced_disconnect_logging',allow_emails='$allow_emails',level_8_disable_add='$level_8_disable_add',queuemetrics_record_hold='$queuemetrics_record_hold',country_code_list_stats='$country_code_list_stats',queuemetrics_pause_type='$queuemetrics_pause_type',frozen_server_call_clear='$frozen_server_call_clear',callback_time_24hour='$callback_time_24hour',enable_languages='$enable_languages',language_method='$language_method',meetme_enter_login_filename='$meetme_enter_login_filename',meetme_enter_leave3way_filename='$meetme_enter_leave3way_filename',enable_did_entry_list_id='$enable_did_entry_list_id',enable_third_webform='$enable_third_webform',allow_chats='$allow_chats',chat_url='" . mysqli_real_escape_string($link, $chat_url) . "',chat_timeout='$chat_timeout',agent_debug_logging='$agent_debug_logging',default_language='$default_language',agent_whisper_enabled='$agent_whisper_enabled',user_hide_realtime_enabled='$user_hide_realtime_enabled',usacan_phone_dialcode_fix='$usacan_phone_dialcode_fix',cache_carrier_stats_realtime='$cache_carrier_stats_realtime',log_recording_access='$log_recording_access',report_default_format='$report_default_format',alt_ivr_logging='$alt_ivr_logging',default_phone_code='$default_phone_code',admin_row_click='$admin_row_click',admin_screen_colors='$admin_screen_colors',ofcom_uk_drop_calc='$ofcom_uk_drop_calc',agent_screen_colors='$agent_screen_colors',script_remove_js='$script_remove_js',manual_auto_next='$manual_auto_next',user_new_lead_limit='$user_new_lead_limit',agent_xfer_park_3way='$agent_xfer_park_3way',agent_soundboards='$agent_soundboards',web_loader_phone_length='$web_loader_phone_length',agent_script='$agent_script',agent_chat_screen_colors='$agent_chat_screen_colors',enable_auto_reports='$enable_auto_reports',enable_pause_code_limits='$enable_pause_code_limits',enable_drop_lists='$enable_drop_lists',allow_ip_lists='$allow_ip_lists',system_ip_blacklist='$system_ip_blacklist',agent_push_events='$agent_push_events',agent_push_url='$agent_push_url',hide_inactive_lists='$hide_inactive_lists',allow_manage_active_lists='$allow_manage_active_lists',expired_lists_inactive='$expired_lists_inactive',did_system_filter='$did_system_filter',anyone_callback_inactive_lists='$anyone_callback_inactive_lists',enable_gdpr_download_deletion='$enable_gdpr_download_deletion',source_id_display='$source_id_display',agent_logout_link='$agent_logout_link',manual_dial_validation='$manual_dial_validation',mute_recordings='$mute_recordings',user_admin_redirect='$user_admin_redirect',list_status_modification_confirmation='$list_status_modification_confirmation',sip_event_logging='$sip_event_logging',call_quota_lead_ranking='$call_quota_lead_ranking',enable_second_script='$enable_second_script',enable_first_webform='$enable_first_webform',recording_buttons='$recording_buttons',opensips_cid_name='$opensips_cid_name',require_password_length='$require_password_length',user_account_emails='$user_account_emails',outbound_cid_any='$outbound_cid_any',entries_per_page='$entries_per_page',browser_call_alerts='$browser_call_alerts',queuemetrics_pausereason='$queuemetrics_pausereason',inbound_answer_config='$inbound_answer_config',enable_international_dncs='$enable_international_dncs',web_loader_phone_strip='$web_loader_phone_strip',manual_dial_phone_strip='$manual_dial_phone_strip',daily_call_count_limit='$daily_call_count_limit',allow_shared_dial='$allow_shared_dial',agent_search_method='$agent_search_method',phone_defaults_container='$phone_defaults_container',qc_claim_limit='$qc_claim_limit',qc_expire_days='$qc_expire_days',two_factor_auth_hours='$two_factor_auth_hours',two_factor_container='$two_factor_container',agent_hidden_sound='$agent_hidden_sound',agent_hidden_sound_volume='$agent_hidden_sound_volume',agent_hidden_sound_seconds='$agent_hidden_sound_seconds',agent_screen_timer='$agent_screen_timer',call_limit_24hour='$call_limit_24hour',allowed_sip_stacks='$allowed_sip_stacks',agent_hide_hangup='$agent_hide_hangup',allow_web_debug='$allow_web_debug',max_logged_in_agents='$max_logged_in_agents',user_codes_admin='$user_codes_admin',login_kickall='$login_kickall',abandon_check_queue='$abandon_check_queue',agent_notifications='$agent_notifications',demographic_quotas='$demographic_quotas',log_latency_gaps='$log_latency_gaps',inbound_credits='$inbound_credits',weekday_resets='$weekday_resets',two_factor_auth_agent_hours='$two_factor_auth_agent_hours',hopper_hold_inserts='$hopper_hold_inserts',coldstorage_server_ip='$coldstorage_server_ip',coldstorage_dbname='$coldstorage_dbname',coldstorage_login='$coldstorage_login',coldstorage_pass='$coldstorage_pass',coldstorage_port='$coldstorage_port',enhanced_agent_monitoring='$enhanced_agent_monitoring',agent_hide_dial_fail='$agent_hide_dial_fail',agent_man_dial_filter='$agent_man_dial_filter',agent_3way_dial_filter='$agent_3way_dial_filter',stereo_recording='$stereo_recording',recording_dtmf_detection='$recording_dtmf_detection',recording_dtmf_muting='$recording_dtmf_muting',stereo_parallel_recording='$stereo_parallel_recording'$custom_dialplanSQL;"; + $stmt="UPDATE system_settings set use_non_latin='$use_non_latin',webroot_writable='$webroot_writable',enable_queuemetrics_logging='$enable_queuemetrics_logging',queuemetrics_server_ip='$queuemetrics_server_ip',queuemetrics_dbname='$queuemetrics_dbname',queuemetrics_login='$queuemetrics_login',queuemetrics_pass='$queuemetrics_pass',queuemetrics_url='" . mysqli_real_escape_string($link, $queuemetrics_url) . "',queuemetrics_log_id='$queuemetrics_log_id',queuemetrics_eq_prepend='$queuemetrics_eq_prepend',vicidial_agent_disable='$vicidial_agent_disable',allow_sipsak_messages='$allow_sipsak_messages',admin_home_url='" . mysqli_real_escape_string($link, $admin_home_url) . "',enable_agc_xfer_log='$enable_agc_xfer_log',timeclock_end_of_day='$timeclock_end_of_day',vdc_header_date_format='$vdc_header_date_format',vdc_customer_date_format='$vdc_customer_date_format',vdc_header_phone_format='$vdc_header_phone_format',vdc_agent_api_active='$vdc_agent_api_active',enable_vtiger_integration='$enable_vtiger_integration',vtiger_server_ip='$vtiger_server_ip',vtiger_dbname='$vtiger_dbname',vtiger_login='$vtiger_login',vtiger_pass='$vtiger_pass',vtiger_url='" . mysqli_real_escape_string($link, $vtiger_url) . "',qc_features_active='$qc_features_active',outbound_autodial_active='$outbound_autodial_active',outbound_calls_per_second='$outbound_calls_per_second',enable_tts_integration='$enable_tts_integration',agentonly_callback_campaign_lock='$agentonly_callback_campaign_lock',sounds_central_control_active='$sounds_central_control_active',sounds_web_server='$sounds_web_server',sounds_web_directory='$sounds_web_directory',active_voicemail_server='$active_voicemail_server',auto_dial_limit='$auto_dial_limit',user_territories_active='$user_territories_active',allow_custom_dialplan='$allow_custom_dialplan',enable_second_webform='$enable_second_webform',default_webphone='$default_webphone',default_external_server_ip='$default_external_server_ip',webphone_url='" . mysqli_real_escape_string($link, $webphone_url) . "',enable_agc_dispo_log='$enable_agc_dispo_log',queuemetrics_loginout='$queuemetrics_loginout',callcard_enabled='$callcard_enabled',queuemetrics_callstatus='$queuemetrics_callstatus',default_codecs='$default_codecs',admin_web_directory='$admin_web_directory',label_title='$label_title',label_first_name='$label_first_name',label_middle_initial='$label_middle_initial',label_last_name='$label_last_name',label_address1='$label_address1',label_address2='$label_address2',label_address3='$label_address3',label_city='$label_city',label_state='$label_state',label_province='$label_province',label_postal_code='$label_postal_code',label_vendor_lead_code='$label_vendor_lead_code',label_gender='$label_gender',label_phone_number='$label_phone_number',label_phone_code='$label_phone_code',label_alt_phone='$label_alt_phone',label_security_phrase='$label_security_phrase',label_email='$label_email',label_comments='$label_comments',label_lead_id='$label_lead_id',label_list_id='$label_list_id',label_entry_date='$label_entry_date',label_gmt_offset_now='$label_gmt_offset_now',label_source_id='$label_source_id',label_called_since_last_reset='$label_called_since_last_reset',label_status='$label_status',label_user='$label_user',label_date_of_birth='$label_date_of_birth',label_country_code='$label_country_code',label_last_local_call_time='$label_last_local_call_time',label_called_count='$label_called_count',label_rank='$label_rank',label_owner='$label_owner',label_entry_list_id='$label_entry_list_id',custom_fields_enabled='$custom_fields_enabled',slave_db_server='$slave_db_server',reports_use_slave_db='$reports_use_slave_db'$custom_reports_slave_SQL,webphone_systemkey='$webphone_systemkey',first_login_trigger='$first_login_trigger',default_phone_registration_password='$default_phone_registration_password',default_phone_login_password='$default_phone_login_password',default_server_password='$default_server_password',admin_modify_refresh='$admin_modify_refresh',nocache_admin='$nocache_admin',generate_cross_server_exten='$generate_cross_server_exten',queuemetrics_addmember_enabled='$queuemetrics_addmember_enabled',queuemetrics_dispo_pause='$queuemetrics_dispo_pause',label_hide_field_logs='$label_hide_field_logs',queuemetrics_pe_phone_append='$queuemetrics_pe_phone_append',test_campaign_calls='$test_campaign_calls',agents_calls_reset='$agents_calls_reset',default_voicemail_timezone='$default_voicemail_timezone',default_local_gmt='$default_local_gmt',noanswer_log='$noanswer_log',alt_log_server_ip='$alt_log_server_ip',alt_log_dbname='$alt_log_dbname',alt_log_login='$alt_log_login',alt_log_pass='$alt_log_pass',tables_use_alt_log_db='$tables_use_alt_log_db',did_agent_log='$did_agent_log',campaign_cid_areacodes_enabled='$campaign_cid_areacodes_enabled',pllb_grouping_limit='$pllb_grouping_limit',did_ra_extensions_enabled='$did_ra_extensions_enabled',expanded_list_stats='$expanded_list_stats',contacts_enabled='$contacts_enabled',call_menu_qualify_enabled='$call_menu_qualify_enabled',admin_list_counts='$admin_list_counts',allow_voicemail_greeting='$allow_voicemail_greeting',queuemetrics_socket='$queuemetrics_socket',queuemetrics_socket_url='$queuemetrics_socket_url',enhanced_disconnect_logging='$enhanced_disconnect_logging',allow_emails='$allow_emails',level_8_disable_add='$level_8_disable_add',queuemetrics_record_hold='$queuemetrics_record_hold',country_code_list_stats='$country_code_list_stats',queuemetrics_pause_type='$queuemetrics_pause_type',frozen_server_call_clear='$frozen_server_call_clear',callback_time_24hour='$callback_time_24hour',enable_languages='$enable_languages',language_method='$language_method',meetme_enter_login_filename='$meetme_enter_login_filename',meetme_enter_leave3way_filename='$meetme_enter_leave3way_filename',enable_did_entry_list_id='$enable_did_entry_list_id',enable_third_webform='$enable_third_webform',allow_chats='$allow_chats',chat_url='" . mysqli_real_escape_string($link, $chat_url) . "',chat_timeout='$chat_timeout',agent_debug_logging='$agent_debug_logging',default_language='$default_language',agent_whisper_enabled='$agent_whisper_enabled',user_hide_realtime_enabled='$user_hide_realtime_enabled',usacan_phone_dialcode_fix='$usacan_phone_dialcode_fix',cache_carrier_stats_realtime='$cache_carrier_stats_realtime',log_recording_access='$log_recording_access',report_default_format='$report_default_format',alt_ivr_logging='$alt_ivr_logging',default_phone_code='$default_phone_code',admin_row_click='$admin_row_click',admin_screen_colors='$admin_screen_colors',ofcom_uk_drop_calc='$ofcom_uk_drop_calc',agent_screen_colors='$agent_screen_colors',script_remove_js='$script_remove_js',manual_auto_next='$manual_auto_next',user_new_lead_limit='$user_new_lead_limit',agent_xfer_park_3way='$agent_xfer_park_3way',agent_soundboards='$agent_soundboards',web_loader_phone_length='$web_loader_phone_length',agent_script='$agent_script',agent_chat_screen_colors='$agent_chat_screen_colors',enable_auto_reports='$enable_auto_reports',enable_pause_code_limits='$enable_pause_code_limits',enable_drop_lists='$enable_drop_lists',allow_ip_lists='$allow_ip_lists',system_ip_blacklist='$system_ip_blacklist',agent_push_events='$agent_push_events',agent_push_url='$agent_push_url',hide_inactive_lists='$hide_inactive_lists',allow_manage_active_lists='$allow_manage_active_lists',expired_lists_inactive='$expired_lists_inactive',did_system_filter='$did_system_filter',anyone_callback_inactive_lists='$anyone_callback_inactive_lists',enable_gdpr_download_deletion='$enable_gdpr_download_deletion',source_id_display='$source_id_display',agent_logout_link='$agent_logout_link',manual_dial_validation='$manual_dial_validation',mute_recordings='$mute_recordings',user_admin_redirect='$user_admin_redirect',list_status_modification_confirmation='$list_status_modification_confirmation',sip_event_logging='$sip_event_logging',call_quota_lead_ranking='$call_quota_lead_ranking',enable_second_script='$enable_second_script',enable_first_webform='$enable_first_webform',recording_buttons='$recording_buttons',opensips_cid_name='$opensips_cid_name',require_password_length='$require_password_length',user_account_emails='$user_account_emails',outbound_cid_any='$outbound_cid_any',entries_per_page='$entries_per_page',browser_call_alerts='$browser_call_alerts',queuemetrics_pausereason='$queuemetrics_pausereason',inbound_answer_config='$inbound_answer_config',enable_international_dncs='$enable_international_dncs',web_loader_phone_strip='$web_loader_phone_strip',manual_dial_phone_strip='$manual_dial_phone_strip',daily_call_count_limit='$daily_call_count_limit',allow_shared_dial='$allow_shared_dial',agent_search_method='$agent_search_method',phone_defaults_container='$phone_defaults_container',qc_claim_limit='$qc_claim_limit',qc_expire_days='$qc_expire_days',two_factor_auth_hours='$two_factor_auth_hours',two_factor_container='$two_factor_container',agent_hidden_sound='$agent_hidden_sound',agent_hidden_sound_volume='$agent_hidden_sound_volume',agent_hidden_sound_seconds='$agent_hidden_sound_seconds',agent_screen_timer='$agent_screen_timer',call_limit_24hour='$call_limit_24hour',allowed_sip_stacks='$allowed_sip_stacks',agent_hide_hangup='$agent_hide_hangup',allow_web_debug='$allow_web_debug',max_logged_in_agents='$max_logged_in_agents',user_codes_admin='$user_codes_admin',login_kickall='$login_kickall',abandon_check_queue='$abandon_check_queue',agent_notifications='$agent_notifications',demographic_quotas='$demographic_quotas',log_latency_gaps='$log_latency_gaps',inbound_credits='$inbound_credits',weekday_resets='$weekday_resets',two_factor_auth_agent_hours='$two_factor_auth_agent_hours',hopper_hold_inserts='$hopper_hold_inserts',coldstorage_server_ip='$coldstorage_server_ip',coldstorage_dbname='$coldstorage_dbname',coldstorage_login='$coldstorage_login',coldstorage_pass='$coldstorage_pass',coldstorage_port='$coldstorage_port',enhanced_agent_monitoring='$enhanced_agent_monitoring',agent_hide_dial_fail='$agent_hide_dial_fail',agent_man_dial_filter='$agent_man_dial_filter',agent_3way_dial_filter='$agent_3way_dial_filter',stereo_recording='$stereo_recording',recording_dtmf_detection='$recording_dtmf_detection',recording_dtmf_muting='$recording_dtmf_muting',stereo_parallel_recording='$stereo_parallel_recording',db_crashed_tables_check='$db_crashed_tables_check'$custom_dialplanSQL;"; $rslt=mysql_to_mysqli($stmt, $link); $update_main_rows=mysqli_affected_rows($link); if ($DB) {echo "$update_main_rows|$stmt|\n";} @@ -44478,7 +44483,7 @@ function ajax_logout_now() $ALLagent_count = $rowx[2]; } - $stmt="SELECT version,install_date,use_non_latin,webroot_writable,enable_queuemetrics_logging,queuemetrics_server_ip,queuemetrics_dbname,queuemetrics_login,queuemetrics_pass,queuemetrics_url,queuemetrics_log_id,queuemetrics_eq_prepend,vicidial_agent_disable,allow_sipsak_messages,admin_home_url,enable_agc_xfer_log,db_schema_version,auto_user_add_value,timeclock_end_of_day,timeclock_last_reset_date,vdc_header_date_format,vdc_customer_date_format,vdc_header_phone_format,vdc_agent_api_active,qc_last_pull_time,enable_vtiger_integration,vtiger_server_ip,vtiger_dbname,vtiger_login,vtiger_pass,vtiger_url,qc_features_active,outbound_autodial_active,outbound_calls_per_second,enable_tts_integration,agentonly_callback_campaign_lock,sounds_central_control_active,sounds_web_server,sounds_web_directory,active_voicemail_server,auto_dial_limit,user_territories_active,allow_custom_dialplan,db_schema_update_date,enable_second_webform,default_webphone,default_external_server_ip,webphone_url,enable_agc_dispo_log,custom_dialplan_entry,queuemetrics_loginout,callcard_enabled,queuemetrics_callstatus,default_codecs,admin_web_directory,label_title,label_first_name,label_middle_initial,label_last_name,label_address1,label_address2,label_address3,label_city,label_state,label_province,label_postal_code,label_vendor_lead_code,label_gender,label_phone_number,label_phone_code,label_alt_phone,label_security_phrase,label_email,label_comments,custom_fields_enabled,slave_db_server,reports_use_slave_db,webphone_systemkey,first_login_trigger,default_phone_registration_password,default_phone_login_password,default_server_password,admin_modify_refresh,nocache_admin,generate_cross_server_exten,queuemetrics_addmember_enabled,queuemetrics_dispo_pause,label_hide_field_logs,queuemetrics_pe_phone_append,test_campaign_calls,agents_calls_reset,default_voicemail_timezone,default_local_gmt,noanswer_log,alt_log_server_ip,alt_log_dbname,alt_log_login,alt_log_pass,tables_use_alt_log_db,did_agent_log,campaign_cid_areacodes_enabled,pllb_grouping_limit,did_ra_extensions_enabled,expanded_list_stats,contacts_enabled,call_menu_qualify_enabled,admin_list_counts,allow_voicemail_greeting,svn_revision,queuemetrics_socket,queuemetrics_socket_url,enhanced_disconnect_logging,allow_emails,level_8_disable_add,pass_hash_enabled,pass_key,pass_cost,disable_auto_dial,queuemetrics_record_hold,country_code_list_stats,reload_timestamp,queuemetrics_pause_type,frozen_server_call_clear,callback_time_24hour,allow_chats,chat_url,chat_timeout,enable_languages,language_method,meetme_enter_login_filename,meetme_enter_leave3way_filename,enable_did_entry_list_id,enable_third_webform,agent_debug_logging,default_language,agent_whisper_enabled,user_hide_realtime_enabled,usacan_phone_dialcode_fix,cache_carrier_stats_realtime,oldest_logs_date,log_recording_access,report_default_format,alt_ivr_logging,default_phone_code,admin_row_click,admin_screen_colors,ofcom_uk_drop_calc,agent_screen_colors,script_remove_js,manual_auto_next,user_new_lead_limit,agent_xfer_park_3way,rec_prompt_count,agent_soundboards,web_loader_phone_length,agent_script,agent_chat_screen_colors,enable_auto_reports,enable_pause_code_limits,enable_drop_lists,allow_ip_lists,system_ip_blacklist,agent_push_events,agent_push_url,hide_inactive_lists,allow_manage_active_lists,expired_lists_inactive,did_system_filter,anyone_callback_inactive_lists,enable_gdpr_download_deletion,source_id_display,agent_logout_link,manual_dial_validation,mute_recordings,user_admin_redirect,list_status_modification_confirmation,sip_event_logging,call_quota_lead_ranking,enable_second_script,enable_first_webform,recording_buttons,opensips_cid_name,require_password_length,user_account_emails,outbound_cid_any,entries_per_page,browser_call_alerts,queuemetrics_pausereason,inbound_answer_config,enable_international_dncs,web_loader_phone_strip,manual_dial_phone_strip,daily_call_count_limit,allow_shared_dial,agent_search_method,phone_defaults_container,qc_claim_limit,qc_expire_days,two_factor_auth_hours,two_factor_container,agent_hidden_sound,agent_hidden_sound_volume,agent_hidden_sound_seconds,agent_screen_timer,label_lead_id,label_list_id,label_entry_date,label_gmt_offset_now,label_source_id,label_called_since_last_reset,label_status,label_user,label_date_of_birth,label_country_code,label_last_local_call_time,label_called_count,label_rank,label_owner,label_entry_list_id,call_limit_24hour,allowed_sip_stacks,agent_hide_hangup,allow_web_debug,max_logged_in_agents,user_codes_admin,login_kickall,abandon_check_queue,agent_notifications,demographic_quotas,log_latency_gaps,inbound_credits,weekday_resets,two_factor_auth_agent_hours,highest_lead_id,hopper_hold_inserts,coldstorage_server_ip,coldstorage_dbname,coldstorage_login,coldstorage_pass,coldstorage_port,enhanced_agent_monitoring,agent_hide_dial_fail,agent_man_dial_filter,agent_3way_dial_filter,stereo_recording,recording_dtmf_detection,recording_dtmf_muting,stereo_parallel_recording from system_settings;"; + $stmt="SELECT version,install_date,use_non_latin,webroot_writable,enable_queuemetrics_logging,queuemetrics_server_ip,queuemetrics_dbname,queuemetrics_login,queuemetrics_pass,queuemetrics_url,queuemetrics_log_id,queuemetrics_eq_prepend,vicidial_agent_disable,allow_sipsak_messages,admin_home_url,enable_agc_xfer_log,db_schema_version,auto_user_add_value,timeclock_end_of_day,timeclock_last_reset_date,vdc_header_date_format,vdc_customer_date_format,vdc_header_phone_format,vdc_agent_api_active,qc_last_pull_time,enable_vtiger_integration,vtiger_server_ip,vtiger_dbname,vtiger_login,vtiger_pass,vtiger_url,qc_features_active,outbound_autodial_active,outbound_calls_per_second,enable_tts_integration,agentonly_callback_campaign_lock,sounds_central_control_active,sounds_web_server,sounds_web_directory,active_voicemail_server,auto_dial_limit,user_territories_active,allow_custom_dialplan,db_schema_update_date,enable_second_webform,default_webphone,default_external_server_ip,webphone_url,enable_agc_dispo_log,custom_dialplan_entry,queuemetrics_loginout,callcard_enabled,queuemetrics_callstatus,default_codecs,admin_web_directory,label_title,label_first_name,label_middle_initial,label_last_name,label_address1,label_address2,label_address3,label_city,label_state,label_province,label_postal_code,label_vendor_lead_code,label_gender,label_phone_number,label_phone_code,label_alt_phone,label_security_phrase,label_email,label_comments,custom_fields_enabled,slave_db_server,reports_use_slave_db,webphone_systemkey,first_login_trigger,default_phone_registration_password,default_phone_login_password,default_server_password,admin_modify_refresh,nocache_admin,generate_cross_server_exten,queuemetrics_addmember_enabled,queuemetrics_dispo_pause,label_hide_field_logs,queuemetrics_pe_phone_append,test_campaign_calls,agents_calls_reset,default_voicemail_timezone,default_local_gmt,noanswer_log,alt_log_server_ip,alt_log_dbname,alt_log_login,alt_log_pass,tables_use_alt_log_db,did_agent_log,campaign_cid_areacodes_enabled,pllb_grouping_limit,did_ra_extensions_enabled,expanded_list_stats,contacts_enabled,call_menu_qualify_enabled,admin_list_counts,allow_voicemail_greeting,svn_revision,queuemetrics_socket,queuemetrics_socket_url,enhanced_disconnect_logging,allow_emails,level_8_disable_add,pass_hash_enabled,pass_key,pass_cost,disable_auto_dial,queuemetrics_record_hold,country_code_list_stats,reload_timestamp,queuemetrics_pause_type,frozen_server_call_clear,callback_time_24hour,allow_chats,chat_url,chat_timeout,enable_languages,language_method,meetme_enter_login_filename,meetme_enter_leave3way_filename,enable_did_entry_list_id,enable_third_webform,agent_debug_logging,default_language,agent_whisper_enabled,user_hide_realtime_enabled,usacan_phone_dialcode_fix,cache_carrier_stats_realtime,oldest_logs_date,log_recording_access,report_default_format,alt_ivr_logging,default_phone_code,admin_row_click,admin_screen_colors,ofcom_uk_drop_calc,agent_screen_colors,script_remove_js,manual_auto_next,user_new_lead_limit,agent_xfer_park_3way,rec_prompt_count,agent_soundboards,web_loader_phone_length,agent_script,agent_chat_screen_colors,enable_auto_reports,enable_pause_code_limits,enable_drop_lists,allow_ip_lists,system_ip_blacklist,agent_push_events,agent_push_url,hide_inactive_lists,allow_manage_active_lists,expired_lists_inactive,did_system_filter,anyone_callback_inactive_lists,enable_gdpr_download_deletion,source_id_display,agent_logout_link,manual_dial_validation,mute_recordings,user_admin_redirect,list_status_modification_confirmation,sip_event_logging,call_quota_lead_ranking,enable_second_script,enable_first_webform,recording_buttons,opensips_cid_name,require_password_length,user_account_emails,outbound_cid_any,entries_per_page,browser_call_alerts,queuemetrics_pausereason,inbound_answer_config,enable_international_dncs,web_loader_phone_strip,manual_dial_phone_strip,daily_call_count_limit,allow_shared_dial,agent_search_method,phone_defaults_container,qc_claim_limit,qc_expire_days,two_factor_auth_hours,two_factor_container,agent_hidden_sound,agent_hidden_sound_volume,agent_hidden_sound_seconds,agent_screen_timer,label_lead_id,label_list_id,label_entry_date,label_gmt_offset_now,label_source_id,label_called_since_last_reset,label_status,label_user,label_date_of_birth,label_country_code,label_last_local_call_time,label_called_count,label_rank,label_owner,label_entry_list_id,call_limit_24hour,allowed_sip_stacks,agent_hide_hangup,allow_web_debug,max_logged_in_agents,user_codes_admin,login_kickall,abandon_check_queue,agent_notifications,demographic_quotas,log_latency_gaps,inbound_credits,weekday_resets,two_factor_auth_agent_hours,highest_lead_id,hopper_hold_inserts,coldstorage_server_ip,coldstorage_dbname,coldstorage_login,coldstorage_pass,coldstorage_port,enhanced_agent_monitoring,agent_hide_dial_fail,agent_man_dial_filter,agent_3way_dial_filter,stereo_recording,recording_dtmf_detection,recording_dtmf_muting,stereo_parallel_recording,db_crashed_tables_check from system_settings;"; $rslt=mysql_to_mysqli($stmt, $link); $row=mysqli_fetch_row($rslt); $version = $row[0]; @@ -44729,6 +44734,7 @@ function ajax_logout_now() $recording_dtmf_detection = $row[245]; $recording_dtmf_muting = $row[246]; $stereo_parallel_recording = $row[247]; + $db_crashed_tables_check = $row[248]; if ($pass_hash_enabled > 0) {$pass_hash_enabled = 'ENABLED';} else {$pass_hash_enabled = 'DISABLED';} @@ -44797,6 +44803,7 @@ function ajax_logout_now() echo "\n"; echo "$NWB#settings-agent_disable$NWE\n"; echo "\n"; + echo "\n"; echo "\n"; + $crashed_rows .= "\n"; + $crashed_rows .= "\n"; + $crashed_rows .= "\n"; + $crashed_rows .= "\n"; + $crashed_rows .= "\n"; + $o++; $o_ct++; + } + + if ($o > 0) + { + echo "


"._QXZ("Your Database has crashed tables. Please contact your system administrator.")."

\n"; + } + else + { + echo "


"._QXZ("There are no Database crashed tables detected on your system currently")."

\n"; + } + + echo "
# "._QXZ("LEAD").""._QXZ("DATE/TIME")." "._QXZ("SECONDS")."   "._QXZ("RECID").""._QXZ("FILENAME").""._QXZ("LOCATION").""._QXZ("TSR")."
# "._QXZ("LEAD").""._QXZ("DATE/TIME")." "._QXZ("SECONDS")."   "._QXZ("RECID").""._QXZ("FILENAME").""._QXZ("LOCATION").""._QXZ("TSR")."
$stereo_flag   $dtmf_detected   $dtmf_muting  
"._QXZ("Clear Frozen Calls").": $NWB#settings-frozen_server_call_clear$NWE
"._QXZ("Auto Check DB Crashed Tables").": $NWB#settings-db_crashed_tables_check$NWE
"._QXZ("Allowed SIP Stacks").":
$o_ct$rowx[0]$rowx[1]$rowx[2]
\n"; + echo ""; + + echo "
"._QXZ("CRASHED DATABASE TABLES")."\n"; + echo "
\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "$crashed_rows"; + echo "
# "._QXZ("Table Name").""._QXZ("First Crash Date-Time").""._QXZ("Last Crash Check Date-Time")."
\n"; + } +##### END CRASHED DATABASE TABLES display page ##### + echo "
\n"; echo "\n"; diff --git a/www/vicidial/admin_header.php b/www/vicidial/admin_header.php index d8940f305..56035b8f6 100644 --- a/www/vicidial/admin_header.php +++ b/www/vicidial/admin_header.php @@ -1,7 +1,7 @@ LICENSE: AGPLv2 +# Copyright (C) 2025 Matt Florell LICENSE: AGPLv2 # # CHANGES @@ -98,6 +98,7 @@ # 221230-2230 - Added Postal Codes Cities submenu # 230118-0835 - Added Agent Call Hangup Change function # 230613-1835 - Added VIDPROMPTSPECIAL options +# 251025-1953 - Added crashed DB table display # $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'; @@ -2756,6 +2757,22 @@ function dynamic_call_action_link(field,route) { echo " | "._QXZ("Change language").""; } +if ($LOGuser_level >= 9) + { + $stmt = "SELECT count(*) FROM crashed_tables;"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($DB) {echo "$stmt\n";} + $crashes_ct = mysqli_num_rows($rslt); + if ($crashes_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $crashed_tables = $row[0]; + } + if ($crashed_tables > 0) + { + echo "           "._QXZ("Crashed DB Tables").": $crashed_tables   "; + } + } ?>   diff --git a/www/vicidial/help_documentation.txt b/www/vicidial/help_documentation.txt index 5da6db243..2b6aa5a34 100644 --- a/www/vicidial/help_documentation.txt +++ b/www/vicidial/help_documentation.txt @@ -1,4 +1,4 @@ -# version: 20251017123601 +# version: 20251025191301 users-user User ID 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-. users-pass Password This field is where you put the users password. Must be at least 2 characters in length, unless the User Password Minimum Length system setting is enabled, which will require a longer password. 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. users-force_change_password Force Change Password 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. @@ -1124,6 +1124,7 @@ settings-default_language Default Language This is the language that the ag settings-webroot_writable Webroot Writable This setting allows you to define whether temp files and authentication files should be placed in the webroot on your web server. Default is 1. settings-agent_disable Agent Disable Display This field is used to select when to show an agent notices when their session has been disabled by the system, a manager action or by an external measure. The NOT_ACTIVE setting will disable the message on the agents screen. The LIVE_AGENT setting will only display the disabled message when the agents auto_calls record has been removed, such as during a force logout or emergency logout. Default is ALL. settings-frozen_server_call_clear Clear Frozen Calls This option can enable the ability for the general Reports page and the optional AST_timecheck.pl script to clear out the auto_calls entries for a frozen server so they do not affect call routing. Default is 0 for disabled. +settings-db_crashed_tables_check Auto Check DB Crashed Tables If this option is set to 1 or higher, the system will automatically check to see if any of the database tables are in a crashed state. If a crashed table is found, then a message will appear at the top of the Admin Web screens for level-9 users stating that there are crashed DB tables, you can then click on that message for details on which tables are crashed. If this option is set to -1-, then the check will happen only once a day at the Timeclock-End-of-Day time. If this is set to -2-, then the check will happen once every hour. If this is set to -3-, then the check will happen every 10 minutes. If this is set to -4-, then the check will happen every minute. Default is 1. settings-allowed_sip_stacks Allowed SIP Stacks This option will determine which SIP modules in Asterisk will be allowed to be configured on your dialers for Phones and Carriers. The standard up until Asterisk 16 is -SIP- which uses the older chan_sip module. The newer PJSIP can be used with Asterisk 16 and higher, if configured properly. Default is SIP. settings-allow_sipsak_messages Allow SIPSAK Messages If set to 1, this will allow the sipsak phones table setting to work if the phone is set to the SIP protocol. The server will send messages to the SIP phone to display on the phone display when logged into the system. This feature only works with SIP phones and requires sipsak application to be installed on the web server that the agent is logged into. Default is 0. settings-vdc_agent_api_active Agent API Active If set to 1, this will allow the Agent API interface to function. Default is 0. From 002c2456810d3f7226d6a7f99f30ede014de0d0d Mon Sep 17 00:00:00 2001 From: Logan Cook <2997336+MWG-Logan@users.noreply.github.com> Date: Wed, 5 Nov 2025 15:51:57 -0500 Subject: [PATCH 11/12] fix: Restore original ViciDial license (AGPLv2) --- LICENSE | 1197 +++++++++++++++++++++++++------------------------------ 1 file changed, 538 insertions(+), 659 deletions(-) diff --git a/LICENSE b/LICENSE index 0ad25db4b..9f7ce1a9e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,661 +1,540 @@ - GNU AFFERO GENERAL PUBLIC LICENSE - Version 3, 19 November 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU Affero General Public License is a free, copyleft license for -software and other kinds of works, specifically designed to ensure -cooperation with the community in the case of network server software. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -our General Public Licenses are intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - Developers that use our General Public Licenses protect your rights -with two steps: (1) assert copyright on the software, and (2) offer -you this License which gives you legal permission to copy, distribute -and/or modify the software. - - A secondary benefit of defending all users' freedom is that -improvements made in alternate versions of the program, if they -receive widespread use, become available for other developers to -incorporate. Many developers of free software are heartened and -encouraged by the resulting cooperation. However, in the case of -software used on network servers, this result may fail to come about. -The GNU General Public License permits making a modified version and -letting the public access it on a server without ever releasing its -source code to the public. - - The GNU Affero General Public License is designed specifically to -ensure that, in such cases, the modified source code becomes available -to the community. It requires the operator of a network server to -provide the source code of the modified version running there to the -users of that server. Therefore, public use of a modified version, on -a publicly accessible server, gives the public access to the source -code of the modified version. - - An older license, called the Affero General Public License and -published by Affero, was designed to accomplish similar goals. This is -a different license, not a version of the Affero GPL, but Affero has -released a new version of the Affero GPL which permits relicensing under -this license. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU Affero General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Remote Network Interaction; Use with the GNU General Public License. - - Notwithstanding any other provision of this License, if you modify the -Program, your modified version must prominently offer all users -interacting with it remotely through a computer network (if your version -supports such interaction) an opportunity to receive the Corresponding -Source of your version by providing access to the Corresponding Source -from a network server at no charge, through some standard or customary -means of facilitating copying of software. This Corresponding Source -shall include the Corresponding Source for any work covered by version 3 -of the GNU General Public License that is incorporated pursuant to the -following paragraph. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the work with which it is combined will remain governed by version -3 of the GNU General Public License. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU Affero General Public License from time to time. Such new versions -will be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU Affero General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU Affero General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU Affero General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +AFFERO GENERAL PUBLIC LICENSE (AGPLv2) + +Version 2, November 2007 + +Copyright © 2007 Affero Inc. +510 Third Street - Suite 225, San Francisco, CA 94107, USA + +This is version 2 of the Affero General Public License. It gives each licensee +permission to distribute the Program or a work based on the Program (as defined +in version 1 of the Affero GPL) under the GNU Affero General Public License, +version 2 or any later version. + +This license is a modified version of the GNU General Public License copyright +(C) 1989, 1991 Free Software Foundation, Inc. made with their permission. +Section 2(d) has been added to cover use of software over a computer network. + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +Preamble + +The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the Affero General Public License is intended to +guarantee your freedom to share and change free software--to make sure the +software is free for all its users. This Public License applies to most of +Affero's software and to any other program whose authors commit to using it. +(Some other Affero software is covered by the GNU Library General Public License +instead.) You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. This +General Public License is designed to make sure that you have the freedom to +distribute copies of free software (and charge for this service if you wish), +that you receive source code or can get it if you want it, that you can change +the software or use pieces of it in new free programs; and that you know you can +do these things. + +To protect your rights, we need to make restrictions that forbid anyone to deny +you these rights or to ask you to surrender the rights. These restrictions +translate to certain responsibilities for you if you distribute copies of the +software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or for a +fee, you must give the recipients all the rights that you have. You must make +sure that they, too, receive or can get the source code. And you must show them +these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) offer +you this license which gives you legal permission to copy, distribute and/or +modify the software. + +Also, for each author's protection and ours, we want to make certain that +everyone understands that there is no warranty for this free software. If the +software is modified by someone else and passed on, we want its recipients to +know that what they have is not the original, so that any problems introduced by +others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We wish +to avoid the danger that redistributors of a free program will individually +obtain patent licenses, in effect making the program proprietary. To prevent +this, we have made it clear that any patent must be licensed for everyone's free +use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification +follow. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a notice +placed by the copyright holder saying it may be distributed under the terms of +this Affero General Public License. The "Program", below, refers to any such +program or work, and a "work based on the Program" means either the Program or +any derivative work under copyright law: that is to say, a work containing the +Program or a portion of it, either verbatim or with modifications and/or +translated into another language. (Hereinafter, translation is included without +limitation in the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not covered by +this License; they are outside its scope. The act of running the Program is not +restricted, and the output from the Program is covered only if its contents +constitute a work based on the Program (independent of having been made by +running the Program). Whether that is true depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's source code as +you receive it, in any medium, provided that you conspicuously and appropriately +publish on each copy an appropriate copyright notice and disclaimer of warranty; +keep intact all the notices that refer to this License and to the absence of any +warranty; and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and you may at +your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, thus +forming a work based on the Program, and copy and distribute such modifications +or work under the terms of Section 1 above, provided that you also meet all of +these conditions: + +* a) You must cause the modified files to carry prominent notices stating that +you changed the files and the date of any change. + +* b) You must cause any work that you distribute or publish, that in whole or in +part contains or is derived from the Program or any part thereof, to be licensed +as a whole at no charge to all third parties under the terms of this License. + +* c) If the modified program normally reads commands interactively when run, you +must cause it, when started running for such interactive use in the most +ordinary way, to print or display an announcement including an appropriate +copyright notice and a notice that there is no warranty (or else, saying that +you provide a warranty) and that users may redistribute the program under these +conditions, and telling the user how to view a copy of this License. (Exception: +if the Program itself is interactive but does not normally print such an +announcement, your work based on the Program is not required to print an +announcement.) + +* d) If the Program as you received it is intended to interact with users +through a computer network and if, in the version you received, any user +interacting with the Program was given the opportunity to request transmission +to that user of the Program's complete source code, you must not remove that +facility from your modified version of the Program or work based on the Program, +and must offer an equivalent opportunity for all users interacting with your +Program through a computer network to request immediate transmission by HTTP of +the complete source code of your modified version or other derivative work. + +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Program, and can be reasonably +considered independent and separate works in themselves, then this License, and +its terms, do not apply to those sections when you distribute them as separate +works. But when you distribute the same sections as part of a whole which is a +work based on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the entire whole, +and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise the +right to control the distribution of derivative or collective works based on the +Program. + +In addition, mere aggregation of another work not based on the Program with the +Program (or with a work based on the Program) on a volume of a storage or +distribution medium does not bring the other work under the scope of this +License. + +3. You may copy and distribute the Program (or a work based on it, under Section +2) in object code or executable form under the terms of Sections 1 and 2 above +provided that you also do one of the following: + +* a) Accompany it with the complete corresponding machine-readable source code, +which must be distributed under the terms of Sections 1 and 2 above on a medium +customarily used for software interchange; or, + +* b) Accompany it with a written offer, valid for at least three years, to give +any third party, for a charge no more than your cost of physically performing +source distribution, a complete machine-readable copy of the corresponding +source code, to be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange; or, + +* c) Accompany it with the information you received as to the offer to +distribute corresponding source code. (This alternative is allowed only for +noncommercial distribution and only if you received the program in object code +or executable form with such an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for making +modifications to it. For an executable work, complete source code means all the +source code for all modules it contains, plus any associated interface +definition files, plus the scripts used to control compilation and installation +of the executable. However, as a special exception, the source code distributed +need not include anything that is normally distributed (in either source or +binary form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component itself +accompanies the executable. + +If distribution of executable or object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the source code +from the same place counts as distribution of the source code, even though third +parties are not compelled to copy the source along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program except as +expressly provided under this License. Any attempt otherwise to copy, modify, +sublicense or distribute the Program is void, and will automatically terminate +your rights under this License. However, parties who have received copies, or +rights, from you under this License will not have their licenses terminated so +long as such parties remain in full compliance. + +5. You are not required to accept this License, since you have not signed it. +However, nothing else grants you permission to modify or distribute the Program +or its derivative works. These actions are prohibited by law if you do not +accept this License. Therefore, by modifying or distributing the Program (or any +work based on the Program), you indicate your acceptance of this License to do +so, and all its terms and conditions for copying, distributing or modifying the +Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the Program), +the recipient automatically receives a license from the original licensor to +copy, distribute or modify the Program subject to these terms and conditions. +You may not impose any further restrictions on the recipients' exercise of the +rights granted herein. You are not responsible for enforcing compliance by third +parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent infringement +or for any other reason (not limited to patent issues), conditions are imposed +on you (whether by court order, agreement or otherwise) that contradict the +conditions of this License, they do not excuse you from the conditions of this +License. If you cannot distribute so as to satisfy simultaneously your +obligations under this License and any other pertinent obligations, then as a +consequence you may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by all those +who receive copies directly or indirectly through you, then the only way you +could satisfy both it and this License would be to refrain entirely from +distribution of the Program. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply and the +section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents or +other property right claims or to contest validity of any such claims; this +section has the sole purpose of protecting the integrity of the free software +distribution system, which is implemented by public license practices. Many +people have made generous contributions to the wide range of software +distributed through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing to +distribute software through any other system and a licensee cannot impose that +choice. + +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain +countries either by patents or by copyrighted interfaces, the original copyright +holder who places the Program under this License may add an explicit +geographical distribution limitation excluding those countries, so that +distribution is permitted only in or among countries not thus excluded. In such +case, this License incorporates the limitation as if written in the body of this +License. + +9. Affero Inc. may publish revised and/or new versions of the Affero General +Public License from time to time. Such new versions will be similar in spirit to +the present version, but may differ in detail to address new problems or +concerns. + +Each version is given a distinguishing version number. If the Program specifies +a version number of this License which applies to it and "any later version", +you have the option of following the terms and conditions either of that version +or of any later version published by Affero, Inc. If the Program does not +specify a version number of this License, you may choose any version ever +published by Affero, Inc. + +You may also choose to redistribute modified versions of this program under any +version of the Free Software Foundation's GNU General Public License version 2 +or higher, so long as that version of the GNU GPL includes terms and conditions +substantially equivalent to those of this license. +10. If you wish to incorporate parts of the Program into other free programs +whose distribution conditions are different, write to the author to ask for +permission. For software which is copyrighted by Affero, Inc., write to us; we +sometimes make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and of +promoting the sharing and reuse of software generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE +PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED +IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS +IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT +NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published - by the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If your software can interact with users remotely through a computer -network, you should also make sure that it provides a way for users to -get its source. For example, if your program is a web application, its -interface could display a "Source" link that leads users to an archive -of the code. There are many ways you could offer source, and different -solutions will be better for different programs; see section 13 for the -specific requirements. - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU AGPL, see -. +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL +ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE +PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, +SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY +TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF +THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER +PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + + + +The above AGPLv2 license is what the entire VICIdial codebase is released under. + + + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + + + +We have also incorporated another small open-soruce project's code into VICIdial +, pure-knob, that is under the Apache 2.0 License, which is shown below: + +Andre Plötze, © 2018 + + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + + + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + + + +We have also incorporated another small open-soruce project's code into VICIdial +, Chart.js, that is under the MIT License, which is shown below: + + + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + +The MIT License (MIT) + +Copyright (c) 2018 Chart.js Contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. From cca254dc73c3d840ffec808097878ddf8e15ac18 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Mon, 10 Nov 2025 16:45:44 -0500 Subject: [PATCH 12/12] Fix variable name typo in AST_timeonVDADall.php URL parameter (#9) * Initial plan * Fix variable name typo: change $ingroupQ to $ingroupQS Co-authored-by: MWG-Logan <2997336+MWG-Logan@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: MWG-Logan <2997336+MWG-Logan@users.noreply.github.com> --- www/vicidial/AST_timeonVDADall.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/vicidial/AST_timeonVDADall.php b/www/vicidial/AST_timeonVDADall.php index 7d8513303..be5d64258 100644 --- a/www/vicidial/AST_timeonVDADall.php +++ b/www/vicidial/AST_timeonVDADall.php @@ -1526,7 +1526,7 @@ function hide_ingroup_info() \n"; - echo"\n"; + echo"\n"; echo "$report_name: $group\n"; $short_header=1;