Contrib: queue_devstate.agi patched for recognizing paused members backwards compatible with original AGI 2.9.x

I’ve seen a lot of questions from people about how to pause the Queue from FreePbx,

I’ve created this functionality and like to contribute it to this project. I’ve done this by patching the freepbx script: queue_devstate.agi. The first step is to actually detect if a queue member is paused or not. This patch to the queue_devstate.agi will provide you this information and also (old behavior) the default output of the scripts which is detect if a user is logged in or not and if a agent is static or not.

Below is a simple implementation that pauses and un-pauses the used on all queue’s and checks a single queue for the status. It also has a self correction loop in case an external program changes the pause state.
And it sets the HINT if the pause is active or not. (ONHOLD/NOT_INUSE)

Place the code below in extensions_custom.conf
Then set your Queue number on line 7
And use *46 to toggle the pause on and off

include => agent-pause

exten => *46,1,Verbose(1,AgentPause)
same => n,Answer()
same => n,Wait(1)
same => n,Macro(user-callerid,)
same => n,Set(QUEUENO=100)
same => n,AGI(queue_devstate.agi,getqueues,${AMPUSER})
same => n,GotoIf($[${AGENTPAUSE} = PAUSED]?unpause:pause)
same => n(unpause),Verbose(1, *** Unpause ***)
same => n,UnPauseQueueMember(,Local/${CALLBACKNUM}@from-queue/n)

same => n,Set(DEVHINT=46${DB(AMPUSER/${AMPUSER}/device)}${QUEUENO})
same => n,Set(DEVICE_STATE(Custom:${DEVHINT})=NOT_INUSE)

same => n,Playback(dictate/paused&ha/off)
same => n,Hangup
same => n(pause),Verbose(1, ### Pause ####)
same => n,Set(DEVHINT=46${DB(AMPUSER/${AMPUSER}/device)}${QUEUENO})
same => n,GotoIf( $[${DEVICE_STATE(Custom:${DEVHINT})} = ONHOLD]?unpause)
same => n,PauseQueueMember(,Local/${CALLBACKNUM}@from-queue/n)
same => n,Set(DEVICE_STATE(Custom:${DEVHINT})=ONHOLD)

same => n,Playback(dictate/paused)
same => n,Hangup

; Creates some hints based on your device login numbers if you like to use BLF on the pause button
; Below is an example if our device number is 999
exten => 46999100,hint,Custom:46999100

also replace the script /var/lib/asterisk/agi-bin/queue_devstate.agi with the code in the second code below ( make a back up first )

Below is the patched AGI queue_devstate.agi script that I created to create the Queue Pause functionality. it is backward compatible with the original queue_devstate.agi script of FreePBX 2.9x

This AGI adds an additional return variable AGENTPAUSE. If the agent is paused AGENTPAUSE = “PAUSED” if the agent is not paused in the Queue it is empty.

I hope that one of the Core Developers can merge this contribution into FreePBX’s next version and put me on the contribution list :slight_smile:

#!/usr/bin/php -q

<?php require_once "phpagi.php"; require_once "phpagi-asmanager.php"; /* Usage: * * AGI(queue_dev_state.agi,getqueues|getall[,user][,queue]) * * ARG1: action * ARG2: user * ARG3: queue * * Added paused detection by Wessel de Roode, jan 2012 */ $agi = new AGI(); // get manager credentials out of the channel // $ampmgruser = get_var( "AMPMGRUSER" ); $ampmgrpass = get_var( "AMPMGRPASS" ); $astspooldir = get_var( "ASTSPOOLDIR" ); $ast_version = get_var( "ASTVERSION" ); $ast_version14 = version_compare($ast_version, "1.4", "ge"); /* $ampmgruser = 'admin'; $ampmgrpass = 'amp111'; */ $astman = new AGI_AsteriskManager( ); $queues=array(); $logged_agents_array=array(); $static_agents_array=array(); if (!$astman->connect("", $ampmgruser , $ampmgrpass)) { exit (1); } $action = get_action(); switch ($action) { case 'getqueues': $new_user = get_login_user(); $queueno=get_var('QUEUENO'); sortqueues(); debug("Getting Queue Status for user $new_user in queue $queueno"); //debug($logged_agents_array); $loggedvar=(array_search(trim($new_user),$logged_agents_array[$queueno]))?'LOGGEDIN':'LOGGEDOUT'; $queuestat=(array_search(trim($new_user),$static_agents_array[$queueno]))?'STATIC':$loggedvar; debug("Agent $new_user is $queuestat"); $agi->set_variable('QUEUESTAT',$queuestat); $agentpause=(array_search(trim($new_user),$paused_agent_array[$queueno]))?'PAUSED':''; $agi->set_variable('AGENTPAUSE',$agentpause); break; default: debug("Got unknown action: $action, exiting"); } exit; // Get the requested action // function get_action() { global $argv; return strtolower(trim($argv['1'])); } function sortqueues() { global $agi; global $astman; global $queues; global $logged_agents_array; global $static_agents_array; global $paused_agent_array; $response = $astman->send_request('Command',array('Command'=>"queue show")); $response1=explode("\n",trim($response['data'])); // Lets try and process our results here. $inqueue='false'; foreach ($response1 as $item) { $item1=trim($item); if ($inqueue == 'false') { if (preg_match('/^(\d+)/',$item1)) { preg_match_all ("/(\\d+)/is", $item1,$matches); if (isset($matches[1][0]) && $matches[1][0] != '') { $queues[]=$matches[1][0]; $inqueue=$matches[1][0]; $logged_agents_array[$inqueue][]=''; $static_agents_array[$inqueue][]=''; $paused_agent_array[$inqueue][]=''; } } } else { // We should test to see if the item is an Agent description if (strstr($item1,'Local/') !== false) { preg_match_all ("/(Local).*?(\\d+)/is", $item1, $matches); $loggedagent=$matches[2][0]; $item1='ADD'; } switch ($item1) { case '': break; case '\n': break; case 'No Members': debug("Queue $inqueue has no one logged in"); $inqueue='false'; break; case 'No Callers': case 'Callers': debug("Finished processing members for $inqueue"); $inqueue='false'; break; case 'ADD': $logged_agents_array[$inqueue][]=$loggedagent; if (strstr($item,'(dynamic)') !== false) { debug("Agent $loggedagent is dynamic"); }else{ debug("Agent $loggedagent is static"); $static_agents_array[$inqueue][]=$loggedagent; } if (strstr($item,'(paused)') !== false) { debug("Agent $loggedagent is paused"); $paused_agent_array[$inqueue][]=$loggedagent; } debug("Agent $loggedagent is assigned to queue $inqueue"); break; default: debug("No Matches"); } } } debug( $paused_agent_array ); debug( $logged_agents_array ); debug( $static_agents_array ); debug("Finished sorting"); } // function get_login_user() { global $argv; return trim($argv['2']); } // Get a channel variable // function get_var($value) { global $agi; $r = $agi->get_variable( $value ); if ($r['result'] == 1) { $result = $r['data']; return trim($result); } return ''; } function debug($string, $level=3) { global $agi; $agi->verbose($string, $level); } [/php] Enjoy! Wessel