Queue: call the same agent who took our last call?

Hello everyone,

I want to know if it’s possible to make a queue whose agents logged in could take a call from caller they have already taken earlier in the day?

My queue configuration on Asterisk:


Thank you for your answers.

Nobody can answer me?
I really need to know if it’s possible or not? :smiley:

No answer to a question like this normally means that no-one knows a way of doing it, but they don’t have the time to research the code to give a definitive answer.

However, I’ve done a lot of work on the queue module, based on version, and in that version, there is definitely no such function and I wouldn’t expect any support in later versions. The queue function just isn’t going to be high enough level to do things that require arbitrarily large databases to be stored.

You would need to code your own database code, and maintain individual queues for each agent, as well as the shared queue for new callers.

To add to David’s suggestion, you’d need a main queue, and individual queues for each member. When they log in or out, they would need added or removed from both queues.

You already have setinterfacevar=yes (or 1 works too), so now you just need a table to populate.

queue_clid varchar(64) NOT NULL,
queue_name varchar(128) DEFAULT NULL,
queue_start datetime DEFAULT NULL,
queue_stop datetime DEFAULT NULL,
queue_stop_type varchar(1) DEFAULT NULL,
queue_agent_phone varchar(64) DEFAULT NULL,
KEY queue_clid (queue_clid,queue_start,queue_stop),
KEY queue_stop_type (queue_stop_type),
KEY queue_name (queue_name),
KEY queue_agent_phone (queue_agent_phone)

Here’s some dialplan code with pseudo code for the parts you could use…


exten => s,1,Answer
same => n,Set(queueid=${ARG1})
same => n,Set(currtime=${STRFTIME(${EPOCH},%Y-%m-%d %H:%M:%S)})

;Check for agents logged in to the queue
same => n,Set(acount=${QUEUE_MEMBER(${queueid},count)})
same => n,GoToIf($["${acount}" > “0”]?agentexists)
same => n,Festival(Play closed message)
same => n,GotoIf($["${vmbox}" != “”]?vm)

;;;Do a database lookup to see if you find a call within whatever timeframe
;;;you’re looking for, and get the agent who answered. Change ${ARG1} to that queue.
;;;You may also want to keep a login/logout log of agents, but that’s a separate discussion
same => n(agentexists)…

same => n,Set(ODBC_WRITESQL()=insert into queue_log (queue_clid,queue_name,queue_start) values(’${CALLERID(num)}’,’${queueid}’,’${currtime}’))
same => n,Queue(${ARG1},queue_log.php)
same => n,Hangup()

same => n(vm),Voicemail(${vmbox}@from-internal-sip,us)
same => n,Hangup()

exten => i,1,Hangup()
exten => t,1,Hangup()
exten => h,1,Set(currtime=${STRFTIME(${EPOCH},%Y-%m-%d %H:%M:%S)})
same => n,Set(ODBC_WRITESQL()=UPDATE queue_log set queue_stop=’${currtime}’,queue_stop_type=‘h’ where queue_clid=’${CALLERID(num)}’ and queue_stop IS NULL)
same => n,Hangup()

And an AGI script to update the agent channel when they answer a call.

#!/usr/bin/php -q

<?php $agivars = array(); while (!feof(STDIN)) { $agivar = trim(fgets(STDIN)); if ($agivar === '') { break; } $agivar = explode(':', $agivar); $agivars[$agivar[0]] = trim($agivar[1]); } extract($agivars); $stdin = fopen('php://stdin', 'r'); $stdout = fopen( 'php://stdout', 'w' ); $currtime = date('Y-m-d H:i:s'); mysql_connect("localhost", "dbusername", "dbpassword"); mysql_select_db("asterisk") or die( "Unable to select database"); $memberinterface = execute_agi("GET VARIABLE MEMBERINTERFACE"); $sql = "UPDATE queue_log set queue_stop = '$currtime', queue_stop_type = 'a', queue_agent_phone='$memberinterface' where queue_clid='$agi_callerid' and queue_stop IS NULL"; mysql_query($sql); mysql_close(); exit; function execute_agi($command) { GLOBAL $stdin, $stdout; fputs( $stdout, $command . "\n" ); fflush( $stdout ); $resp = trim(fgets( $stdin, 4096 )); $exp = explode('(', $resp); $ext = str_replace(')','', $exp[1]); return $ext; } ?>

