The Dynamic Routes module for FreePBX, specifically the one in the ISSABEL distribution lets you route based database lookups, asterisk variables, agi 's. The version I'm testing with is in the ISSABEL distro, however although the GUI is slightly different, this applies to regular FreePBX as well.
I've provided a few different examples of what you can do with the Dynamic Routes. Its quite powerful feature and you can do some neat things without needing to tear apart and customize a dialplan with it in most cases.
We can do something similar as above, but use a system already built into IssabelPBX to create unique SQL tables, the PINSET module. We can use this module to maintain a SQL table of data without needing to create one.
In the example below, a PINSET with the description of "DynamicRoutePinSet" is created. I've included a single number of " 1 " which will use along with a "0" to control our call path.
For this example, using PINSET, its important to only use one single entry. Don't put in multiple pins because of the way PINSET is saved in the database.
Now create a dynamic route that does a MSQL look up, enter in your MYSQL login information.
For a query put in:
select passwords from pinsets where description = 'DynamicRoutePinSet'
Set a destination for 1 and 0 to go to a destination of your choice. In my example, I'm using 1 to goto a queue or 0 to goto a mail box.
Setting the value in PINset to 1 or 0 will adjust the direction of this traffic automatically.
When you run this, you'll see it in the live log. It will look something like this:
Dynamic Route
EXAMPLE 1a:
SQL LOOKUP (hardcoded value)
I'm doing lookups in the SQL database that exists, but you could easily make a table and put in your own values.
Here is "USER" the table in Asterisk with some test data.
This will do a hard coded lookup for a specific value each time. In this case the system will see if the hard value of "1000" exists in the extension column of the "USER" table in the "ASTERISK" database
I'm doing lookups in the SQL database that exists, but you could easily make a table and put in your own values.
Here is "USER" the table in Asterisk with some test data.
+-----------+----------+-------+-----------+-----------+----------+-----------+----------+
| extension | password | name | voicemail | ringtimer | noanswer | recording | mohclass |
+-----------+----------+-------+-----------+-----------+----------+-----------+----------+
| 1000 | | Agent1| default | 0 | | | default |
+-----------+----------+-------+-----------+-----------+----------+-----------+----------+
Here is what my Dynamic Route looks like for a hard coded SQL data lookup.
The QUERY is executed and will always look for the existence extension 1000
select extension from users where extension = 1000
The select statement looks to see if there is anything in the "Extension" column that has the value of "1000", and there is a match. Anything that matches 1000 goes to the Feature Code Admin "Echo Test".
IF the SQL statement were to change to hardcoded value "1001"
select extension from users where extension = 1001
If the script were run, this script would FAIL and go to the "DEFAULT DESTINATION" (dial voicemail) and NOT Speaking Clock because there is no extension 1001 in my SQL example.
IF you were to add extension 1001 to the PBX, and call from that extensions and ran that select statement, the system would then go to "Speaking Clock"
EXAMPLE 1b:
SQL LOOKUP (hardcoded value built in "PINSETS").We can do something similar as above, but use a system already built into IssabelPBX to create unique SQL tables, the PINSET module. We can use this module to maintain a SQL table of data without needing to create one.
In the example below, a PINSET with the description of "DynamicRoutePinSet" is created. I've included a single number of " 1 " which will use along with a "0" to control our call path.
For this example, using PINSET, its important to only use one single entry. Don't put in multiple pins because of the way PINSET is saved in the database.
Now create a dynamic route that does a MSQL look up, enter in your MYSQL login information.
For a query put in:
select passwords from pinsets where description = 'DynamicRoutePinSet'
Set a destination for 1 and 0 to go to a destination of your choice. In my example, I'm using 1 to goto a queue or 0 to goto a mail box.
Setting the value in PINset to 1 or 0 will adjust the direction of this traffic automatically.
When you run this, you'll see it in the live log. It will look something like this:
EXAMPLE 2a:
SQL Lookup (Dynamic Lookup) with touch tone phone input
This example, the caller will be asked to enter in data using their number pad on their phone (DTMF) which the system will look for a match in the database.
The caller will be asked to enter an extension and press the # key.
The value entered into the phone is stored in the Input Variable " UserExt "
That variable is passed to the Query statement, formatted to look like this: '[UserExt]' It will need the single quote tick and square bracket on both sides.
The complete Query will look like this for the example shown here
select extension from users where extension = '[UserExt]'
Here is what the config looks like in Dynamic Routes
The caller enters the dynamic route, and enters "1000#"
The system will look at the USERS table, and look at the EXTENSION column and see if the value stored in "UserExt" (which would be 1000) exists.
In our example there would be a match, and the caller would be sent to the "ECHO TEST" system.
EXAMPLE 2b:
SQL Lookup (Dynamic Lookup) with touch tone phone using PINSETS as a qualifier
This example will let you use PINSETS to control a lookup. Again this is for example purposes to give you some usecases.
Lets create a pinset with some PINS in it. 500, 200 and 689
(Due to a technical limitation, please make all PINS in this the same length.)
Now we'll create a dynamic route to query the PINSet database.
Set DTMF input, and put an input variable of PINnumber.
put this in the QUERY
select MID((select passwords from pinsets where description = 'DynamicRoutePinSet'), INSTR ((select passwords from pinsets), '[PINnumber]'),3)
Note that in the query, the "DynamicRoutePinSet" is the PINSET description, the PINnumber is the database variable, and the "3" at the very end of the statement is the length of the pins numbers.
Now we'll need to use a bit of a long query with PINSET because of the way it is configured in the database, just copy and paste the following in the query.
Make a test call. Entering in 500 will take you to the queue, and 200 will take you to voicemail.
EXAMPLE 2c:
SQL Lookup (Dynamic Lookup) using PINSETS to route calls based on CallerID number
Do you want to route calls based on callerdID number? Here's a way you can do it in Issabel deployment of asterisk
Create a PIN set for each of your different extensions you want to receive specific calls.
The Pinset description will be used to direct matching calls in dynmaic routes.
The pinset "PIN LIST" will contain the CallerID numbers you want to match
Now create a Dynamic route
Give it a descriptive name, then select SOURCE TYPE "MYSQL"
Put in your host, user and password for your SQL database, then in "QUERY" put in this command
select description from pinsets where passwords like '%${REALCALLERIDNUM}%'
You'll see how I've placed in the "MATCH" column the descriptive names from the PINSETS. Any CLID number that matches in pinset, will return its descriptor that we can use to route the call.
EXAMPLE 3:
ROUTE BASED ON ASTERISK VARIABLE
The system can route based on an internal asterisk variable. Active variables in asterisk can be utilized. In this example, we'll use the variable ${AMPUSER}, which is a system variable, its value containing the extension number making the call.
We set the SOURCE TYPE to be asterisk variable
In the Variable String we put in the asterisk string ${AMPUSER}
When an extension makes a call through this dynamic route, it will get the value of ${AMPUSER} and route based on that number. Since my examples I'm testing from extension 1000, that is the value of AMPUSER.
If extension 1000 is calling the dynamic route, the call will go to "ECHO TEST"
If extension 1001 is calling the dynamic route, the system will play "SYSTEM CLOCK"
If there is no match, the system will play "DIAL VOICEMAIL"
You can use most any asterisk variable to route a call.
REGEX
You can further do some REGEX command in the variable box to check for a value.
For example, putting in this will have the system check to see if callerID number STARTS with 155 . If it does, it will return a "1" as a value (true).
^155. means anything starting with 155, regardless of length.
${REGEX("^155." ${CALLERID(num)})}
By putting in a 1 as match destination, all calls starting with 155 will go to that route.
Refer to "REGEX" for linux to get some other matches
EXAMPLE 4:
Route based on a URL result
This one is a little more strict, has quite a few limitations, but this will send callers to a destination based on the text on a web page that return very simple text responses.
We can test this easily in an Issabel deployment using the built in "HELP" system.
If you go to this URL (put in the IP of your server)
You should get something like : "The selected menu is not valid"
Put in the URL that you want the system to check. (change my IP to your PBX ip or server name)
https://10.1.80.193/help/frameRight.php
Now I've copy and pasted the EXACT return into the box match box
"The selected menu is not valid."
When the caller enters the Dynamic Rout, the server will check that web page, and if it sees the matching data, it will play the Speaking Clock.
For troubleshooting, you can sometimes see exactly what asterisk sees when it goes to a URL by looking at the live log with an entry similar to this:
-- Executing [s@dynroute-2:7] Set("SIP/1000-0000002e", "dynroute=The selected menu is not valid.") in new stack
The entry "dynroute=" will contain what asterisk received when it went to that site.
EXAMPLE 5:
Route based on a AGI result
I haven't done a lot with the AGI, but here is a demo config of kind of how it would work.
The AGI script and parameters contains the path to the .AGI file you want to run.
AGI variable is where the return data gets stored
In the above example, we call the AGI, it returns with the hard coded variable dynroute value of 0
We can then put the values we expect and route. In the example, we send the call to "ECHO TEST" if it returns a 0.
I haven't done anything else with AGI, so if anyone has information for this I would love to add it!
Dynamic Route CONFIG PARAMETERS
The information below comes from http://www.voipsupport.it/wiki/index.php/Dynamic_Routes_Reference_documentation
The following information documents how to fill in the fields of
a Dynamic Route. This documentation refers to the V13 functionality. Not all
options are available in previous versions.
Field name
|
Comment
|
Dynamic Route Name
|
The name of the dynamic route. This can be chosen at will. It is
used to identify the route when selecting it as a destination from other
applications or inbound routes.
|
Dynamic Route Description
|
Optional description text for the Dynamic Route. This is for
documentation purposes only
|
Enable DTMF Input
|
Setting: Yes or No. Default: No. If set to yes the call waits
for input on the touch tone keypad. This can be used to capture caller input
(for example a customer number).
|
Announcement
|
The system recording to be played back. If Enable DTMF input is
set to Yes then playback takes place before waiting for DTMF input.
|
Timeout
|
Timeout in seconds to wait for DTMF input. This value is only
used if Enable DTMF Input is set to Yes. If no value is given for timeout,
the default for the channel is used. It is best to set an explicit value to
avoid doubts.
|
Validation
|
Validation rules using a Asterisk regular expression (see
Asterisk REGEX). For example to ensure the input is
between 3 and 4 digits long you could use ^[0-9]\{3,4\}$
|
Invalid Retries
|
Number of times to retry if DTMF input does not match validation
rules.
|
Invalid Retry Recording
|
Recording to play if DTMF input does not match validation rules.
|
Invalid Recording
|
Recording to play if DTMF input does not match validation rules
and Invalid Retries have been exhausted.
|
Invalid Destination
|
The destination to send the call to if DTMF input does not match
the validation rules and Invalid Retries ahve been exhausted. The call is
sent to this destination after playing the Invalid Recording if it is
defined.
|
Saved input variable name
|
Name of variable in which to save DTMF input for future use in
the dial plan or further dynamic routes. This is available as [name] in the
query/lookup where name is the name of the variable you specify here. To use
the variable in the dial plan (e.g. custom applications) it is necessary to
prefix it with DYNROUTE_ e.g. DYNROUTE_name
|
Saved result variable name
|
Name of variable in which to save lookup result for future use
in the dial plan or further dynamic routes. This is available as [name] in
the query/lookup where name is the name of the variable you specify here. To
use the variable in the dial plan (e.g. custom applications) it is necessary
to prefix it with DYNROUTE_ e.g. DYNROUTE_name
|
Source Type
|
The type of lookup (see under Source types below for further
information
|
Default Destination
|
Destination to send the call to if the lookup result does not
match one of the match values in the Dynamic Route Entries section or if the
lookup fails. This is optional but is strongly recommended. If there is no
default destination defined, then in the case of a lookup failure or if the
lookup result does not match one of the defined values, the call will be
disconnected. If this is not what is required, define the default destination
with the desired behaviour.
|
Dynamic Route Entries
|
Zero or more entries to be matched by the lookup result. If the
lookup matches, then the call is routed to the chosen destination. Each match
is tried in the order given until one matches. If no match is found then the
call is sent to the Default Destination. Additional rows may be added by
clicking the + symbol. Entries may be deleted by cancelling the value in the
Match field.
|
Source Type
The following are the currently available source types for
lookups. Each source type has its own specific fields for defining the lookup
parameters.
Source Type
|
Comment
|
none
|
No lookup is carried out. The call is sent to the default
destination
|
MySQL
|
A lookup is done to a MySQL database. The parameters used are:
·
MySQL
hostname: hostname of server
·
MySQL
database: database name
·
MySQL
username: username
·
MySQL
password: password
·
MySQL
query: the SQL to be used. It can contain substitutions as indicated in the
table below. Example: select destination from callerid_table where
calleridnum like '%[NUMBER]'
|
ODBC
|
A lookup is done to an
Asterisk ODBC data source. The parameters used are:
·
ODBC
function: the Asterisk ODBC function name that has been configured
·
ODBC
query: the query. It can contain substitutions as indicated in the table
below. Example: select destination from callerid_table where calleridnum like
'%[NUMBER]'
For information about setting up ODBC see this article
|
URL
|
A lookup is done to a
URL. The parameters used are:
·
URL
Looup: the URL to be used for the lookup. The results must be text only.
HTML, XML and JSON is not supported. The URL may contains parameters and the
parameter values may include the substitutions indicated in the following
table. Example: http://localhost/test.php?param1=4¶m2=[NUMBER]
|
AGI
|
A lookup is done by
launching an Asterisk AGI script. The parameters used are:
·
AGI
Lookup: the name of the Asterisk AGI script to be launched.
·
AGI
Result Variable: the name of the variable that the script uses to communicate
the result. The script should execute a SET VARIABLE command using this
variable name at the end of execution in order to pass back the lookup
result. An example script is given in the installation directory (test.agi).
|
Asterisk Variable
|
The lookup value is
read from an Asterisk Variable. The parameters used are:
·
Asterisk
Variable: the variable name from which to read the result. Example: ${xxx}.
Complex expressions may also be written provided they use valid Asterisk
functions, for example: ${REGEX("^1.3$" ${DYNROUTE_dtmf})} would
check that the DTMF input was in the range 1000-1999 (providing that the
Saved input variable name was set to "dtmf")
|
Substitutions
In the lookup
When defining the query field for the lookup, the following
Variable Names will be substituted by the corresponding value at the time of
the call routing.
Variable Name
|
Substituted by
|
[INPUT]
|
The DTMF input by the caller on the touchtone keypad
|
[NUMBER]
|
The callerid of the incoming call
|
[DID]
|
The called number
|
[name]
|
Where "name" is the value of one of these two fields:
Saved input varibale name or Saved result varibale name. In the case of Saved
input variable name, the DTMF input is saved under this name. This is useful
if you are using two levels of Dynamic Route so that you can save the DTMF
from the previous Dynamic Route in a uniquely named variable and use that
variable in the lookup of the second Dynamic Route. In the case of Saved
result variable name, the result returned from the lookup is saved to the
variable name and can be used in a later Dynamic Route.
If you want to use a variable created outside Dynamic Routes in the lookup, then name the variable with a DYNROUTE_ prefix. Then [name] will be substituted by the value of the asterisk variable DYNROUTE_name. There is currently no way of reading an arbitrarily named asterisk variable, except for the lookup type "Asterisk variable". |
In custom dial plan or other FreePBX modules
Variable Name
|
Substituted by
|
DYNROUTE_name
|
Where "name" is the value of one of these two fields:
Saved input varibale name or Saved result varibale name. In the case of Saved
input variable name, the DTMF input is saved under this name. This is useful
if you need to use the value in a custom dial plan application or another
FreePBX module. In the case of Saved result variable name, the result
returned from the lookup is saved to the variable name and can be used in a
custom dial plan application or another FreePBX module. To obtain the value
of the variable named name, use ${DYNROUTE_name} in the Asterisk dial plan.
|
ufff super muchas gracias !
ReplyDeletesúper muy bienvenido!
DeleteThank you because you have been willing to share information with us. we will always appreciate all you have done here because I know you are very concerned with our. asterisk based phone systems
ReplyDeleteThank you ! Very nice documentation !
ReplyDeletesi quisiera hacer una encuesta como seria? no necesito consultar. lo que necesito es almacenar la evaluacion que pueda hacer el cliente luego de seleccionar la opcion. Calificar servicio en el IVR. por ejemplo
ReplyDelete