How to make internal calls ring differently from external ones

Every so often I see someone ask whether it’s possible to make internal calls have a distinctive ring from external ones. I thought it would not be that difficult, but I was wrong. Let’s say that you have three-digit extensions, and whenever someone calls extension 234 you want it to ring with the normal pattern if it’s an external call, but with a different pattern if it’s an internal call (and we assume here that the endpoint supports this). This is as far as I got - in extensions_custom.conf, I added the following at the bottom of the [from-internal-custom] context:

exten => 234,1,Goto(checkiflocal,${EXTEN},1)

exten => _XXX,1,GotoIf($["${CALLERID(num)}" > “999”]?notfromext)
exten => _XXX,n,GotoIf($["${CALLERID(num)}" < “100”]?notfromext)
exten => _XXX,n,Set(__ALERT_INFO=Bellcore-r4)
exten => _XXX,n(notfromext),Goto(from-internal,${EXTEN},2)

The above actually works in testing, but it’s not right. The problem here is returning to the from-internal context. What I want it to do is return to from-internal and continue processing without skipping anything that should execute, but an include apparently isn’t designed that way. The first statement that matches extension 234 apparently means that the next statement must be number 2, or something like that (I’m REALLY confused at the moment). Anyway, the difference is that when I make a call without the above added lines, the first two lines of CLI output are these:

-- Executing [[email protected]:1] GotoIf("SIP/230-b7d17a30", "0?ext-local|234|1") in new stack
-- Executing [[email protected]:2] Macro("SIP/230-b7d17a30", "user-callerid|") in new stack

BUT, if I use the above added code, the conditional call to ext-local is completely skipped, and after executing my added lines it picks up with the second line. You might say “but of course, because you are specifying line 2 in the Goto” - but if I specify Line 1, it just goes into an endless loop until I hang up.

Is there some way I can accomplish the above without skipping the conditional call to ext-local? So far that doesn’t seem to make a difference, but then I have no idea where that Gosub is in the actual code so I have no idea under what circumstances the call to ext-local is supposed to be invoked. And there may be other includes that are being skipped as well.

Any thoughts?

We have done this by setting all indound DID’s with alert info and have our endpoints configured so that it will trigger the second ring signal if alert info is received. Internal calls will ring whatever the signal is set to on the endpoint as default.

Thanks… I knew there was some obvious solution I was overlooking … although it would be nice to be able to explicitly specify an alert-info for internal calls, and another for external calls, as requested here: (although the more I think about it, the more I think this functionality really ought to be on a per-extension basis, not a per-followme basis, since different endpoints may use different alert info strings, and not all of those may be configurable).

I was actually on the right track, but not doing it in the right place. The trick is to put the following code in /etc/asterisk/extensions_override_freepbx.conf :

include => set-alert-if-local

include => from-internal-xfer
include => bad-number

exten => 234,1,GotoIf($["${CALLERID(num)}" > "999"]?notfromlocal)
exten => 234,n,GotoIf($["${CALLERID(num)}" < "100"]?notfromlocal)
exten => 234,n,Set(__ALERT_INFO=Bellcore-r3)
exten => 234,n(notfromlocal),Goto(from-internal-original,${EXTEN},1)
;The following three lines must not be changed!
exten => _.,1,Goto(from-internal-original,${EXTEN},1)
exten => s,1,Goto(from-internal-original,s,1)
exten => h,1,Macro(hangupcall)

The real action is in the four lines following the [set-alert-if-local] context tag, which can be duplicated as often as necessary for the number of extensions you have and the different ring patterns. Specifically:

All four lines must begin with either exten => extension, or exten => _pattern, — this defines which extension or group of extensions the rule is to apply to. Don’t forget the leading underscore if using a pattern.

The first two lines define the upper and lower boundaries of what is considered a local extension - in this case, anything above 999 or below 100 would not be considered local. Therefore, you can set the distinctive ring to occur only if the call is from a particular group of extensions (a subset of your local extensions) or even compress this down to a single line and do an exact match on a particular calling extension (e.g. the boss!).

The third line sets the Alert Info string, and must be the correct string for the endpoint. You could have multiple rules to have different distinctive rings for different individual calling extensions, or groups of extensions.

The fourth line after the [set-alert-if-local] context tag should be included verbatim, except of course that if you have multiple rule sets then each one must have a unique label here (and that label must also be changed to match in the first two lines after the [set-alert-if-local] tag). So, if I had multiple rules here, instead of using notfromlocal I might use notfromlocal234, so I could keep my labels straight when reading down the list (also that would be easier to auto-generate if anyone ever writes a module to do this).

All the other lines should probably be left unchanged, although I have a feeling that someone will say I should not use the _. pattern in the catch-all line that follows the comment. I was basically following the lead of whoever wrote the [from-sip-external] context in extensions.conf (see the comment in that section of code).

One caveat, I haven’t upgraded to 2.6 yet so if you have, be sure to check /etc/asterisk/extensions.conf and make sure that the [from-internal] context hasn’t changed - that’s what I copied verbatim to the [from-internal-original] context here, so if that changes in extensions.conf then it must be changed here in extensions_override_freepbx.conf as well.

I’ll probably copy this information to a How-To in a day or two, but wanted to post it here first so that you guys could critique it and tell me if I’m doing anything I shouldn’t here. And no, I an not real crazy about putting the [from-internal] context in extensions_override_freepbx.conf, but everything I tried in extensions_custom.conf had unwanted side effects. When I get around to doing the How-To I’ll definitely mention mickecarlsson’s technique first, since that will be easier in many situations (especially where are your endpoints use the same Alert Info strings).


I’ve actually used the technique referred to by mickecarlsson and it works as long as the destination object of the inbound route is an extension.

As soon as the destination of the call is a different object (queue, ring group, etc.) it looses the Alert-Info information along the way and by the time the call goes to an extension.

This is my experience with FreePBX 2.5

Hi All,
Just an update to an old thread - still relevant.
I have successfully used the method recommended by mickecarlsson.

Mappletree found this did not work in Freepbx 2.5 if the destination is not an extension.

In Free PBX 2.10 it works well, regardless whether the first destination is an extension, or, in my case, an Announcement.

The text you need to put in the Alert_info field itself seems to be endpoint (handset) dependent.

I am using Grandstream GXP phones, and used this setting in the Alert Info Field (copy and paste the entire next line, including the <> but replace the first _ with a < ( I can’t get the forum to accept the code if it has the initial < ) :

This is recognised by the handset without any configuration required on the handset, and is different to the default ringtone.
You can also use (for slightly different styles of ringtones):

It really is a simple and effective solution to what is quite a real problem.

If you want to get fancy, you can define your own Alert_info code, then set your grandstream handset to respond to this particular indial signal with one of the 3 inbuilt special ring tones in the handset (which are none of the above options). I am not keen on this as I find changing the handset settings a chore, and the above solution requires no handset changes, and no mucking about with conf files within Asterisk either (with all respect to wiseoldowl’s post!)

This is the link to the howto from Grandstream forum:

Hope this makes life easier for the next person along…