QueueMetrics > Outbound and QueueMetrics

alternative dialplan for using outbound queues

(1/1)

qmax:
Here is dialplan we developed for our call-center.
I'm not sure it works perfectly in all cases, but for last months it showed no problems.
I'm publishing it here in hope that it may appear useful for someone else,
and may be improved by community.

Features are:

* agents do register on the line using special dial-code
* all outbound calls from registered line assigned to that agent and queue
* calls w/out agent registration are prohibited
* agents are marked on pause between calls
* agents do release line using another dial-code
* dialplan handles bogus registration/deregistration
* registration data stored in astdb and thus stay persistent
* there's one easter egg inside
This example uses:

* code 08*agentnum*queuenum - for registering line, agentnum is exact 3 digits. im not sure if pattern with "*.*." will work
* code 09 - for releasing line
* code 22 - as pause code between calls
* Dial(Local/...@outbound-allroutes) for making external calls. the context outbound-allroutes is taken from dialplan generated by FreePBX outbound calls routing. it simply selects appropriate trunk for call.
* playing "agent-music" while dialing
* various custom speech files from directory callcenter/ for audial status and actions confirmation
* recording all calls into /var/spool/asterisk/monitor/q${QUEUEID}-${UNIQUEID}.wavAll this stuff could and probably should be adjusted.


--- Code: ---[callcenter]
; NB: adjust terminal devices to do not handle '*'-containg codes
exten => _08*XXX*.,1,Answer
exten => _08*XXX*.,n,Macro(register-outque,${CALLERID(num)},${EXTEN:3:3},${EXTEN:7})
exten => _08*XXX*.,n,Hangup

exten => _09,1,Answer
exten => _09,n,Macro(unregister-outque,${CALLERID(num)})
exten => _09,n,Hangup

exten => _NXXXXX.,1,Answer
exten => _NXXXXX.,n,GotoIf($[${DB_EXISTS(outques/${CALLERID(num)}/agent)}]?:notregistered)
exten => _NXXXXX.,n,Macro(outbound-queue-call,${CALLERID(num)},${EXTEN})
exten => _NXXXXX.,n,Hangup
exten => _NXXXXX.,n(notregistered),Playback(callcenter/agent-registration-required)
exten => _NXXXXX.,n,Hangup

; telling the line number
exten => *65,1,Answer()
exten => *65,n,Playback(callcenter/nomer-linii)
exten => *65,n,SayDigits(${CALLERID(num)})
exten => *65,n,Hangup()

; telling the line agent and queue
exten => *64,1,Answer()
exten => *64,n,GotoIf($[${DB_EXISTS(outques/${CALLERID(num)}/agent)}]?:notregistered)
exten => *64,n,Set(AGENTID=${DB(outques/${CALLERID(num)}/agent)})
exten => *64,n,Set(QUEUEID=${DB(outques/agent${AGENTID}/queue)})
exten => *64,n,Playback(callcenter/line-registered-&callcenter/for-agent-)
exten => *64,n,SayDigits(${AGENTID})
exten => *64,n,Playback(callcenter/in-queue-)
exten => *64,n,SayDigits(${QUEUEID})
exten => *64,n,Hangup
exten => *64,n(notregistered),Playback(callcenter/line-is-not registered)
exten => *64,n,Hangup

[macro-register-outque]
exten => s,1,NoOp(CC: registering line ${ARG1} for agent ${ARG2} in queue ${ARG3})
exten => s,n,MacroIf($[${DB_EXISTS(outques/${ARG1}/agent)}]?unregister-outque,${ARG1})
exten => s,n,MacroIf($[${DB_EXISTS(outques/agent${ARG2}/line)}]?unregister-outque,${DB(outques/agent${ARG2}/line)})
exten => s,n,Set(LINE=${ARG1})
exten => s,n,Set(AGENTID=${ARG2})
exten => s,n,Set(QUEUEID=${ARG3})
exten => s,n,Set(DB(outques/${LINE}/agent)=${AGENTID})
exten => s,n,Set(DB(outques/agent${AGENTID}/queue)=${QUEUEID})
exten => s,n,Set(DB(outques/agent${AGENTID}/line)=${CALLERID(num)})
exten => s,n,QueueLog(${QUEUEID},${UNIQUEID},Agent/${AGENTID},ADDMEMBER)
exten => s,n,QueueLog(NONE,NONE,Agent/${AGENTID},PAUSEALL)
exten => s,n,QueueLog(NONE,${UNIQUEID},Agent/${AGENTID},PAUSEREASON,22)
exten => s,n,Playback(callcenter/line-registered-&callcenter/for-agent-)
exten => s,n,SayDigits(${AGENTID})
exten => s,n,Playback(callcenter/in-queue-)
exten => s,n,SayDigits(${QUEUEID})

