Is there some way I can do an IF statement?

Hi all,

So, I’ve built my fair share of applications, call flows, menu’s and queues in Cisco UCCX scripts and one thing I use often is an IF statement to take action based on a certain condition or data. I don’t really know where to start in order to get the same sort of thing in FreePBX, nor do I even know what to search for! :slight_smile:

The idea is that a menu will give callers several unique options, for example, an English School’s Sales department has options for students ringing from China, South America, Europe etc. Each ‘region’ selection puts you through to a single agent, the expert in that market. In reality, the options destination is a ring-group with one (maybe two) extensions/agents in it. If they miss the call, the caller gets a new menu to either leave a voicemail to speak to someone else (that option sends callers to another “General Sales” ring group).

The problem is - if a caller wants to leave a voicemail message; how would I be able to identify which IVR selection they made so as to send them to the correct mailbox?

In a UCCX script, I would set some data on that call - if they selected China, then I could set a variable Country=“China”, and later in the script use an IF statement such as “If (Country==China) is True then Redirect Call to China_Sales_Voicemail”.

Is there some way that I could do something similar in FreePBX? I have some ideas in my head such as;

  • Duplicate the IVR for each set of agents so that I can set the correct mailbox option (seems inefficient to have like 5 of the same menu)
  • Create a group mailbox, and allow Users to access this Voicemail in their UCP (this could annoy users, as the South America agents would get false positives for China VM’s etc).
  • Voicemail Blasting?

Here’s a crude diagram of what I am trying to achieve.

Thanks in advance,

So yes, you can do what you want, but not purely within the GUI, you would have to use some of your own dial plan. This is the type of thing we do in support if you have a budget for it. To blend custom dial plan with normal FreePBX call flow, you use a Custom Destination. The broad strokes would be to:

  • add a different Custom Destination from each option from IVR1 that sets a channel variable to a unique value for each selection before going to the Ring Group.
  • create a 4th Custom Destination for when the caller chooses 1 from IVR2 that branches the call based on the value of the channel variable set by the first Custom Destination.

Harder to explain than to do in practice. Its a fun exercise if you are the type that likes to tinker,

Potentially you can look at switching from ring groups to queues, and utilize our Queue Pro, or Virtual Queue functionality, that allows you to have different entry and exit points for callers within the same queue.

We do offer free 30 day trials of this module if you want to test it out.

You can largely eliminate your “first column”

which essentially provides your IF condition.

Hi Lorne,

I decided this was the way I want to tackle it, as it seems to be the closest to what I want. What I didn’t originally know was that there is an Asterisk command GotoIf. I’ve done some reading on this, but getting into writing these configs/scripts isn’t my strong point at all. I’ll appreciate your patience in helping me out with this, if it’s not too much trouble. Here’s my plan;

I’ll add the following to extensions_custom.conf;


exten => s,1,GotoIf($[${CALLERID(nam)} = SA.*]?sa_voicemail)
exten => s,n,GotoIf($[${CALLERID(nam)} = CH.*]?ch_voicemail)
exten => s,n,GotoIf($[${CALLERID(nam)} = SEA.*]?sea_voicemail)
exten => s,n,GotoIf($[${CALLERID(nam)} = KRTW.*]?krtw_voicemail)
exten => s,n,GotoIf($[${CALLERID(nam)} = ME.*]?me_voicemail:nomatch)

exten => s,n(sa_voicemail),Voicemail(sb2504)
exten => s,n,Hangup()
exten => s,n(ch_voicemail),Voicemail(sb2505)
exten => s,n,Hangup()
exten => s,n(sea_voicemail),Voicemail(sb2506)
exten => s,n,Hangup()
exten => s,n(krtw_voicemail),Voicemail(sb2507)
exten => s,n,Hangup()
exten => s,n(me_voicemail),Voicemail(sb2508)
exten => s,n,Hangup()

exten => s,n(nomatch),Playback(an-error-has-occurred)
exten => s,n,Hangup()

The idea is that as calls time out of the Ring Group, I’ll send them to the Set Caller ID module and add a country code prefix to the CNAM.

I’ll then add the above to Custom Destination as ‘agentvm-conditional-branching,s,1’, so that I can select it as a destination out of the Set Caller ID module.

Hopefully then, my “thing” (application? script?) will pick up the CNAM prefix, using the GotoIf statement to send the call to the correct label and thus the correct mailbox (playing the Busy greeting, without instructions).

My assumptions are;

  • that CallerID(nam) is correct for looking at CNAM, and that I can match using regex
  • that I didn’t need to specify context when sending the call to the mailbox

The last part is to deal with exceptions, where I can’t match a CNAM properly instead I play an error and hang up the call.

Now - will this work? What have I stuffed up?


Edit: Yes, I did like the idea of setting a channel variable, I’m assuming then that this is transparent to the user. I decided on the CID prefix as callers will have an option to talk to a general sales group - and it may be useful for those agents to see what IVR selection the caller originally made.

