[general] static=yes ; never rewrite this file writeprotect=yes autofallthrough=yes ; hang up if end of dialplan is reached clearglobalvars=yes ; clear global vars on dialplan reload [globals] #include ext_utils.conf ; include utilities #include ext_ivr.conf ; include IVR TRANSFER_CONTEXT=transfer [transfer] exten => 0,1,Verbose(TRANSFER IVR) same => n,Set(__IS_RECORDING=0) same => n,StopMixMonitor() same => n,ForkCDR(erv) same => n,Gosub(pre-any,s,1(IVR,TRANSFER)) same => n,Gosub(ivr,s,1) same => n,Wait(0.5) same => n,Hangup() exten => _Z,1,Verbose(TRANSFER) same => n,Set(__IS_RECORDING=0) same => n,StopMixMonitor() same => n,ForkCDR(erv) same => n,Gosub(pre-any,s,1(${EXTEN},TRANSFER)) same => n,Gosub(inbound-queued,s,1(${EXTEN})) same => n,Wait(0.5) same => n,Hangup() include => catchall [pre-any] exten => s,1,Gosub(clear-callerid,s,1) same => n,Set(__CALLER=${CALLERID(num)}) same => n,Set(__CALLEE=${ARG1}) same => n,Set(__CALL_OPERATION=${ARG2}) same => n,Set(CDR(actualsrc)=${CALLER}) same => n,Set(CDR(actualdst)=${CALLEE}) same => n,Set(CDR(realcall)=1) same => n,Verbose(${CALL_OPERATION}: ${CALLER} -> ${CALLEE}) same => n,Set(LIMIT_PLAYAUDIO_CALLER=no,LIMIT_PLAYAUDIO_CALLEE=yes) same => n,Set(LIMIT_TIMEOUT_FILE=custom/call-expired) same => n,Set(LIMIT_WARNING_FILE=custom/call-expiring-soon) same => n,Return() [pre-call] exten => s,1,Gosub(volume-setup,s,1) same => n,Gosub(record-start,s,1) same => n,Set(CDR(realcall)=2) same => n,Set(CDR(startedat)=${EPOCH}) same => n,Set(CDR(actualdisposition)=ANSWERED) same => n,Set(CDR(actualdst2)=${CALLERID(num)}) same => n,Return() [pre-out-call] exten => s,1,Gosub(volume-setup,s,1) same => n,Gosub(record-start,s,1) same => n,Set(CDR(realcall)=2) same => n,Set(CDR(startedat)=${EPOCH}) same => n,Return() ; 1.1. Place an inbound call into a single queue [inbound-queued] exten => s,1,Gosub(pre-any,s,1(${ARG1},INBOUND-QUEUED)) same => n,Verbose(DS ${DEVICE_STATE(PJSIP/${CALLEE})}) same => n,GosubIf($["${DEVICE_STATE(PJSIP/${CALLEE})}" = "BUSY"]?inbound-queued-busy,s,1) same => n,GosubIf($["${DEVICE_STATE(PJSIP/${CALLEE})}" = "INUSE"]?inbound-queued-busy,s,1) same => n,GosubIf($["${DEVICE_STATE(PJSIP/${CALLEE})}" = "RINGINUSE"]?inbound-queued-busy,s,1) same => n,GosubIf($["${DEVICE_STATE(PJSIP/${CALLEE})}" = "RINGING"]?inbound-queued-busy,s,1) same => n,GosubIf($["${DEVICE_STATE(PJSIP/${CALLEE})}" = "UNAVAILABLE"]?inbound-queued-unavail,s,1) same => n,Queue(queue-${CALLEE},inrt,,,,,,pre-call) same => n,Wait(0.5) same => n,Hangup() ; 1.2. Callee is busy, play a message (if appropriate) and place it into a single queue [inbound-queued-busy] exten => s,1,Verbose(QUEUED BUSY) same => n,GotoIf($["${CALLEE}"="9"]?busy-le) same => n,GotoIf($[ $["${CALLEE}"="6"] | $["${CALLEE}"="8"] | $["${CALLEE}"="10"] | $["${CALLEE}"="12"] ]?busy-spb) same => n,Background(custom/this-busy-ask-redirect,m,,inbound-queued-select-busy)) same => n,Queue(queue-${CALLEE},inrt,,,,,,pre-call) same => n,Wait(0.5) same => n,Hangup() same => n(busy-le),Playback(custom/this-busy-le) same => n,Queue(queue-${CALLEE},inrt,,,,,,pre-call) same => n,Wait(0.5) same => n,Hangup() same => n(busy-spb),Playback(custom/this-busy-spb) same => n,Queue(queue-${CALLEE},inrt,,,,,,pre-call) same => n,Wait(0.5) same => n,Hangup() ; 1.25. Callee is not available, play a message and place it into a single queue ;same => n,GosubIf($[ $["${CALLEE}"="6"] | $["${CALLEE}"="8"] | $["${CALLEE}"="10"] | $["${CALLEE}"="12"] ]?inbound-queued-unavail-spb,s,1) [inbound-queued-unavail] exten => s,1,Verbose(QUEUED UNAVAIL) same => n,GosubIf($["${CALLEE}"="9"]?inbound-queued-unavail-le,s,1) same => n,Playback(custom/this-unavail-will-redirect) same => n,Set(CDR(ivr)=3) same => n,Queue(queue-some-${CALLEE},inrt,,,,,,pre-call) same => n,Wait(0.5) same => n,Hangup() ; 1.25.1 LE callee is not available, play a message and hang up [inbound-queued-unavail-le] exten => s,1,Playback(custom/this-unavail-le) same => n,Wait(0.5) same => n,Hangup() ; 1.25.2 SPB callee is not available, play a message and hang up ;[inbound-queued-unavail-spb] ;exten => s,1,Playback(custom/this-unavail-spb) ; same => n,Wait(0.5) ; same => n,Hangup() ; 1.3. Caller has requested to join a "some" queue, place it there [inbound-queued-to-some] exten => s,1,Verbose(QUEUE TO SOME) same => n,Set(CDR(ivr)=3) same => n,Queue(queue-some-${CALLEE},inrt,,,,,,pre-call) same => n,Wait(0.5) same => n,Hangup() ; 1.1.1. Allow callers to exit from a background playback to dial some [inbound-queued-select-busy] exten => 1,1,Gosub(inbound-queued-to-some,s,1) ; 1.2.1. Allow callers to exit from a queue to dial some ; Invalid DTMF keypresses get redirected back to inbound queue [inbound-queued-inqueue-busy] exten => 1,1,Gosub(inbound-queued-to-some,s,1) exten => i,1,Gosub(inbound-queued,s,1(${CALLEE})) ; Inbound calls from Multifon trunk to LE endpoint (9) [inbound-multifon] exten => _Z.,1,Gosub(inbound-queued,s,1(9)) same => n,Hangup() ; Inbound calls from Dom.ru 222003 endpoint directly to ext 1 [inbound-domru-3] exten => _Z.,1,Gosub(inbound-queued,s,1(1)) same => n,Hangup() ; Inbound calls from Dom.ru 222004 endpoint to IVR [inbound-domru-4] exten => _Z.,1,Gosub(pre-any,s,1(IVR,INBOUND)) same => n,Gosub(ivr,s,1) same => n,Wait(0.5) same => n,Hangup() ; Inbound calls from Smart SPB trunk to SPB IVR [inbound-smart-spb] exten => _Z.,1,Gosub(pre-any,s,1(IVR,INBOUND)) same => n,Gosub(ivr-spb,s,1) same => n,Wait(0.5) same => n,Hangup() ; Outbound calls from all local endpoints [outbound] exten => _Z,hint,PJSIP/${EXTEN} exten => _ZX,hint,PJSIP/${EXTEN} exten => _Z,1,Gosub(outbound-internal,s,1(${EXTEN})) exten => _ZX,1,Gosub(outbound-internal,s,1(${EXTEN})) exten => _7XXXXXXXXXX,1,GosubIf($[ $["${CALLERID(num)}"="6"] | $["${CALLERID(num)}"="8"] | $["${CALLERID(num)}"="10"] | $["${CALLERID(num)}"="12"] ]?outbound-external,s,1(8${EXTEN:1}):outbound-external,s,1(+${EXTEN})) exten => _8XXXXXXXXXX,1,GosubIf($[ $["${CALLERID(num)}"="6"] | $["${CALLERID(num)}"="8"] | $["${CALLERID(num)}"="10"] | $["${CALLERID(num)}"="12"] ]?outbound-external,s,1(${EXTEN}):outbound-external,s,1(+7${EXTEN:1})) exten => _+7XXXXXXXXXX,1,GosubIf($[ $["${CALLERID(num)}"="6"] | $["${CALLERID(num)}"="8"] | $["${CALLERID(num)}"="10"] | $["${CALLERID(num)}"="12"] ]?outbound-external,s,1(8${EXTEN:2}):outbound-external,s,1(${EXTEN})) exten => _9XXXXXXXXX,1,GosubIf($[ $["${CALLERID(num)}"="6"] | $["${CALLERID(num)}"="8"] | $["${CALLERID(num)}"="10"] | $["${CALLERID(num)}"="12"] ]?outbound-external,s,1(8${EXTEN}):outbound-external,s,1(+7${EXTEN})) exten => _XXXXXX,1,Gosub(outbound-external,s,1(+78332${EXTEN})) exten => _XXXXXXX,1,GosubIf($[ $["${CALLERID(num)}"="6"] | $["${CALLERID(num)}"="8"] | $["${CALLERID(num)}"="10"] | $["${CALLERID(num)}"="12"] ]?outbound-external,s,1(${EXTEN})) include => service include => catchall ; Internal calls [outbound-internal] exten => s,1,Gosub(pre-any,s,1(${ARG1},INTERNAL)) same => n,GotoIf($["${CALLERID(number)}" = "${ARG1}"]?busy,s,1) ; dialing the same extension as caller same => n,GotoIf($["${DEVICE_STATE(PJSIP/${ARG1})}" = "INVALID"]?invalid-ext,s,1) ; extension is invalid same => n,GotoIf($["${DEVICE_STATE(PJSIP/${ARG1})}" = "UNAVAILABLE"]?offline-ext,s,1) ; extension is valid but offline same => n,Dial(PJSIP/${ARG1},900,girtTL(3600000:60000)U(pre-out-call)) same => n,Wait(0.5) same => n,Hangup() [outbound-external] exten => s,1,Gosub(pre-any,s,1(${ARG1},OUTBOUND)) same => n,GosubIf($[${CALLERID(num)} = 9]?outbound-multifon,s,1(${ARG1})) same => n,GosubIf($[${CALLERID(num)} = 6]?outbound-smart-spb,s,1(${ARG1})) same => n,GosubIf($[${CALLERID(num)} = 8]?outbound-smart-spb,s,1(${ARG1})) same => n,GosubIf($[${CALLERID(num)} = 10]?outbound-smart-spb,s,1(${ARG1})) same => n,GosubIf($[${CALLERID(num)} = 12]?outbound-smart-spb,s,1(${ARG1})) same => n,Gosub(outbound-domru,s,1(${ARG1})) same => n,Wait(0.5) same => n,Hangup() [outbound-multifon] exten => s,1,Dial(PJSIP/${ARG1}@endpoint-multifon,900,irTL(3600000:60000)U(pre-out-call)) same => n,Wait(0.5) same => n,Hangup() [outbound-domru] exten => s,1,Dial(PJSIP/${ARG1}@endpoint-domru-4,900,irTL(3600000:60000)U(pre-out-call)) same => n,Wait(0.5) same => n,Hangup() [outbound-smart-spb] exten => s,1,Dial(PJSIP/${ARG1}@endpoint-smart-spb,900,irTL(3600000:60000)U(pre-out-call)) same => n,Wait(0.5) same => n,Hangup() [service] ; Simple ring test exten => 001,1,Ringing() same => n,Wait(20) same => n,Hangup() ; Hello World playback exten => 002,1,Answer(250) same => n,Playback(hello-world) same => n,Wait(0.5) same => n,Hangup() ; Echo test exten => 003,1,Answer(250) same => n,Playback(demo-echotest) same => n,Echo same => n,Playback(demo-echodone) same => n,Wait(0.5) same => n,Hangup() ; Internal IVR exten => 004,1,Answer(250) same => n,Gosub(ivr,s,1) same => n,Wait(0.5) same => n,Hangup() ; Congestion test exten => 005,1,Congestion() same => n,Wait(20) same => n,Hangup() [catchall] exten => _X.,1,Gosub(invalid-ext,s,1) ; go to invalid extension macro on all extensions exten => i,1,Gosub(invalid-ext,s,1) ; same, but with invalid extensions