Use Dynamic Routes to Execute a shell script

If you’ve had a chance to explore the features of Dynamic Routes, you will probably already have noted that an admin is able to dynamically branch call flow based on a result of a lookup source. Lookup sources are limited to SQL, a URL, an AGI file or an Asterisk variable. There’s no ability to use a local script as a lookup source. Or is there …?

The Asterisk Variable lookup source is more useful than it might seem at first glance. The intended use of this feature (in its simplest form) is to look at the value of a channel variable (for example TEST) and choose a different FreePBX destination based on the value. In the GUI it would look like this:

which results in this line being added to the dynroute asterisk dialplan:

 exten => s,n,Set(dynroute=${TEST})

When we peek under the covers with Asterisk, we see that whatever we put in the Asterisk Variable field in the GUI, will be written to the dialplan as shown. Which means we should be free to put whatever Asterisk function we want so long as the resulting dialplan is valid. We’ve already seen examples in the forum of using dynroutes to branch calls based on the CID number ${CALLERID(number)} or a fragment of the CID such as the Area Code. It occurred to me recently that we can use the Asterisk SHELL function to run a script, so long as the script is executable by the asterisk user.

As and example, lets use the common bash expression to send an email. You can see this floating around the forum in slightly different variations, but essentially looks like this:

echo 'Call from ${CALLERID(name)} at  ${CALLERID(number)}' | mail -s 'EMAIL SUBJECT' '[email protected]'

running the above from the bash prompt will generate an outbound email from the PBX to [email protected] with the subject, “EMAIL SUBJECT” and the body is the Caller ID details as shown. I can execute that expression whenever a call goes to a Dynamic Route by putting it in the Asterisk function SHELL, like this:

${SHELL(echo 'Call from ${CALLERID(name)} at  ${CALLERID(number)}' | mail -s 'EMAIL SUBJECT' '[email protected]')}

And while the general purpose of dynroues is to branch a call, there is actually no requirement to do so. You can configure the dynroute as above without any destinations, just run the shell script, send off the email and then have the call always flow to the dynroute default destination, which in many cases might be another dynroute if you’re doing something complex.

Another example. Suppose I have a local file on the PBX that depending on some external condition will be updated periodically to either have the word true or false. You want to check the content of that file, and branch the call flow based on the file content. An Asterisk variable expression of:

${SHELL(cat /var/spool/value)}

Again, as long as the file /var/spool/value is readable by the asterisk user, then dynroutes will read the file send the call to the corresponding destination.

Another example of an Asterisk expression using SHELL to branch call flow based on whether a file simply exists is described in this thread.

Note: The above is meant to be illustrative, as I’m sure there are easier ways to do this by not relying on the GUI (or relying on it less). I’m a pragmatist, there is no wrong answer here if the objective is met.

7 Likes

I really like these tips, tricks, and how-to posts. Thanks!

1 Like

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