Well you won’t be surprised to learn that you made a bunch of creative leaps that won’t work:

  1. The CID Name is stored in the variable CALLERID(name)
  2. You can’t do the compare in the way you have it. If you will want to compare the first 2 characters of callerid name explicitly try this:
    exten => s,1,GotoIf($[${CALLERID(name):0:2}=SA]?sa_voicemail)
  3. If it was me, I would use the built in macro for voicemail, which for extension 2002 would take the form:

Hi Lorne,

Thanks so much - as you probably expect, this has worked perfectly!! :smiley:

Makes the decision and sends calls to the correct mailbox based on the CNAME prefix I add in the Set CallerID module. Added to Custom Destinations so that it appears as a valid destination after the IVR. Very slick that I can have all of this in the FreePBX UI!

I need to do a little more research on the vm macro. I assume this was written by Sangoma, not an Asterisk built-in thing? Just want to know if, as in my original example, you can control which greetings are played (and whether or not to play instructions). The example you provided is perfect - it plays the Busy greeting with no instructions; but who knows what the customer will ask for once it’s in production (they may ask for no greeting, perhaps).

Very much appreciate the help with this one.

1 Like

You were close with

exten => s,n(sa_voicemail),Voicemail(sb2504)

but the syntax has changed


exten => s,n(sa_voicemail),Voicemail([email protected],sb)


exten => s,n(sa_voicemail),Voicemail([email protected],s)

for less noise, might be less confusing than deciphering the macro.

Thanks, dicko.

Ha - my google-fu took me to the 2nd Edition of the link above :wink:

I’ll keep this command in mind - it’s documented, so if the customer requires some tweaking of which greeting to play, that makes it easier for me. For now though, I’ve tested and implemented the changes Lorne suggested above, and it’s all working well.

This has been a great intro into Asterisk dialplan or scripting for me, and I’m glad this is how I was introduced - something simple and not too frustrating. Plus, I often get asked for conditional style call flows - which, I’ve always been able to work around with what’s available in the UI.

Do you think that this Conditional Branching will eventually become a module unto itself? Or, is it too difficult to create given that there are so many variables that need to be accounted for?

1 Like

I can’t speak for any pending modules.

To look at your use case, I would write an inbound context based on [from-pstn-e164] that you would expand to encompass your likely callers, and “normalize” the callerid(num) over your trunks,I would also add something like

exten => _+1NXXNXXXXXX,Set(CHANNEL(language)=en_US)
exten => _+44XXXXXXXX.,Set(CHANNEL(language)=en_GB)
exten => _+49XXXXXXXX.,Set(CHANNEL(language)=de)
for each country section as appropriate, ref: etc.

Of course installing the appropriate “language pack” ref:-

That would be a start at rationalizing your calls , i,e, the IVR’s when properly set up would be caller aware by language and accent based on CID, China might be a bit harder between Manderin and Cantonese. As you will find, that is likely not easy to setup in the GUI so your choice of scripting is probably the way to go, there are of course man y ways to skin a cat but you seem to be doing quite well so far, congrats.

Dicko, now you’re just making me want to do this a whole lot smarter. I’m seeing some real nice positives about setting a language channel variable - especially in things like reporting on callers’ origin, which origins are making which IVR selections, and of course very user-transparent conditional branching.

The customer hasn’t asked for language-specific prompts however. I assume that, using the language variable, I could ensure Chinese callers would hear Chinese prompts? Could you have a single IVR, that played language-specifc prompts based on that variable? (Multiple languages isn’t something I’ve played with in any Cisco or FreePBX deployments). Can I also assume that, when the language variable is set (and packs are installed), that a Chinese caller would also hear Chinese system prompts (if, there’s such a thing)?

All very interesting however I’m getting off-topic, so I understand if we kill this thread right here. On the other hand, the customer hasn’t expressed any desire for this nor would want to pay the additional labour costs for getting this all configured - but, it’s still good to know.

If the voice prompts exist in the language set on the channel, either system wide or in the IVR’s etc. in /var/lib/asterisk/sounds/(language)/custom , they will be played, if not then the default prompt will be played, It is all covered in the 3rd edition (and the 4th).This does not go down to Comedian Mail which was there before Asterisk, but a previous link in this thread posted by me covers a workaround to temporarily replace the busy/unavailable prompts.

Cheers, dicko.

1 Like

Late to the party, but in case it is of any value, the second arg passed to the FreePBX vm macro indicates the message played to the caller. Acceptable values are BUSY, DIRECTDIAL, INSTRUCT, NOMESSAGE and null.

1 Like

Perhaps I should look at that macro and expand my concept of tricking vmail into playing a language specific message if it exists in /var/spool/asterisk/voicemail/(context)/(extension)/(language). I love you Comedian Mail but you could do with a facelift :wink: