Added Per-User Per-In-Group daily call limits.

git-svn-id: svn://192.168.202.10@3805 3d104415-ff17-0410-8863-d5cf3c621b8a
This commit is contained in:
mattf
2024-02-21 02:49:58 +00:00
parent 832ee75112
commit caad79b868
20 changed files with 1379 additions and 93 deletions
+6
View File
@@ -847,6 +847,12 @@ OTHER CHANGES:
Non-Agent API function. Checks for duplicate phone against both the
phone_number and alt_phone fields.
241. Added State Descriptions Banner campaign and in-group settings, allowing
for a custom description and color banner to appear on the agent screen
on a per-campaign and per-in-group basis.
242. Added Per-User Per-In-Group daily call limits.
+61 -6
View File
@@ -82,7 +82,7 @@
#exten => _99909*.,2,AGI(agi-VDAD_ALL_inbound.agi)
#exten => _99909*.,3,Hangup
#
# Copyright (C) 2023 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
# Copyright (C) 2024 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
#
# changes:
# 70828-0924 - First Build
@@ -257,6 +257,7 @@
# 230612-2044 - Added second_alert_container, second_alert_only and second_alert_trigger TIMEOUT options
# 230810-2006 - Added third_alert_trigger features
# 231026-0917 - Fix for rare fronter/closer logging issue
# 240219-1527 - Added daily_limit in-group user parameter
#
$script = 'agi-VDAD_ALL_inbound.agi';
@@ -3042,7 +3043,7 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override
if (length($qp_groupWAIT_aco)<2)
{$qp_groupWAIT_aco="''";}
### Get list of users that should take higher priority inbound calls first
$stmtA = "SELECT distinct user from vicidial_live_inbound_agents where group_id IN($qp_groupWAIT_aco);";
$stmtA = "SELECT distinct user from vicidial_live_inbound_agents where group_id IN($qp_groupWAIT_aco) and ( (daily_limit = '-1') or (daily_limit > calls_today) );";
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
$sthArows=$sthA->rows;
@@ -3071,7 +3072,7 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override
@GRADEuser=@MT;
@GRADEgrade=@MT;
@userGRADEarray=@MT;
$stmtA = "SELECT vicidial_live_agents.user,vicidial_live_inbound_agents.group_grade,vicidial_live_agents.campaign_grade from vicidial_live_agents, vicidial_live_inbound_agents WHERE vicidial_live_agents.user=vicidial_live_inbound_agents.user and status IN('CLOSER','READY') and lead_id<1 $server_onlySQL $ADUfindSQL and vicidial_live_inbound_agents.group_id='$channel_group' and last_update_time > '$BDtsSQLdate' and vicidial_live_agents.user NOT IN($ring_no_answer_agents$vlia_users) and ring_callerid='' $qp_groupWAIT_camp_SQL $AGENTDIRECT_higherSQL limit 1000;";
$stmtA = "SELECT vicidial_live_agents.user,vicidial_live_inbound_agents.group_grade,vicidial_live_agents.campaign_grade from vicidial_live_agents, vicidial_live_inbound_agents WHERE vicidial_live_agents.user=vicidial_live_inbound_agents.user and status IN('CLOSER','READY') and lead_id<1 $server_onlySQL $ADUfindSQL and vicidial_live_inbound_agents.group_id='$channel_group' and last_update_time > '$BDtsSQLdate' and vicidial_live_agents.user NOT IN($ring_no_answer_agents$vlia_users) and ring_callerid='' and ( (vicidial_live_inbound_agents.daily_limit = '-1') or (vicidial_live_inbound_agents.daily_limit > vicidial_live_inbound_agents.calls_today) ) $qp_groupWAIT_camp_SQL $AGENTDIRECT_higherSQL limit 1000;";
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
$sthArows=$sthA->rows;
@@ -3135,7 +3136,7 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override
### END grade random next-agent-call routing ###
else
{
$stmtA = "SELECT vicidial_live_agents.conf_exten,vicidial_live_agents.user,vicidial_live_agents.extension,vicidial_live_agents.server_ip,vicidial_live_inbound_agents.group_weight,ra_user,vicidial_live_agents.campaign_id,on_hook_agent,on_hook_ring_time,vicidial_live_inbound_agents.group_grade,vicidial_live_agents.campaign_grade from vicidial_live_agents, vicidial_live_inbound_agents WHERE vicidial_live_agents.user=vicidial_live_inbound_agents.user and status IN('CLOSER','READY') and lead_id<1 $server_onlySQL $ADUfindSQL and vicidial_live_inbound_agents.group_id='$channel_group' and last_update_time > '$BDtsSQLdate' and vicidial_live_agents.user NOT IN($ring_no_answer_agents$vlia_users) and ring_callerid='' $qp_groupWAIT_camp_SQL $AGENTDIRECT_higherSQL $agent_call_order limit 1;";
$stmtA = "SELECT vicidial_live_agents.conf_exten,vicidial_live_agents.user,vicidial_live_agents.extension,vicidial_live_agents.server_ip,vicidial_live_inbound_agents.group_weight,ra_user,vicidial_live_agents.campaign_id,on_hook_agent,on_hook_ring_time,vicidial_live_inbound_agents.group_grade,vicidial_live_agents.campaign_grade from vicidial_live_agents, vicidial_live_inbound_agents WHERE vicidial_live_agents.user=vicidial_live_inbound_agents.user and status IN('CLOSER','READY') and lead_id<1 $server_onlySQL $ADUfindSQL and vicidial_live_inbound_agents.group_id='$channel_group' and last_update_time > '$BDtsSQLdate' and vicidial_live_agents.user NOT IN($ring_no_answer_agents$vlia_users) and ring_callerid='' and ( (vicidial_live_inbound_agents.daily_limit = '-1') or (vicidial_live_inbound_agents.daily_limit > vicidial_live_inbound_agents.calls_today) ) $qp_groupWAIT_camp_SQL $AGENTDIRECT_higherSQL $agent_call_order limit 1;";
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
$sthArows=$sthA->rows;
@@ -4135,7 +4136,7 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override
### update calls_today for vicidial_live_inbound_agents ###
$calls_today_filteredSQL='';
$stmtA = "SELECT calls_today,calls_today_filtered from vicidial_inbound_group_agents WHERE user='$VDADuser' and group_id='$channel_group';";
$stmtA = "SELECT calls_today,calls_today_filtered,daily_limit from vicidial_inbound_group_agents WHERE user='$VDADuser' and group_id='$channel_group';";
if ($AGILOG) {$agi_string = "|$stmtA|"; &agi_output;}
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
@@ -4147,6 +4148,7 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override
$calls_today = $aryA[0];
$calls_today_filtered = $aryA[1];
$calls_today++;
$daily_limit = $aryA[2];
# if ($VU_max_inbound_filter_enabled > 0)
# {
# $VU_max_inbound_filter_ingroupsTEST = ",$VU_max_inbound_filter_ingroups,";
@@ -4190,6 +4192,8 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override
### Check for inbound max calls daily limit
$max_inbound_triggered=0;
$inbound_credits_triggered=0;
$user_ingroup_limit_triggered=0;
if ( ($VU_max_inbound_calls > 0) || ($CP_max_inbound_calls > 0) )
{
$max_inbound_calls = $CP_max_inbound_calls;
@@ -4273,6 +4277,7 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override
### Check for inbound calls credits available, if feature enabled
if ( ($VU_inbound_credits < 1) && ($VU_inbound_credits >= 0) && ($SSinbound_credits > 0) )
{
$inbound_credits_triggered++;
$outbound_autodial='0';
$stmtA = "SELECT outbound_autodial,closer_campaigns FROM vicidial_live_agents where user='$VDADuser';";
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
@@ -4326,7 +4331,57 @@ while ( ($drop_timer <= $DROP_TIME) && ($wait_in_queue > 0) && ($MCdrop_override
if ($AGILOG) {$agi_string = "-- INBOUND CALLS CREDITS TRIGGER: |$VU_inbound_credits|$VDADuser|$callerid|$max_inbound_calls_outcome|$closer_campaigns|$ADcloser_campaignsARYct|"; &agi_output;}
}
}
##### END check for user max inbound calls #####
# check for per-user & per-in-group daily limits, if max-inbound and inbound-credits not triggered
if ( ($calls_today >= $daily_limit) && ($daily_limit >= 0) && ($max_inbound_triggered < 1) && ($inbound_credits_triggered < 1) )
{
$user_ingroup_limit_triggered++;
$outbound_autodial='0';
$stmtA = "SELECT outbound_autodial,closer_campaigns FROM vicidial_live_agents where user='$VDADuser';";
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
$sthArowsVLA=$sthA->rows;
$dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$sthArows; &mysql_error_logging;
if ($sthArowsVLA > 0)
{
@aryA = $sthA->fetchrow_array;
if ($aryA[0] =~ /Y/)
{$outbound_autodial = '1';}
$closer_campaigns = $aryA[1];
}
$closer_campaigns =~ s/^ | -$//gi;
@ADcloser_campaignsARY = split(/ /,$closer_campaigns);
$ADcloser_campaignsARYct = scalar(@ADcloser_campaignsARY);
$ADc=0;
$ADcloser_campaigns='';
while ($ADc < $ADcloser_campaignsARYct)
{
if ($ADcloser_campaignsARY[$ADc] !~ /^$channel_group$/i)
{$ADcloser_campaigns .= "$ADcloser_campaignsARY[$ADc] ";}
$ADc++;
}
if (length($ADcloser_campaigns) > 3)
{$ADcloser_campaigns = " ".$ADcloser_campaigns."-";}
else
{$ADcloser_campaigns = " -";}
$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='$VDADuser'";
$stmtB = "DELETE FROM vicidial_live_inbound_agents where user='$VDADuser' and group_id='$channel_group';";
$affected_rows = $dbhA->do($stmtA);
$dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging;
$affected_rows = $dbhA->do($stmtB);
$dbhP=$dbhA; $mysql_count='02XXX'; $MEL_aff_rows=$affected_rows; &mysql_error_logging;
$SQL_log = "$stmtA|$stmtB";
$SQL_log =~ s/'|%//gi;
$stmtC = "INSERT INTO vicidial_admin_log set event_date=NOW(), user='$VDADuser', ip_address='$VARserver_ip', event_section='USERS', event_type='MODIFY', record_id='$VDADuser', event_code='DAILY LIMIT MODIFY USER', event_sql='$SQL_log', event_notes='|$calls_today >= $daily_limit|$VDADuser|$channel_group|$callerid|IC|$max_inbound_calls_outcome|$closer_campaigns|$ADcloser_campaignsARYct|';";
$affected_rows = $dbhA->do($stmtC);
$dbhP=$dbhA; $mysql_count='02204'; $MEL_aff_rows=$affected_rows; &mysql_error_logging;
if ($AGILOG) {$agi_string = "-- INBOUND AGENT DAILY LIMIT TRIGGER: |$calls_today >= $daily_limit|$VDADuser|$channel_group|$callerid|$max_inbound_calls_outcome|$closer_campaigns|$ADcloser_campaignsARYct|"; &agi_output;}
}
##### END check for user max inbound calls, inbound credits and user/in-group daily limits #####
&trigger_transfer_process;
+6 -5
View File
@@ -6,7 +6,7 @@
# adjusts the auto_dial_level for vicidial adaptive-predictive campaigns.
# gather call stats for campaigns and in-groups
#
# Copyright (C) 2023 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
# Copyright (C) 2024 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
#
# CHANGELOG
# 60823-1302 - First build from AST_VDhopper.pl
@@ -60,9 +60,10 @@
# 212207-2207 - Added IQNANQ to drop SQL calculation queries
# 211122-1457 - Fix for logging bug and modification to drop percentage calculation
# 230309-1009 - Added abandon_check_queue feature
# 240219-1514 - Added vicidial_live_inbound_agents.daily_limit parameter
#
$build='230309-1009';
$build='240219-1514';
# constants
$DB=0; # Debug flag, set to 0 for no debug messages, On an active system this will generate lots of lines of output per minute
$US='__';
@@ -1040,7 +1041,7 @@ while ($master_loop < $CLIloops)
if (length($qp_groupWAIT_aco)<2)
{$qp_groupWAIT_aco="''";}
### Get list of users that should take higher priority inbound calls first
$stmtA = "SELECT distinct user from vicidial_live_inbound_agents where group_id IN($qp_groupWAIT_aco);";
$stmtA = "SELECT distinct user from vicidial_live_inbound_agents where group_id IN($qp_groupWAIT_aco) and ( (daily_limit = '-1') or (daily_limit > calls_today) );";
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
$sthArows=$sthA->rows;
@@ -1068,7 +1069,7 @@ while ($master_loop < $CLIloops)
@GRADEuser=@MT;
@GRADEgrade=@MT;
@userGRADEarray=@MT;
$stmtA = "SELECT vicidial_live_agents.user,vicidial_live_inbound_agents.group_grade,vicidial_live_agents.campaign_grade from vicidial_live_agents, vicidial_live_inbound_agents WHERE vicidial_live_agents.user=vicidial_live_inbound_agents.user and status IN('CLOSER','READY') and lead_id<1 $ADUfindSQL and vicidial_live_inbound_agents.group_id='$ICBQgroup_id[$r]' and last_update_time > '$BDtsSQLdate' and vicidial_live_agents.user NOT IN($vlia_users) and ring_callerid='' $qp_groupWAIT_camp_SQL limit 1000;";
$stmtA = "SELECT vicidial_live_agents.user,vicidial_live_inbound_agents.group_grade,vicidial_live_agents.campaign_grade from vicidial_live_agents, vicidial_live_inbound_agents WHERE vicidial_live_agents.user=vicidial_live_inbound_agents.user and status IN('CLOSER','READY') and lead_id<1 $ADUfindSQL and vicidial_live_inbound_agents.group_id='$ICBQgroup_id[$r]' and last_update_time > '$BDtsSQLdate' and vicidial_live_agents.user NOT IN($vlia_users) and ring_callerid='' and ( (vicidial_live_inbound_agents.daily_limit = '-1') or (vicidial_live_inbound_agents.daily_limit > vicidial_live_inbound_agents.calls_today) ) $qp_groupWAIT_camp_SQL limit 1000;";
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
$sthArows=$sthA->rows;
@@ -1134,7 +1135,7 @@ while ($master_loop < $CLIloops)
{
$sthArowsFA=0;
$VDADuser='';
$stmtA = "SELECT vicidial_live_agents.conf_exten,vicidial_live_agents.user,vicidial_live_agents.extension,vicidial_live_agents.server_ip,vicidial_live_inbound_agents.group_weight,ra_user,vicidial_live_agents.campaign_id,on_hook_agent,on_hook_ring_time,vicidial_live_inbound_agents.group_grade,vicidial_live_agents.campaign_grade from vicidial_live_agents, vicidial_live_inbound_agents WHERE vicidial_live_agents.user=vicidial_live_inbound_agents.user and status IN('CLOSER','READY') and lead_id<1 $ADUfindSQL and vicidial_live_inbound_agents.group_id='$ICBQgroup_id[$r]' and last_update_time > '$BDtsSQLdate' and vicidial_live_agents.user NOT IN($routed_user_list$vlia_users) and ring_callerid='' $qp_groupWAIT_camp_SQL $agent_call_order limit 1;";
$stmtA = "SELECT vicidial_live_agents.conf_exten,vicidial_live_agents.user,vicidial_live_agents.extension,vicidial_live_agents.server_ip,vicidial_live_inbound_agents.group_weight,ra_user,vicidial_live_agents.campaign_id,on_hook_agent,on_hook_ring_time,vicidial_live_inbound_agents.group_grade,vicidial_live_agents.campaign_grade from vicidial_live_agents, vicidial_live_inbound_agents WHERE vicidial_live_agents.user=vicidial_live_inbound_agents.user and status IN('CLOSER','READY') and lead_id<1 $ADUfindSQL and vicidial_live_inbound_agents.group_id='$ICBQgroup_id[$r]' and last_update_time > '$BDtsSQLdate' and vicidial_live_agents.user NOT IN($routed_user_list$vlia_users) and ring_callerid='' and ( (vicidial_live_inbound_agents.daily_limit = '-1') or (vicidial_live_inbound_agents.daily_limit > vicidial_live_inbound_agents.calls_today) ) $qp_groupWAIT_camp_SQL $agent_call_order limit 1;";
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
$sthArowsFA=$sthA->rows;
+4 -3
View File
@@ -25,7 +25,7 @@
# It is good practice to keep this program running by placing the associated
# KEEPALIVE script running every minute to ensure this program is always running
#
# Copyright (C) 2023 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
# Copyright (C) 2024 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
#
# CHANGELOG:
# 50125-1201 - Changed dial timeout to 120 seconds from 180 seconds
@@ -157,9 +157,10 @@
# 230223-0826 - Fix for enhanced_disconnect_logging=3 issue
# 231116-0911 - Added hopper_hold_inserts option
# 231129-0901 - Added vicidial_phone_number_call_daily_counts updates/inserts
# 240219-1524 - Added daily_limit in-group parameter
#
$build='231129-0901';
$build='240219-1524';
$script='AST_VDauto_dial';
### begin parsing run-time options ###
if (length($ARGV[0])>1)
@@ -1334,7 +1335,7 @@ while($one_day_interval > 0)
{
$DBIPinbound_no_agents_no_dial_trigger[$user_CIPct]=1;
$DBIPinand_users[$user_CIPct]='';
$stmtA = "SELECT distinct(user) FROM vicidial_live_inbound_agents where group_id IN('$DBIPinand_container_entry[$user_CIPct]');";
$stmtA = "SELECT distinct(user) FROM vicidial_live_inbound_agents where group_id IN('$DBIPinand_container_entry[$user_CIPct]') and ( (daily_limit = '-1') or (daily_limit > calls_today) );";
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
$sthArows=$sthA->rows;
+6 -3
View File
@@ -11,7 +11,7 @@
# agents that should appear to be logged in so that the calls can be transferred
# out to them properly.
#
# Copyright (C) 2023 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
# Copyright (C) 2024 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
#
# CHANGELOG:
# 50215-0954 - First version of script
@@ -55,6 +55,7 @@
# 190716-1628 - Added code for Call Quotas
# 191017-1909 - Added code for filtered maximum inbound calls
# 230523-0825 - Added User inbound_credits feature
# 240219-1518 - Added daily_limit inbound option
#
### begin parsing run-time options ###
@@ -922,9 +923,10 @@ while($one_day_interval > 0)
$TEMPagentWEIGHT=0;
$TEMPagentCALLS=0;
$TEMPexistsVLIA=0;
$TEMPagentLIMIT=-1;
# grab the group weight and calls today of the agent in each in-group
$DBuser_level[$h]='1';
$stmtA = "SELECT group_weight,calls_today,group_grade,calls_today_filtered FROM vicidial_inbound_group_agents where user='$DBuser_start[$h]' and group_id='$TEMPingroups[$s]';";
$stmtA = "SELECT group_weight,calls_today,group_grade,calls_today_filtered,daily_limit FROM vicidial_inbound_group_agents where user='$DBuser_start[$h]' and group_id='$TEMPingroups[$s]';";
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
$sthArowsVIGA=$sthA->rows;
@@ -935,6 +937,7 @@ while($one_day_interval > 0)
$TEMPagentCALLS = $aryA[1];
$TEMPagentGRADE = $aryA[2];
$TEMPagentCALLSftl = $aryA[3];
$TEMPagentLIMIT = $aryA[4];
}
$sthA->finish();
@@ -955,7 +958,7 @@ while($one_day_interval > 0)
if ($TEMPexistsVLIA < 1)
{
$stmtA = "INSERT IGNORE INTO vicidial_live_inbound_agents SET user='$DBremote_user[$h]', group_id='$TEMPingroups[$s]', group_weight='$TEMPagentWEIGHT', calls_today='$TEMPagentCALLS', calls_today_filtered='$TEMPagentCALLSftl', last_call_time='$SQLdate', last_call_time_filtered='$SQLdate', last_call_finish='$SQLdate', group_grade='$TEMPagentGRADE' ON DUPLICATE KEY UPDATE group_weight='$TEMPagentWEIGHT',group_grade='$TEMPagentGRADE';";
$stmtA = "INSERT IGNORE INTO vicidial_live_inbound_agents SET user='$DBremote_user[$h]', group_id='$TEMPingroups[$s]', group_weight='$TEMPagentWEIGHT', calls_today='$TEMPagentCALLS', calls_today_filtered='$TEMPagentCALLSftl', last_call_time='$SQLdate', last_call_time_filtered='$SQLdate', last_call_finish='$SQLdate', group_grade='$TEMPagentGRADE', daily_limit='$TEMPagentLIMIT' ON DUPLICATE KEY UPDATE group_weight='$TEMPagentWEIGHT',group_grade='$TEMPagentGRADE';";
$affected_rows = $dbhA->do($stmtA);
if ( ($DBX) && ($affected_rows > 0) ) {print STDERR "$DBremote_user[$h] VLIA UPDATE: $affected_rows|$TEMPingroups[$s]|$TEMPagentWEIGHT\n";}
+68 -1
View File
@@ -9,7 +9,7 @@
# !!!!!!!! IMPORTANT !!!!!!!!!!!!!!!!!!
# THIS SCRIPT SHOULD ONLY BE RUN ON ONE SERVER ON YOUR CLUSTER
#
# Copyright (C) 2023 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
# Copyright (C) 2024 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
#
# CHANGES
# 60717-1214 - changed to DBI by Marin Blu
@@ -34,6 +34,7 @@
# 230414-1622 - Added --reset-stuck-leads option
# 231118-1256 - Added clearing of old vicidial_3way_press_live records
# 231228-1901 - Added optimizing of vicidial_3way_press_multi records
# 240219-0811 - Added optimizing of server_live_... tables
#
$session_flush=0;
@@ -207,6 +208,17 @@ if ($Smin < 10) {$Smin = "0$Smin";}
if ($Ssec < 10) {$Ssec = "0$Ssec";}
$SQLdate_NEG_sixhour="$Syear-$Smon-$Smday $Shour:$Smin:$Ssec";
($Dsec,$Dmin,$Dhour,$Dmday,$Dmon,$Dyear,$Dwday,$Dyday,$Disdst) = localtime(time() - 43200);
$Dyear = ($Dyear + 1900);
$Dyy = $Dyear; $Dyy =~ s/^..//gi;
$Dmon++;
if ($Dmon < 10) {$Dmon = "0$Dmon";}
if ($Dmday < 10) {$Dmday = "0$Dmday";}
if ($Dhour < 10) {$Dhour = "0$Dhour";}
if ($Dmin < 10) {$Dmin = "0$Dmin";}
if ($Dsec < 10) {$Dsec = "0$Dsec";}
$DQLdate_NEG_twelvehour="$Dyear-$Dmon-$Dmday $Dhour:$Dmin:$Dsec";
($Tsec,$Tmin,$Thour,$Tmday,$Tmon,$Tyear,$Twday,$Tyday,$Tisdst) = localtime(time() - 600);
$Tyear = ($Tyear + 1900);
$Tyy = $Tyear; $Tyy =~ s/^..//gi;
@@ -626,6 +638,61 @@ if (!$T)
if (!$Q) {print " - OPTIMIZE vicidial_3way_press_multi \n";}
$stmtA = "DELETE from server_live_stats where update_time < '$DQLdate_NEG_twelvehour';";
if($DB){print STDERR "\n|$stmtA|\n";}
if (!$T) { $affected_rows = $dbhA->do($stmtA);}
if (!$Q) {print " - server_live_stats flush: $affected_rows rows\n";}
$stmtA = "DELETE from server_live_drives where update_time < '$DQLdate_NEG_twelvehour';";
if($DB){print STDERR "\n|$stmtA|\n";}
if (!$T) { $affected_rows = $dbhA->do($stmtA);}
if (!$Q) {print " - server_live_drives flush: $affected_rows rows\n";}
$stmtA = "DELETE from server_live_partitions where update_time < '$DQLdate_NEG_twelvehour';";
if($DB){print STDERR "\n|$stmtA|\n";}
if (!$T) { $affected_rows = $dbhA->do($stmtA);}
if (!$Q) {print " - server_live_partitions flush: $affected_rows rows\n";}
$stmtA = "OPTIMIZE table server_live_stats;";
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 server_live_stats \n";}
$stmtA = "OPTIMIZE table server_live_drives;";
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 server_live_drives \n";}
$stmtA = "OPTIMIZE table server_live_partitions;";
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 server_live_partitions \n";}
if ($session_flush > 0)
{
$stmtA = "DELETE from vicidial_sessions_recent where call_date < '$SQLdate_NEG_1hour';";
+850
View File
@@ -0,0 +1,850 @@
#!/usr/bin/perl
#
# SERVER_stats.pl version 2.14
#
# This script gathers several system metrics and stores them in the MySQL database
#
# Copyright (C) 2024 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
#
# CHANGES
# 240217-2226 - First build
#
$start_epoch = time();
# constants
$DB=0; # Debug flag, set to 0 for no debug messages, lots of output
$DBX=0;
$run_check=1; # concurrency check
$iodelay=60;
### 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 " [--test] = test\n";
print " [--debug] = verbose debug messages\n";
print " [--debugX] = Extra-verbose debug messages\n";
print " [--help] = this screen\n";
print "\n";
exit;
}
else
{
if ($args =~ /--debug/i)
{
$DB=1; # Debug flag
print "\n----- DEBUGGING ENABLED -----\n\n";
}
if ($args =~ /--debugX/i)
{
$DBX=1;
print "\n----- SUPER-DUPER DEBUGGING -----\n\n";
}
if ($args =~ /--test/i)
{
$TEST=1;
$T=1;
}
}
}
### end parsing run-time options ###
# default path to astguiclient configuration file:
$PATHconf = '/etc/astguiclient.conf';
open(conf, "$PATHconf") || die "can't open $PATHconf: $!\n";
@conf = <conf>;
close(conf);
$i=0;
foreach(@conf)
{
$line = $conf[$i];
$line =~ s/ |>|\n|\r|\t|\#.*|;.*//gi;
if ($line =~ /^PATHhome/) {$PATHhome = $line; $PATHhome =~ s/.*=//gi;}
if ($line =~ /^PATHlogs/) {$PATHlogs = $line; $PATHlogs =~ s/.*=//gi;}
if ($line =~ /^PATHagi/) {$PATHagi = $line; $PATHagi =~ s/.*=//gi;}
if ($line =~ /^PATHweb/) {$PATHweb = $line; $PATHweb =~ s/.*=//gi;}
if ($line =~ /^PATHsounds/) {$PATHsounds = $line; $PATHsounds =~ s/.*=//gi;}
if ($line =~ /^PATHmonitor/) {$PATHmonitor = $line; $PATHmonitor =~ s/.*=//gi;}
if ($line =~ /^VARserver_ip/) {$VARserver_ip = $line; $VARserver_ip =~ s/.*=//gi;}
if ($line =~ /^VARDB_server/) {$VARDB_server = $line; $VARDB_server =~ s/.*=//gi;}
if ($line =~ /^VARDB_database/) {$VARDB_database = $line; $VARDB_database =~ s/.*=//gi;}
if ($line =~ /^VARDB_user/) {$VARDB_user = $line; $VARDB_user =~ s/.*=//gi;}
if ($line =~ /^VARDB_pass/) {$VARDB_pass = $line; $VARDB_pass =~ s/.*=//gi;}
if ($line =~ /^VARDB_custom_user/) {$VARDB_custom_user = $line; $VARDB_custom_user =~ s/.*=//gi;}
if ($line =~ /^VARDB_custom_pass/) {$VARDB_custom_pass = $line; $VARDB_custom_pass =~ s/.*=//gi;}
if ($line =~ /^VARDB_port/) {$VARDB_port = $line; $VARDB_port =~ s/.*=//gi;}
$i++;
}
# Customized Variables
$server_ip = $VARserver_ip; # Asterisk server IP
### find df binary (partition usage)
$dfbin = '';
if ( -e ('/bin/df')) {$dfbin = '/bin/df';}
else
{
if ( -e ('/usr/bin/df')) {$dfbin = '/usr/bin/df';}
else
{
if ( -e ('/usr/local/bin/df')) {$dfbin = '/usr/local/bin/df';}
else
{
print "Can't find df binary! Exiting...\n";
exit;
}
}
}
### find iostat binary (device IO usage)
$iostatbin = '';
if ( -e ('/bin/iostat')) {$iostatbin = '/bin/iostat';}
else
{
if ( -e ('/usr/bin/iostat')) {$iostatbin = '/usr/bin/iostat';}
else
{
if ( -e ('/usr/local/bin/iostat')) {$iostatbin = '/usr/local/bin/iostat';}
else
{
print "Can't find iostat binary! Exiting...\n";
exit;
}
}
}
### find nproc binary (CPU count)
$nprocbin = '';
if ( -e ('/bin/nproc')) {$nprocbin = '/bin/nproc';}
else
{
if ( -e ('/usr/bin/nproc')) {$nprocbin = '/usr/bin/nproc';}
else
{
if ( -e ('/usr/local/bin/nproc')) {$nprocbin = '/usr/local/bin/nproc';}
else
{
print "Can't find nproc binary! Exiting...\n";
exit;
}
}
}
### find uptime binary
if ( -e ('/bin/uptime')) {$uptimebin = '/bin/uptime';}
else
{
if ( -e ('/usr/bin/uptime')) {$uptimebin = '/usr/bin/uptime';}
else
{
if ( -e ('/usr/local/bin/uptime')) {$uptimebin = '/usr/local/bin/uptime';}
else
{
print "Can't find uptime binary!\n";
}
}
}
### find hostname binary (line and word count)
$hostnamebin = '';
if ( -e ('/bin/hostname')) {$hostnamebin = '/bin/hostname';}
else
{
if ( -e ('/usr/bin/hostname')) {$hostnamebin = '/usr/bin/hostname';}
else
{
if ( -e ('/usr/local/bin/hostname')) {$hostnamebin = '/usr/local/bin/hostname';}
else
{
if ($DB > 0) {print "Can't find hostname binary, not going to gather database info.\n";}
}
}
}
### find mysqladmin binary (database admin)
$mysqladminbin = '';
if ( -e ('/bin/mysqladmin')) {$mysqladminbin = '/bin/mysqladmin';}
else
{
if ( -e ('/usr/bin/mysqladmin')) {$mysqladminbin = '/usr/bin/mysqladmin';}
else
{
if ( -e ('/usr/local/bin/mysqladmin')) {$mysqladminbin = '/usr/local/bin/mysqladmin';}
else
{
if ($DB > 0) {print "Can't find mysqladmin binary, not going to gather database info.\n";}
}
}
}
### find wc binary (line and word count)
$wcbin = '';
if ( -e ('/bin/wc')) {$wcbin = '/bin/wc';}
else
{
if ( -e ('/usr/bin/wc')) {$wcbin = '/usr/bin/wc';}
else
{
if ( -e ('/usr/local/bin/wc')) {$wcbin = '/usr/local/bin/wc';}
else
{
if ($DB > 0) {print "Can't find wc binary, not going to gather database info.\n";}
}
}
}
if (!$VARDB_port) {$VARDB_port='3306';}
&get_time_now;
#use lib './lib', '../lib';
use Time::HiRes ('gettimeofday','usleep','sleep'); # necessary to have perl sleep command of less than one second
use DBI;
use Switch;
use POSIX;
use Scalar::Util qw(looks_like_number);
$dbhA = DBI->connect("DBI:mysql:$VARDB_database:$VARDB_server:$VARDB_port", "$VARDB_user", "$VARDB_pass")
or die "Couldn't connect to database: " . DBI->errstr;
### concurrency check (SCREEN uses script path, so check for more than 2 entries)
if ($run_check > 0)
{
my $grepout = `/bin/ps ax | grep $0 | grep -v grep | grep -v '/bin/sh'`;
my $grepnum=0;
$grepnum++ while ($grepout =~ m/\n/g);
if ($grepnum > 2)
{
if ($DB) {print "I am not alone! Another $0 is running! Exiting...\n";}
$event_string = "I am not alone! Another $0 is running! Exiting...";
&event_logger($SYSLOG,$event_string);
exit;
}
}
$event_string="STARTING NEW STATS GRAB";
event_logger($SYSLOG,$event_string);
# insert/update server_live_stats record in the DB
$stmtA = "INSERT INTO server_live_stats set update_time=NOW(), server_ip='$server_ip' ON DUPLICATE KEY UPDATE update_time=NOW();";
if($DB){print STDERR "\n$stmtA\n";}
$dbhA->do($stmtA);
$affected_rows = $dbhA->do($stmtA);
# gather server stats
$MYSQLuptime=0; $MYSQLconnections=0; $MYSQLqueries=0;
$hostname = get_hostname();
$cpu_count = get_cpu_count();
( $loadavg_1, $loadavg_5, $loadavg_15 ) = get_cpu_load();
( $mem_total, $mem_used, $mem_free ) = get_mem_usage();
$num_processes = get_num_processes();
$system_uptime = get_uptime();
( $cpu_user_percent,
$cpu_idle_percent,
$cpu_iowait_percent,
$cpu_sys_percent,
$cpu_vm_percent,
$user_diff,
$nice_diff,
$system_diff,
$idle_diff,
$iowait_diff,
$irq_diff,
$softirq_diff,
$steal_diff,
$guest_diff,
$guest_nice_diff ) = get_cpu_percent();
( $reads, $writes ) = get_disk_rw();
my ( $asterisk_channels_total, $asterisk_agents_total ) = get_asterisk_data($dbhA,$server_ip);
if (length($mysqladminbin) > 2)
{
$mysql_data_begin = time();
( $MYSQLuptime, $MYSQLconnections, $MYSQLqueries ) = get_mysqlstatus();
$MYSQLqueriesOLD = $MYSQLqueries;
}
# insert/update server_live_stats record in the DB
$stmtA = "UPDATE server_live_stats set update_time=NOW(),server_name='$hostname',cpu_count='$cpu_count',loadavg_1='$loadavg_1',loadavg_5='$loadavg_5',loadavg_15='$loadavg_15',freeram='$mem_free',usedram='$mem_used',processes='$num_processes',system_uptime='$system_uptime',asterisk_channels_total='$asterisk_channels_total',asterisk_agents_total='$asterisk_agents_total',mysql_uptime='$MYSQLuptime',mysql_connections='$MYSQLconnections' WHERE server_ip='$server_ip';";
if($DB){print STDERR "\n$stmtA\n";}
$dbhA->do($stmtA);
$affected_rows = $dbhA->do($stmtA);
my $disk_usage = get_disk_space($dbhA,$server_ip);
my $storage_devices = get_disk_io($dbhA,$server_ip);
( $reads, $writes ) = get_disk_rw();
( $cpu_user_percent,
$cpu_idle_percent,
$cpu_iowait_percent,
$cpu_sys_percent,
$cpu_vm_percent,
$user_diff,
$nice_diff,
$system_diff,
$idle_diff,
$iowait_diff,
$irq_diff,
$softirq_diff,
$steal_diff,
$guest_diff,
$guest_nice_diff ) = get_cpu_percent();
$read_write_cpu_SQL = "disk_reads='$reads',disk_writes='$writes',cpu_user_percent='$cpu_user_percent',cpu_sys_percent='$cpu_sys_percent',cpu_idle_percent='$cpu_idle_percent',cpu_iowait_percent='$cpu_iowait_percent',cpu_vm_percent='$cpu_vm_percent'";
if (length($mysqladminbin) > 2)
{
$mysql_data_end = time();
( $MYSQLuptime, $MYSQLconnections, $MYSQLqueries ) = get_mysqlstatus();
$MYSQLqueriesTEMP = ($MYSQLqueries - $MYSQLqueriesOLD);
$mysql_data_sec = ($mysql_data_end - $mysql_data_begin);
$mysql_queries_per_second = sprintf("%.0f", ($MYSQLqueriesTEMP / $mysql_data_sec));
if($DB){print STDERR "\n$MYSQLqueriesTEMP = ($MYSQLqueries - $MYSQLqueriesOLD)\n";}
# update server_live_stats record in the DB
$stmtA = "UPDATE server_live_stats set update_time=NOW(),mysql_uptime='$MYSQLuptime',mysql_connections='$MYSQLconnections',mysql_queries_per_second='$mysql_queries_per_second',$read_write_cpu_SQL WHERE server_ip='$server_ip';";
if($DB){print STDERR "\n$stmtA\n";}
$dbhA->do($stmtA);
$affected_rows = $dbhA->do($stmtA);
}
else
{
# update server_live_stats record in the DB
$stmtA = "UPDATE server_live_stats set update_time=NOW(),$read_write_cpu_SQL WHERE server_ip='$server_ip';";
if($DB){print STDERR "\n$stmtA\n";}
$dbhA->do($stmtA);
$affected_rows = $dbhA->do($stmtA);
}
$event_string='FINISHING UP|';
event_logger($SYSLOG,$event_string);
$sthA->finish();
$dbhA->disconnect();
$end_epoch = time();
$run_time = ($end_epoch - $start_epoch);
if($DB){print "DONE... Exiting... Goodbye... See you later! runtime: $run_time seconds \n";}
exit;
#################### SUBROUTINES #########################
sub event_logger
{
my ($SYSLOG,$event_string) = @_;
if ($SYSLOG)
{
### open the log file for writing ###
open(Lout, ">>$PATHlogs/server_stats.$action_log_date")
|| die "Can't open $PATHlogs/server_stats.$action_log_date: $!\n";
print Lout "$now_date|$event_string|\n";
close(Lout);
}
$event_string='';
}
sub get_time_now #get the current date and time and epoch for logging call lengths and datetimes
{
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$year = ($year + 1900);
$mon++;
if ($mon < 10) {$mon = "0$mon";}
if ($mday < 10) {$mday = "0$mday";}
if ($hour < 10) {$hour = "0$hour";}
if ($min < 10) {$min = "0$min";}
if ($sec < 10) {$sec = "0$sec";}
$now_date_epoch = time();
$now_date = "$year-$mon-$mday $hour:$min:$sec";
$action_log_date = "$year-$mon-$mday";
}
sub print_now
{
my $string = shift;
# get the current time in microseconds
my ( $now_sec, $now_micro_sec ) = gettimeofday();
# figure out how many micro seconds since epoch
my $now_micro_epoch = $now_sec * 1000000;
$now_micro_epoch = $now_micro_epoch + $now_micro_sec;
print "\n$string|$now_micro_epoch\n\n";
}
sub get_cpu_percent
{
# stat file in proc
$stat = '/proc/stat';
# read it
open( FH , "<$stat" );
@lines = <FH>;
close( FH );
# get the various times spent doing stuff ( $cpu is useless )
($cpu, $user, $nice, $system, $idle, $iowait, $irq, $softirq, $steal, $guest, $guest_nice ) = split( ' ', $lines[0] );
# total the different catagories of time
$cpu_user = $user + $nice;
$cpu_idle = $idle;
$cpu_iowait = $iowait;
$cpu_sys = $system + $irq + $softirq;
$cpu_vm = $steal + $guest + $guest_nice;
# check if we have previous values
if ( defined ( $prev_user ) )
{
# get the differential from last time
$cpu_user_diff = $cpu_user - $prev_cpu_user;
$cpu_idle_diff = $cpu_idle - $prev_cpu_idle;
$cpu_iowait_diff = $cpu_iowait - $prev_cpu_iowait;
$cpu_sys_diff = $cpu_sys - $prev_cpu_sys;
$cpu_vm_diff = $cpu_vm - $prev_cpu_vm;
$user_diff = $user - $prev_user;
$nice_diff = $nice - $prev_nice;
$system_diff = $system - $prev_system;
$idle_diff = $idle - $prev_idle;
$iowait_diff = $iowait - $prev_iowait;
$irq_diff = $irq - $prev_irq;
$softirq_diff = $softirq - $prev_softirq;
$steal_diff = $steal - $prev_steal;
$guest_diff = $guest - $prev_guest;
$guest_nice_diff = $guest_nice - $prev_guest_nice;
# total the differentials
$cpu_total_diff = $cpu_user_diff + $cpu_idle_diff + $cpu_sys_diff + $cpu_vm_diff + $cpu_iowait_diff;
$cpu_user_percent = sprintf("%.2f", (( $cpu_user_diff / $cpu_total_diff ) * 100 ));
$cpu_idle_percent = sprintf("%.2f", (( $cpu_idle_diff / $cpu_total_diff ) * 100 ));
$cpu_iowait_percent = sprintf("%.2f", (( $cpu_iowait_diff / $cpu_total_diff ) * 100 ));
$cpu_sys_percent = sprintf("%.2f", (( $cpu_sys_diff / $cpu_total_diff ) * 100 ));
$cpu_vm_percent = sprintf("%.2f", (( $cpu_vm_diff / $cpu_total_diff ) * 100 ));
}
else
{
# first time runnings so there are no previous values.
# all we can do is base it off the system totals since boot.
$cpu_total = $cpu_user + $cpu_idle + $cpu_sys + $cpu_vm;
$cpu_user_percent = sprintf("%.2f", (( $cpu_user / $cpu_total ) * 100 ));
$cpu_idle_percent = sprintf("%.2f", (( $cpu_idle / $cpu_total ) * 100 ));
$cpu_iowait_percent = sprintf("%.2f", (( $cpu_iowait / $cpu_total ) * 100 ));
$cpu_sys_percent = sprintf("%.2f", (( $cpu_sys / $cpu_total ) * 100 ));
$cpu_vm_percent = sprintf("%.2f", (( $cpu_vm / $cpu_total ) * 100 ));
}
# store the values for the next call
$prev_user = $user;
$prev_nice = $nice;
$prev_system = $system;
$prev_idle = $idle;
$prev_iowait = $iowait;
$prev_irq = $irq;
$prev_softirq = $softirq;
$prev_steal = $steal;
$prev_guest = $guest;
$prev_guest_nice = $guest_nice;
$prev_cpu_user = $cpu_user;
$prev_cpu_idle = $cpu_idle;
$prev_cpu_iowait = $cpu_iowait;
$prev_cpu_sys = $cpu_sys;
$prev_cpu_vm = $cpu_vm;
return (
$cpu_user_percent,
$cpu_idle_percent,
$cpu_iowait_percent,
$cpu_sys_percent,
$cpu_vm_percent,
$user_diff,
$nice_diff,
$system_diff,
$idle_diff,
$iowait_diff,
$irq_diff,
$softirq_diff,
$steal_diff,
$guest_diff,
$guest_nice_diff
);
}
sub get_cpu_load
{
$lavg = '/proc/loadavg';
open( FH , "<$lavg" );
@lines = <FH>;
close( FH );
@loadavg_data = split(' ',$lines[0]);
$loadavg_1 = $loadavg_data[0];
$loadavg_5 = $loadavg_data[1];
$loadavg_15 = $loadavg_data[2];
return ( $loadavg_1, $loadavg_5, $loadavg_15 );
}
sub get_mem_usage
{
$meminfo = '/proc/meminfo';
open( FH , "<$meminfo" );
@lines = <FH>;
close( FH );
$mem_total = $lines[0];
$mem_total =~ s/MemTotal: *//g;
$mem_free = $lines[1];
$mem_free =~ s/MemFree: *//g;
$mem_used = $mem_total - $mem_free;
$mem_used = floor( $mem_used / 1024 );
$mem_total = floor( $mem_total / 1024 );
$mem_free = floor( $mem_free / 1023 );
return ( $mem_total, $mem_used, $mem_free );
}
sub get_disk_space
{
my ($dbhA,$server_ip) = @_;
# df -B 1048576 -x nfs -x cifs -x sshfs -x ftpfs
#Filesystem 1M-blocks Used Available Use% Mounted on
#devtmpfs 4 0 4 0% /dev
#tmpfs 64395 1 64395 1% /dev/shm
#tmpfs 25758 42 25717 1% /run
#tmpfs 4 0 4 0% /sys/fs/cgroup
#/dev/md0 933742 99229 787010 12% /
#tmpfs 6144 0 6144 0% /var/spool/asterisk/monitor
#/dev/md2 937801 363804 531254 41% /srv/mysql
#tmpfs 12879 0 12879 0% /run/user/0
@serverDISK = `$dfbin -B 1048576 -x nfs -x cifs -x sshfs -x ftpfs`;
$ct=0;
$ct_PCT=0;
$disk_usage = '';
foreach(@serverDISK)
{
if ($serverDISK[$ct] =~ /(\d+\%)/)
{
$usage = $1;
$usage =~ s/\%//gi;
$disk_usage .= "$ct_PCT $usage|";
$partition_path = $serverDISK[$ct];
$partition_path =~ s/.*\% |\r|\n|\t//gi;
$partition_filesystem = $serverDISK[$ct];
$partition_filesystem =~ s/ .*|\r|\n|\t//gi;
$disk_data = $serverDISK[$ct];
$disk_data =~ s/\s+/ /gi;
@disk_dataARY = split(/ /,$disk_data);
$mb_used = $disk_dataARY[2];
$mb_available = $disk_dataARY[3];
# insert/update server_live_drives record in the DB
$stmtA = "INSERT INTO server_live_partitions set server_ip='$server_ip',partition_path='$partition_path',update_time=NOW(),partition_order='$ct_PCT',partition_filesystem='$partition_filesystem',use_pct='$usage',mb_used='$mb_used',mb_available='$mb_available' ON DUPLICATE KEY UPDATE update_time=NOW(),partition_order='$ct_PCT',partition_filesystem='$partition_filesystem',use_pct='$usage',mb_used='$mb_used',mb_available='$mb_available';";
if($DB){print STDERR "\n$stmtA\n";}
$dbhA->do($stmtA);
$affected_rows = $dbhA->do($stmtA);
$ct_PCT++;
}
$ct++;
}
return $disk_usage;
}
sub get_disk_io
{
my ($dbhA,$server_ip) = @_;
$ct_DEVICES = -1;
# Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util
# nvme0n1 2.22 23.56 10.10 129.77 0.00 7.24 0.00 23.50 2.13 0.68 0.03 4.55 5.51 0.95 2.45
# @serverDISKio = `$iostatbin -yx 59 1`;
@serverDISKioVERSION = `$iostatbin -V`;
$IOSTATversion = $serverDISKioVERSION[0];
$IOSTATversion =~ s/.*version |\..*//gi;
$IOSTATversion =~ s/\D//gi;
if ($IOSTATversion >= 11)
{
@serverDISKio = `$iostatbin -yx $iodelay 1`;
$ct=0;
$devices_trigger=0;
$ct_DEVICES=0;
$disk_io = '';
foreach(@serverDISKio)
{
if ($serverDISKio[$ct] =~ /^Device/)
{$devices_trigger++;}
else
{
if ( ($devices_trigger > 0) && (length($serverDISKio[$ct]) > 14) )
{
$drive_order[$ct_DEVICES] = $ct_DEVICES;
$drive_device[$ct_DEVICES] = substr($serverDISKio[$ct],0,13);
$read_sec[$ct_DEVICES] = substr($serverDISKio[$ct],13,8);
$write_sec[$ct_DEVICES] = substr($serverDISKio[$ct],21,8);
$kb_read_sec[$ct_DEVICES] = substr($serverDISKio[$ct],29,10);
$kb_write_sec[$ct_DEVICES] = substr($serverDISKio[$ct],39,10);
$util_pct[$ct_DEVICES] = substr($serverDISKio[$ct],129,7);
$drive_device[$ct_DEVICES] =~ s/\s//gi;
$read_sec[$ct_DEVICES] =~ s/\s//gi;
$write_sec[$ct_DEVICES] =~ s/\s//gi;
$kb_read_sec[$ct_DEVICES] =~ s/\s//gi;
$kb_write_sec[$ct_DEVICES] =~ s/\s//gi;
$util_pct[$ct_DEVICES] =~ s/\s//gi;
# insert/update server_live_drives record in the DB
$stmtA = "INSERT INTO server_live_drives set server_ip='$server_ip',drive_device='$drive_device[$ct_DEVICES]',update_time=NOW(),drive_order='$drive_order[$ct_DEVICES]',read_sec='$read_sec[$ct_DEVICES]',write_sec='$write_sec[$ct_DEVICES]',kb_read_sec='$kb_read_sec[$ct_DEVICES]',kb_write_sec='$kb_write_sec[$ct_DEVICES]',util_pct='$util_pct[$ct_DEVICES]' ON DUPLICATE KEY UPDATE update_time=NOW(),drive_order='$drive_order[$ct_DEVICES]',read_sec='$read_sec[$ct_DEVICES]',write_sec='$write_sec[$ct_DEVICES]',kb_read_sec='$kb_read_sec[$ct_DEVICES]',kb_write_sec='$kb_write_sec[$ct_DEVICES]',util_pct='$util_pct[$ct_DEVICES]';";
if($DB){print STDERR "\n$stmtA\n";}
$dbhA->do($stmtA);
$affected_rows = $dbhA->do($stmtA);
$ct_DEVICES++;
}
}
$ct++;
}
}
return $ct_DEVICES;
}
sub get_cpu_count
{
@serverNPROC = `$nprocbin`;
$ct_CPUS = $serverNPROC[0];
$ct_CPUS =~ s/\D//gi;
return $ct_CPUS;
}
sub get_hostname
{
@serverHOSTNAME = `$hostnamebin`;
$hostname = $serverHOSTNAME[0];
$hostname =~ s/\n|\r|\t//gi;
return $hostname;
}
sub get_uptime
{
@sysuptime = `$uptimebin`;
# 18:26:14 up 153 days, 23:59, 4 users, load average: 0.01, 0.01, 0.00
# 10:03am up 123 days 0:10, 1 user, load average: 0.11, 0.05, 0.01
# 10:03am up 3:17, 2 users, load average: 0.41, 0.28, 0.21
if ($DBX) {print "Uptime debug 1: |$sysuptime[0]|\n";}
$sysuptime[0] =~ s/ days, / days /gi;
$sysuptime[0] =~ s/,.*//gi;
$sysuptime[0] =~ s/ / /gi;
$sysuptime[0] =~ s/ / /gi;
$sysuptime[0] =~ s/\r|\n|\t//gi;
@uptimedata = split(/ up /,$sysuptime[0]);
$system_uptime = $uptimedata[1];
return $system_uptime;
}
sub get_num_processes
{
$num_processes = 0;
opendir( DH, '/proc');
while ( readdir( DH ) )
{
if ( looks_like_number( $_ ) ) { $num_processes++; }
}
closedir( DH );
return ($num_processes);
}
sub get_disk_rw
{
$total_reads = 0;
$total_writes = 0;
$diskstats = "/proc/diskstats";
open( FH , "<$diskstats" );
@lines = <FH>;
close( FH );
foreach $line ( @lines )
{
# remove excess white space
$line =~ s/\h+/ /g;
$line =~ s/^\s+|\s+$//g;
# split the line
(
$major,
$minor,
$device,
$reads_completed,
$reads_merged,
$sectors_read,
$time_reading,
$writes_completed,
$writes_merged,
$sectors_written,
$time_writing,
$current_ios,
$ios_time,
$weighted_ios_time
) = split( ' ', $line );
# check if device is a drive or partition or raid
if ( $device !~ /\d/ )
{
$total_reads += $sectors_read;
$total_writes += $sectors_written;
}
}
# check if we previously got the total reads
if ( defined ( $prev_total_reads ) )
{
$reads = $total_reads - $prev_total_reads;
$writes = $total_writes - $prev_total_writes;
}
else
{
# cannot figure out the difference
# if we don't know what it was before
$reads = 0;
$writes = 0;
}
$prev_total_reads = $total_reads;
$prev_total_writes = $total_writes;
return ( $reads, $writes );
}
sub get_asterisk_data
{
my ($dbhA,$server_ip) = @_;
$live_channels=0;
$stmtA = "SELECT count(*) FROM live_channels where server_ip='$server_ip';";
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
@aryA = $sthA->fetchrow_array;
$live_channels = $aryA[0];
if($DB){print STDERR "\n|$live_channels|$stmtA|\n";}
$live_sip_channels=0;
$stmtA = "SELECT count(*) FROM live_sip_channels where server_ip='$server_ip';";
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
@aryA = $sthA->fetchrow_array;
$live_sip_channels = $aryA[0];
if($DB){print STDERR "\n|$live_sip_channels|$stmtA|\n";}
$total_channels = ($live_channels + $live_sip_channels);
$live_agents=0;
$stmtA = "SELECT count(*) FROM vicidial_live_agents where server_ip='$server_ip';";
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
@aryA = $sthA->fetchrow_array;
$live_agents = $aryA[0];
if($DB){print STDERR "\n|$live_agents|$stmtA|\n";}
return ( $total_channels, $live_agents );
}
sub get_mysqlstatus
{
# Uptime: 3848845 Threads: 1 Questions: 231036439 Slow queries: 46 Opens: 54008 Flush tables: 2 Open tables: 64 Queries per second avg: 60.027
@serverMYSQL = `$mysqladminbin status`;
$MYSQLuptime=0;
$MYSQLthreads=0;
$MYSQLqueries=0;
$MYSQLconnections=0;
@mysql_status_data = split(' ',$serverMYSQL[0]);
$MYSQLuptime = $mysql_status_data[0];
$MYSQLuptime =~ s/\D//gi;
$MYSQLthreads = $mysql_status_data[1];
$MYSQLthreads =~ s/\D//gi;
$MYSQLqueries = $mysql_status_data[2];
$MYSQLqueries =~ s/\D//gi;
if($DB){print STDERR "\n $mysqladminbin processlist | $wcbin \n";}
@serverMYSQLconnections = `$mysqladminbin processlist | $wcbin`;
$connection_data = $serverMYSQLconnections[0];
$connection_data =~ s/\s+/ /gi;
@serverMYSQLconnectionsARY = split(/ /,$connection_data);
$MYSQLconnections = ($serverMYSQLconnectionsARY[1] - 4);
return ( $MYSQLuptime, $MYSQLconnections, $MYSQLqueries );
}
+3 -2
View File
@@ -2,7 +2,7 @@
# default path to astguiclient configuration file:
$PATHconf = '/etc/astguiclient.conf';
# Copyright (C) 2019 Joe Johnson, Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
# Copyright (C) 2024 Joe Johnson, Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
#
# VD_email_inbound.pl
# This script is responsible for assigning transferred and new emails to
@@ -26,6 +26,7 @@ $PATHconf = '/etc/astguiclient.conf';
# 180610-1812 - Added code to not allow XFER emails to go to user who transferred
# 190216-0810 - Fix for user-group, email-group and campaign allowed/permissions matching issues
# 191017-2043 - Added filtered routing options
# 240219-1526 - Added daily_limit in-group parameter
#
if ($ARGV[0]=~/--help/)
@@ -275,7 +276,7 @@ sub AssignAgents()
$stmtA = "LOCK TABLES vicidial_live_agents WRITE, vicidial_live_inbound_agents WRITE;";
my $LOCKaffected_rows = $dbhA->do($stmtA);
$stmtA = "SELECT vicidial_live_agents.user from vicidial_live_agents, vicidial_live_inbound_agents WHERE vicidial_live_agents.user=vicidial_live_inbound_agents.user and status IN('CLOSER','READY') and lead_id<1 $ADUfindSQL and vicidial_live_inbound_agents.group_id='$group_id' and last_update_time > '$BDtsSQLdate' and vicidial_live_agents.user NOT IN($ring_no_answer_agents$vlia_users) and ring_callerid='' $qp_groupWAIT_camp_SQL $agent_call_order limit 1;";
$stmtA = "SELECT vicidial_live_agents.user from vicidial_live_agents, vicidial_live_inbound_agents WHERE vicidial_live_agents.user=vicidial_live_inbound_agents.user and status IN('CLOSER','READY') and lead_id<1 $ADUfindSQL and vicidial_live_inbound_agents.group_id='$group_id' and last_update_time > '$BDtsSQLdate' and vicidial_live_agents.user NOT IN($ring_no_answer_agents$vlia_users) and ring_callerid='' and ( (vicidial_live_inbound_agents.daily_limit = '-1') or (vicidial_live_inbound_agents.daily_limit > vicidial_live_inbound_agents.calls_today) ) $qp_groupWAIT_camp_SQL $agent_call_order limit 1;";
$sthA = $dbhA->prepare($stmtA) or die "preparing: ",$dbhA->errstr;
$sthA->execute or die "executing: $stmtA ", $dbhA->errstr;
$sthArows=$sthA->rows;
+55 -1
View File
@@ -2119,6 +2119,7 @@ group_web_vars VARCHAR(255) default '',
group_grade TINYINT(2) UNSIGNED default '1',
group_type VARCHAR(1) default 'C',
calls_today_filtered SMALLINT(5) UNSIGNED default '0',
daily_limit SMALLINT(5) default '-1',
index (group_id),
index (user),
unique index viga_user_group_id (user, group_id)
@@ -2135,6 +2136,7 @@ group_grade TINYINT(2) UNSIGNED default '1',
calls_today_filtered SMALLINT(5) UNSIGNED default '0',
last_call_time_filtered DATETIME,
last_call_finish_filtered DATETIME,
daily_limit SMALLINT(5) default '-1',
index (group_id),
index (group_weight),
unique index vlia_user_group_id (user, group_id)
@@ -5178,6 +5180,58 @@ status VARCHAR(40) default '',
index(call_date)
) ENGINE=MyISAM;
CREATE TABLE server_live_stats (
update_time DATETIME NOT NULL,
server_ip VARCHAR(15) NOT NULL,
server_name VARCHAR(100) NOT NULL,
cpu_count SMALLINT(5) UNSIGNED default '0',
loadavg_1 DECIMAL(8,2) default '0.00',
loadavg_5 DECIMAL(8,2) default '0.00',
loadavg_15 DECIMAL(8,2) default '0.00',
freeram INT(9) default '0',
usedram INT(9) default '0',
processes SMALLINT(4) default '0',
system_uptime VARCHAR(255) default '',
cpu_user_percent DECIMAL(6,2) default '0.00',
cpu_sys_percent DECIMAL(6,2) default '0.00',
cpu_idle_percent DECIMAL(6,2) default '0.00',
cpu_iowait_percent DECIMAL(6,2) default '0.00',
cpu_vm_percent DECIMAL(6,2) default '0.00',
disk_reads INT(9) UNSIGNED default '0',
disk_writes INT(9) UNSIGNED default '0',
asterisk_channels_total SMALLINT(4) UNSIGNED default '0',
asterisk_agents_total SMALLINT(4) UNSIGNED default '0',
mysql_uptime VARCHAR(20) default '0',
mysql_queries_per_second INT(9) UNSIGNED default '0',
mysql_connections MEDIUMINT(7) UNSIGNED default '0',
unique index liveservers (server_ip)
) ENGINE=MyISAM;
CREATE TABLE server_live_drives (
update_time DATETIME NOT NULL,
server_ip VARCHAR(15) NOT NULL,
drive_order TINYINT UNSIGNED default '0',
drive_device VARCHAR(100) default '',
read_sec DECIMAL(8,2) default '0.0',
write_sec DECIMAL(8,2) default '0.0',
kb_read_sec DECIMAL(12,2) default '0.0',
kb_write_sec DECIMAL(12,2) default '0.0',
util_pct DECIMAL(7,2) default '0.0',
unique index livedrives (server_ip, drive_device)
) ENGINE=MyISAM;
CREATE TABLE server_live_partitions (
update_time DATETIME NOT NULL,
server_ip VARCHAR(15) NOT NULL,
partition_order TINYINT UNSIGNED default '0',
partition_path VARCHAR(100) default '',
partition_filesystem VARCHAR(100) default '',
use_pct TINYINT UNSIGNED default '0',
mb_used BIGINT(14) default '0',
mb_available BIGINT(14) default '0',
unique index livepartitions (server_ip, partition_path)
) ENGINE=MyISAM;
ALTER TABLE vicidial_email_list MODIFY message text character set utf8;
@@ -5577,4 +5631,4 @@ INSERT INTO `wallboard_reports` VALUES ('AGENTS_AND_QUEUES','Agents and Queues',
UPDATE system_settings set vdc_agent_api_active='1';
UPDATE system_settings SET db_schema_version='1707',db_schema_update_date=NOW(),reload_timestamp=NOW();
UPDATE system_settings SET db_schema_version='1708',db_schema_update_date=NOW(),reload_timestamp=NOW();
+58
View File
@@ -2603,3 +2603,61 @@ ALTER TABLE vicidial_campaigns ADD state_descriptions VARCHAR(40) default '---DI
ALTER TABLE vicidial_inbound_groups ADD state_descriptions VARCHAR(40) default '---DISABLED---';
UPDATE system_settings SET db_schema_version='1707',db_schema_update_date=NOW() where db_schema_version < 1707;
ALTER TABLE vicidial_inbound_group_agents ADD daily_limit SMALLINT(5) default '-1';
ALTER TABLE vicidial_live_inbound_agents ADD daily_limit SMALLINT(5) default '-1';
CREATE TABLE server_live_stats (
update_time DATETIME NOT NULL,
server_ip VARCHAR(15) NOT NULL,
server_name VARCHAR(100) NOT NULL,
cpu_count SMALLINT(5) UNSIGNED default '0',
loadavg_1 DECIMAL(8,2) default '0.00',
loadavg_5 DECIMAL(8,2) default '0.00',
loadavg_15 DECIMAL(8,2) default '0.00',
freeram INT(9) default '0',
usedram INT(9) default '0',
processes SMALLINT(4) default '0',
system_uptime VARCHAR(255) default '',
cpu_user_percent DECIMAL(6,2) default '0.00',
cpu_sys_percent DECIMAL(6,2) default '0.00',
cpu_idle_percent DECIMAL(6,2) default '0.00',
cpu_iowait_percent DECIMAL(6,2) default '0.00',
cpu_vm_percent DECIMAL(6,2) default '0.00',
disk_reads INT(9) UNSIGNED default '0',
disk_writes INT(9) UNSIGNED default '0',
asterisk_channels_total SMALLINT(4) UNSIGNED default '0',
asterisk_agents_total SMALLINT(4) UNSIGNED default '0',
mysql_uptime VARCHAR(20) default '0',
mysql_queries_per_second INT(9) UNSIGNED default '0',
mysql_connections MEDIUMINT(7) UNSIGNED default '0',
unique index liveservers (server_ip)
) ENGINE=MyISAM;
CREATE TABLE server_live_drives (
update_time DATETIME NOT NULL,
server_ip VARCHAR(15) NOT NULL,
drive_order TINYINT UNSIGNED default '0',
drive_device VARCHAR(100) default '',
read_sec DECIMAL(8,2) default '0.0',
write_sec DECIMAL(8,2) default '0.0',
kb_read_sec DECIMAL(12,2) default '0.0',
kb_write_sec DECIMAL(12,2) default '0.0',
util_pct DECIMAL(7,2) default '0.0',
unique index livedrives (server_ip, drive_device)
) ENGINE=MyISAM;
CREATE TABLE server_live_partitions (
update_time DATETIME NOT NULL,
server_ip VARCHAR(15) NOT NULL,
partition_order TINYINT UNSIGNED default '0',
partition_path VARCHAR(100) default '',
partition_filesystem VARCHAR(100) default '',
use_pct TINYINT UNSIGNED default '0',
mb_used BIGINT(14) default '0',
mb_available BIGINT(14) default '0',
unique index livepartitions (server_ip, partition_path)
) ENGINE=MyISAM;
UPDATE system_settings SET db_schema_version='1708',db_schema_update_date=NOW() where db_schema_version < 1708;
+8 -5
View File
@@ -1,7 +1,7 @@
<?php
# api.php
#
# Copyright (C) 2023 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
# Copyright (C) 2024 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
#
# This script is designed as an API(Application Programming Interface) to allow
# other programs to interact with the VICIDIAL Agent screen
@@ -112,10 +112,11 @@
# 230519-0731 - Fix for input variable filtering
# 231129-1457 - Added refresh_panel function
# 231222-2105 - Added multi_dial_phones option to the transfer_conference function
# 240219-1500 - Added daily_limit setting to change_ingroups function
#
$version = '2.14-77';
$build = '231222-2105';
$version = '2.14-78';
$build = '240219-1500';
$php_script = 'api.php';
$startMS = microtime();
@@ -2656,7 +2657,7 @@ if ($function == 'change_ingroups')
{
if (strlen($in_groups[$k])>1)
{
$stmtB="SELECT group_weight,calls_today,group_grade,calls_today_filtered FROM vicidial_inbound_group_agents where user='$agent_user' and group_id='$in_groups[$k]';";
$stmtB="SELECT group_weight,calls_today,group_grade,calls_today_filtered,daily_limit FROM vicidial_inbound_group_agents where user='$agent_user' and group_id='$in_groups[$k]';";
$rslt=mysql_to_mysqli($stmtB, $link);
if ($DB) {echo "$stmtB\n";}
$viga_ct = mysqli_num_rows($rslt);
@@ -2667,6 +2668,7 @@ if ($function == 'change_ingroups')
$calls_today = $row[1];
$group_grade = $row[2];
$calls_today_filtered = $row[3];
$daily_limit = $row[4];
}
else
{
@@ -2674,8 +2676,9 @@ if ($function == 'change_ingroups')
$calls_today = 0;
$group_grade = 0;
$calls_today_filtered = 0;
$daily_limit = -1;
}
$stmtB="INSERT IGNORE INTO vicidial_live_inbound_agents set user='$agent_user',group_id='$in_groups[$k]',group_weight='$group_weight',group_grade='$group_grade',calls_today='$calls_today',calls_today_filtered='$calls_today_filtered',last_call_time='$NOW_TIME',last_call_finish='$NOW_TIME',last_call_time_filtered='$NOW_TIME',last_call_finish_filtered='$NOW_TIME' ON DUPLICATE KEY UPDATE group_weight='$group_weight',group_grade='$group_grade',calls_today='$calls_today',calls_today_filtered='$calls_today_filtered';";
$stmtB="INSERT IGNORE INTO vicidial_live_inbound_agents set user='$agent_user',group_id='$in_groups[$k]',group_weight='$group_weight',group_grade='$group_grade',calls_today='$calls_today',calls_today_filtered='$calls_today_filtered',last_call_time='$NOW_TIME',last_call_finish='$NOW_TIME',last_call_time_filtered='$NOW_TIME',last_call_finish_filtered='$NOW_TIME',daily_limit='$daily_limit' ON DUPLICATE KEY UPDATE group_weight='$group_weight',group_grade='$group_grade',calls_today='$calls_today',calls_today_filtered='$calls_today_filtered',daily_limit='$daily_limit';";
$stmtBlog .= "$stmtB|";
if ($format=='debug') {echo "\n<!-- $stmtB -->";}
$rslt=mysql_to_mysqli($stmtB, $link);
+122 -14
View File
@@ -1,7 +1,7 @@
<?php
# vdc_db_query.php
#
# Copyright (C) 2023 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
# Copyright (C) 2024 Matt Florell <vicidial@gmail.com> LICENSE: AGPLv2
#
# This script is designed to exchange information between vicidial.php and the database server for various actions
#
@@ -545,10 +545,11 @@
# 231129-1403 - Fix for ConfBridge blind monitoring issue #1494
# 231129-1541 - Added refresh_panel agent API function
# 231207-1520 - Fix for ConfBridge blind monitoring issue #1497
# 240219-2130 - Added daily_limit for user/in-group parameter
#
$version = '2.14-438';
$build = '231207-1520';
$version = '2.14-439';
$build = '240219-2130';
$php_script = 'vdc_db_query.php';
$mel=1; # Mysql Error Log enabled = 1
$mysql_log_count=913;
@@ -1688,6 +1689,22 @@ if ($ACTION == 'regCLOSER')
$max_inbound_calls_outcome = $row[1];
}
# 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 ($DB) {echo "$stmt\n";}
$VD_hit_limit_ingroups_ct = mysqli_num_rows($rslt);
$VD_hit_limit_ingroups="'',";
$jx=0;
while ($jx < $VD_hit_limit_ingroups_ct)
{
$row=mysqli_fetch_row($rslt);
$VD_hit_limit_ingroups .= "'$row[0]',";
$jx++;
}
$VD_hit_limit_ingroups = substr("$VD_hit_limit_ingroups", 0, -1);
$max_inbound_triggered=0;
if ( ($VU_max_inbound_calls > 0) or ($CP_max_inbound_calls > 0) )
{
@@ -1779,7 +1796,7 @@ if ($ACTION == 'regCLOSER')
$camp_choice = preg_replace("/ /","','",$camp_choice);
$camp_choice = "'$camp_choice'";
$stmt = "SELECT group_id FROM vicidial_inbound_groups where group_id IN($user_choice) and group_id IN($camp_choice) and active='Y';";
$stmt = "SELECT group_id FROM vicidial_inbound_groups where group_id IN($user_choice) and group_id IN($camp_choice) and active='Y' and group_id NOT IN($VD_hit_limit_ingroups);";
$rslt=mysql_to_mysqli($stmt, $link);
if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00537',$user,$server_ip,$session_name,$one_mysql_log);}
if ($DB) {echo "$stmt\n";}
@@ -1864,7 +1881,7 @@ if ($ACTION == 'regCLOSER')
{
if (strlen($in_groups[$k])>1)
{
$stmt="SELECT group_weight,calls_today,group_grade,calls_today_filtered FROM vicidial_inbound_group_agents where user='$user' and group_id='$in_groups[$k]';";
$stmt="SELECT group_weight,calls_today,group_grade,calls_today_filtered,daily_limit FROM vicidial_inbound_group_agents where user='$user' and group_id='$in_groups[$k]';";
$rslt=mysql_to_mysqli($stmt, $link);
if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00013',$user,$server_ip,$session_name,$one_mysql_log);}
if ($DB) {echo "$stmt\n";}
@@ -1876,14 +1893,16 @@ if ($ACTION == 'regCLOSER')
$calls_today = $row[1];
$group_grade = $row[2];
$calls_today_filtered = $row[3];
$daily_limit = $row[4];
}
else
{
$group_weight = 0;
$calls_today = 0;
$group_grade = 1;
$daily_limit = -1;
}
$stmt="INSERT INTO vicidial_live_inbound_agents set user='$user',group_id='$in_groups[$k]',group_weight='$group_weight',calls_today='$calls_today',last_call_time='$NOW_TIME',last_call_finish='$NOW_TIME',last_call_time_filtered='$NOW_TIME',last_call_finish_filtered='$NOW_TIME',group_grade='$group_grade',calls_today_filtered='$calls_today_filtered';";
$stmt="INSERT INTO vicidial_live_inbound_agents set user='$user',group_id='$in_groups[$k]',group_weight='$group_weight',calls_today='$calls_today',last_call_time='$NOW_TIME',last_call_finish='$NOW_TIME',last_call_time_filtered='$NOW_TIME',last_call_finish_filtered='$NOW_TIME',group_grade='$group_grade',calls_today_filtered='$calls_today_filtered',daily_limit='$daily_limit';";
if ($format=='debug') {echo "\n<!-- $stmt -->";}
$rslt=mysql_to_mysqli($stmt, $link);
if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00014',$user,$server_ip,$session_name,$one_mysql_log);}
@@ -11510,11 +11529,27 @@ if ($ACTION == 'VDADcheckINCOMINGother')
$email_ct = mysqli_num_rows($rslt);
$xferred_email=$email_ct;
# 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 ($DB) {echo "$stmt\n";}
$VD_hit_limit_ingroups_ct = mysqli_num_rows($rslt);
$VD_hit_limit_ingroups="'',";
$jx=0;
while ($jx < $VD_hit_limit_ingroups_ct)
{
$row=mysqli_fetch_row($rslt);
$VD_hit_limit_ingroups .= "'$row[0]',";
$jx++;
}
$VD_hit_limit_ingroups = substr("$VD_hit_limit_ingroups", 0, -1);
# Check if there are any QUEUE emails
if ($email_ct==0)
{
# Check if there are any QUEUE emails
$stmt = "SELECT lead_id, UNIX_TIMESTAMP(email_date), email_to, email_from, subject, group_id, email_row_id from vicidial_email_list where status='QUEUE' and direction='INBOUND' and user='$user' and group_id in ($email_group_str) order by email_date asc;";
$stmt = "SELECT lead_id, UNIX_TIMESTAMP(email_date), email_to, email_from, subject, group_id, email_row_id from vicidial_email_list where status='QUEUE' and direction='INBOUND' and user='$user' and group_id IN ($email_group_str) and group_id NOT IN($VD_hit_limit_ingroups) order by email_date asc;";
if ($DB) {echo "$stmt\n";}
$rslt=mysql_to_mysqli($stmt, $link);
if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00488',$user,$server_ip,$session_name,$one_mysql_log);}
@@ -11525,7 +11560,7 @@ if ($ACTION == 'VDADcheckINCOMINGother')
if ($email_ct==0)
{
# Chats don't have a priority setting, but we use it for the AGENTDIRECT_CHAT one (which has it set to 99 and is uneditable through the admin) so that is always the highest priority. Also ensures that agent does not transfer to self if transferring to the same ingroup (transferring_agent!=user clause)
$stmt="SELECT vlc.chat_id,UNIX_TIMESTAMP(vlc.chat_start_time),vlc.status,vlc.chat_creator,vlc.group_id,vlc.lead_id,vlc.user_direct_group_id,vig.queue_priority,vig.get_call_launch from vicidial_live_chats vlc, vicidial_inbound_groups vig where vlc.status='WAITING' and (vlc.group_id in ($chat_group_str) or (vlc.group_id='AGENTDIRECT_CHAT' and user_direct='$user')) and (transferring_agent is null or transferring_agent!='$user') order by queue_priority desc, chat_id asc limit 1;";
$stmt="SELECT vlc.chat_id,UNIX_TIMESTAMP(vlc.chat_start_time),vlc.status,vlc.chat_creator,vlc.group_id,vlc.lead_id,vlc.user_direct_group_id,vig.queue_priority,vig.get_call_launch from vicidial_live_chats vlc, vicidial_inbound_groups vig where vlc.status='WAITING' and (vlc.group_id IN ($chat_group_str) or (vlc.group_id='AGENTDIRECT_CHAT' and user_direct='$user')) and vlc.group_id NOT IN($VD_hit_limit_ingroups) and (transferring_agent is null or transferring_agent!='$user') order by queue_priority desc, chat_id asc limit 1;";
if ($DB) {echo "$stmt\n";}
$rslt=mysql_to_mysqli($stmt, $link);
if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00638',$user,$server_ip,$session_name,$one_mysql_log);}
@@ -11621,10 +11656,10 @@ if ($ACTION == 'VDADcheckINCOMINGother')
$rslt=mysql_to_mysqli($stmt, $link);
if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00491',$user,$server_ip,$session_name,$one_mysql_log);}
$stmtA = "UPDATE vicidial_live_inbound_agents set calls_today='$calls_today',last_call_time=NOW() WHERE user='$user' and group_id='$VDADchannel_group';";
$stmtA = "UPDATE vicidial_live_inbound_agents set calls_today=(calls_today + 1),last_call_time=NOW() WHERE user='$user' and group_id='$VDADchannel_group';";
$rsltA=mysql_to_mysqli($stmtA, $link);
if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmtA,'00549',$user,$server_ip,$session_name,$one_mysql_log);}
$stmtA = "UPDATE vicidial_inbound_group_agents set calls_today='$calls_today',group_type='E' WHERE user='$user' and group_id='$VDADchannel_group';";
$stmtA = "UPDATE vicidial_inbound_group_agents set calls_today=(calls_today + 1),group_type='E' WHERE user='$user' and group_id='$VDADchannel_group';";
$rsltA=mysql_to_mysqli($stmtA, $link);
if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmtA,'00550',$user,$server_ip,$session_name,$one_mysql_log);}
@@ -11794,10 +11829,10 @@ if ($ACTION == 'VDADcheckINCOMINGother')
$rslt=mysql_to_mysqli($stmt, $link);
if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00641',$user,$server_ip,$session_name,$one_mysql_log);}
$stmtA = "UPDATE vicidial_live_inbound_agents set calls_today='$calls_today',last_call_time=NOW() WHERE user='$user' and group_id='$VDADchannel_group';";
$stmtA = "UPDATE vicidial_live_inbound_agents set calls_today=(calls_today + 1),last_call_time=NOW() WHERE user='$user' and group_id='$VDADchannel_group';";
$rsltA=mysql_to_mysqli($stmtA, $link);
if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmtA,'00642',$user,$server_ip,$session_name,$one_mysql_log);}
$stmtA = "UPDATE vicidial_inbound_group_agents set calls_today='$calls_today',group_type='C' WHERE user='$user' and group_id='$VDADchannel_group';";
$stmtA = "UPDATE vicidial_inbound_group_agents set calls_today=(calls_today + 1),group_type='C' WHERE user='$user' and group_id='$VDADchannel_group';";
$rsltA=mysql_to_mysqli($stmtA, $link);
if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmtA,'00643',$user,$server_ip,$session_name,$one_mysql_log);}
@@ -11857,9 +11892,80 @@ if ($ACTION == 'VDADcheckINCOMINGother')
if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00791',$user,$server_ip,$session_name,$one_mysql_log);}
}
if ($email_ct>0 || $chat_ct>0) {
if ($email_ct>0 || $chat_ct>0)
{
### ANYTHING AFTER THIS POINT - DOES NOT MATTER WHETHER AN EMAIL OR CHAT IS BEING FIELDED
# check for inbound daily limits and remove selected in-groups if limit is reached
$VDCL_calls_today = 1;
$VDCL_daily_limit = -1;
$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);}
$VDIG_cidgwv_ct = mysqli_num_rows($rslt);
if ($VDIG_cidgwv_ct > 0)
{
$row=mysqli_fetch_row($rslt);
$VDCL_calls_today = $row[0];
$VDCL_daily_limit = $row[1];
}
if ( ($VDCL_daily_limit >= 0) and ($VDCL_daily_limit <= $VDCL_calls_today) )
{
$outbound_autodial='0';
$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);}
$VDIG_cidgwv_ct = mysqli_num_rows($rslt);
if ($VDIG_cidgwv_ct > 0)
{
$row=mysqli_fetch_row($rslt);
$TEMPoutbound_autodial = $row[0];
if (preg_match("/Y/",$TEMPoutbound_autodial))
{$outbound_autodial='1';}
$closer_campaigns = $row[1];
}
$closer_campaigns = preg_replace("/^ | -$/",'',$closer_campaigns);
$ADcloser_campaignsARY = explode(" ",$closer_campaigns);
$ADcloser_campaignsARYct = count($ADcloser_campaignsARY);
$ADc=0;
$ADcloser_campaigns='';
while ($ADc < $ADcloser_campaignsARYct)
{
if (!preg_match("/^$VDADchannel_group$/i",$ADcloser_campaignsARY[$ADc]))
{$ADcloser_campaigns .= "$ADcloser_campaignsARY[$ADc] ";}
$ADc++;
}
if (strlen($ADcloser_campaigns) > 3)
{$ADcloser_campaigns = " ".$ADcloser_campaigns."-";}
else
{$ADcloser_campaigns = " -";}
### update the live agents record to use the new set of closer_campaigns
$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);}
$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);}
$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);}
$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|";}
}
### gather custom_call_id from vicidial_log_extended table
$custom_call_id='';
@@ -13901,8 +14007,10 @@ if ($ACTION == 'updateDISPO')
# fwrite ($fp, "$NOW_TIME|DISPO_CALL3|$user|$max_inbound_count - $row[0] - $row[1]|\n");
# fclose($fp);
$max_inbound_triggered=0;
if ($max_inbound_count >= $max_inbound_calls)
{
$max_inbound_triggered++;
$outbound_autodial='0';
$stmt="SELECT outbound_autodial,closer_campaigns FROM vicidial_live_agents where user='$user';";
$rslt=mysql_to_mysqli($stmt, $link);
@@ -13953,7 +14061,7 @@ if ($ACTION == 'updateDISPO')
$affected_rowsB = mysqli_affected_rows($link);
$SQL_log = "$stmtA|$stmtB";
$SQL_log = preg_replace("/'|%//",'',$SQL_log);
$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='MAX IN CALLS MODIFY USER', event_sql='$SQL_log', event_notes='|$dispo_choice|$customer_sec|$max_inbound_count|$max_inbound_calls|$user|IC|$max_inbound_calls_outcome|$closer_campaigns|$affected_rowsA|$affected_rowsB|';";
$rslt=mysql_to_mysqli($stmtC, $link);
if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmtC,'00817',$user,$server_ip,$session_name,$one_mysql_log);}
+22 -5
View File
@@ -732,10 +732,11 @@
# 231129-1359 - Fix for Dial-In-Group user-group issue #1493
# 231129-1540 - Added refresh_panel agent API function
# 240214-0400 - Added state_descriptions banners
# 240220-0245 - Added daily_limit for user/in-group parameter
#
$version = '2.14-698c';
$build = '240214-0400';
$version = '2.14-699c';
$build = '240220-0245';
$php_script = 'vicidial.php';
$mel=1; # Mysql Error Log enabled = 1
$mysql_log_count=103;
@@ -3800,6 +3801,22 @@ else
if ( ($dial_method == 'INBOUND_MAN') or ($outbound_autodial_active < 1) )
{$VU_closer_default_blended=0;}
# 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 ($DB) {echo "$stmt\n";}
$VD_hit_limit_ingroups_ct = mysqli_num_rows($rslt);
$VD_hit_limit_ingroups="'',";
$jx=0;
while ($jx < $VD_hit_limit_ingroups_ct)
{
$row=mysqli_fetch_row($rslt);
$VD_hit_limit_ingroups .= "'$row[0]',";
$jx++;
}
$VD_hit_limit_ingroups = substr("$VD_hit_limit_ingroups", 0, -1);
$closer_campaigns = preg_replace("/^ | -$/","",$closer_campaigns);
$closer_campaigns = preg_replace("/ /","','",$closer_campaigns);
$ADcloser_campaigns = preg_replace("/'/",'',$closer_campaigns);
@@ -3909,7 +3926,7 @@ else
$VARphonegroups='';
$VARemailgroups='';
$VARchatgroups='';
$stmt="SELECT group_id,group_handling from vicidial_inbound_groups where active = 'Y' and group_id IN($closer_campaigns) order by group_id limit 800;";
$stmt="SELECT group_id,group_handling from vicidial_inbound_groups where active = 'Y' and group_id IN($closer_campaigns) and group_id NOT IN($VD_hit_limit_ingroups) order by group_id limit 800;";
$rslt=mysql_to_mysqli($stmt, $link);
if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'01015',$VD_login,$server_ip,$session_name,$one_mysql_log);}
if ($DB) {echo "$stmt\n";}
@@ -3962,7 +3979,7 @@ else
if ($in_group_dial_select == 'CAMPAIGN_SELECTED')
{
$VARdialingroups='';
$stmt="select group_id from vicidial_inbound_groups where active = 'Y' and group_id IN($closer_campaigns) order by group_id limit 800;";
$stmt="select group_id from vicidial_inbound_groups where active = 'Y' and group_id IN($closer_campaigns) and group_id NOT IN($VD_hit_limit_ingroups) order by group_id limit 800;";
$rslt=mysql_to_mysqli($stmt, $link);
if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'01076',$VD_login,$server_ip,$session_name,$one_mysql_log);}
if ($DB) {echo "$stmt\n";}
@@ -3980,7 +3997,7 @@ else
if ($in_group_dial_select == 'ALL_USER_GROUP')
{
$VARdialingroups='';
$stmt="select group_id from vicidial_inbound_groups where active = 'Y' and user_group IN('---ALL---','$VU_user_group') order by group_id limit 800;";
$stmt="select group_id from vicidial_inbound_groups where active = 'Y' and user_group IN('---ALL---','$VU_user_group') and group_id NOT IN($VD_hit_limit_ingroups) order by group_id limit 800;";
$rslt=mysql_to_mysqli($stmt, $link);
if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'01077',$VD_login,$server_ip,$session_name,$one_mysql_log);}
if ($DB) {echo "$stmt\n";}
+95 -28
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -400,7 +400,6 @@ if ($action == "BLANK")
$o=0;
if ($lead_list['count'] > 0)
{
# while (list($owner,) = each($lead_list[$since_reset]))
foreach($lead_list[$since_reset] as $owner => $blank)
{
$owner_var = preg_replace('/ |\n|\r|\t/','',$owner);
+2 -2
View File
@@ -1,4 +1,4 @@
# version: 20240214213601
# version: 20240220093401
users-user User ID <QXZ>This field is where you put the users ID number, can be up to 20 digits in length, Must be at least 2 characters in length. We strongly recommend not reusing user accounts for different users, for reporting accuracy. To disable a user account, set the Active option to -N-.</QXZ>
users-pass Password <QXZ>This field is where you put the users password. Must be at least 2 characters in length, 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.</QXZ>
users-force_change_password Force Change Password <QXZ>If this option is set to Y then the user will be prompted to change their password the next time they log in to the administration webpage or the agent screen. Default is N.</QXZ>
@@ -56,7 +56,7 @@ users-wrapup_seconds_override Wrap Seconds Override <QXZ>If this setting is set
users-ready_max_logout Agent Ready Max Logout Override <QXZ>If this setting is set to a number 0 or greater, then it will override the Campaign setting for Agent Ready Max Logout Seconds. This is a setting that is only refreshed in the agent interface at agent login time. Default is -1 for disabled.</QXZ>
users-status_group_id Additional Status Group <QXZ>This optional setting will allow you to define a Status Group of call disposition statuses that will be available to this agent to status calls with. This will be in addition to the statuses that the agent will already have as a part of the system statuses, campaign statuses as well as list and in-group status groups. The default is blank for disabled.</QXZ>
users-campaign_ranks Campaign Ranks <QXZ>In this section you can define the rank an agent will have for each campaign. These ranks can be used to allow for preferred call routing when Next Agent Call is set to campaign_rank. Also in this section are the WEB VARs for each campaign. These allow each agent to have a different variable string that can be added to the WEB FORM or SCRIPT tab URLs by simply putting --A--web_vars--B-- as you would put any other field. Another field in this section is GRADE, which allows for the campaign_grade_random Next Agent Call setting to be used. This grade setting will increase or decrease the probability that the agent will receive the call.</QXZ>
users-closer_campaigns Inbound Groups <QXZ>Here is where you select the inbound groups you want to receive calls from if you have selected the CLOSER campaign. You will also be able to set the rank, or skill level, in this section for each of the inbound groups as well as being able to see the number of calls received from each inbound group for this specific agent. Also in this section is the ability to give the agent a rank for each inbound group. These ranks can be used for preferred call routing when that option is selected in the in-group screen. Also in this section are the WEB VARs for each campaign. These allow each agent to have a different variable string that can be added to the WEB FORM or SCRIPT tab URLs by simply putting --A--web_vars--B-- as you would put any other field.</QXZ>
users-closer_campaigns Inbound Groups <QXZ>Here is where you select the inbound groups you want to receive calls from if you have selected the CLOSER campaign. You will also be able to set the rank, or skill level, in this section for each of the inbound groups as well as being able to see the number of calls received from each inbound group for this specific agent. Also in this section is the ability to give the agent a rank for each inbound group. These ranks can be used for preferred call routing when that option is selected in the in-group screen. Also in this section are the WEB VARs for each campaign. These allow each agent to have a different variable string that can be added to the WEB FORM or SCRIPT tab URLs by simply putting --A--web_vars--B-- as you would put any other field. The LIMIT field allows you to set daily call limits for each Inbound Group for each agent, default for LIMIT is -1 which is no limit.</QXZ>
users-alter_custdata_override Agent Alter Customer Data Override <QXZ>This option will override whatever the option is in the campaign for altering of customer data. NOT_ACTIVE will use whatever setting is present for the campaign. ALLOW_ALTER will always allow for the agent to alter the customer data, no matter what the campaign setting is. Default is NOT_ACTIVE.</QXZ>
users-alter_custphone_override Agent Alter Customer Phone Override <QXZ>This option will override whatever the option is in the campaign for altering of customer phone number. NOT_ACTIVE will use whatever setting is present for the campaign. ALLOW_ALTER will always allow for the agent to alter the customer phone number, no matter what the campaign setting is. Default is NOT_ACTIVE.</QXZ>
users-custom_one Custom User Fields <QXZ>These five fields can be used for various purposes, and they can be populated in the web form addresses and scripts as user_custom_one and so on. The Custom 5 field can be used as a field to define a dialplan number to send a call to from an AGENTDIRECT in-group if the user is unavailable, you just need to put AGENTEXT in the MESSAGE or EXTENSION field in the AGENTDIRECT in-group and the system will look up the custom five field and send the call to that dialplan number.</QXZ>
-4
View File
@@ -275,7 +275,6 @@ if ($reload_chat_span) {
echo "<TD rowspan=3 valign='top'>";
echo "<select name='available_chat_agents[]' multiple size='12' style=\"width:350px\">\n";
if (count($user_array)==0) {echo "<option value=''>---- "._QXZ("NO LIVE AGENTS")." ----</option>";}
#while (list($user, $full_name) = each($user_array)) {
foreach($user_array as $user => $full_name) {
echo "<option value='$user'>$user - $full_name</option>\n";
}
@@ -284,7 +283,6 @@ if ($reload_chat_span) {
echo "<TD valign='top'>";
echo "<select name='available_chat_campaigns[]' multiple size='5' style=\"width:350px\">\n";
if (count($campaign_id_array)==0) {echo "<option value=''>---- "._QXZ("NO LIVE CAMPAIGNS")." ----</option>";}
#while (list($campaign_id, $campaign_name) = each($campaign_id_array)) {
foreach($campaign_id_array as $campaign_id => $campaign_name) {
echo "<option value='$campaign_id'>$campaign_id - $campaign_name</option>\n";
}
@@ -297,7 +295,6 @@ if ($reload_chat_span) {
echo "<TD valign='top'>";
echo "<select name='available_chat_groups[]' multiple size='5' style=\"width:350px\">\n";
if (count($user_group_array)==0) {echo "<option value=''>---- "._QXZ("NO LIVE USER GROUPS")." ----</option>";}
# while (list($user_group, $group_name) = each($user_group_array)) {
foreach($user_group_array as $user_group => $group_name) {
echo "<option value='$user_group'>$user_group - $group_name</option>\n";
}
@@ -354,7 +351,6 @@ if ($reload_chat_span) {
}
$chat_subids_array=preg_replace("/,$/", "", $chat_subids_array);
$chat_subids_array.="]";
# while (list($chat_subid, $text) = each($chat_output_header)) {
foreach($chat_output_header as $chat_subid => $text) {
echo $chat_output_header[$chat_subid];
echo $chat_output_text[$chat_subid];
-4
View File
@@ -799,7 +799,6 @@ $NWE = "')\" WIDTH=20 HEIGHT=20 BORDER=0 ALT=\"HELP\" ALIGN=TOP>";
echo "<TD rowspan=3 valign='top'>";
echo "<select name='available_chat_agents[]' multiple size='12' style=\"width:350px\">\n";
if (count($user_array)==0) {echo "<option value=''>---- "._QXZ("NO LIVE AGENTS")." ----</option>";}
# while (list($user, $full_name) = each($user_array)) {
foreach($user_array as $user => $full_name) {
echo "<option value='$user'>$user - $full_name</option>\n";
}
@@ -808,7 +807,6 @@ $NWE = "')\" WIDTH=20 HEIGHT=20 BORDER=0 ALT=\"HELP\" ALIGN=TOP>";
echo "<TD valign='top'>";
echo "<select name='available_chat_campaigns[]' multiple size='5' style=\"width:350px\">\n";
if (count($campaign_id_array)==0) {echo "<option value=''>---- "._QXZ("NO LIVE CAMPAIGNS")." ----</option>";}
# while (list($campaign_id, $campaign_name) = each($campaign_id_array)) {
foreach($campaign_id_array as $campaign_id => $campaign_name) {
echo "<option value='$campaign_id'>$campaign_id - $campaign_name</option>\n";
}
@@ -821,7 +819,6 @@ $NWE = "')\" WIDTH=20 HEIGHT=20 BORDER=0 ALT=\"HELP\" ALIGN=TOP>";
echo "<TD valign='top'>";
echo "<select name='available_chat_groups[]' multiple size='5' style=\"width:350px\">\n";
if (count($user_group_array)==0) {echo "<option value=''>---- "._QXZ("NO LIVE USER GROUPS")." ----</option>";}
# while (list($user_group, $group_name) = each($user_group_array)) {
foreach($user_group_array as $user_group => $group_name) {
echo "<option value='$user_group'>$user_group - $group_name</option>\n";
}
@@ -906,7 +903,6 @@ $NWE = "')\" WIDTH=20 HEIGHT=20 BORDER=0 ALT=\"HELP\" ALIGN=TOP>";
}
$chat_subids_array=preg_replace("/,$/", "", $chat_subids_array);
$chat_subids_array.="]";
# while (list($chat_subid, $text) = each($chat_output_header))
foreach($chat_output_header as $chat_subid => $text)
{
echo $chat_output_header[$chat_subid];
File diff suppressed because one or more lines are too long