[macro-unregister-outque]
exten => s,1,NoOp(CC: releasing line ${ARG1})
exten => s,n,Set(LINEID=${ARG1})
exten => s,n,Set(AGENTID=${DB(outques/${LINEID}/agent)})
exten => s,n,GotoIf($["${AGENTID}"=""]?skip)
exten => s,n,Set(QUEUEID=${DB(outques/agent${AGENTID}/queue)})
exten => s,n,DbDel(outques/${LINEID}/agent)
exten => s,n,DbDel(outques/agent${AGENTID}/line)
exten => s,n,DbDel(outques/agent${AGENTID}/queue)
exten => s,n,QueueLog(${QUEUEID},${UNIQUEID},Agent/${AGENTID},REMOVEMEMBER)
exten => s,n,Playback(callcenter/line-released)
exten => s,n,MacroExit()
exten => s,n(skip),Playback(callcenter/line-was-not-registered)
exten => s,n,MacroExit()

[macro-outbound-queue-call]
exten => s,1,NoOp(CC: outbound call from ${ARG1} to ${ARG2})
exten => s,n,Set(CALLER=${ARG1})
exten => s,n,Set(DIALNUM=${ARG2})
exten => s,n,Set(AGENTID=${DB(outques/${CALLER}/agent)})
exten => s,n,Set(QUEUEID=${DB(outques/agent${AGENTID}/queue)})
exten => s,n,QueueLog(NONE,NONE,Agent/${AGENTID},UNPAUSEALL)
exten => s,n,QueueLog(${QUEUEID},${UNIQUEID},Agent/${AGENTID},CALLOUTBOUND,-,${DIALNUM})
exten => s,n,Dial(Local/${DIALNUM}@outbound-allroutes,30,m(agent-music)M(outbound-answer^${CALLER}^${UNIQUEID}^${QUEUEID}^${AGENTID}^${EPOCH})g)
exten => s,n,NoOp(CC: outbound call from ${CALLER} to ${DIALNUM} canceled: ${DIALSTATUS})
exten => s,n,QueueLog(NONE,NONE,Agent/${AGENTID},PAUSEALL)
exten => s,n,QueueLog(NONE,${UNIQUEID},Agent/${AGENTID},PAUSEREASON,22)
exten => s,n,GotoIf($["${DIALSTATUS}" == "ANSWER"]?answered)
exten => s,n(failed),QueueLog(${QUEUEID},${UNIQUEID},Agent/${AGENTID},ABANDON,1,1,${DIALEDTIME})
exten => s,n,Playback(callcenter/${DIALSTATUS})
exten => s,n,MacroExit()
exten => s,n(answered),QueueLog(${QUEUEID},${UNIQUEID},Agent/${AGENTID},COMPLETEAGENT,$[${DIALEDTIME} - ${ANSWEREDTIME}],${ANSWEREDTIME})
exten => s,n,Playback(callcenter/CANCEL)
exten => s,n,Wait(3)
exten => s,n,Playback(callcenter/how-vexing-excl)
exten => s,n,MacroExit()

exten => h,1,NoOp(CC: outbound call from ${CALLER} to ${DIALNUM} completed: ${DIALSTATUS})
exten => h,n,QueueLog(NONE,NONE,Agent/${AGENTID},PAUSEALL)
exten => h,n,QueueLog(NONE,${UNIQUEID},Agent/${AGENTID},PAUSEREASON,22)
exten => h,n,GotoIf($["${DIALSTATUS}" == "ANSWER"]?answered)
; CHANUNAVAIL | CONGESTION | NOANSWER | BUSY | CANCEL
exten => h,n(failed),QueueLog(${QUEUEID},${UNIQUEID},Agent/${AGENTID},ABANDON,1,1,${DIALEDTIME})
exten => h,n,MacroExit()
; ANSWERED
exten => h,n(answered),QueueLog(${QUEUEID},${UNIQUEID},Agent/${AGENTID},COMPLETECALLER,$[${DIALEDTIME} - ${ANSWEREDTIME}],${ANSWEREDTIME})
exten => h,n,MacroExit()

[macro-outbound-answer]
exten => s,1,NoOp(CC: connection in outbound queue: caller:${ARG1} uid:${ARG2} queue:${ARG3} agent:${ARG4} time:${ARG5})
exten => s,n,MixMonitor(/var/spool/asterisk/monitor/q${ARG3}-${ARG2}.wav)
exten => s,n,QueueLog(${ARG3},${ARG2},Agent/${ARG4},CONNECT,$[${EPOCH} - ${ARG5}])

--- End code ---

QueueMetrics:
that's coooll!

Navigation

[0] Message Index

Go to full version