| 1 |
; FreePBX |
|---|
| 2 |
; Copyright (C) 2004 Coalescent Systems Inc (Canada) |
|---|
| 3 |
; Copyright (C) 2006 Why Pay More 4 Less Pty Ltd (Australia) |
|---|
| 4 |
; Released under the GNU GPL Licence version 2. |
|---|
| 5 |
|
|---|
| 6 |
; dialparties.agi (http://www.sprackett.com/asterisk/) |
|---|
| 7 |
; Asterisk::AGI (http://asterisk.gnuinter.net/) |
|---|
| 8 |
; gsm (http://www.ibiblio.org/pub/Linux/utils/compress/!INDEX.short.html) |
|---|
| 9 |
; loligo sounds (http://www.loligo.com/asterisk/sounds/) |
|---|
| 10 |
; mpg123 (http://voip-info.org/wiki-Asterisk+config+musiconhold.conf) |
|---|
| 11 |
|
|---|
| 12 |
|
|---|
| 13 |
; include extension contexts generated from AMP |
|---|
| 14 |
#include extensions_additional.conf |
|---|
| 15 |
|
|---|
| 16 |
; Customizations to this dialplan should be made in extensions_custom.conf |
|---|
| 17 |
; See extensions_custom.conf.sample for an example |
|---|
| 18 |
#include extensions_custom.conf |
|---|
| 19 |
|
|---|
| 20 |
[from-trunk] ; just an alias since VoIP shouldn't be called PSTN |
|---|
| 21 |
include => from-pstn |
|---|
| 22 |
|
|---|
| 23 |
[from-pstn] |
|---|
| 24 |
include => from-pstn-custom ; create this context in extensions_custom.conf to include customizations |
|---|
| 25 |
include => ext-did-direct ; MODIFICATOIN (PL) put before ext-did to take precedence |
|---|
| 26 |
include => ext-did |
|---|
| 27 |
include => from-did-direct ; MODIFICATOIN (PL) for findmefollow if enabled, should be bofore ext-local |
|---|
| 28 |
exten => fax,1,Goto(ext-fax,in_fax,1) |
|---|
| 29 |
|
|---|
| 30 |
; MODIFICATION (PL) |
|---|
| 31 |
; |
|---|
| 32 |
; Required to assure that direct dids go to personal ring group before local extension. |
|---|
| 33 |
; This could be auto-generated however I it is prefered to be put here and hard coded |
|---|
| 34 |
; so that it can be modified if ext-local should take precedence in certain situations. |
|---|
| 35 |
; will have to decide what to do later. |
|---|
| 36 |
; |
|---|
| 37 |
[from-did-direct] |
|---|
| 38 |
include => ext-findmefollow |
|---|
| 39 |
include => ext-local |
|---|
| 40 |
|
|---|
| 41 |
|
|---|
| 42 |
|
|---|
| 43 |
; ############################################################################ |
|---|
| 44 |
; Macros [macro] |
|---|
| 45 |
; ############################################################################ |
|---|
| 46 |
|
|---|
| 47 |
; Rings one or more extensions. Handles things like call forwarding and DND |
|---|
| 48 |
; We don't call dial directly for anything internal anymore. |
|---|
| 49 |
; ARGS: $TIMER, $OPTIONS, $EXT1, $EXT2, $EXT3, ... |
|---|
| 50 |
; Use a Macro call such as the following: |
|---|
| 51 |
; Macro(dial,$DIAL_TIMER,$DIAL_OPTIONS,$EXT1,$EXT2,$EXT3,...) |
|---|
| 52 |
[macro-dial] |
|---|
| 53 |
exten => s,1,DeadAGI(dialparties.agi) |
|---|
| 54 |
exten => s,2,NoOp(Returned from dialparties with no extensions to call) |
|---|
| 55 |
exten => s,3,NoOp(DIALSTATUS is '${DIALSTATUS}') |
|---|
| 56 |
|
|---|
| 57 |
exten => s,10,Dial(${ds}) ; dialparties will set the priority to 10 if $ds is not null |
|---|
| 58 |
|
|---|
| 59 |
exten => s,20,NoOp(Returned from dialparties with hunt groups to dial ) |
|---|
| 60 |
exten => s,21,Set(HuntLoop=0) |
|---|
| 61 |
exten => s,22,GotoIf($[${HuntMembers} >= 1]?30 ) ; if this is from rg-group, don't strip prefix |
|---|
| 62 |
exten => s,23,NoOp(Returning there are no members left in the hunt group to ring) |
|---|
| 63 |
|
|---|
| 64 |
exten => s,30,Set(HuntMember=HuntMember${HuntLoop}) |
|---|
| 65 |
exten => s,31,GotoIf($[$["${CALLTRACE_HUNT}" != "" ] & $["${RingGroupMethod}" = "hunt" ]]?32:35 ) ; Set CAll Trace for Hunt member we are going to call |
|---|
| 66 |
exten => s,32,Set(CT_EXTEN=${CUT(ARG3,,$[${HuntLoop} + 1])}) |
|---|
| 67 |
exten => s,33,Set(DB(CALLTRACE/${CT_EXTEN})=${CALLTRACE_HUNT}) |
|---|
| 68 |
exten => s,34,Goto(s,42) |
|---|
| 69 |
|
|---|
| 70 |
exten => s,35,GotoIf($[$["${CALLTRACE_HUNT}" != "" ] & $["${RingGroupMethod}" = "memoryhunt" ]]?36:50 ) ;Set Call Trace for each hunt member we are going to call "Memory groups have multiple members to set CALL TRACE For hence the loop |
|---|
| 71 |
exten => s,36,Set(CTLoop=0) |
|---|
| 72 |
exten => s,37,GotoIf($[${CTLoop} > ${HuntLoop}]?42 ) ; if this is from rg-group, don't strip prefix |
|---|
| 73 |
exten => s,38,Set(CT_EXTEN=${CUT(ARG3,,$[${CTLoop} + 1])}) |
|---|
| 74 |
exten => s,39,Set(DB(CALLTRACE/${CT_EXTEN})=${CALLTRACE_HUNT}) |
|---|
| 75 |
exten => s,40,Set(CTLoop=$[1 + ${CTLoop}]) |
|---|
| 76 |
exten => s,41,Goto(s,37) |
|---|
| 77 |
|
|---|
| 78 |
exten => s,42,Dial(${${HuntMember}}${ds} ) ; dialparties will set the priority to 20 if $ds is not null and its a hunt group |
|---|
| 79 |
exten => s,43,Set(HuntLoop=$[1 + ${HuntLoop}]) |
|---|
| 80 |
exten => s,44,Set(HuntMembers=$[${HuntMembers} - 1]) |
|---|
| 81 |
exten => s,45,Goto(s,22) |
|---|
| 82 |
exten => s,50,DBdel(CALLTRACE/${CT_EXTEN}) |
|---|
| 83 |
exten => s,51,Goto(s,42) |
|---|
| 84 |
|
|---|
| 85 |
; make sure hungup calls go here so that proper cleanup occurs from call confirmed calls and the like |
|---|
| 86 |
; |
|---|
| 87 |
exten => h,1,Macro(hangupcall) |
|---|
| 88 |
|
|---|
| 89 |
; Ring an extension, if the extension is busy or there is no answer send it |
|---|
| 90 |
; to voicemail |
|---|
| 91 |
; ARGS: $VMBOX, $EXT |
|---|
| 92 |
[macro-exten-vm] |
|---|
| 93 |
exten => s,1,Macro(user-callerid) |
|---|
| 94 |
|
|---|
| 95 |
exten => s,n,Set(FROMCONTEXT=exten-vm) |
|---|
| 96 |
exten => s,n,Set(VMBOX=${ARG1}) |
|---|
| 97 |
exten => s,n,Set(EXTTOCALL=${ARG2}) |
|---|
| 98 |
exten => s,n,Set(CFUEXT=${DB(CFU/${EXTTOCALL})}) |
|---|
| 99 |
exten => s,n,Set(RT=${IF($[$["${VMBOX}"!="novm"] | $["foo${CFUEXT}"!="foo"]]?${RINGTIMER}:"")}) |
|---|
| 100 |
exten => s,n,Macro(record-enable,${EXTTOCALL},IN) |
|---|
| 101 |
|
|---|
| 102 |
exten => s,n,Macro(dial,${RT},${DIAL_OPTIONS},${EXTTOCALL}) |
|---|
| 103 |
exten => s,n,GosubIf($[$["${DIALSTATUS}"="NOANSWER"] & $["foo${CFUEXT}"!="foo"]]?docfu,1) ; check for CFU in use on no answer |
|---|
| 104 |
exten => s,n,NoOp(Voicemail is '${VMBOX}') |
|---|
| 105 |
exten => s,n,GotoIf($["${VMBOX}" = "novm"]?s-${DIALSTATUS},1) ; no voicemail in use for this extension |
|---|
| 106 |
exten => s,n,NoOp(Sending to Voicemail box ${EXTTOCALL}) |
|---|
| 107 |
exten => s,n,Macro(vm,${VMBOX},${DIALSTATUS}) |
|---|
| 108 |
|
|---|
| 109 |
; Try the Call Forward on No Answer / Unavailable number |
|---|
| 110 |
exten => docfu,1,Set(RTCFU=${IF($["${VMBOX}"!="novm"]?${RINGTIMER}:"")}) |
|---|
| 111 |
exten => docfu,n,Dial(Local/${CFUEXT}@from-internal/n,${RTCFU},${DIAL_OPTIONS}) |
|---|
| 112 |
exten => docfu,n,Return |
|---|
| 113 |
|
|---|
| 114 |
; Extensions with no Voicemail box reporting BUSY come here |
|---|
| 115 |
exten => s-BUSY,1,NoOp(Extension is reporting BUSY and not passing to Voicemail) |
|---|
| 116 |
exten => s-BUSY,n,Playtones(busy) |
|---|
| 117 |
exten => s-BUSY,n,Busy(20) |
|---|
| 118 |
|
|---|
| 119 |
; Anything but BUSY comes here |
|---|
| 120 |
exten => _s-.,1,Playtones(congestion) |
|---|
| 121 |
exten => _s-.,n,Congestion(10) |
|---|
| 122 |
|
|---|
| 123 |
[macro-vm] |
|---|
| 124 |
exten => s,1,Macro(user-callerid,SKIPTTL) |
|---|
| 125 |
exten => s,n,Set(VMGAIN=${IF($["foo${VM_GAIN}"!="foo"]?"g(${VM_GAIN})":"")}) |
|---|
| 126 |
; |
|---|
| 127 |
; If BLKVM_OVERRIDE is set, then someone told us to block calls from going to |
|---|
| 128 |
; voicemail. This variable is reset by the answering channel so subsequent |
|---|
| 129 |
; transfers will properly function. |
|---|
| 130 |
; |
|---|
| 131 |
exten => s,n,GotoIf($["foo${DB(${BLKVM_OVERRIDE})}" != "fooTRUE"]?s-${ARG2},1) |
|---|
| 132 |
; |
|---|
| 133 |
; we didn't branch so block this from voicemail |
|---|
| 134 |
; |
|---|
| 135 |
exten => s,n,Noop(CAME FROM: ${NODEST} - Blocking VM cause of key: ${DB(BLKVM_OVERRIDE)}) |
|---|
| 136 |
|
|---|
| 137 |
exten => s-BUSY,1,NoOp(BUSY voicemail) |
|---|
| 138 |
exten => s-BUSY,n,Macro(get-vmcontext,${ARG1}) |
|---|
| 139 |
exten => s-BUSY,n,Voicemail(${ARG1}@${VMCONTEXT}|${VM_OPTS}b${VMGAIN}) ; Voicemail Busy message |
|---|
| 140 |
exten => s-BUSY,n,Goto(exit-${VMSTATUS},1) |
|---|
| 141 |
|
|---|
| 142 |
exten => s-DIRECTDIAL,1,NoOp(DIRECTDIAL voicemail) |
|---|
| 143 |
exten => s-DIRECTDIAL,n,Macro(get-vmcontext,${ARG1}) |
|---|
| 144 |
exten => s-DIRECTDIAL,n,Voicemail(${ARG1}@${VMCONTEXT}|${VM_OPTS}${VM_DDTYPE}${VMGAIN}) |
|---|
| 145 |
exten => s-DIRECTDIAL,n,Goto(exit-${VMSTATUS},1) |
|---|
| 146 |
|
|---|
| 147 |
exten => _s-.,1,Macro(get-vmcontext,${ARG1}) |
|---|
| 148 |
exten => _s-.,n,Voicemail(${ARG1}@${VMCONTEXT}|${VM_OPTS}u${VMGAIN}) ; Voicemail Unavailable message |
|---|
| 149 |
exten => _s-.,n,Goto(exit-${VMSTATUS},1) |
|---|
| 150 |
|
|---|
| 151 |
exten => o,1,Background(one-moment-please) ; 0 during vm message will hangup |
|---|
| 152 |
exten => o,n,GotoIf($["x${OPERATOR_XTN}"="x"]?nooper:from-internal,${OPERATOR_XTN},1) |
|---|
| 153 |
exten => o,n(nooper),GotoIf($["x${FROM_DID}"="x"]?nodid) |
|---|
| 154 |
exten => o,n,Dial(Local/${FROM_DID)@from-pstn) |
|---|
| 155 |
exten => o,n,Macro(hangup) |
|---|
| 156 |
exten => o,n(nodid),Dial(Local/s@from-pstn) |
|---|
| 157 |
exten => o,n,Macro(hangup) |
|---|
| 158 |
|
|---|
| 159 |
exten => a,1,Macro(get-vmcontext,${ARG1}) |
|---|
| 160 |
exten => a,n,VoiceMailMain(${ARG1}@${VMCONTEXT}) |
|---|
| 161 |
exten => a,n,Hangup |
|---|
| 162 |
|
|---|
| 163 |
exten => exit-FAILED,1,Playback(im-sorry&an-error-has-occured) |
|---|
| 164 |
exten => exit-FAILED,n,Hangup() |
|---|
| 165 |
|
|---|
| 166 |
exten => exit-SUCCESS,1,Playback(goodbye) |
|---|
| 167 |
exten => exit-SUCCESS,n,Hangup() |
|---|
| 168 |
|
|---|
| 169 |
exten => exit-USEREXIT,1,Playback(goodbye) |
|---|
| 170 |
exten => exit-USEREXIT,n,Hangup() |
|---|
| 171 |
|
|---|
| 172 |
exten => t,1,Hangup() |
|---|
| 173 |
|
|---|
| 174 |
;------------------------------------------------------------------------ |
|---|
| 175 |
; [macro-simple-dial] |
|---|
| 176 |
;------------------------------------------------------------------------ |
|---|
| 177 |
; This macro was derived from macro-exten-vm, which is what is normally used to |
|---|
| 178 |
; ring an extension. It has been simplified and designed to never go to voicemail |
|---|
| 179 |
; and always return regardless of the DIALSTATUS for any incomplete call. |
|---|
| 180 |
; |
|---|
| 181 |
; It's current primary purpose is to allow findmefollow ring an extension prior |
|---|
| 182 |
; to trying the follow-me ringgroup that is provided. |
|---|
| 183 |
; |
|---|
| 184 |
; Ring an extension, if the extension is busy or there is no answer, return |
|---|
| 185 |
; ARGS: $EXTENSION, $RINGTIME |
|---|
| 186 |
;------------------------------------------------------------------------ |
|---|
| 187 |
[macro-simple-dial] |
|---|
| 188 |
exten => s,1,Macro(user-callerid,SKIPTTL) ; already called from follow-me |
|---|
| 189 |
|
|---|
| 190 |
; FROMCONTEXT was in the original macro-exten-vm where this macro was derived from. A |
|---|
| 191 |
; search through all the modules does not come up with any place using this |
|---|
| 192 |
; variable, but it is left here as a reminder in case there is functionality |
|---|
| 193 |
; that eventually behaves in a certain way as a result of this variable being set |
|---|
| 194 |
; and this macro has to masquerade as exten-vm. |
|---|
| 195 |
; |
|---|
| 196 |
exten => s,n,Set(EXTTOCALL=${ARG1}) |
|---|
| 197 |
exten => s,n,Set(RT=${ARG2}) |
|---|
| 198 |
exten => s,n,Set(CFUEXT=${DB(CFU/${EXTTOCALL})}) |
|---|
| 199 |
exten => s,n,Macro(record-enable,${EXTTOCALL},IN) |
|---|
| 200 |
|
|---|
| 201 |
exten => s,n,Set(BVM=${IF($[$["${DIAL_OPTIONS:-13}"!="M(auto-blkvm)"]]?M(auto-blkvm):"")}) |
|---|
| 202 |
|
|---|
| 203 |
exten => s,n,Macro(dial,${RT},${DIAL_OPTIONS}${BVM},${EXTTOCALL}) |
|---|
| 204 |
|
|---|
| 205 |
exten => s,n,Set(PR_DIALSTATUS=${DIALSTATUS}) |
|---|
| 206 |
|
|---|
| 207 |
; if we return, thus no answer, and they have a CFU setting, then we try that next |
|---|
| 208 |
; |
|---|
| 209 |
exten => s,n,GosubIf($[$["${DIALSTATUS}"="NOANSWER"] & $["foo${CFUEXT}"!="foo"]]?docfu,1) ; check for CFU in use on no answer |
|---|
| 210 |
|
|---|
| 211 |
; Nothing yet, then go to the end (which will just return, but in case we decide to do something with certain |
|---|
| 212 |
; return situations, this is left in. |
|---|
| 213 |
; |
|---|
| 214 |
exten => s,n,Goto(s-${DIALSTATUS},1) |
|---|
| 215 |
|
|---|
| 216 |
; Try the Call Forward on No Answer / Unavailable number. |
|---|
| 217 |
; We want to try CFU if set, but we want the same ring timer as was set to our call (or do we want the |
|---|
| 218 |
; system ringtimer? - probably not). Then if no answer there (assuming it doesn't drop into their vm or |
|---|
| 219 |
; something we return, which will have the net effect of returning to the followme setup.) |
|---|
| 220 |
; |
|---|
| 221 |
; want to avoid going to other follow-me settings here. So check if the CFUEXT is a user and if it is |
|---|
| 222 |
; then direct it straight to ext-local (to avoid getting intercepted by findmefollow) otherwise send it |
|---|
| 223 |
; to from-internal since it may be an outside line. |
|---|
| 224 |
; |
|---|
| 225 |
exten => docfu,1,GotoIf( $[ "foo${DB(AMPUSER/${CFUEXT}/device)}" = "foo" ], chlocal) |
|---|
| 226 |
exten => docfu,n,Dial(Local/${CFUEXT}@ext-local,${RT},${DIAL_OPTIONS}) |
|---|
| 227 |
exten => docfu,n,Return |
|---|
| 228 |
exten => docfu,n(chlocal),Dial(Local/${CFUEXT}@from-internal/n,${RT},${DIAL_OPTIONS}) |
|---|
| 229 |
exten => docfu,n,Return |
|---|
| 230 |
|
|---|
| 231 |
; In all cases of no connection, come here and simply return, since the calling dialplan will |
|---|
| 232 |
; decide what to do next |
|---|
| 233 |
exten => _s-.,1,NoOp(Extension is reporting ${EXTEN}) |
|---|
| 234 |
;------------------------------------------------------------------------ |
|---|
| 235 |
|
|---|
| 236 |
|
|---|
| 237 |
; get the voicemail context for the user in ARG1 |
|---|
| 238 |
[macro-get-vmcontext] |
|---|
| 239 |
exten => s,1,Set(VMCONTEXT=${DB(AMPUSER/${ARG1}/voicemail)}) |
|---|
| 240 |
exten => s,2,GotoIf($["foo${VMCONTEXT}" = "foo"]?200:300) |
|---|
| 241 |
exten => s,200,Set(VMCONTEXT=default) |
|---|
| 242 |
exten => s,300,NoOp() |
|---|
| 243 |
|
|---|
| 244 |
; For some reason, if I don't run setCIDname, CALLERID(name) will be blank in my AGI |
|---|
| 245 |
; ARGS: none |
|---|
| 246 |
[macro-fixcid] |
|---|
| 247 |
exten => s,1,Set(CALLERID(name)=${CALLERID(name)}) |
|---|
| 248 |
|
|---|
| 249 |
; Ring groups of phones |
|---|
| 250 |
; ARGS: comma separated extension list |
|---|
| 251 |
; 1 - Ring Group Strategy |
|---|
| 252 |
; 2 - ringtimer |
|---|
| 253 |
; 3 - prefix |
|---|
| 254 |
; 4 - extension list |
|---|
| 255 |
[macro-rg-group] |
|---|
| 256 |
exten => s,1,Macro(user-callerid,SKIPTTL) ; already called from ringgroup |
|---|
| 257 |
exten => s,2,GotoIf($["${CALLERID(name):0:${LEN(${RGPREFIX})}}" != "${RGPREFIX}"]?4:3) ; check for old prefix |
|---|
| 258 |
exten => s,3,Set(CALLERID(name)=${CALLERID(name):${LEN(${RGPREFIX})}}) ; strip off old prefix |
|---|
| 259 |
exten => s,4,Set(RGPREFIX=${ARG3}) ; set new prefix |
|---|
| 260 |
exten => s,5,Set(CALLERID(name)=${RGPREFIX}${CALLERID(name)}) ; add prefix to callerid name |
|---|
| 261 |
exten => s,6,Set(RecordMethod=Group) ; set new prefix |
|---|
| 262 |
exten => s,7,Macro(record-enable,${MACRO_EXTEN},${RecordMethod}) |
|---|
| 263 |
exten => s,8,Set(RingGroupMethod=${ARG1}) ; |
|---|
| 264 |
exten => s,9,Macro(dial,${ARG2},${DIAL_OPTIONS},${ARG4}) |
|---|
| 265 |
exten => s,10,Set(RingGroupMethod='') ; |
|---|
| 266 |
|
|---|
| 267 |
|
|---|
| 268 |
; |
|---|
| 269 |
; Outgoing channel(s) are busy ... inform the client |
|---|
| 270 |
; but use noanswer features like ringgroups don't break by being answered |
|---|
| 271 |
; just to play the message. |
|---|
| 272 |
; |
|---|
| 273 |
[macro-outisbusy] |
|---|
| 274 |
exten => s,1,Playback(all-circuits-busy-now,noanswer) |
|---|
| 275 |
exten => s,n,Playback(pls-try-call-later,noanswer) |
|---|
| 276 |
exten => s,n,Macro(hangupcall) |
|---|
| 277 |
|
|---|
| 278 |
; What to do on hangup. |
|---|
| 279 |
[macro-hangupcall] |
|---|
| 280 |
exten => s,1,ResetCDR(w) |
|---|
| 281 |
exten => s,n,NoCDR() |
|---|
| 282 |
|
|---|
| 283 |
; Cleanup any remaining RG flag |
|---|
| 284 |
; |
|---|
| 285 |
exten => s,n,GotoIf($[ "foo${USE_CONFIRMATION}" = "foo" | "foo${RINGGROUP_INDEX}" = "foo" | "${CHANNEL}" != "${UNIQCHAN}"]?skiprg) |
|---|
| 286 |
exten => s,n,Noop(Cleaning Up Confirmation Flag: RG/${RINGGROUP_INDEX}/${CHANNEL}) |
|---|
| 287 |
exten => s,n,DBDel(RG/${RINGGROUP_INDEX}/${CHANNEL}) |
|---|
| 288 |
|
|---|
| 289 |
; Cleanup any remaining BLKVM flag |
|---|
| 290 |
; |
|---|
| 291 |
exten => s,n(skiprg),GotoIf($[ "foo${BLKVM_BASE}" = "foo" | "BLKVM/${BLKVM_BASE}/${CHANNEL}" != "${BLKVM_OVERRIDE}" ]?theend) |
|---|
| 292 |
exten => s,n,Noop(Cleaning Up Block VM Flag: ${BLKVM_OVERRIDE}) |
|---|
| 293 |
exten => s,n,DBDel(${BLKVM_OVERRIDE}) |
|---|
| 294 |
|
|---|
| 295 |
exten => s,n(theend),Wait(5) |
|---|
| 296 |
exten => s,n,Hangup |
|---|
| 297 |
|
|---|
| 298 |
[macro-faxreceive] |
|---|
| 299 |
exten => s,1,Set(FAXFILE=/var/spool/asterisk/fax/${UNIQUEID}.tif) |
|---|
| 300 |
exten => s,2,Set(EMAILADDR=${FAX_RX_EMAIL}) |
|---|
| 301 |
exten => s,3,rxfax(${FAXFILE}) |
|---|
| 302 |
exten => s,103,Set(EMAILADDR=${FAX_RX_EMAIL}) |
|---|
| 303 |
exten => s,104,Goto(3) |
|---|
| 304 |
|
|---|
| 305 |
; dialout and strip the prefix |
|---|
| 306 |
[macro-dialout] |
|---|
| 307 |
exten => s,1,Macro(user-callerid,SKIPTTL) |
|---|
| 308 |
exten => s,2,GotoIf($["${ECID${CALLERID(number)}}" = ""]?5) ;check for CID override for exten |
|---|
| 309 |
exten => s,3,Set(CALLERID(all)=${ECID${CALLERID(number)}}) |
|---|
| 310 |
exten => s,4,Goto(7) |
|---|
| 311 |
exten => s,5,GotoIf($["${OUTCID_${ARG1}}" = ""]?7) ;check for CID override for trunk |
|---|
| 312 |
exten => s,6,Set(CALLERID(all)=${OUTCID_${ARG1}}) |
|---|
| 313 |
exten => s,7,Set(length=${LEN(${DIAL_OUT_${ARG1}})}) |
|---|
| 314 |
exten => s,8,Dial(${OUT_${ARG1}}/${ARG2:${length}}) |
|---|
| 315 |
exten => s,9,Playtones(congestion) |
|---|
| 316 |
exten => s,10,Congestion(5) |
|---|
| 317 |
exten => s,109,Macro(outisbusy) |
|---|
| 318 |
|
|---|
| 319 |
|
|---|
| 320 |
; dialout using default OUT trunk - no prefix |
|---|
| 321 |
[macro-dialout-default] |
|---|
| 322 |
exten => s,1,Macro(user-callerid,SKIPTTL) |
|---|
| 323 |
exten => s,2,Macro(record-enable,${CALLERID(number)},OUT) |
|---|
| 324 |
exten => s,3,Macro(outbound-callerid,${ARG1}) |
|---|
| 325 |
exten => s,4,Dial(${OUT}/${ARG1}) |
|---|
| 326 |
exten => s,5,Playtones(congestion) |
|---|
| 327 |
exten => s,6,Congestion(5) |
|---|
| 328 |
exten => s,105,Macro(outisbusy) |
|---|
| 329 |
|
|---|
| 330 |
; dialout using a trunk, using pattern matching (don't strip any prefix) |
|---|
| 331 |
; arg1 = trunk number, arg2 = number, arg3 = route password |
|---|
| 332 |
; |
|---|
| 333 |
; MODIFIED (PL) |
|---|
| 334 |
; |
|---|
| 335 |
; Modified both Dial() commands to include the new TRUNK_OPTIONS from the general |
|---|
| 336 |
; screen of AMP |
|---|
| 337 |
; |
|---|
| 338 |
[macro-dialout-trunk] |
|---|
| 339 |
exten => s,1,Set(DIAL_TRUNK=${ARG1}) |
|---|
| 340 |
|
|---|
| 341 |
; If NODEST is set, clear it. No point in remembering since dialout-trunk will just end in the |
|---|
| 342 |
; bit bucket. But if answered by an outside line with transfer capability, we want NODEST to be |
|---|
| 343 |
; clear so a subsequent transfer to an internal extension works and goes to voicmail or other |
|---|
| 344 |
; destinations. |
|---|
| 345 |
; |
|---|
| 346 |
exten => s,n,Set(_NODEST=) |
|---|
| 347 |
|
|---|
| 348 |
exten => s,n,Set(DIAL_NUMBER=${ARG2}) |
|---|
| 349 |
exten => s,n,Set(ROUTE_PASSWD=${ARG3}) |
|---|
| 350 |
exten => s,n,Set(DIAL_TRUNK_OPTIONS=${DIAL_OPTIONS}) // will be reset to TRUNK_OPTIONS if not intra-company |
|---|
| 351 |
exten => s,n,GotoIf($["${ROUTE_PASSWD}" = ""]?noauth) ; arg3 is pattern password |
|---|
| 352 |
exten => s,n(auth),Authenticate(${ROUTE_PASSWD}) |
|---|
| 353 |
exten => s,n(noauth),Set(GROUP()=OUT_${DIAL_TRUNK}) |
|---|
| 354 |
exten => s,n,Macro(user-callerid,SKIPTTL) |
|---|
| 355 |
exten => s,n,Macro(record-enable,${CALLERID(number)},OUT) |
|---|
| 356 |
exten => s,n,GotoIf($["${INTRACOMPANYROUTE}" = "YES"]?skipoutcid) ;Set to YES if treated like internal |
|---|
| 357 |
exten => s,n,Set(DIAL_TRUNK_OPTIONS=${TRUNK_OPTIONS}) |
|---|
| 358 |
exten => s,n,Macro(outbound-callerid,${DIAL_TRUNK}) |
|---|
| 359 |
exten => s,n(skipoutcid),GotoIf($["${OUTMAXCHANS_${DIAL_TRUNK}}foo" = "foo"]?nomax) |
|---|
| 360 |
exten => s,n(checkmax),GotoIf($[ ${GROUP_COUNT()} > ${OUTMAXCHANS_${DIAL_TRUNK}} ]?chanfull) |
|---|
| 361 |
exten => s,n(nomax),DeadAGI(fixlocalprefix) ; this sets DIAL_NUMBER to the proper dial string for this trunk |
|---|
| 362 |
exten => s,n,Set(OUTNUM=${OUTPREFIX_${DIAL_TRUNK}}${DIAL_NUMBER}) ; OUTNUM is the final dial number |
|---|
| 363 |
exten => s,n,Set(custom=${CUT(OUT_${DIAL_TRUNK},:,1)}) ; Custom trunks are prefixed with "AMP:" |
|---|
| 364 |
|
|---|
| 365 |
; Back to normal processing, whether intracompany or not. |
|---|
| 366 |
; But add the macro-setmusic if we don't want music on this outbound call |
|---|
| 367 |
; |
|---|
| 368 |
exten => s,n,GotoIf($[$["${MOHCLASS}" = "default"] | $["foo${MOHCLASS}" = "foo"]]?gocall) ; Set to YES if we should pump silence |
|---|
| 369 |
exten => s,n,Set(DIAL_TRUNK_OPTIONS=M(setmusic^${MOHCLASS})${DIAL_TRUNK_OPTIONS}) ; set MoH or off |
|---|
| 370 |
|
|---|
| 371 |
exten => s,n(gocall),GotoIf($["${custom}" = "AMP"]?customtrunk) |
|---|
| 372 |
exten => s,n,Dial(${OUT_${DIAL_TRUNK}}/${OUTNUM},300,${DIAL_TRUNK_OPTIONS}) ; Regular Trunk Dial |
|---|
| 373 |
exten => s,n,Goto(s-${DIALSTATUS},1) |
|---|
| 374 |
exten => s,n(customtrunk),Set(pre_num=${CUT(OUT_${DIAL_TRUNK},$,1)}) |
|---|
| 375 |
exten => s,n,Set(the_num=${CUT(OUT_${DIAL_TRUNK},$,2)}) ; this is where we expect to find string OUTNUM |
|---|
| 376 |
exten => s,n,Set(post_num=${CUT(OUT_${DIAL_TRUNK},$,3)}) |
|---|
| 377 |
exten => s,n,GotoIf($["${the_num}" = "OUTNUM"]?outnum:skipoutnum) ; if we didn't find "OUTNUM", then skip to Dial |
|---|
| 378 |
exten => s,n(outnum),Set(the_num=${OUTNUM}) ; replace "OUTNUM" with the actual number to dial |
|---|
| 379 |
exten => s,n(skipoutnum),Dial(${pre_num:4}${the_num}${post_num},300,${DIAL_TRUNK_OPTIONS}) |
|---|
| 380 |
exten => s,n,Goto(s-${DIALSTATUS},1) |
|---|
| 381 |
|
|---|
| 382 |
exten => s,n(chanfull),Noop(max channels used up) |
|---|
| 383 |
|
|---|
| 384 |
exten => s-BUSY,1,NoOp(Dial failed due to trunk reporting BUSY - giving up) |
|---|
| 385 |
exten => s-BUSY,2,Busy(20) |
|---|
| 386 |
|
|---|
| 387 |
exten => s-NOANSWER,1,NoOp(Dial failed due to trunk reporting NOANSWER - giving up) |
|---|
| 388 |
exten => s-NOANSWER,2,Playtones(congestion) |
|---|
| 389 |
exten => s-NOANSWER,3,Congestion(20) |
|---|
| 390 |
|
|---|
| 391 |
exten => s-CANCEL,1,NoOp(Dial failed due to trunk reporting CANCEL - giving up) |
|---|
| 392 |
exten => s-CANCEL,2,Playtones(congestion) |
|---|
| 393 |
exten => s-CANCEL,3,Congestion(20) |
|---|
| 394 |
|
|---|
| 395 |
exten => _s-.,1,NoOp(Dial failed due to ${DIALSTATUS} - failing through to other trunks) |
|---|
| 396 |
|
|---|
| 397 |
exten => h,1,Macro(hangupcall) |
|---|
| 398 |
|
|---|
| 399 |
; Adds a dynamic agent/member to a Queue |
|---|
| 400 |
; Prompts for call-back number - in not entered, uses CIDNum |
|---|
| 401 |
[macro-agent-add] |
|---|
| 402 |
exten => s,1,Wait(1) |
|---|
| 403 |
exten => s,2,Macro(user-callerid,SKIPTTL) |
|---|
| 404 |
exten => s,3,Read(CALLBACKNUM,agent-user) ; get callback number from user |
|---|
| 405 |
exten => s,4,GotoIf($["${CALLBACKNUM}" = ""]?5:7) ; if user just pressed # or timed out, use cidnum |
|---|
| 406 |
exten => s,5,Set(CALLBACKNUM=${CALLERID(number)}) |
|---|
| 407 |
exten => s,6,GotoIf($["${CALLBACKNUM}" = ""]?2) ; if still no number, start over |
|---|
| 408 |
exten => s,7,GotoIf($["${ARG2}" = ""]?9:8) ; arg2 is queue password |
|---|
| 409 |
exten => s,8,Authenticate(${ARG2}) |
|---|
| 410 |
exten => s,9,AddQueueMember(${ARG1}|Local/${CALLBACKNUM}@from-internal/n) ; using chan_local allows us to have agents over trunks |
|---|
| 411 |
exten => s,10,UserEvent(Agentlogin|Agent: ${CALLBACKNUM}) |
|---|
| 412 |
exten => s,11,Wait(1) |
|---|
| 413 |
exten => s,12,Playback(agent-loginok) |
|---|
| 414 |
exten => s,13,Hangup() |
|---|
| 415 |
|
|---|
| 416 |
; Removes a dynamic agent/member from a Queue |
|---|
| 417 |
; Prompts for call-back number - in not entered, uses CIDNum |
|---|
| 418 |
[macro-agent-del] |
|---|
| 419 |
exten => s,1,Wait(1) |
|---|
| 420 |
exten => s,2,Macro(user-callerid,SKIPTTL) |
|---|
| 421 |
exten => s,3,Read(CALLBACKNUM,agent-user) ; get callback number from user |
|---|
| 422 |
exten => s,4,GotoIf($["${CALLBACKNUM}" = ""]?5:7) ; if user just pressed # or timed out, use cidnum |
|---|
| 423 |
exten => s,5,Set(CALLBACKNUM=${CALLERID(number)}) |
|---|
| 424 |
exten => s,6,GotoIf($["${CALLBACKNUM}" = ""]?2) ; if still no number, start over |
|---|
| 425 |
exten => s,7,RemoveQueueMember(${ARG1}|Local/${CALLBACKNUM}@from-internal/n) |
|---|
| 426 |
exten => s,8,UserEvent(RefreshQueue) |
|---|
| 427 |
exten => s,9,Wait(1) |
|---|
| 428 |
exten => s,10,Playback(agent-loggedoff) |
|---|
| 429 |
exten => s,11,Hangup() |
|---|
| 430 |
|
|---|
| 431 |
; arg1 = trunk number, arg2 = number |
|---|
| 432 |
[macro-dialout-enum] |
|---|
| 433 |
; This has been violently beaten upon by Rob Thomas, xrobau@gmail.com |
|---|
| 434 |
; to 1: Be compliant with all the depreciated bits in asterisk 1.2 and |
|---|
| 435 |
; above, and 2: to give a good shot at attempting to be compliant with |
|---|
| 436 |
; RFC3761 by honouring the order in which records are returned. |
|---|
| 437 |
exten => s,1,GotoIf($["${ARG3}" = ""]PASSWD?NOPASSWD); arg3 is pattern password |
|---|
| 438 |
exten => s,n(PASSWD),Authenticate(${ARG3}) |
|---|
| 439 |
exten => s,n(NOPASSWD),Macro(user-callerid,SKIPTTL) |
|---|
| 440 |
exten => s,n,Macro(record-enable,${CALLERID(number)},OUT) |
|---|
| 441 |
exten => s,n,Macro(outbound-callerid,${ARG1}) |
|---|
| 442 |
exten => s,n,Set(GROUP()=OUT_${ARG1}) |
|---|
| 443 |
exten => s,n,GotoIf($[ ${GROUP_COUNT()} > ${OUTMAXCHANS_${ARG1}} ]?nochans) |
|---|
| 444 |
exten => s,n,Set(DIAL_NUMBER=${ARG2}) |
|---|
| 445 |
exten => s,n,Set(DIAL_TRUNK=${ARG1}) |
|---|
| 446 |
exten => s,n,DeadAGI(fixlocalprefix) ; this sets DIAL_NUMBER to the proper dial string for this trunk |
|---|
| 447 |
exten => s,n,Set(E164NETWORKS=e164.arpa-e164.info-e164.org) ; enum networks to check |
|---|
| 448 |
exten => s,n,GotoIf($["${DIAL_NUMBER:0:1}" = "+"]?begin) ; Skip next line if it already is prefixed by a plus |
|---|
| 449 |
exten => s,n,Set(DIAL_NUMBER=+${DIAL_NUMBER}) ; Add a plus to the start, becasue ENUMLOOKUP needs it. |
|---|
| 450 |
|
|---|
| 451 |
; start of main network loop |
|---|
| 452 |
exten => s,n(begin),NoOp(E164NETWORKS is ${E164NETWORKS}) |
|---|
| 453 |
exten => s,n,GotoIf($["${E164NETWORKS:1:2}"=""]?failedtotally) |
|---|
| 454 |
exten => s,n,Set(ENUMNET=${CUT(E164NETWORKS,-,1)}) |
|---|
| 455 |
exten => s,n,Set(E164NETWORKS=${CUT(E164NETWORKS,-,2-)}) |
|---|
| 456 |
|
|---|
| 457 |
exten => s,n,NoOp(E164NETWORKS is now ${E164NETWORKS}) |
|---|
| 458 |
exten => s,n,NoOp(ENUMNET is ${ENUMNET}) |
|---|
| 459 |
|
|---|
| 460 |
exten => s,n,Set(ENUMCOUNT=${ENUMLOOKUP(${DIAL_NUMBER},all,c,${ENUMNET})}) |
|---|
| 461 |
exten => s,n,Set(ENUMPTR=0) |
|---|
| 462 |
exten => s,n,Set(LOOKUPBUG=0) |
|---|
| 463 |
|
|---|
| 464 |
; start of main lookup loop |
|---|
| 465 |
exten => s,n(startloop),GotoIf($["${ENUMPTR}"<"${ENUMCOUNT}"]?continue:failed) |
|---|
| 466 |
|
|---|
| 467 |
; Now, let's start through them. |
|---|
| 468 |
exten => s,n(continue),Set(ENUMPTR=$[${ENUMPTR}+1]) |
|---|
| 469 |
exten => s,n,NoOp(Doing ENUMLOOKUP(${DIAL_NUMBER},all,${ENUMPTR},${ENUMNET})) |
|---|
| 470 |
exten => s,n,Set(ENUM=${ENUMLOOKUP(${DIAL_NUMBER},all,${ENUMPTR},${ENUMNET})}) |
|---|
| 471 |
|
|---|
| 472 |
; Deal with reponse |
|---|
| 473 |
exten => s,n,GotoIf($["${ENUM:0:3}" = "sip" ]?sipuri) |
|---|
| 474 |
exten => s,n,GotoIf($["${ENUM:0:3}" = "iax" ]?iaxuri) |
|---|
| 475 |
; It doesn't matter if you don't have h323 enabled, as when it tries to dial, it cares |
|---|
| 476 |
; about dialstatus and retries if there are any enum results left. |
|---|
| 477 |
exten => s,n,GotoIf($["${ENUM:0:3}" = "h32" ]?h323uri) |
|---|
| 478 |
|
|---|
| 479 |
; e164.org can return 'ADDRESS' lines. Because of *'s poor handling of Enum |
|---|
| 480 |
; lookups, we want to DECREMENT the enum pointer. Yes. That means we try more |
|---|
| 481 |
; times than there actually exists entries. |
|---|
| 482 |
exten => s,n,GotoIf($["${ENUM:0:3}" = "ADD" ]?enumbug) |
|---|
| 483 |
|
|---|
| 484 |
; OK. If we're here, we've still got some enum entries to go through. Back to |
|---|
| 485 |
; the start with you! |
|---|
| 486 |
exten => s,n,Goto(startloop) |
|---|
| 487 |
|
|---|
| 488 |
; We're here because of the poor implementation of ENUMLOOKUP in Asterisk. It |
|---|
| 489 |
; is quite possible to do three ENUMLOOKUPS and get the same entry each time. |
|---|
| 490 |
; The only workaround I can think of is when we hit an invalid entry, do a |
|---|
| 491 |
; DECREMENT of the pointer, and keep trying. |
|---|
| 492 |
exten => s,n(enumbug),Set(ENUMPTR=$[${ENUMPTR}-1]) |
|---|
| 493 |
exten => s,n,NoOp(If this is looping with the same ENUM value, The ENUMLOOKUP function is fixed!) |
|---|
| 494 |
exten => s,n,Set(LOOKUPBUG=$[${LOOKUPBUG}+1]) |
|---|
| 495 |
; If we've done this more than, ooh, 5 times, then give up on this network. Sorry. |
|---|
| 496 |
exten => s,n,GotoIf($["${LOOKUPBUG}" > 5 ]?failed) |
|---|
| 497 |
exten => s,n,Goto(continue) |
|---|
| 498 |
|
|---|
| 499 |
; If the prefix is 'sip:'... |
|---|
| 500 |
exten => s,n(sipuri),Set(DIALSTR=SIP/${ENUM:4}) |
|---|
| 501 |
exten => s,n,Goto(dodial) |
|---|
| 502 |
|
|---|
| 503 |
; If it's IAX2... |
|---|
| 504 |
exten => s,n(iaxuri),Set(DIALSTR=IAX2/${ENUM:5}) |
|---|
| 505 |
exten => s,n,Goto(dodial) |
|---|
| 506 |
|
|---|
| 507 |
; Or even if it's H323. |
|---|
| 508 |
exten => s,n(h323uri),Set(DIALSTR=H323/${ENUM:5}) |
|---|
| 509 |
|
|---|
| 510 |
exten => s,n(dodial),Dial(${DIALSTR}) |
|---|
| 511 |
exten => s,n,NoOp(Dial exited in macro-enum-dialout with ${DIALSTATUS}) |
|---|
| 512 |
|
|---|
| 513 |
; Now, if we're still here, that means the Dial failed for some reason. |
|---|
| 514 |
; If it's CONGESTION or CHANUNAVAIL we probably want to try again on a |
|---|
| 515 |
; different channel. However, if it's the last one, we don't have any |
|---|
| 516 |
; left, and I didn't keep any previous dialstatuses, so hopefully |
|---|
| 517 |
; someone looking throught the logs would have seen the NoOp's |
|---|
| 518 |
exten => s,n,GotoIf($["${ENUMPTR}"<"${ENUMCOUNT}"]?maybemore:dialfailed) |
|---|
| 519 |
exten => s,n(maybemore),GotoIf($[ $[ "${DIALSTATUS}" = "CHANUNAVAIL" ] | $[ "${DIALSTATUS}" = "CONGESTION" ] ]?continue) |
|---|
| 520 |
|
|---|
| 521 |
; If we're here, then it's BUSY or NOANSWER or something and well, deal with it. |
|---|
| 522 |
exten => s,n(dialfailed),Goto(s-${DIALSTATUS},1) |
|---|
| 523 |
|
|---|
| 524 |
; Here are the exit points for the macro. |
|---|
| 525 |
exten => s,n(failed),NoOp(EnumLookup failed on network ${ENUMNET}) |
|---|
| 526 |
exten => s,n,Goto(begin) |
|---|
| 527 |
|
|---|
| 528 |
exten => s,n(failedtotally),NoOp(EnumLookup failed -- no more networks to try) |
|---|
| 529 |
exten => s,n,Goto(end) |
|---|
| 530 |
|
|---|
| 531 |
exten => s,n(nochans),NoOp(max channels used up) |
|---|
| 532 |
|
|---|
| 533 |
exten => s,n(end),NoOp(Exiting macro-dialout-enum) |
|---|
| 534 |
|
|---|
| 535 |
exten => s-BUSY,1,NoOp(Trunk is reporting BUSY) |
|---|
| 536 |
exten => s-BUSY,2,Busy(20) |
|---|
| 537 |
|
|---|
| 538 |
exten => _s-.,1,NoOp(Dial failed due to ${DIALSTATUS}) |
|---|
| 539 |
|
|---|
| 540 |
[macro-record-enable] |
|---|
| 541 |
exten => s,1,GotoIf(${LEN(${BLINDTRANSFER})} > 0?2:4) |
|---|
| 542 |
exten => s,2,ResetCDR(w) |
|---|
| 543 |
exten => s,3,StopMonitor() |
|---|
| 544 |
; I haven't figured out how, but occasionally a hung up |
|---|
| 545 |
; call can end up here. If you don't use DeadAGI (which does |
|---|
| 546 |
; work fine as a normal AGI), asterisk deadlocks a thread, |
|---|
| 547 |
; and ends up grumpy. |
|---|
| 548 |
exten => s,4,DeadAGI(recordingcheck,${TIMESTAMP},${UNIQUEID}) |
|---|
| 549 |
exten => s,5,Noop(No recording needed) |
|---|
| 550 |
exten => s,999,MixMonitor(${CALLFILENAME}.wav) |
|---|
| 551 |
|
|---|
| 552 |
;exten => s,3,BackGround(for-quality-purposes) |
|---|
| 553 |
;exten => s,4,BackGround(this-call-may-be) |
|---|
| 554 |
;exten => s,5,BackGround(recorded) |
|---|
| 555 |
|
|---|
| 556 |
; This macro is for dev purposes and just dumps channel/app variables. Useful when designing new contexts. |
|---|
| 557 |
[macro-dumpvars] |
|---|
| 558 |
exten => s,1,Noop(ACCOUNTCODE=${ACCOUNTCODE}) |
|---|
| 559 |
exten => s,2,Noop(ANSWEREDTIME=${ANSWEREDTIME}) |
|---|
| 560 |
exten => s,3,Noop(BLINDTRANSFER=${BLINDTRANSFER}) |
|---|
| 561 |
exten => s,4,Noop(CALLERID=${CALLERID(all)}) |
|---|
| 562 |
exten => s,5,Noop(CALLERID(name)=${CALLERID(name)}) |
|---|
| 563 |
exten => s,6,Noop(CALLERID(number)=${CALLERID(number)}) |
|---|
| 564 |
exten => s,7,Noop(CALLINGPRES=${CALLINGPRES}) |
|---|
| 565 |
exten => s,8,Noop(CHANNEL=${CHANNEL}) |
|---|
| 566 |
exten => s,9,Noop(CONTEXT=${CONTEXT}) |
|---|
| 567 |
exten => s,10,Noop(DATETIME=${DATETIME}) |
|---|
| 568 |
exten => s,11,Noop(DIALEDPEERNAME=${DIALEDPEERNAME}) |
|---|
| 569 |
exten => s,12,Noop(DIALEDPEERNUMBER=${DIALEDPEERNUMBER}) |
|---|
| 570 |
exten => s,13,Noop(DIALEDTIME=${DIALEDTIME}) |
|---|
| 571 |
exten => s,14,Noop(DIALSTATUS=${DIALSTATUS}) |
|---|
| 572 |
exten => s,15,Noop(DNID=${DNID}) |
|---|
| 573 |
exten => s,16,Noop(EPOCH=${EPOCH}) |
|---|
| 574 |
exten => s,17,Noop(EXTEN=${EXTEN}) |
|---|
| 575 |
exten => s,18,Noop(HANGUPCAUSE=${HANGUPCAUSE}) |
|---|
| 576 |
exten => s,19,Noop(INVALID_EXTEN=${INVALID_EXTEN}) |
|---|
| 577 |
exten => s,20,Noop(LANGUAGE=${LANGUAGE}) |
|---|
| 578 |
exten => s,21,Noop(MEETMESECS=${MEETMESECS}) |
|---|
| 579 |
exten => s,22,Noop(PRIORITY=${PRIORITY}) |
|---|
| 580 |
exten => s,23,Noop(RDNIS=${RDNIS}) |
|---|
| 581 |
exten => s,24,Noop(SIPDOMAIN=${SIPDOMAIN}) |
|---|
| 582 |
exten => s,25,Noop(SIP_CODEC=${SIP_CODEC}) |
|---|
| 583 |
exten => s,26,Noop(SIPCALLID=${SIPCALLID}) |
|---|
| 584 |
exten => s,27,Noop(SIPUSERAGENT=${SIPUSERAGENT}) |
|---|
| 585 |
exten => s,28,Noop(TIMESTAMP=${TIMESTAMP}) |
|---|
| 586 |
exten => s,29,Noop(TXTCIDNAME=${TXTCIDNAME}) |
|---|
| 587 |
exten => s,30,Noop(UNIQUEID=${UNIQUEID}) |
|---|
| 588 |
exten => s,31,Noop(TOUCH_MONITOR=${TOUCH_MONITOR}) |
|---|
| 589 |
exten => s,32,Noop(MACRO_CONTEXT=${MACRO_CONTEXT}) |
|---|
| 590 |
exten => s,33,Noop(MACRO_EXTEN=${MACRO_EXTEN}) |
|---|
| 591 |
exten => s,34,Noop(MACRO_PRIORITY=${MACRO_PRIORITY}) |
|---|
| 592 |
|
|---|
| 593 |
[macro-user-logon] |
|---|
| 594 |
; check device type |
|---|
| 595 |
exten => s,1,Set(DEVICETYPE=${DB(DEVICE/${CALLERID(number)}/type)}) |
|---|
| 596 |
exten => s,2,GotoIf($["${DEVICETYPE}" = "fixed"]?s-FIXED,1) |
|---|
| 597 |
; get user's extension |
|---|
| 598 |
exten => s,3,Set(AMPUSER=${ARG1}) |
|---|
| 599 |
exten => s,4,GotoIf($["${AMPUSER}" = ""]?5:9) |
|---|
| 600 |
exten => s,5,BackGround(please-enter-your) |
|---|
| 601 |
exten => s,6,Playback(extension) |
|---|
| 602 |
exten => s,7,Read(AMPUSER,then-press-pound) |
|---|
| 603 |
; get user's password and authenticate |
|---|
| 604 |
exten => s,8,Wait(1) |
|---|
| 605 |
exten => s,9,Set(AMPUSERPASS=${DB(AMPUSER/${AMPUSER}/password)}) |
|---|
| 606 |
exten => s,10,GotoIf($[${LEN(${AMPUSERPASS})} = 0]?s-NOPASSWORD,1) |
|---|
| 607 |
; do not continue if the user has already logged onto this device |
|---|
| 608 |
exten => s,11,Set(DEVICEUSER=${DB(DEVICE/${CALLERID(number)}/user)}) |
|---|
| 609 |
exten => s,12,GotoIf($["${DEVICEUSER}" = "${AMPUSER}"]?s-ALREADYLOGGEDON,1) |
|---|
| 610 |
exten => s,13,Authenticate(${AMPUSERPASS}) |
|---|
| 611 |
; devices can only be mapped to one user - loggoff anyone else who is here |
|---|
| 612 |
exten => s,14,Macro(user-logoff) |
|---|
| 613 |
; map user to device |
|---|
| 614 |
exten => s,15,Set(AMPUSERDEVICES=${DB(AMPUSER/${AMPUSER}/device)}) |
|---|
| 615 |
exten => s,16,GotoIf($[${LEN(${AMPUSERDEVICES})} = 0]?18) |
|---|
| 616 |
exten => s,17,Set(AMPUSERDEVICES=${AMPUSERDEVICES}&) |
|---|
| 617 |
exten => s,18,Set(AMPUSERDEVICES=${AMPUSERDEVICES}${CALLERID(number)}) |
|---|
| 618 |
exten => s,19,Set(DB(AMPUSER/${AMPUSER}/device)=${AMPUSERDEVICES}) |
|---|
| 619 |
; map device to user |
|---|
| 620 |
exten => s,20,Set(DB(DEVICE/${CALLERID(number)}/user)=${AMPUSER}) |
|---|
| 621 |
; create symlink from dummy device mailbox to user's mailbox |
|---|
| 622 |
exten => s,21,System(/bin/ln -s /var/spool/asterisk/voicemail/default/${AMPUSER}/ /var/spool/asterisk/voicemail/device/${CALLERID(number)}) |
|---|
| 623 |
|
|---|
| 624 |
exten => s-FIXED,1,NoOp(Device is FIXED and cannot be logged into) |
|---|
| 625 |
exten => s-FIXED,2,Playback(ha/phone) |
|---|
| 626 |
exten => s-FIXED,3,SayDigits(${CALLERID(number)}) |
|---|
| 627 |
exten => s-FIXED,4,Playback(is-curntly-unavail) |
|---|
| 628 |
exten => s-FIXED,5,Playback(vm-goodbye) |
|---|
| 629 |
exten => s-FIXED,6,Hangup ;TODO should play msg indicated device cannot be logged into |
|---|
| 630 |
|
|---|
| 631 |
exten => s-ALREADYLOGGEDON,1,NoOp(This device has already been logged into by this user) |
|---|
| 632 |
exten => s-ALREADYLOGGEDON,2,Playback(vm-goodbye) |
|---|
| 633 |
exten => s-ALREADYLOGGEDON,3,Hangup ;TODO should play msg indicated device is already logged into |
|---|
| 634 |
|
|---|
| 635 |
exten => s-NOPASSWORD,1,NoOp(This extension does not exist or no password is set) |
|---|
| 636 |
exten => s-NOPASSWORD,2,Playback(an-error-has-occured) |
|---|
| 637 |
exten => s-NOPASSWORD,3,Playback(vm-goodbye) |
|---|
| 638 |
exten => s-NOPASSWORD,4,Hangup ;TODO should play msg indicated device is already logged into |
|---|
| 639 |
|
|---|
| 640 |
[macro-user-logoff] |
|---|
| 641 |
; check device type |
|---|
| 642 |
exten => s,1,Set(DEVICETYPE=${DB(DEVICE/${CALLERID(number)}/type)}) |
|---|
| 643 |
exten => s,2,GotoIf($["${DEVICETYPE}" = "fixed"]?s-FIXED,1) |
|---|
| 644 |
; remove entry from user's DEVICE key |
|---|
| 645 |
; delete the symlink to user's voicemail box |
|---|
| 646 |
exten => s,3,System(rm -f /var/spool/asterisk/voicemail/device/${CALLERID(number)}) |
|---|
| 647 |
exten => s,4,Set(DEVAMPUSER=${DB(DEVICE/${CALLERID(number)}/user)}) |
|---|
| 648 |
exten => s,5,Set(AMPUSERDEVICES=${DB(AMPUSER/${DEVAMPUSER}/device)}) |
|---|
| 649 |
exten => s,6,DeadAGI(list-item-remove.php,${AMPUSERDEVICES},${CALLERID(number)},AMPUSERDEVICES,&) |
|---|
| 650 |
; reset user -> device mapping |
|---|
| 651 |
; users can log onto multiple devices, need to just remove device from value |
|---|
| 652 |
exten => s,7,Set(DB(AMPUSER/${DEVAMPUSER}/device)=${AMPUSERDEVICES}) |
|---|
| 653 |
; reset device -> user mapping |
|---|
| 654 |
exten => s,8,Set(DB(DEVICE/${CALLERID(number)}/user)=none) |
|---|
| 655 |
exten => s,9,Playback(vm-goodbye) |
|---|
| 656 |
|
|---|
| 657 |
exten => s-FIXED,1,NoOp(Device is FIXED and cannot be logged out of) |
|---|
| 658 |
exten => s-FIXED,2,Playback(an-error-has-occured) |
|---|
| 659 |
exten => s-FIXED,3,Playback(vm-goodbye) |
|---|
| 660 |
exten => s-FIXED,4,Hangup ;TODO should play msg indicated device cannot be logged into |
|---|
| 661 |
|
|---|
| 662 |
[macro-systemrecording] |
|---|
| 663 |
exten => s,1,Goto(${ARG1},1) |
|---|
| 664 |
|
|---|
| 665 |
exten => dorecord,1,Record(/tmp/${CALLERID(number)}-ivrrecording:wav) |
|---|
| 666 |
exten => dorecord,n,Wait(1) |
|---|
| 667 |
exten => dorecord,n,Goto(confmenu,1) |
|---|
| 668 |
|
|---|
| 669 |
exten => docheck,1,Playback(/tmp/${CALLERID(number)}-ivrrecording) |
|---|
| 670 |
exten => docheck,n,Wait(1) |
|---|
| 671 |
exten => docheck,n,Goto(confmenu,1) |
|---|
| 672 |
|
|---|
| 673 |
exten => confmenu,1,Background(to-listen-to-it&press-1&to-rerecord-it&press-star|m||macro-systemrecording) |
|---|
| 674 |
exten => confmenu,n,Read(RECRESULT||1|||4) |
|---|
| 675 |
exten => confmenu,n,GotoIf($["x${RECRESULT}"="x*"]?dorecord,1) |
|---|
| 676 |
exten => confmenu,n,GotoIf($["x${RECRESULT}"="x1"]?docheck,1) |
|---|
| 677 |
exten => confmenu,n,Goto(1) |
|---|
| 678 |
|
|---|
| 679 |
exten => 1,1,Goto(docheck,1) |
|---|
| 680 |
exten => *,1,Goto(dorecord,1) |
|---|
| 681 |
|
|---|
| 682 |
exten => t,1,Playback(goodbye) |
|---|
| 683 |
exten => t,n,Hangup |
|---|
| 684 |
|
|---|
| 685 |
exten => i,1,Playback(pm-invalid-option) |
|---|
| 686 |
exten => i,n,Goto(confmenu,1) |
|---|
| 687 |
|
|---|
| 688 |
exten => h,1,Hangup |
|---|
| 689 |
|
|---|
| 690 |
|
|---|
| 691 |
; |
|---|
| 692 |
; ############################################################################ |
|---|
| 693 |
; CallerID Handling |
|---|
| 694 |
; ############################################################################ |
|---|
| 695 |
|
|---|
| 696 |
;sets the callerid of the device to that of the logged in user |
|---|
| 697 |
[macro-user-callerid] |
|---|
| 698 |
exten => s,1,Noop(user-callerid: ${CALLERID(name)} ${CALLERID(number)}) |
|---|
| 699 |
exten => s,n,GotoIf($["${CHANNEL:0:5}" = "Local"]?report) |
|---|
| 700 |
exten => s,n,GotoIf($["${REALCALLERIDNUM:1:2}" != ""]?start) |
|---|
| 701 |
exten => s,n,Set(REALCALLERIDNUM=${CALLERID(number)}) |
|---|
| 702 |
exten => s,n(start),NoOp(REALCALLERIDNUM is ${REALCALLERIDNUM}) |
|---|
| 703 |
exten => s,n,Set(AMPUSER=${DB(DEVICE/${REALCALLERIDNUM}/user)}) |
|---|
| 704 |
exten => s,n,Set(AMPUSERCIDNAME=${DB(AMPUSER/${AMPUSER}/cidname)}) |
|---|
| 705 |
exten => s,n,GotoIf($["x${AMPUSERCIDNAME:1:2}" = "x"]?report) |
|---|
| 706 |
exten => s,n,Set(CALLERID(all)=${AMPUSERCIDNAME} <${AMPUSER}>) |
|---|
| 707 |
exten => s,n,Set(REALCALLERIDNUM=${DB(DEVICE/${REALCALLERIDNUM}/user)}) |
|---|
| 708 |
exten => s,n(report),Noop(TTL: ${TTL} ARG1: ${ARG1}) |
|---|
| 709 |
exten => s,n,GotoIf($[ "${ARG1}" = "SKIPTTL" ]?continue) |
|---|
| 710 |
exten => s,n(report2),Set(_TTL=${IF($["foo${TTL}" = "foo"]?64:$[ ${TTL} - 1 ])}) |
|---|
| 711 |
exten => s,n,GotoIf($[ ${TTL} > 0 ]?continue) |
|---|
| 712 |
exten => s,n,Wait(${RINGTIMER}) ; wait for a while, to give it a chance to be picked up by voicemail |
|---|
| 713 |
exten => s,n,Answer() |
|---|
| 714 |
exten => s,n,Wait(2) |
|---|
| 715 |
exten => s,n,Playback(im-sorry&an-error-has-occured&with&call-forwarding) |
|---|
| 716 |
exten => s,n,Macro(hangupcall) |
|---|
| 717 |
exten => s,n,Congestion() |
|---|
| 718 |
exten => s,n(continue),NoOp(Using CallerID ${CALLERID(all)}) |
|---|
| 719 |
exten => h,1,Macro(hangupcall) |
|---|
| 720 |
|
|---|
| 721 |
; overrides callerid out trunks |
|---|
| 722 |
; arg1 is trunk |
|---|
| 723 |
; macro-user-callerid should be called _before_ using this macro |
|---|
| 724 |
[macro-outbound-callerid] |
|---|
| 725 |
; Keep the original CallerID number, for failover to the next trunk. |
|---|
| 726 |
exten => s,1,GotoIf($["${REALCALLERIDNUM:1:2}" != ""]?start) |
|---|
| 727 |
exten => s,n,Set(REALCALLERIDNUM=${CALLERID(number)}) |
|---|
| 728 |
exten => s,n(start),NoOp(REALCALLERIDNUM is ${REALCALLERIDNUM}) |
|---|
| 729 |
|
|---|
| 730 |
; If this came through a ringgroup or CF, then we want to retain original CID unless |
|---|
| 731 |
; OUTKEEPCID_${trunknum} is set. |
|---|
| 732 |
; |
|---|
| 733 |
exten => s,n,GotoIf($["${KEEPCID}" != "TRUE"]?normcid) ;Set to TRUE if coming from ringgroups, CF, etc. |
|---|
| 734 |
exten => s,n,GotoIf($["x${OUTKEEPCID_${ARG1}}" = "xon"]?normcid) |
|---|
| 735 |
exten => s,n,GotoIf($["foo${REALCALLERIDNUM}" = "foo"]?normcid) ;if not set to anything, go through normal processing |
|---|
| 736 |
exten => s,n,Set(USEROUTCID=${REALCALLERIDNUM}) |
|---|
| 737 |
|
|---|
| 738 |
; We now have to make sure the CID is valid. If we find an AMPUSER with the same CID, we assume it is an internal |
|---|
| 739 |
; call (would be quite a conincidence if not) and go through the normal processing to get that CID. If a device |
|---|
| 740 |
; is set for this CID, then it must be internal |
|---|
| 741 |
; |
|---|
| 742 |
exten => s,n,GotoIf($["foo${DB(AMPUSER/${REALCALLERIDNUM}/device)}" = "foo"]?bypass:normcid) |
|---|
| 743 |
|
|---|
| 744 |
exten => s,n(normcid),Set(USEROUTCID=${DB(AMPUSER/${REALCALLERIDNUM}/outboundcid)}) |
|---|
| 745 |
exten => s,n(bypass),Set(EMERGENCYCID=${DB(DEVICE/${REALCALLERIDNUM}/emergency_cid)}) |
|---|
| 746 |
exten => s,n,Set(TRUNKOUTCID=${OUTCID_${ARG1}}) |
|---|
| 747 |
exten => s,n,GotoIf($["${EMERGENCYROUTE:1:2}" = ""]?trunkcid) ; check EMERGENCY ROUTE |
|---|
| 748 |
exten => s,n,GotoIf($["${EMERGENCYCID:1:2}" = ""]?trunkcid) ; empty EMERGENCY CID, so default back to trunk |
|---|
| 749 |
exten => s,n,Set(CALLERID(all)=${EMERGENCYCID}) ; emergency cid for device |
|---|
| 750 |
exten => s,n,Goto(report) |
|---|
| 751 |
exten => s,n(trunkcid),GotoIf($["${TRUNKOUTCID:1:2}" = ""]?usercid) ;check for CID override for trunk (global var) |
|---|
| 752 |
exten => s,n,Set(CALLERID(all)=${TRUNKOUTCID}) |
|---|
| 753 |
exten => s,n(usercid),GotoIf($["${USEROUTCID:1:2}" = ""]?report) ; check CID override for extension |
|---|
| 754 |
exten => s,n,Set(CALLERID(all)=${USEROUTCID}) |
|---|
| 755 |
exten => s,n,GotoIf($["x${CALLERID(name)}"!="hidden"]?report:hidecid) ; check CID blocking for extension |
|---|
| 756 |
exten => s,n(hidecid),SetCallerPres(prohib_passed_screen) ; Only works with ISDN (T1/E1/BRI) |
|---|
| 757 |
exten => s,n(report),NoOp(CallerID set to ${CALLERID(all)}) |
|---|
| 758 |
|
|---|
| 759 |
; Privacy Manager Macro makes sure that any calls that don't pass the privacy manager are presented |
|---|
| 760 |
; with congestion since there have been observed cases of the call continuing if not stopped with a |
|---|
| 761 |
; congestion, and this provides a slightly more friendly 'sorry' message in case the user is |
|---|
| 762 |
; legitamately trying to be cooperative. |
|---|
| 763 |
; |
|---|
| 764 |
; Note: the following options are configurable in privacy.conf: |
|---|
| 765 |
; |
|---|
| 766 |
; maxretries = 3 ; default value, number of retries before failing |
|---|
| 767 |
; minlength = 10 ; default value, number of digits to be accepted as valid CID |
|---|
| 768 |
; |
|---|
| 769 |
[macro-privacy-mgr] |
|---|
| 770 |
exten => s,1,Set(KEEPCID=${CALLERID(num)}) |
|---|
| 771 |
exten => s,n,GotoIf($["foo${CALLERID(num):0:1}"="foo+"]?CIDTEST2:CIDTEST1) |
|---|
| 772 |
exten => s,n(CIDTEST1),Set(TESTCID=${MATH(1+${CALLERID(num)})}) |
|---|
| 773 |
exten => s,n,Goto(TESTRESULT) |
|---|
| 774 |
exten => s,n(CIDTEST2),Set(TESTCID=${MATH(1+${CALLERID(num):1})}) |
|---|
| 775 |
exten => s,n(TESTRESULT),GotoIf($["foo${TESTCID}"="foo"]?CLEARCID:PRIVMGR) |
|---|
| 776 |
exten => s,n(CLEARCID),Set(CALLERID(num)=) |
|---|
| 777 |
exten => s,n(PRIVMGR),PrivacyManager() |
|---|
| 778 |
exten => s,n,SetCallerPres(allowed_passed_screen); stop gap until app_privacy.c clears unavailble bit |
|---|
| 779 |
exten => s,PRIVMGR+101,Noop(STATUS: ${PRIVACYMGRSTATUS} CID: ${CALLERID(num)} ${CALLERID(name)} CALLPRES: ${CALLLINGPRES}) |
|---|
| 780 |
exten => s,n,Playback(sorry-youre-having-problems) |
|---|
| 781 |
exten => s,n,Playback(goodbye) |
|---|
| 782 |
exten => s,n,Playtones(congestion) |
|---|
| 783 |
exten => s,n,Congestion(5) |
|---|
| 784 |
|
|---|
| 785 |
|
|---|
| 786 |
; |
|---|
| 787 |
; ############################################################################ |
|---|
| 788 |
; Inbound Contexts [from] |
|---|
| 789 |
; ############################################################################ |
|---|
| 790 |
|
|---|
| 791 |
[from-sip-external] |
|---|
| 792 |
;give external sip users congestion and hangup |
|---|
| 793 |
; Yes. This is _really_ meant to be _. - I know asterisk whinges about it, but |
|---|
| 794 |
; I do know what I'm doing. This is correct. |
|---|
| 795 |
exten => _.,1,NoOp(Received incoming SIP connection from unknown peer to ${EXTEN}) |
|---|
| 796 |
exten => _.,n,Set(DID=${IF($["${EXTEN:1:2}"=""]?s:${EXTEN})}) |
|---|
| 797 |
exten => _.,n,Goto(s,1) |
|---|
| 798 |
exten => s,1,Ringing |
|---|
| 799 |
exten => s,n,GotoIf($["${ALLOW_SIP_ANON}"="yes"]?from-trunk,${DID},1) |
|---|
| 800 |
exten => s,n,Set(TIMEOUT(absolute)=15) |
|---|
| 801 |
exten => s,n,Answer |
|---|
| 802 |
exten => s,n,Wait(2) |
|---|
| 803 |
exten => s,n,Playback(ss-noservice) |
|---|
| 804 |
exten => s,n,Playtones(congestion) |
|---|
| 805 |
exten => s,n,Congestion(5) |
|---|
| 806 |
exten => h,1,NoOp(Hangup) |
|---|
| 807 |
exten => i,1,NoOp(Invalid) |
|---|
| 808 |
exten => t,1,NoOp(Timeout) |
|---|
| 809 |
|
|---|
| 810 |
[from-internal] |
|---|
| 811 |
; applications are now mostly all found in from-internal-additional in _custom.conf |
|---|
| 812 |
include => parkedcalls |
|---|
| 813 |
include => from-internal-custom |
|---|
| 814 |
;allow phones to dial other extensions |
|---|
| 815 |
include => ext-fax |
|---|
| 816 |
;allow phones to access generated contexts |
|---|
| 817 |
; |
|---|
| 818 |
; MODIFIED (PL) |
|---|
| 819 |
; |
|---|
| 820 |
; Currently the include for findmefollow is being auto-generated before ext-local which is the desired behavior. |
|---|
| 821 |
; However, I haven't been able to do anything that I know of to force this. We need to determine if it should |
|---|
| 822 |
; be hardcoded into here to make sure it doesn't change with some configuration. For now I will leave it out |
|---|
| 823 |
; until we can discuss this. |
|---|
| 824 |
; |
|---|
| 825 |
include => from-internal-additional |
|---|
| 826 |
include => ext-local-confirm |
|---|
| 827 |
include => bad-number |
|---|
| 828 |
exten => s,1,Macro(hangupcall) |
|---|
| 829 |
exten => h,1,Macro(hangupcall) |
|---|
| 830 |
|
|---|
| 831 |
;------------------------------------------------------------------------ |
|---|
| 832 |
; [bad-number] |
|---|
| 833 |
;------------------------------------------------------------------------ |
|---|
| 834 |
; This is where all calls go that don't have any other destination provided |
|---|
| 835 |
; |
|---|
| 836 |
;------------------------------------------------------------------------ |
|---|
| 837 |
[bad-number] |
|---|
| 838 |
exten => _X.,1,Wait(1) |
|---|
| 839 |
exten => _X.,n,Playback(silence/1&cannot-complete-as-dialed&check-number-dial-again,noanswer) |
|---|
| 840 |
exten => _X.,n,Wait(1) |
|---|
| 841 |
exten => _X.,n,Congestion(20) |
|---|
| 842 |
exten => _X.,n,Hangup() |
|---|
| 843 |
|
|---|
| 844 |
exten => _*.,1,Wait(1) |
|---|
| 845 |
exten => _*.,n,Playback(silence/1&feature-not-avail-line&silence/1&cannot-complete-as-dialed&check-number-dial-again,noanswer) |
|---|
| 846 |
exten => _*.,n,Wait(1) |
|---|
| 847 |
exten => _*.,n,Congestion(20) |
|---|
| 848 |
exten => _*.,n,Hangup() |
|---|
| 849 |
;------------------------------------------------------------------------ |
|---|
| 850 |
|
|---|
| 851 |
[from-zaptel] |
|---|
| 852 |
exten => _X.,1,Set(DID=${EXTEN}) |
|---|
| 853 |
exten => _X.,n,Goto(s,1) |
|---|
| 854 |
exten => s,1,NoOp(Entering from-zaptel with DID == ${DID}) |
|---|
| 855 |
; Some trunks _require_ a RINGING be sent before an Answer. |
|---|
| 856 |
exten => s,n,Ringing() |
|---|
| 857 |
; If ($did == "") { $did = "s"; } |
|---|
| 858 |
exten => s,n,Set(DID=${IF($["${DID}"= ""]?s:${DID})}) |
|---|
| 859 |
exten => s,n,NoOp(DID is now ${DID}) |
|---|
| 860 |
exten => s,n,GotoIf($["${CHANNEL:0:3}"="Zap"]?zapok:notzap) |
|---|
| 861 |
exten => s,n(notzap),Goto(from-pstn,${DID},1) |
|---|
| 862 |
; If there's no ext-did,s,1, that means there's not a no did/no cid route. Hangup. |
|---|
| 863 |
exten => s,n,Macro(hangup) |
|---|
| 864 |
exten => s,n(zapok),NoOp(Is a Zaptel Channel) |
|---|
| 865 |
exten => s,n,Set(CHAN=${CHANNEL:4}) |
|---|
| 866 |
exten => s,n,Set(CHAN=${CUT(CHAN,-,1)}) |
|---|
| 867 |
exten => s,n,Macro(from-zaptel-${CHAN},${DID},1) |
|---|
| 868 |
; If nothing there, then treat it as a DID |
|---|
| 869 |
exten => s,n,NoOp(Returned from Macro from-zaptel-${CHAN}) |
|---|
| 870 |
exten => s,n,Goto(from-pstn,${DID},1) |
|---|
| 871 |
exten => fax,1,Goto(ext-fax,in_fax,1) |
|---|
| 872 |
|
|---|
| 873 |
;------------------------------------------------------------------------ |
|---|
| 874 |
; [macro-setmusic] |
|---|
| 875 |
;------------------------------------------------------------------------ |
|---|
| 876 |
; CONTEXT: macro-setmusic |
|---|
| 877 |
; PURPOSE: to turn off moh on routes where it is not desired |
|---|
| 878 |
; |
|---|
| 879 |
;------------------------------------------------------------------------ |
|---|
| 880 |
[macro-setmusic] |
|---|
| 881 |
exten => s,1,NoOp(Setting Outbound Route MoH To: ${ARG1}) |
|---|
| 882 |
exten => s,2,SetMusicOnHold(${ARG1}) |
|---|
| 883 |
;------------------------------------------------------------------------ |
|---|
| 884 |
|
|---|
| 885 |
; ########################################## |
|---|
| 886 |
; ## Ring Groups with Confirmation macros ## |
|---|
| 887 |
; ########################################## |
|---|
| 888 |
; Used by followme and ringgroups |
|---|
| 889 |
|
|---|
| 890 |
;------------------------------------------------------------------------ |
|---|
| 891 |
; [macro-dial-confirm] |
|---|
| 892 |
;------------------------------------------------------------------------ |
|---|
| 893 |
; This has now been incorporated into dialparties. It still only works with ringall |
|---|
| 894 |
; and ringall-prim strategies. Have not investigated why it doesn't work with |
|---|
| 895 |
; hunt and memory hunt. |
|---|
| 896 |
; |
|---|
| 897 |
;------------------------------------------------------------------------ |
|---|
| 898 |
[macro-dial-confirm] |
|---|
| 899 |
; This was written to make it easy to use macro-dial-confirm instead of macro-dial in generated dialplans. |
|---|
| 900 |
; This takes the same paramaters, with an additional paramater of the ring group Number |
|---|
| 901 |
; ARG1 is the timeout |
|---|
| 902 |
; ARG2 is the DIAL_OPTIONS |
|---|
| 903 |
; ARG3 is a list of xtns to call - 203-222-240-123123123#-211 |
|---|
| 904 |
; ARG4 is the ring group number |
|---|
| 905 |
|
|---|
| 906 |
; This sets a unique value to indicate that the channel is ringing. This is used for warning slow |
|---|
| 907 |
; users that the call has already been picked up. |
|---|
| 908 |
; |
|---|
| 909 |
exten => s,1,Set(DB(RG/${ARG4}/${CHANNEL})=RINGING) |
|---|
| 910 |
|
|---|
| 911 |
; We need to keep that channel variable, because it'll change when we do this dial, so set it to |
|---|
| 912 |
; fallthrough to every sibling. |
|---|
| 913 |
; |
|---|
| 914 |
exten => s,n,Set(__UNIQCHAN=${CHANNEL}) |
|---|
| 915 |
|
|---|
| 916 |
; The calling ringgroup should have set RingGroupMethod appropriately. We need to set two |
|---|
| 917 |
; additional parameters: |
|---|
| 918 |
; |
|---|
| 919 |
; USE_CONFIRMATION, RINGGROUP_INDEX |
|---|
| 920 |
; |
|---|
| 921 |
; Thse are passed to inform dialparties to place external calls through the [grps] context |
|---|
| 922 |
; |
|---|
| 923 |
exten => s,n,Set(USE_CONFIRMATION=TRUE) |
|---|
| 924 |
exten => s,n,Set(RINGGROUP_INDEX=${ARG4}) |
|---|
| 925 |
exten => s,n,Set(ARG4=) ; otherwise it gets passed to dialparties.agi which processes it (prob bug) |
|---|
| 926 |
|
|---|
| 927 |
exten => s,n,Macro(dial,${ARG1},${ARG2},${ARG3}) |
|---|
| 928 |
|
|---|
| 929 |
exten => s,n,Set(USE_CONFIRMATION=) |
|---|
| 930 |
exten => s,n,Set(RINGGROUP_INDEX=) |
|---|
| 931 |
|
|---|
| 932 |
; delete the variable, if we are here, we are done trying to dial and it may have been left around |
|---|
| 933 |
; |
|---|
| 934 |
exten => s,n,DBDel(RG/${ARG4}/${CHANNEL}) |
|---|
| 935 |
;------------------------------------------------------------------------ |
|---|
| 936 |
|
|---|
| 937 |
;------------------------------------------------------------------------ |
|---|
| 938 |
; [macro-auto-confirm] |
|---|
| 939 |
;------------------------------------------------------------------------ |
|---|
| 940 |
; This macro is called from ext-local-confirm to auto-confirm a call so that other extensions |
|---|
| 941 |
; are aware that the call has been answered. |
|---|
| 942 |
; |
|---|
| 943 |
;------------------------------------------------------------------------ |
|---|
| 944 |
[macro-auto-confirm] |
|---|
| 945 |
exten => s,1,Set(__MACRO_RESULT=) |
|---|
| 946 |
exten => s,n,DBDel(${BLKVM_OVERRIDE}) |
|---|
| 947 |
exten => s,n,DBDel(RG/${ARG1}/${UNIQCHAN}) |
|---|
| 948 |
|
|---|
| 949 |
;------------------------------------------------------------------------ |
|---|
| 950 |
; [macro-auto-blkvm] |
|---|
| 951 |
;------------------------------------------------------------------------ |
|---|
| 952 |
; This macro is called for any extension dialed form a queue, ringgroup |
|---|
| 953 |
; or followme, so that the answering extension can clear the voicemail block |
|---|
| 954 |
; override allow subsequent transfers to properly operate. |
|---|
| 955 |
; |
|---|
| 956 |
;------------------------------------------------------------------------ |
|---|
| 957 |
[macro-auto-blkvm] |
|---|
| 958 |
exten => s,1,Set(__MACRO_RESULT=) |
|---|
| 959 |
exten => s,n,DBDel(${BLKVM_OVERRIDE}) |
|---|
| 960 |
|
|---|
| 961 |
;------------------------------------------------------------------------ |
|---|
| 962 |
; [ext-local-confirm] |
|---|
| 963 |
;------------------------------------------------------------------------ |
|---|
| 964 |
; If call confirm is being used in a ringgroup, then calls that do not require confirmation are sent |
|---|
| 965 |
; to this extension instead of straight to the device. |
|---|
| 966 |
; |
|---|
| 967 |
; The sole purpose of sending them here is to make sure we run Macro(auto-confirm) if this |
|---|
| 968 |
; extension answers the line. This takes care of clearing the database key that is used to inform |
|---|
| 969 |
; other potential late comers that the extension has been answered by someone else. |
|---|
| 970 |
; |
|---|
| 971 |
;------------------------------------------------------------------------ |
|---|
| 972 |
[ext-local-confirm] |
|---|
| 973 |
exten => _LC-.,1,Noop(IN ext-local-confirm with - RT: ${RT}, RG_IDX: ${RG_IDX}) |
|---|
| 974 |
exten => _LC-.,n,dial(${DB(DEVICE/${EXTEN:3}/dial)},${RT},M(auto-confirm^${RG_IDX})${DIAL_OPTIONS}) |
|---|
| 975 |
|
|---|
| 976 |
;------------------------------------------------------------------------ |
|---|
| 977 |
; [macro-confirm] |
|---|
| 978 |
;------------------------------------------------------------------------ |
|---|
| 979 |
; CONTEXT: macro-confirm |
|---|
| 980 |
; PURPOSE: added default message if none supplied |
|---|
| 981 |
; |
|---|
| 982 |
; Follom-Me and Ringgroups provide an option to supply a message to be |
|---|
| 983 |
; played as part of the confirmation. These changes have added a default |
|---|
| 984 |
; message if none is supplied. |
|---|
| 985 |
; |
|---|
| 986 |
;------------------------------------------------------------------------ |
|---|
| 987 |
[macro-confirm] |
|---|
| 988 |
exten => s,1,Set(LOOPCOUNT=0) |
|---|
| 989 |
exten => s,n,Noop(CALLCONFIRMCID: ${CALLCONFIRMCID}) |
|---|
| 990 |
|
|---|
| 991 |
; We set ABORT rather than CONTINUE, as we want the server to forget about this channel |
|---|
| 992 |
; if it's declined, hung up, or timed out. We don't want it to continue on to the next |
|---|
| 993 |
; step in the dialplan, which could be anything! |
|---|
| 994 |
exten => s,n,Set(__MACRO_RESULT=ABORT) |
|---|
| 995 |
|
|---|
| 996 |
; ARG1 is the announcement to play to tell the user that they've got a call they need |
|---|
| 997 |
; to confirm. Something along the lines of 'You have an incoming call. Press 1 to accept, 9 to reject' |
|---|
| 998 |
exten => s,n,Set(MSG1=${IF($["foo${ARG1}" != "foo"]?${ARG1}:"incoming-call-1-accept-2-decline")}) |
|---|
| 999 |
exten => s,n(start),Read(INPUT|${MSG1}|1||1|5) |
|---|
| 1000 |
|
|---|
| 1001 |
; So. We've now read something, or nothing. We should check to make sure that the call hasn't |
|---|
| 1002 |
; already been answered by someone else. If it has, send this call to toolate |
|---|
| 1003 |
exten => s,n,GotoIf(${DB_EXISTS(RG/${ARG3}/${UNIQCHAN})}?check:toolate) |
|---|
| 1004 |
|
|---|
| 1005 |
; We passed that test, so it means the call hasn't been answered. Has this user pushed 1? If so, |
|---|
| 1006 |
; then go to OK. |
|---|
| 1007 |
exten => s,n(check),GotoIf($["${INPUT}"="1"]?ok) |
|---|
| 1008 |
|
|---|
| 1009 |
; If they've pushed 9, then they definately don't want the call. Just pretend there was no response |
|---|
| 1010 |
; and go to noanswer (or 2 since that will be default for asterisk) |
|---|
| 1011 |
exten => s,n,GotoIf($["${INPUT}"="9"]?noanswer) |
|---|
| 1012 |
exten => s,n,GotoIf($["${INPUT}"="2"]?noanswer) |
|---|
| 1013 |
exten => s,n,GotoIf($["${INPUT}"="3"]?playcid) |
|---|
| 1014 |
|
|---|
| 1015 |
; Increment LOOPCOUNT, and check to make sure we haven't played it 5 times by now. We assume that |
|---|
| 1016 |
; the person is able to push '1' in a reasonably short time. |
|---|
| 1017 |
exten => s,n,Set(LOOPCOUNT=$[ ${LOOPCOUNT} + 1 ]) |
|---|
| 1018 |
exten => s,n,GotoIf($[ ${LOOPCOUNT} < 5 ]?start) |
|---|
| 1019 |
|
|---|
| 1020 |
; If we're here, that means we've played it MORE than 5 times. Set __MACRO_RESULT=ABORT, well, just |
|---|
| 1021 |
; coz, and goto fin, which is the last line, meaning it returns to the previous Dial, and pretends as |
|---|
| 1022 |
; if nothing has happened. |
|---|
| 1023 |
exten => s,n(noanswer),Set(__MACRO_RESULT=ABORT) |
|---|
| 1024 |
exten => s,n,Goto(fin) |
|---|
| 1025 |
|
|---|
| 1026 |
; Test play callerid |
|---|
| 1027 |
; |
|---|
| 1028 |
exten => s,n(playcid),Noop(Playing CID: ${CALLCONFIRMCID}) |
|---|
| 1029 |
exten => s,n,SayDigits(${CALLCONFIRMCID}) |
|---|
| 1030 |
exten => s,n,Goto(start) |
|---|
| 1031 |
|
|---|
| 1032 |
; If we're here, it's because the call was already accepted by someone else. |
|---|
| 1033 |
exten => s,n(toolate),Set(MSG2=${IF($["foo${ARG2}" != "foo"]?${ARG2}:"incoming-call-no-longer-avail")}) |
|---|
| 1034 |
exten => s,n,Playback(${MSG2}) |
|---|
| 1035 |
exten => s,n,Goto(noanswer) |
|---|
| 1036 |
|
|---|
| 1037 |
; If we made it here, it's because the call _WAS_ accepted, AND it's still ringing. We delete the |
|---|
| 1038 |
; database entry (so that the DB_EXISTS line above will trigger a 'toolate' jump), and set the |
|---|
| 1039 |
; MACRO_RESULT variable to NOTHING. This is the magic string that joins both legs of the call together |
|---|
| 1040 |
exten => s,n(ok),DBDel(RG/${ARG3}/${UNIQCHAN}) |
|---|
| 1041 |
exten => s,n,DBDel(${BLKVM_OVERRIDE}) |
|---|
| 1042 |
exten => s,n,Set(__MACRO_RESULT=) |
|---|
| 1043 |
|
|---|
| 1044 |
; The end. |
|---|
| 1045 |
exten => s,n(fin),NoOp(Finished) |
|---|
| 1046 |
exten => h,1,Noop(Hangup Extension in macro-confirm) |
|---|
| 1047 |
exten => h,n,Macro(hangupcall) |
|---|
| 1048 |
|
|---|
| 1049 |
;------------------------------------------------------------------------ |
|---|
| 1050 |
|
|---|
| 1051 |
; ############################################################################ |
|---|
| 1052 |
; Extension Contexts [ext] |
|---|
| 1053 |
; ############################################################################ |
|---|
| 1054 |
|
|---|
| 1055 |
[ext-fax] |
|---|
| 1056 |
exten => s,1,Answer |
|---|
| 1057 |
exten => s,2,Goto(in_fax,1) |
|---|
| 1058 |
exten => in_fax,1,StopPlayTones |
|---|
| 1059 |
exten => in_fax,2,GotoIf($["${FAX_RX}" = "system"]?3:analog_fax,1) |
|---|
| 1060 |
exten => in_fax,3,Macro(faxreceive) |
|---|
| 1061 |
exten => in_fax,4,Hangup |
|---|
| 1062 |
exten => analog_fax,1,GotoIf($["${FAX_RX}" = "disabled"]?4:2) ;if fax is disabled, just hang up |
|---|
| 1063 |
exten => analog_fax,2,Set(DIAL=${DB(DEVICE/${FAX_RX}/dial)}); |
|---|
| 1064 |
exten => analog_fax,3,Dial(${DIAL},20,d) |
|---|
| 1065 |
exten => analog_fax,4,Hangup |
|---|
| 1066 |
;exten => out_fax,1,wait(7) |
|---|
| 1067 |
exten => out_fax,1,txfax(${TXFAX_NAME}|caller) |
|---|
| 1068 |
exten => out_fax,2,Hangup |
|---|
| 1069 |
exten => h,1,system(/var/lib/asterisk/bin/fax-process.pl --to ${EMAILADDR} --from ${FAX_RX_FROM} --subject "Fax from ${URIENCODE(${CALLERID(number)})} ${URIENCODE(${CALLERID(name)})}" --attachment fax_${URIENCODE(${CALLERID(number)})}.pdf --type application/pdf --file ${FAXFILE}); |
|---|
| 1070 |
exten => h,2,Hangup() |
|---|
| 1071 |
|
|---|
| 1072 |
;this is where parked calls go if they time-out. Should probably re-ring |
|---|
| 1073 |
[default] |
|---|
| 1074 |
include => ext-local |
|---|
| 1075 |
exten => s,1,Playback(vm-goodbye) |
|---|
| 1076 |
exten => s,2,Macro(hangupcall) |
|---|