Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

 

...

 


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>

...

Info

Smart Dialplan explains how to use Custom Applications in Wildix Dialplan to interact with external software and databases.

Updated: March 2019

Permalink: https://confluence.wildix.com/x/swBuAQ

Table of Contents

...

AGI in “Custom Application”

Variables in Dialplan

Variables are needed to store the information necessary to execute the application.

...

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)

...

The condition syntax is the following one: $[expr1operatorexpr2], 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)

...

expr1 >= expr2 → greater than or equal


Example:  


In this example:

set(FOO=1) - we introduce FOO variable with the value 1.

...

  • 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

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.

  • Jump to if -> "${QUEUE_MEMBER(<call_group_id>,free)}"="0"

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

Warning

Limitation: the system recognizes unregistered (offline) CG members as available for answering calls. In case unregistered members are present in CG -> QUEUE_MEMBER = 0 performance is false.



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]$

...

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!


Request to remote server: CURL

...


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

...

-- Executing [555@accounting:1] Read("SIP/252-0000000f", "CALLER,00000/accounting/code,,,,10")
-- <SIP/252-0000000f> Playing '00000/accounting/code.g729' (language 'fr')
-- User entered '1234'
-- Executing [555@accounting:1] MYSQL("SIP/252-0000000f", "Connect connid support-fr.wildix.com odessa2016-12
oDess@0912to18 odessa2016-12")
-- Executing [555@accounting:1] MYSQL("SIP/252-0000000f", "Query resultid 1 SELECT credit FROM accounting WHERE id=1234") -- Executing [555@accounting:1] MYSQL("SIP/252-0000000f", "Fetch fetchid 2 Current_units")
-- Executing [555@accounting:1] MYSQL("SIP/252-0000000f", "Clear 2")
-- Executing [555@accounting:1] NoOp("SIP/252-0000000f", "Current Units : 94")
-- Executing [555@accounting:1] GotoIf("SIP/252-0000000f", "1?accounting,0,1:accounting,1,1")
-- Goto (accounting,0,1)
-- Executing [0@accounting:1] GotoIf("SIP/252-0000000f", "1?accounting,00,1:accounting,01,1")
-- Goto (accounting,00,1)
-- Executing [00@accounting:1] Read("SIP/252-0000000f", "CALLED,00000/accounting/numcorresp,10,,,10")
-- Accepting a maximum of 10 digits.
-- <SIP/252-0000000f> Playing '00000/accounting/numcorresp.g729' (language 'fr')
-- User entered '0176747983'
-- Executing [00@accounting:1] Goto("SIP/252-0000000f", "accounting,0176747983,1")
-- Goto (accounting,0176747983,1)
-- Executing [0176747983@accounting:1] Set("SIP/252-0000000f", "TIMEOUT(absolute)=104")
-- Channel will hangup at 2016-08-18 13:00:21.241 CEST.
-- Executing [0176747983@accounting:1] NoOp("SIP/252-0000000f", "Executing 'Dial the trunk': number - 0176747983, tr_name
-0276510950, callclass - auto")
-- Executing [0176747983@accounting:1] Dial("SIP/252-0000000f", "SIP/ 0276510950/0176747983,,b(predial^extcall^1(+33176747983,,))")
[Aug 18 12:58:50] WARNING[3772][C-0000000d]: chan_sip.c:32923 handle_request_bye: Got request BYE from peer 252; From: "Trunk test2" <sip:252@frtest.wildixin.com:443>;tag=676021154; To: <sip:555@frtest.wildixin.com:443>;tag=as076b897a; callid - '562925853'. Reason cause: 16 (Normal Clearing)
-- Executing [h@accounting:1] Set("SIP/252-0000000f", "New_units=84")
-- Executing [h@accounting:1] MYSQL("SIP/252-0000000f", "Query resultid 1 UPDATE accounting SET credit=84 WHERE id=1234") -- Executing [h@accounting:1] MYSQL("SIP/252-0000000f", "Disconnect 1"

...

phpAGI in “Remote script”

Integrate PHP in dialplan

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

...

Call Remote script it in Dialplan:

...

Call file directory to generate a call

The default path of this directory is  /var/spool/callweaver/outgoing/ but it’s possible to use an external shared directory: WMS->Settings->System->Storages->Add new Windows share->Service Call generation

...

  • 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:

...

GotoIF "${Descript}"="Trento" users_Trento
Goto users_default
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
Goto users_default


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?

...