Can I do this custom context better

Following up on this: What is the purpose of all the includes

I set this up and it works well. It looks up the outbound CID to use based on the last five digits dialled.
Then it sends the call back to from-internal with a different prefix to end up in a different route.
The GotoIf catches that and skips the lookup logic this time around.

exten => s,1,Wait(1)
exten => s,n,NoOp()
;exten => s,n,Log(NOTICE, Arrived in macro-dialout-trunk-predial-hook)
; Check if we came from the route "88_stripped_AUTCODE"
exten => s,n,GotoIf($["${OUTBOUND_ROUTE_NAME}"=="88_stripped_AUTCODE"]?autcodestripped,1)
; If not, pick apart OUTNUM. Normal format 81NXXNXXXXXXXXXXX
exten => s,n,Set(AUTDIALED=${OUTNUM:2:10})
exten => s,n,Set(AUTCODE=${OUTNUM:-5})
; Lookup the outbound CID for this AUTCODE
;exten => s,n,Log(NOTICE, Leaving macro-dialout-trunk-predial-hook)
;exten => s,n,DumpChan
;exten => s,n,Goto(outbound-allroutes)
exten => s,n,Goto(from-internal,881${AUTDIALED},1)
exten => s,n,Hangup()
exten => autcodestripped,1,NoOp()
;exten => autcodestripped,n,Log(NOTICE, In macro-dialout-trunk-predial-hook but already stripped autcode)
;exten => autcodestripped,n,DumpChan
;exten => autcodestripped,1,Log(NOTICE, Leaving macro-dialout-trunk-predial-hook but already stripped autcode)

I assume you tested emergency calls and they’re not adversely affected. Otherwise nothing jumps out at me.

1 Like

@lgaetz not yet. There are other call designs that also have to be dealt with. Emergency call among them.

Now that I have this working as desired, I was thinking this hook should just be multiple gotoif statements sending calls out to other contexts to keep things more organized.

Literally 5pm Friday I was done, but wanted to toss the question out here.

My goal is to break the GUI process as little as possible. That is why I pulled the 81 from the front and prepended 881 after a match. I made a normal outbound route to catch the follow up outbound call.

Been workign on this more and running in to the fact that I would like to jump to a specific outbound route in a goto, but I have no idea what the route name will be ahead of time if I stick with the GUI for them. The routes are named with a numbering scheme that I would not specifically know.


for the names of the trunks, from bash

mysql asterisk -e “select * from outbound_routes”

for the sequence used if you need it

mysql asterisk -e “select * from outbound_route_sequence”

Use dial prefixes. If you want to force a call out [outrt-7], have route 7 containg a dial pattern with a prefix of “666” and then do:


That is what I am doing already. I was trying to come up with a way to put in a route after all other routes that would be impossible for a use to get to as the prefix would match an earlier route but would be the route that actually goes out.

With a prefix if someone tells someone else the super secret trick, you could dial out without the other verification required.

@lgaetz here is a more cleaned up and tested version of things.

