Html |
---|
<div id="fb-root"></div> <script>(function(d, s, id) { var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)) return; js = d.createElement(s); js.id = id; js.src = 'https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.11'; fjs.parentNode.insertBefore(js, fjs); }(document, 'script', 'facebook-jssdk'));</script> |
...
Html |
---|
<div class="lang-box-pdf"> <div> <div class="google-lang"> <div id="google_translate_element"> </div> <script type="text/javascript"> function googleTranslateElementInit() { new google.translate.TranslateElement({pageLanguage: 'en', includedLanguages: 'de,es,fr,it,nl', autoDisplay: false}, 'google_translate_element'); } </script> <script type="text/javascript" src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script> </div> <div class="pdf-button"> <a href="https://confluence.wildix.com/spaces/flyingpdf/pdfpageexport.action?pageId=23986355" alt="Convert to .pdf" title="Convert to .pdf"><img src="https://confluence.wildix.com/download/attachments/14549012/pdf-button-download-wildix-documentation.png"></a> </div> </div> </div> |
Info |
---|
Smart Dialplan explains how to use Custom Applications in Wildix Dialplan to interact with external software and databases. Updated: April November 2019 Permalink: https://confluence.wildix.com/x/swBuAQ |
Table of Contents |
---|
AGI in “Custom Application”
...
${foo} → 123456789
${foO:1} → 23456789
${Foo:-4:3} → 678
Dialplan example:
- set(FOO=101) - sets the name of the variable as FOO and the value as 101
- Dial(SIP/${FOO}) - dials 101
Here are some useful variables:
...
This Dialplan is assigned to user 102.
NoOp function serves to display the variable value in logs:
Conditions in Dialplan
You can use execute a conditional jump to another Dialplan procedure, based on the boolean result (true or false) of the Gotoif function.
Syntax to execute a jump: GotoIf(condition?label1:label2)
Where:
label1:label2 are the destinations of the jump, consisting of: context, extension, priority
context: name of Dialplan procedure
extension: extension or called number present in this Dialplan procedure
priority: line number, usually 1
condition: the choice of Gotoif depends on the boolean result of this expression: true or false, in Dialplan True = 1 and False = 0.
The condition syntax is the following one: $[expr1 operator expr2], where
expr can be a variable, a value, a function, an expression (expressions can be nested)
operator as a rule it is relational (comparison) operator ( =, <>..); for nested expressions it’s possible to use logical operators AND, OR, NOT (explained below)
Logical operators:
expr1 | expr2 → OR
expr1 & expr2 → AND
!expr → NOT
Relational operators:
expr1 = expr2 → equal
expr1 != expr2 → inequal
expr1 < expr2 → less than
expr1 > expr2 → greater than
expr1 <= expr2 → less than or equal
expr1 >= expr2 → greater than or equal
Example:
In this example:
set(FOO=1) - we introduce FOO variable with the value 1.
...
GotoIf(condition?label1:label2) is introduced in our example in the following format:
GotoIf($[${FOO} = 1]?users,101,1:users,102,1), where:
condition: $[${FOO} = 1]
label1: users,101,1
label2: users,102,1
Example 1: Check if a device is INUSE before sending a call
GotoIf($[ ${DEVICE_STATE(SIP/100)} == NOT_INUSE ]?context,101,1)
The function DEVICE_STATE(SIP/100) returns the state of the device, results can be:
UNKNOWN | NOT_INUSE | INUSE | BUSY | INVALID |UNAVAILABLE | RINGING | RINGINUSE | ONHOLD
Example 2: Check if there are available users in a call group before sending a call Anchor QUEUEMEMBER QUEUEMEMBER
QUEUEMEMBER | |
QUEUEMEMBER |
GotoIf($[ ${QUEUE_MEMBER(2,ready)} == 0 ]?context,101,1)
The function QUEUE_MEMBER(2,ready) counts the number of ready members of a call group
...
Note | ||
---|---|---|
With the help of QUEUE_MEMBER function it is possible to configure CG strategy to execute another Dialplan procedure. The function counts the number of free members of a Call group. When there are no available CG members, an incoming call is routed according to another Dialplan procedure.
where "free" - returns the number of not paused / busy members for a specified queue that can answer calls or are currently paused for the duration of wrap up time after a previous call (free CG members). Note: Wrap up time and ringing state are not considered when using the function. For example: All Call group members are put on pause for the duration period of wrap up time -> the incoming call stays in a queue until wrap up time doesn't expire
|
Example 3: Check if the CALLERID(number) matches a regular expression
GotoIf($[${REGEX("^0[6-7][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$" ${CALLERID(number)})}]?noanswer,01,1)
The function REGEX("<regular expression>" <data>) returns true if the regular expression matches the data.
In the example above we check if the caller is a French mobile phone:
Start by 0 then a 6 or 7 then followed by 8 digits => ^0[6-7][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$
Example 4: Check if the call arriving in the system is from a caller that has called in recently and not been answered - example of sqlite query using SHELL COMMAND
The variable helps to recognize that a call entering the system was from a caller that had recently called in and not been answered. In this case, the call can be routed differently, for instance, to a Call Group.
What it does:
Gets a count of calls from the caller ID number of the current call that:
- had called in in the past 5 minutes
- was NOT answered
For this purpose, a query to CDR is made to get a count of unanswered calls from the Caller ID number over the previous X minutes.
NoOp(FromNumber is ${CALLERID(num)}) - detects the Caller ID.
Set(CallCount=${SHELL(value=`sqlite3 /mnt/cdr/cdrdb "select count() from cdr where c_from = '+1${CALLERID(num)}' and answer = '' and start > Datetime('now' ,'localtime','-5 minutes');"` && echo $value)}):
- Set(CallCount= - sets the value of a variable called "CallCount" (can then be used to check later with the 'jump to if' application
- ${SHELL(value=`sqlite3 /mnt/cdr/cdrdb - executes a Linux SHELL command (sqlite query in this case)
- "select count() from cdr where - gets gets count of calls from cdrdb
- c_from = '+1${CALLERID(num)}' - checks cdrdb c_from field (contains caller ID numbers; note that +1 in our example is a prefix – change it with your country's prefix or remove it)
- answer = '' - checks checks cdrdb answer field (contains answer timestamps of previous calls; blank if call was not answered)
- start > Datetime('now' ,'localtime','-5 minutes');"` - checks start field in cdrdb for a date/timestamp within the past 5 minutes (notice the -5 minutes portion)
- && echo $value - syntax required by the SHELL command to return the value of the linux shell command that is being executed
NoOp(CallCount is ${CallCount}) - detects a count of calls.
${CallCount} > 0 - If a count of calls is greater than 0, a call will be routed to the Dialplan procedure.
In case of using MySQL or MSSQL DB, apply one of these custom applications:
MySQL:
Set(CallCount=${SHELL(value=`echo "select count(*) from <TABLE> where c_from = '${CALLERID(num)}' and start = answer and start > date_add(LOCALTIME(),INTERVAL - 5 MINUTE);" | mysql -s --raw -h <DB_HOST> -P 3306 <DATABASE> -u <USER> -p <PASSWORD>` && echo $value)})
MSSQL:
Set(CallCount=${SHELL(value=`echo -e "select count(*) from <TABLE> where c_from = '${CALLERID(num)}' and answer = '1900-01-01 00:00:00.000' and start > dateadd(MI,-5,GETDATE());\nGO\nEXIT\n" | tsql -S <DB_HOST> -p 1433 -U <USER> -P <PASSWORD> -D <DATABASE> | sed '6!d'` && echo $value)})
where:
<DATABASE> - database name
<TABLE> - table name
<DB_HOST> - hostname
<USER> - user
<PASSWORD> - password
Warning |
---|
Important: Time zone of the PBX and the DB server should match! |
Example 5. Check if a user/ users are registered
...
CURL allows sending a request to a web page. As a rule, a CURL(url) is used together with Set() in order to write a value received from a web page into a variable:
Set(variablename=${CURL(URL)})
or
Set(variablename=${FILTER(1234567890,${CURL(URL)})
It is recommended to use the second request so that you escape the unwanted characters.
Example:
Set(foo=${FILTER(1234567890,${CURL(http://myexample.wildix.com/smartdialplan/echo101.php)})})
In this example the value returned is 101.
In this way we can pass the caller number to a web page using ${CALLERID(num)} as an URL parameter:
Set(foo=${CURL(http://192.168.1.1/callernum.php?callernum=${CALLERID(num)})})
To keep it simple, a remote script must return a string or a character. The url string that can integrate variables or functions.
...
Code Block |
---|
<?php echo 101; ?> |
Set(foo=${CURL(http://192.168.1.1/echo.php)})
Dial(SIP/${foo})
Add parameters in CURL url
In the following example the PHP script returns “102” if “callernum” parameter is 0612345678, else the script returns “101”.
...
SayDigits(digits)
Says the digits, one by one, digits can be a variable.
SayNumber(number, gender)
Says number
gender is "f" for female voice; "m" - for male ;"c" - for neutral
Example:
Read(FOO,00000/smartdialplan/numcommande,3,,,10)
SayNumber(${FOO},f)
Dial(SIP/${FOO})
Implementation of Smart Dialplan: limited access to the phone based on the amount of credits purchased
...
ID | Current_units |
1234 | 600 |
2345 | 234 |
User calls the dedicated code (555) from the phone
User enters a secret code for authentication
Connection to the database is established to check if this code valid; if the code is wrong, playback “authentication failed”
Check in the database the amount of the remaining credits; if there are no credits left, playback “no more credits”; else - ask to enter the number consisting of 10 digits
The max duration of a call is defined based on the number of credits left
The other party is called
Once the call is terminated (by user or if reached the max duration of a call), the database values are updated
Implementation:
Create a dedicated Dialplan procedure “accounting”
Record the missing sounds using Sounds menu
Prepare the database
After these initial steps it’s necessary to set up “accounting” procedure:
...
You need to:
Upload PHP AGI (phpagi.sourceforge.net) to /var/www/agi/phpagi/phpagi.php
Upload test script to /var/www/scripts/test.php
...
Then you can use “remote script” in dialplan, example: Remote script
Microsoft SQL Integration
Create /rw2/var/www/scripts/sqllookup.php
...
Code Block |
---|
------------------------------------------------------- Channel: SIP/trunkname/18882223333 Application: Playback Data: 0000/hello-world ----------------------------------------------------------------- |
Syntax of call files
Specify the call destination and the channel to use:
Channel: <channel>: Channel to use for the call.
CallerID: "name" <number> Caller ID, please note: it may not work if you do not respect the format: CallerID: "Some Name" <1234>
MaxRetries: <number> Number of retries before failing (not including the initial attempt, e.g. 0 = total of 1 attempt to make the call). Default is 0.
RetryTime: <number> Seconds between retries. Default is 300 (5 min).
WaitTime: <number> Seconds to wait for an answer. Default is 45.
If the call answers, connect it here:
Context: <context-name> Context in extensions.conf
Extension: <ext> Extension definition in extensions.conf
Priority: <priority> Priority of extension to start with
Set: Set a variable to be used in the extension logic (example: file1=/tmp/to)
Application: Application to run (use it instead of specifying context, extension and priority)
Data: The options to be passed to the application
Use Callfile in dialplan
Create a script file in /var/www/scripts dir.
This script will be executed by dialplan.
Copy a template file and move the duplicated file to /var/spool/callweaver/outgoing/
callfile.sh
Code Block |
---|
------------------------------------------------------ #! /bin/sh cp /var/www/scripts/test.call /var/www/scripts/temp.call mv /var/www/scripts/temp.call /var/spool/callweaver/outgoing/ ------------------------------------------------------ Give permissions to execute the script. #chmod +x /var/www/scripts/callfile.sh Create a template file in /var/www/scripts dir. Test.call ------------------------------------------------------ Channel: SIP/0276510950/0970720101 Application: Playback Data: 00000/callfile/message --------------------------------------------------------- |
Call a remote script in dialplan.
Use device comment field for customize CID of outgoing call
Set comment in WMS -> Devices for devices:
Double click on a device to edit it
Fill out the “Comment” field and click Save
In users dialplan add the following Custom apps:
...
Prior to this, you should create dialplans named like this users_${Descript} and another one -- users_default in our example -- for calls don’t match to a device with comment field.
External outgoing call with audio file playback
Here is our scenario: outgoing call to urban line is placed; this call is being recorded, once it is answered, an audio file is played back automatically informing the called party that this call is being recorded.
This scenario can be carried out using Custom Application Dial:
Dial(SIP/pri1_0_0/${CalledID},30,A(00000/Messages/Recording) where pri1_0_0 is the channel used (PRI in this case), 00000 is the folder that contains the audio messages to be played back.
To remove digits from the called number, you can use function:
Dial(SIP/0123456789/${EXTEN:3},30,A(00000/Message/Recording) - in this example SIP trunk is used and ${EXTEN:3} removes 3 first digits from the called number.
What else can you do with Custom Dialplan Apps?
...