6.5. extensions.conf

Both agent and caller access to the queue are configured in the dialplan (Chapter 3, Programming in the dialplan). Agents log in as queue members via particular extensions, and callers are placed into the queue with the Queue() application (Section B.88, “Queue()).
A minimal extension, which places callers in the queue, might look like this:
exten => 20,1,Answer()                   ; answer
exten => 20,n,Set(MUSICCLASS()=default)  ; set music class "default"
exten => 20,n,Queue(support,t)           ; place call in "support" queue
exten => 20,n,Hangup()                   ; hang-up
We prefer something more complete and use this extension:
exten => 20,n,Wait(2)
exten => 20,n,Answer()                   ; answer
exten => 20,n,Set(MUSICCLASS()=default)  ; set music class default
exten => 20,n,Queue(support,t)           ; place call in "support" queue
; a reminder: the option t allows the agent to 
; transfer calls to another extension
; if call can't be placed in queue,
; Queue() sets QUEUESTATUS =
; and exits:
exten => 20,n,Goto(q-${QUEUESTATUS},1)  ; jump depending on QUEUESTATUS

; no agents in the queue:
; (you could also route calls to VoiceMail() here)
exten => q-JOINEMPTY,1,Wait(1)
exten => q-JOINEMPTY,n,Playback(vm-nobodyavail,noanswer)
exten => q-JOINEMPTY,n,Playback(vm-goodbye,noanswer)
exten => q-JOINEMPTY,n,Hangup()

; no agents in the queue (or only unavailable agents):
exten => q-JOINUNAVAIL,1,Goto(q-JOINEMPTY,1)   ; handle same as JOINEMPTY

; all agents have logged out:
exten => q-LEAVEEMPTY,1,Goto(q-JOINEMPTY,1)    ; handle same as JOINEMPTY

; alle agents (including unavailable agents) have logged out:
exten => q-LEAVEUNAVAIL,1,Goto(q-JOINEMPTY,1)  ; handle same as JOINEMPTY

; no agent is answering:
exten => q-TIMEOUT,1,Goto(q-JOINEMPTY,1)       ; handle same as JOINEMPTY

; The number of callers in the queue has hit the maximum:
; (you could also route calls to VoiceMail() here)
exten => q-FULL,1,Busy(5)
exten => q-FULL,n,Hangup()
If we call this extension now, we hear the "nobody is available" message, because no agents are logged in (iIf you want to fake it, set joinempty=yes and leaveempty=no in queues.conf).
We are still missing an extension through which agents can log in:
exten => 25,1,Answer()       ; answer
exten => 25,n,AgentLogin()   ; log the agent in
exten => 25,n,Hangup()       ; hang-up
AgentLogin() establishes an active channel, and incoming calls are simply switched into this active channel. This is analogous to having the phone off the hook and calls simply coming in without the agent actually having to pick up. If the agent hangs up, she is logged out. This also means that an agent cannot be logged in and make outgoing calls at the same time. As a result, AgentLogin() is only really appropriate for purely inbound call center groups.
AgentCallbackLogin() has the advantage of letting agents log in, and then having the system call back with calls from the queue. They remain logged in after hanging up and can make outgoing calls. This application is, however, deprecated as of Version 1.4.
The example in doc/queues-with-callback-members.txt uses AEL (but this can easily be converted into regular dialplan format)
to identify agents, AddQueueMember() to dynamically add members to the queue and Dial() to call agents back.
If AgentCallbackLogin() were to disappear without a replacement, real functionality and ease of configuration would be lost. (Again, special thanks to Markus Bönke!)
We leave the reader the following exercise: Write a dialplan which brings callers to an IVR menu first; for example, "For sales, press 1; for returns, press 2." and then pass callers to two separate queues, one for each department, depending on the input the caller gives.