exten => s,1,NoOp()
; Skip if this is an emergency call
exten => s,n,GotoIf($["${EMERGENCYROUTE}"=="YES"]?emergencyrouteused)
; Check if the call has already been validated to go out, and skip the rest of the processing
exten => s,n,GotoIf($["${OUTBOUND_ROUTE_NAME}"=="Call_Validated_to_go_Out"]?skipvalidation)
; Depending on the outbound route send the call to be validated
; NANPA style number dialed with a code
exten => s,n,GotoIf($["${OUTBOUND_ROUTE_NAME}"=="NANPA_Dialed_with_Code"]?validatenanpa,s,1)
;More logic coming. For now, dump channel and terminate call.
exten => s,n,DumpChan
exten => s,n,Hangup()
; The call was an emegerncy dial, do no processing, but note the log.
exten => s,n(emergencyrouteused),NoOp()
exten => s,n,Log(NOTICE, 911 was dialed by extension ${FROMEXTEN})
; The call was validated, nothing else to do.
exten => s,n(skipvalidation),NoOp()
exten => s,1,NoOp()
; NANPA format means digit zero is 7 or 8 and digit one is a 1 
; digits two through ten should be a 10 digit number
; the last five digits are the AUTCODE
exten => s,n,Set(USERDIALED=${OUTNUM:2:10})
exten => s,n,Set(AUTCODE=${OUTNUM:-5})
; Go check for a valid code
exten => s,n,Set(RETURNTOCONTEXT=validatenanpa)
exten => s,n,GoTo(checkvalidautcode,s,1)
; Return location if AUTCODE is valid
exten => s,n(autcodevalid),NoOp()
; Check if the AUTCODE has a CID associated with it. 
; If there is no CID jump to autcidno, otherwise autcidyes
exten => s,n,GotoIf($["${AUTCODECIDNUM}" == ""]?autcidno:autcidyes)
exten => s,n,Hangup()
exten => s,n(autcidyes),NoOp()
exten => s,n,Log(NOTICE, The AUTCODE of ${AUTCODE} has an associated CID of ${AUTCODECIDNUM}. Forcing it to apply.
exten => s,n(autcidno),NoOp()
; Go back to outbound route logic with the "secret" prefix of 8675309 (Jenny) that will match the pattern to get to an outboud trunk
exten => s,n,Goto(outbound-allroutes,8675309${USERDIALED},1)
exten => s,n,Hangup()
; This context checks that the AUTCODE value (last five digits) exists in the `autcodes` table
; See func_odbc.conf for the SQL statement.
; This context requires that the variable RETURNTOCONTEXT be set in by the context that calls it
; This context also requres that the calling context have a line labeled autcodevalid to return to
exten => s,1,NoOp()
; Start a rety counter.
exten => s,n,Set(RETRYCODE=0)
; If code is invalid, user is prompted to try again and the call is sent back to here
exten => s,n(tryagain),NoOp()
; Check the database for the autcode. SQL query returns the `id` of the row if found
; if no rows are returned jump to badaut, if something is returned jump to goodaut
exten => s,n,GotoIf($[${ODBCROWS} = 0]?badaut,1:goodaut,1)
exten => s,n,Hangup()
exten => badaut,1,NoOp()
exten => badaut,n(notfound),Log(NOTICE, The AUTCODE of ${AUTCODE} was not found, user needs to try again)
; Increment the fail counter
exten => badaut,n,Set(RETRYCODE=$[${RETRYCODE} + 1])
; If the user has failed 3 times (or more somehow) jump to toomanytries
exten => badaut,n,GotoIf($[${RETRYCODE} >= 3]?toomanytries,1)
; Tell them the code was bad and to try again
exten => badaut,n,Playback(you-entered)
exten => badaut,n,Playback(access-code)
exten => badaut,n,SayDigits(${AUTCODE})
exten => badaut,n,Playback(vm-pls-try-again)
exten => badaut,n,Set(TIMEOUT(response)=10)
exten => badaut,n,Read(AUTCODE,access-code,5,,2,5)
; If the entered code was 5 digits jump back up to try again, otherwise jump up to not found
exten => badaut,n,GotoIf($[${LEN(${AUTCODE})}==5]?s,tryagain:notfound)
exten => badaut,n,Hangup()
exten => goodaut,1,NoOp()
exten => goodaut,n,Log(NOTICE, The AUTCODE of ${AUTCODE} was found, let call proceed)
; The code was found, so go back to the context that we came from at the spot marked autcodevalid
exten => goodaut,n,GoTo(${RETURNTOCONTEXT},s,autcodevalid)
exten => goodaut,n,Hangup()
exten => toomanytries,1,NoOp()
exten => toomanytries,n,Log(NOTICE, The user failed to enter a valid AUTCODE too many times)
; The user the dialed the code wrong too many times, hangup the call
exten => toomanytries,n,Playback(sorry)
exten => toomanytries,n,Playback(goodbye)
exten => toomanytries,n,Hangup()

No closing ) on this.

On the train home, but I’ll check the server later.

Everything was executing.

Very well could have been a typo in the post. But I would just double check sometimes bad dialplan just throws errors but continues.

Just checked, and it was missed. Not going to parse Friday’s log tonight to see what was shown. Fixed now, thanks.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.