Asterisk Queues using AddQueueMember
From Etel
Contents |
Title
How to implement queues and agents using AddQueueMember
Problem
You want to use Queues in Asterisk, but you want to do it in a way where you are not the using deprecated AgentCallBack methods. The solution shows practical examples of using While loops, ARRAY() and CUT().
Solution
In this example we are going to have 2 queues, "sales" and "support". Sales personel will take support calls only if all technical support reps are busy. We assume for this solution all agents will have their extension set as their callerid number.
First thing we'll do is set up the 2 queues.
queues.conf
[general] autofill=yes [sales] strategy=rrmemory ringinuse=no joinempty=no [support] strategy=rrmemory ringinuse=no joinempty=no
Next we'll set up the agent information for authentication. If you have used Agents before, you can reuse the agents.conf file in this scenerio.
agents.conf
[agents] ; agent => <agentid>,<password>,<name> agent => 1000,0001,Agent A agent => 1001,1001,Agent B agent => 1002,2001,Agent C agent => 1003,3001,Agent D
sip.conf Using Templates for easier maintenance.
; Create the sales-agents template [sales-agents](!) context=sales-agents ... ; Create the support-agents template [support-agents](!) context=support-agents ... ; Create 2 sales agents [2001](sales-agents) callerid=Sales Person 1 <2000> ... [2002](sales-agents) callerid=Sales Person 2 <2001> ... ; Create 2 support agents [3001](support-agents) callerid=Support Person 1 <3001> ... [3002](support-agents) callerid=Support Person 2 <3002> ...
extensions.conf
[globals]
AGENT_CONTEXT=agents
[queues]
; Incoming calls to your DID's should direct to the correct queue in this context.
exten => 1000,1,Answer
exten => 1000,n,Queue(sales)
exten => 1000,n,Voicemail(<Sales voicemail info here>)
exten => 1001,1,Answer
exten => 1001,n,Queue(support)
exten => 1001,n,Voicemail(<Support voicemail info here>)
[agents]
; This context is used to dial the agent, Note: we're not sending the calls into voicemail on no answer.
exten => _XXXX,1,Dial(SIP/${EXTEN})
[sales-agents]
include => agents
include => agent-functions
; Login
exten => 54,1,Set(QUEUEDST=support-2\,sales-1)
exten => 54,n,Goto(login,1)
; Logout
exten => 56,1,Set(QUEUEDST=support-2\,sales-1)
exten => 56,n,Goto(logout,1)
; Pause
exten => 55,1,Goto(pause,1)
; UnPause
exten => 58,1,Goto(unpause,1)
[support-agents]
include => agents
include => agent-functions
; Login
exten => 54,1,Set(QUEUEDST=support-1)
exten => 54,n,Goto(login,1)
; Logout
exten => 56,1,Set(QUEUEDST=support-1)
exten => 56,n,Goto(logout,1)
; Pause
exten => 55,1,Goto(pause,1)
; UnPause
exten => 58,1,Goto(unpause,1)
[agent-functions]
;-- This context contains all standard agent actions
All Actions here expect the AGENT_CONTEXT variable which contains the context which has the dialplan to reach the agent.
We also expect ${CALLERID(num)}@${AGENT_CONTEXT} to be able to reach the agent.
--;
;-- login: Authenticate against the agentid/password in agents.conf
Expects the following additional variable to be set:
QUEUEDST = A comma delimited list of queues to add the user to. If you wish to pass
the penalty append it to the end of the queue name seperated by a dash '-'
Example: Set(QUEUEDST=queue1-1\,queue2-5\) which tells us to add the user to 2 queues,
queue1 with a penalty of 1, and queue2 with a penalty of 5.
--;
exten => login,1,Answer()
exten => login,n,Set(COUNTER=0)
exten => login,n,Set(AGENT_SOUND=agent-user)
exten => login,n(agent),Set(COUNTER=$[${COUNTER}+1])
; Prompt for the AgentID
exten => login,n,Read(AID,${AGENT_SOUND});
; If the password exists in agents.conf jump to authenticate agent
; Note: AGENT() is a function to retrieve the agent information
exten => login,n,GotoIf($["${AGENT(${AID}:password)}"!=""]?auth)
exten => login,n,ExecIf($[${COUNTER}<3],Set,AGENT_SOUND=agent-incorrect)
exten => login,n,ExecIf($[${COUNTER}<3],Goto,agent)
; Entered an invalid agentid 3 times, Playback an error beep and hangup.
exten => login,n,Playback(beeperr)
exten => login,n,Hangup
; Authenticate against the agents.conf password
exten => login,n(auth),Authenticate(${AGENT(${AID}:password)})
exten => login,n,Set(i=1)
; Begin the loop for the queues, FIELDQTY will find how many queues we are passing in QUEUEDST delimited by a comma
exten => login,n,While($[${i}<=${FIELDQTY(QUEUEDST,\,)}])
; For each Queue Record, split the name and penalty on a dash and set the variables.
exten => login,n,Set(ARRAY(CURRENT_QUEUE,CURRENT_PENALTY)=${CUT(CUT(QUEUEDST,\,,${i}),,1)},${CUT(CUT(QUEUEDST,\,,${i}),,2)})
; Add the Agent to the queue
exten => login,n,AddQueueMember(${CURRENT_QUEUE},Local/${CALLERID(num)}@${AGENT_CONTEXT}/n,${CURRENT_PENALTY},,${AGENT(${AID}:name)})
exten => login,n,Set(i=$[${i}+1])
exten => login,n,EndWhile
; We're only catching the last AddQueueMember status here.
exten => login,n,ExecIf($["${AQMSTATUS}"="NOSUCHQUEUE"],Playback,sorry&an-error-has-occured)
; If we are either ADDED or MEMBERALREADY playback the agent-loginok message..
exten => login,n,ExecIf($["${AQMSTATUS}"!="NOSUCHQUEUE"],Playback,agent-loginok)
exten => login,n,Hangup
;-- logout: Handles the logging out of the queues
Expects the following additional variable to be set:
QUEUEDST = A comma delimited list of queues to remove the user from. Penalties will be ignored.
--;
exten => logout,1,Answer()
exten => logout,n,Set(i=1)
exten => logout,n,While($[${i}<=${FIELDQTY(QUEUEDST,\,)}])
exten => logout,n,Set(CURRENT_QUEUE=${CUT(QUEUEDST,\,,${i})})
exten => logout,n,RemoveQueueMember(${CURRENT_QUEUE}|Local/${CALLERID(num)}@${AGENT_CONTEXT}/n)
exten => logout,n,Set(i=$[${i}+1])
exten => logout,n,EndWhile
exten => logout,n,Playback(agent-loggedoff)
exten => logout,n,Hangup
;-- pause: Pause the queue member from all queues. --;
exten => pause,1,Answer()
exten => pause,n,PauseQueueMember(|Local/${CALLERID(num)}@${AGENT_CONTEXT}/n)
exten => pause,n,NoOp(${PQMSTATUS})
; Play stutter tones. There is currently no stock voice file for this
exten => pause,n,PlayTones(!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440)
exten => pause,n,Wait(1.5)
exten => pause,n,Hangup
;-- unpause: Unpase the queue member from all queues. --;
exten => unpause,1,Answer()
exten => unpause,n,UnPauseQueueMember(|Local/${CALLERID(num)}@${AGENT_CONTEXT}/n)
exten => unpause,n,NoOp(${UPQMSTATUS})
; Play short stutter tones, no stock voice file for this.
exten => unpause,n,PlayTones(!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440)
exten => unpause,n,Wait(1.0)
exten => unpause,n,Hangup
Discussion
See Also:
Metadata
David Van Ginneken davevg@btwtech.com