When a caller hits the queue, an entry is added to the queue_log table. When an agent answers, it updates that record with the stop time and agent channel. If that same callerid calls back later in the day, you should be able to query the database to find who answered the call, and which queue they’re logged in to, then send the call to that queue (as long as the agent is still logged in), else, send them to the main queue.

I like the concept, and may introduce it to our helpdesk. The downside is that if you get a lot of repeat calls, and one of your agents gets most of them, the queue could start to stack up while other agents are stilling idle.

Thank you for your answers,

I have some questions about what you’ve said:

You said that I need to have a main queue where all members have to be added or removed and also individual queues for each member, why I can’t simply add members on queues where I want they have to be?

In which file can I find the parameter setinterfacevar=yes and what is the meaning of this configuration?

You talked about database, this database is the Asterisk Internal Database, which we can access with the command “core show help database” on the CLI?

Or this is an other database? It already exists or should I create it?

Is this database used in order to store the caller’s last calls datas and use them to lead the caller to the last agent who took his last call?

For information, I use FreePBX (Asterisk GUI) to create queue so I didn’t have to create queues manually on Asterisk.
And for my dialplans, I use Visual Dialplan (other Asterisk GUI) to create, maintain and deploy dial plan in an easy, fast, convenient and natural way.

Thank you again. :smile:

I believe you would want a main queue to handle all of the normal callers (those who haven’t called before), and a queue for each agent where you could send the callers who called earlier that day. You dialplan would check if the caller had called earlier that day; if yes, send them directly to the agent’s personal queue, if no, send them to the main queue.

From the settings you listed, you already have “setinterfacevar” set. If it’s set, a variable called “MEMBERINTERFACE” will be set to the device of the agent who picks up the call from the queue. You’ll need that to see who the caller spoke to earlier.

As for the database, you could use the internal database, but I can’t think of a good mechanism within the dialplan to clean it up. And you will need to clean it up (delete records) if you use the internal database. I was suggesting the use of an external database. I use MySQL for my permanent storage. Get familiar with func_odbc.conf and sql and it will open quite a few doors when it comes to Asterisk application programming.

I left an example of the table layout I use for collecting queued calls.
queue_clid = the caller id of the caller
queue_name = the name of the queue
queue_start = the timestamp when the caller entered the queue
queue_stop = the timestamp when the call was answered from the queue, the caller hung up, or some dtmf event occurred
queue_stop_type = a=answered, h=hung up while waiting in the queue, [0-9]=caller pressed a number
queue_agent_phone = the device of the agent who answered the call (ex. SIP/1001)

If you receive a call in, do a sql query to see if that CALLERID(num) is found in the queue_clid since midnight (example).
select queue_agent_phone from queue_log where queue_clid=’${CALLERID(num)}’ and queue_start >= ‘2015-11-19 00:00:00’ and queue_agent_phone IS NOT NULL

The agi program (listed) will update the table with the queue_stop, queue_stop_type, and queue_agent_phone if the call is answered.

You may want to use this in combination with an agent_log table so you can see which agent answered the call if your agents aren’t always using the same device.

I should refine the query to get the last person the caller talked to…

select queue_agent_phone from queue_log where queue_clid=’${CALLERID(num)}’ and queue_start >= ‘2015-11-19 00:00:00’ and queue_agent_phone IS NOT NULL order by queue_stop DESC limit 1

This is better if the caller has called multiple times.

Thank you very much for yours answers, I will try what you said.