What is the purpose of all the includes

As is probably obvious from some of my recent posts, I am on a project right now with a bit of customization required.

But getting what I need to happen in a coupe of places is really, really a pain in the butt.

Almost everything has an include. Great.

But includes are processed at the end. Not great. Because most contexts have a hangup or something else that causes whatever you want to include not to run.

Or am I totally misunderstanding?

Simple Example:
Speak my extension is *65 and executes this.

include => app-speakextennum-custom
exten => *65,1,Set(CONNECTEDLINE(name-charset,i)=utf8)
exten => *65,n,Set(CONNECTEDLINE(name,i)=Speak Extension)
exten => *65,n,Set(CONNECTEDLINE(num,i)=*65)
exten => *65,n,Answer
exten => *65,n,Wait(1)
exten => *65,n,Macro(user-callerid,)
exten => *65,n,GotoIf($[${DIALPLAN_EXISTS(app-speakextennum,${CHANNEL(language)},1)}]?app-speakextennum,${CHANNEL(language)},1:ap$

exten => en,1,Playback(your)
exten => en,n,Playback(extension)
exten => en,n,Playback(number)
exten => en,n,Playback(is)
exten => en,n,SayDigits(${AMPUSER})
exten => en,n,Wait(2)
exten => en,n,Hangup

What is the point of include => app-speakextennum-custom?
Because I can drop this in extensions_custom.conf and it never executes because of the hangup in [app-speakextennum].

exten => s,1,Noop(look at me in app-speakextennum-custom)
exten => s,n,DumpChan

I cannot find any wiki article or other help article on what context includes are actually useful. Does something like this even exist?

-custom generation is very very old. Maybe 2007 and has just stuck around. Confusing people on how much control they have over their dialplan when they actually have very little unless you use the overrides. Every context that is generated dynamically gets a -custom in the code

As Andrew said, the majority of the predefined includes are not usable. There is an Advanced Setting to disable custom includes if you want to stop seeing them.

Ok @tm1000 @lgaetz, I can accept that. But then where can we interact with the dialplan reliably?

I try to work within the framework as much as possible, but customization always happens on larger setups.

It also never executes because you don’t actually transfer control to the context.

Includes are handy for making sure that your context gets read into the dialplan, but you still need to find a way to execute it. The common way is to use the “-custom” context instead of the regular context and then transfer the execution of the logic back to the original context in the custom code.

In this example, you’d have to use an override to change the transfer in “exten => *65,n,GotoIf($[${DIALPLAN_EXISTS…” from app-speakextennum to app-speakextennum-custom for your code to execute. The fact that the custom code is available doesn’t mean it will magically be executed without some kind of control transfer.

Anything in extensions_custom.conf will get added, so that is really not a problem today. Their explanation on the history of includes definitely means that they are generally useless on the modern FreePBX.

At the current moment you’d have to write a module

But creating an override means that I will forever have to maintain [app-speakextennum] and that begins to defeat the purpose of using something like FreePBX. I should just use raw Asterisk.

/sigh I don’t want to learn that. I know Asterisk and dial plans. I don’t want to learn module development.

I hear you. Lorne and I have some ideas. But they won’t help you in the short term unfortunately. But we are listening.

1 Like

Reliably? There are a few places:

  • inbound calls from trunks can be configured to go to a user defined context, which in turn sends the call to from-trunk
  • diaplan hooks, there are a handful of “hook” macros that are called immediately prior to dialing, such as macro-dialout-trunk-predial-hook. You can safely define these macros in extensions_custom.conf.
  • Custom Destinations. If you want to create a call flow through a block of dialplan, you can define a custom destination, and close your dialplan with a Return to send the call back to the GUI destination.

and last resort:

  • by redefining existing generated contexts in the override file.
1 Like

Good to hear.

I will look for the hook options first. I am mostly needing to handle some outbound dialed number processing.

If that fails I will fall through to a Custom Destination, which is what I used for the Exchange UM connectivity via the advanced tab in the extension (thanks for that tip).

1 Like

Looks like this is the list of hooks.

[[email protected] ~]$ grep '\-hook' /etc/asterisk/*.conf

Sounds like dialout-trunk-predial-hook is the only one that will execute in the path of the call I am targeting.

; macro-dialout-trunk-predial-hook:
; this macro intentionally left blank so it may be safely overwritten for any custom
; requirements that an installation may have.
; the macro is called by macro-dialout-trunk just prior to making a Dial() attempt
; to a trunk.
;                    if set to "BYPASS" then this trunk will be skipped
exten => s,1,MacroExit()

But this is defined, so that means it needs to be in _override.conf?

Negative. You can re-define it in extensions_custom.conf. Try it.

1 Like

Will do, thanks.

@lgaetz A little quick testing shows me that I think I can accomplish what I need in this context, but I have determined that I really want to hook in immediately prior to the outbound route decision making process.

I could not find a way to do that.

You can’t. But you can use the dialout trunk predial hook to change the dialed digits, then go back to outbound-allroutes with a goto.


That is what it looked like to me. Just thought to ask in case I missed something.

Of note, in case it’s useful for you. You can enable “Noop Traces” in Advanced Settings, and if you do a channel variable is populated with the outbound route name which you can use in the predial macro if you need it.

1 Like