|
|
Line 1: |
Line 1: |
− | == Number lookup == | + | === Number lookup === |
− | We make use of the mod_cidlookup for ease of use, but not all features are functional in our implementation.
| + | This script uses mod_cidlookup combined with a custom php page. |
− | Every request is done via HTTP requests to a php script that will check if the number:
| + | It tests the number against a mySQL database, several reversed number lookup websites, the national telecommunications authority database and a coarse array of areas of the world, which are called in order of grannularity. |
− | * is an extension (and returns the name for that)
| + | The script is called both on outgoing and incoming calls |
− | * is stored in the local mySQL database, and return that
| |
− | * can be found online by using reversed number lookup websites for landlines
| |
− | * can be found online by using the national telecommunications authority database (opta.nl) for cell phones returning the associated cell provider
| |
− | * can be categorized by a more coarse lookup, like continent, country, region, town or number block owner, stored in a local array (~500 entries)
| |
| | | |
− | The setting for mod_cidlookup is:
| + | View the scripts at [[Telephone system:Number lookup]] |
− | <param name="url" value="http://webserviceprovider/lookup.php?number=${caller_id_number}"/>
| |
| | | |
− | === lookup.php === | + | === Simple intercom === |
− | This script returns some information about the caller, preferrably the name. | + | This is a dialplan sample of using the secondary phone line put on auto answer, and bridge them in a conference call. |
− | It uses a local MySQL database and fetches info from some sites.
| |
| | | |
− | <pre>
| + | View the dialplan at [[Telephone system:Simple intercom]] |
− | <?php
| |
− | /*
| |
− | * Copyright (c) 2012, ACKspace foundation
| |
− | * All rights reserved.
| |
− | *
| |
− | * Redistribution and use in source and binary forms, with or without
| |
− | * modification, are permitted provided that the following conditions are met:
| |
− | *
| |
− | * 1. Redistributions of source code must retain the above copyright notice, this
| |
− | * list of conditions and the following disclaimer.
| |
− | * 2. Redistributions in binary form must reproduce the above copyright notice,
| |
− | * this list of conditions and the following disclaimer in the documentation
| |
− | * and/or other materials provided with the distribution.
| |
− | *
| |
− | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
| |
− | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
| |
− | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
| |
− | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
| |
− | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
| |
− | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
| |
− | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
| |
− | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
| |
− | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
| |
− | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
| |
− | *
| |
− | * The views and conclusions contained in the software and documentation are those
| |
− | * of the authors and should not be interpreted as representing official policies,
| |
− | * either expressed or implied, of the FreeBSD Project.
| |
− | */
| |
| | | |
− | define( "COUNTRY", "31" );
| + | === Space state === |
− | define( "REGION", "45" );
| |
− | define( "PLUS", "00" );
| |
− | define( "MYSQL_DB", "freeswitch_cidlookup" );
| |
− | | |
− | // Number dial plan, ~500 entries, shortened for wiki
| |
− | $arrNumbers[1]['info'] = "(continent) Verenigde Staten";
| |
− | $arrNumbers[1][4][4][1]['info'] = "Bermuda";
| |
− | $arrNumbers[3]['info'] = "(continent) Europa";
| |
− | $arrNumbers[3][1]['info'] = "(land) Nederland";
| |
− | $arrNumbers[3][1][1][4]['info'] = "Testnetnummer van KPN Telecom";
| |
− | $arrNumbers[3][1][4]['info'] = "(provincies) Oostelijk Noord-Brabant, Limburg";
| |
− | $arrNumbers[3][1][4][5]['info'] = "(regio) Heerlen";
| |
− | $arrNumbers[3][1][6]['info'] = "Mobiele nummers en Semafoondiensten";
| |
− | $arrNumbers[3][1][6][1]['info'] = "Mobiele telefoon";
| |
− | $arrNumbers[3][1][6][1][0]['info'] = "(GSM) KPN";
| |
− | $arrNumbers[3][1][8][5]['info'] = "(type) Plaatsonafhankelijk/VoIP";
| |
− | $arrNumbers[3][1][8][5][8][7]['info'] = "(VoIP) XS4ALL";
| |
− | | |
− | // Normalize the number
| |
− | $arrNumberInfo = normalizeNumber( getVar( "number", true ) );
| |
− | | |
− | // Extension? try and get from dialplan
| |
− | if ( $arrNumberInfo['type'] == "extension" )
| |
− | {
| |
− | echo getExtension( $arrNumberInfo['local'] );
| |
− | exit;
| |
− | }
| |
− | | |
− | if ( !function_exists( "mysql_connect" ))
| |
− | {
| |
− | echo "ERROR";
| |
− | exit;
| |
− | }
| |
− | | |
− | // Fetch the number from the database
| |
− | if ( $strName = dbLookup( $arrNumberInfo ))
| |
− | {
| |
− | echo $strName;
| |
− | exit;
| |
− | }
| |
− | | |
− | // Nothing in the database?
| |
− | // national number starting with 0[1-578]?
| |
− | // Fetch number from website (check last get timestamp to prevent DoS
| |
− | // put result in DB
| |
− | if ( preg_match( "/^0[1-578].*/", $arrNumberInfo['national'] ) && $strName = fetchWebsiteResult( $arrNumberInfo['national'] ))
| |
− | {
| |
− | echo $strName;
| |
− | | |
− | // Add the name to the DB
| |
− | $arrNumberInfo['name'] = $strName;
| |
− | dbInsert( $arrNumberInfo );
| |
− | exit;
| |
− | }
| |
− | else if ( preg_match( "/^0[6].*/", $arrNumberInfo['national'] ) && $strName = fetchOptaResult( $arrNumberInfo['national'] ))
| |
− | {
| |
− | // Number porting
| |
− | echo $strName;
| |
− | | |
− | // Add the name to the DB, so we don't have to look it up anymore
| |
− | $arrNumberInfo['name'] = $strName;
| |
− | dbInsert( $arrNumberInfo );
| |
− | exit;
| |
− | }
| |
− | | |
− | // Nothing on the website? Try and find the number in the array
| |
− | if ( isset( $arrNumberInfo['international'] ))
| |
− | {
| |
− | $strName = _getInfo( str_split( $arrNumberInfo['international'] ));
| |
− | echo $strName;
| |
− | exit;
| |
− | }
| |
− | | |
− | /////////////////////////////////////////////////////////////////////
| |
− | function fetchWebsiteResult( $_strNumber )
| |
− | {
| |
− | | |
− | if ( $strName = fetch_delefoondetective_nl( $_strNumber ))
| |
− | return $strName;
| |
− | | |
− | if ( $strName = fetch_gevonden_cc( $_strNumber ))
| |
− | return $strName;
| |
− | | |
− | if ( $strName = fetch_zoekenbel_nl( $_strNumber ))
| |
− | return $strName;
| |
− | | |
− | if ( $strName = fetch_nummerzoeker_com( $_strNumber ))
| |
− | return $strName;
| |
− | | |
− | if ( $strName = fetch_nummerid_com( $_strNumber ))
| |
− | return $strName;
| |
− | | |
− | if ( $strName = fetch_gebeld_nl( $_strNumber ))
| |
− | return $strName;
| |
− | | |
− | return false;
| |
− | }
| |
− | | |
− | function fetchOptaResult( $_strNumber )
| |
− | {
| |
− | $strPage = file_get_contents( "http://www.opta.nl/nl/nummers/nummers-zoeken/resultaat/?query=".$_strNumber."&page=1&portering=1" );
| |
− | | |
− | if ( !preg_match( "/<strong>Huidige aanbieder<\/strong>.*?<p>(.*?)<\/p>/si", $strPage, $matches ))
| |
− | return false;
| |
− | | |
− | return "(GSM) ".$matches[1];
| |
− | }
| |
− | | |
− | function fetch_delefoondetective_nl( $_strNumber )
| |
− | {
| |
− | $strPage = file_get_contents( "http://www.telefoondetective.nl/telefoonnummer/".$_strNumber."/" );
| |
− | | |
− | if ( !preg_match( "/<div\sid=\"name\"><h\d>(.*?)<\/h\d><\/div>/i", $strPage, $matches ))
| |
− | return false;
| |
− | | |
− | return $matches[1];
| |
− | }
| |
− | | |
− | function fetch_gevonden_cc( $_strNumber )
| |
− | {
| |
− | return false;
| |
− | }
| |
− | | |
− | function fetch_zoekenbel_nl( $_strNumber )
| |
− | {
| |
− | return false;
| |
− | }
| |
− | | |
− | function fetch_nummerzoeker_com( $_strNumber )
| |
− | {
| |
− | return false;
| |
− | }
| |
− | | |
− | | |
− | function fetch_nummerid_com( $_strNumber )
| |
− | {
| |
− | return false;
| |
− | }
| |
− | | |
− | function fetch_gebeld_nl( $_strNumber )
| |
− | {
| |
− | return false;
| |
− | }
| |
− | | |
− | function dbLookup( $_arrNumberInfo )
| |
− | {
| |
− | if (!$db = mysql_connect( NULL, "username", "password" ))
| |
− | return false;
| |
− | | |
− | // TODO: close db
| |
− | if (!mysql_select_db( MYSQL_DB, $db ))
| |
− | return false;
| |
− | | |
− | // Prevent SQL injection on variables
| |
− | $country = mysql_real_escape_string( $_arrNumberInfo['country'] );
| |
− | $international = mysql_real_escape_string( $_arrNumberInfo['international'] );
| |
− | | |
− | // Full number partial listing (experimental)
| |
− | $query = "SELECT name FROM telephone_names WHERE country_code=".$country." AND INSTR( '".$international."', number ) = 1 ORDER BY LENGTH(number), sortorder LIMIT 1";
| |
− | | |
− | if (!$result = mysql_query( $query, $db ))
| |
− | return false;
| |
− | | |
− | $row = mysql_fetch_row( $result );
| |
− | mysql_close( $db );
| |
− | return $row[0];
| |
− | }
| |
− | | |
− | | |
− | function dbInsert( $_arrNumberInfo )
| |
− | {
| |
− | if (!$db = mysql_connect( NULL, "username", "password" ))
| |
− | return false;
| |
− | | |
− | // TODO: close db
| |
− | if (!mysql_select_db( "freeswitch_cidlookup", $db ))
| |
− | return false;
| |
− | | |
− | // Prevent SQL injection on variables
| |
− | $country = mysql_real_escape_string( $_arrNumberInfo['country'] );
| |
− | $international = mysql_real_escape_string( $_arrNumberInfo['international'] );
| |
− | $name = mysql_real_escape_string( $_arrNumberInfo['name'] );
| |
− | | |
− | $query = "INSERT INTO telephone_names (country_code,number,name) VALUES (".$country.",'".$international."','".$name."')";
| |
− | | |
− | if (!$result = mysql_query( $query, $db ))
| |
− | {
| |
− | echo mysql_error( $db );
| |
− | return false;
| |
− | }
| |
− | | |
− | mysql_close( $db );
| |
− | | |
− | return true;
| |
− | }
| |
− | | |
− | | |
− | function getExtension( $_strExtension )
| |
− | {
| |
− | return false;
| |
− | //return "Ext. ".$_strExtension;
| |
− | }
| |
− | | |
− | function normalizeNumber( $_strNumber )
| |
− | {
| |
− | $arrInfo = array();
| |
− | | |
− | if ( preg_match( "/^([19]\d+)/", $_strNumber, $matches ))
| |
− | {
| |
− | $arrInfo['local'] = $matches[1];
| |
− | $arrInfo['type'] = 'extension';
| |
− | return $arrInfo;
| |
− | }
| |
− | | |
− | $_strNumber = preg_replace( "/^([2345678])/", COUNTRY.REGION.'$1', $_strNumber );
| |
− | | |
− | // Add country on national dials
| |
− | $_strNumber = preg_replace( "/^(0)([^0].*)/", COUNTRY.'$2', $_strNumber );
| |
− | | |
− | // Replace + and 00 international symbols before parsing (include space for URI conversion
| |
− | $_strNumber = preg_replace( "/^( |\+|00)/", '', $_strNumber );
| |
− | | |
− | $arrInfo['country'] = intval( substr( $_strNumber, 0, 2 ));
| |
− | $arrInfo['international'] = $_strNumber;
| |
− | $arrInfo['type'] = 'international';
| |
− | | |
− | // National number?
| |
− | if ( $arrInfo['country'] == intval( COUNTRY ))
| |
− | {
| |
− | // only works with countries of 2 digits; replaces it with a 0
| |
− | $arrInfo['national'] = "0".substr( $_strNumber, 2 );
| |
− | $arrInfo['type'] = 'national';
| |
− | }
| |
− | | |
− | return $arrInfo;
| |
− | };
| |
− | | |
− | function GetInfo( $_strNumber )
| |
− | {
| |
− | global $arrNumbers;
| |
− | | |
− | $_strNumber = preg_replace( "/^([2345678])/", COUNTRY.REGION.'$1', $_strNumber );
| |
− | | |
− | // Add country on national dials
| |
− | $_strNumber = preg_replace( "/^(0)([^0].*)/", COUNTRY.'$2', $_strNumber );
| |
− | | |
− | // Replace + and 00 international symbols before parsing
| |
− | $_strNumber = preg_replace( "/^(\+|00)/", '', $_strNumber );
| |
− | | |
− | return _getInfo( str_split( $_strNumber ));
| |
− | };
| |
− | | |
− | function _getInfo( $_arrNumber )
| |
− | {
| |
− | global $arrNumbers;
| |
− | | |
− | $arrInfo = array();
| |
− | | |
− | $arrNumberInfo = $arrNumbers;
| |
− | $nIndent = 0;
| |
− | $strDigits = "";
| |
− | $strDetailedInfo = "";
| |
− | foreach ( $_arrNumber as $digit )
| |
− | {
| |
− | if ( isset( $arrNumberInfo[$digit] ) )
| |
− | {
| |
− | $strDigits .= $digit;
| |
− | $arrNumberInfo = $arrNumberInfo[$digit];
| |
− | if ( isset( $arrNumberInfo['info'] ) )
| |
− | {
| |
− | $arrInfo[] = str_repeat( "-", $nIndent ) . $strDigits . " " . $arrNumberInfo['info'];
| |
− | $strDigits = "";
| |
− | $strDetailedInfo = $arrNumberInfo['info'];
| |
− | }
| |
− | $nIndent++;
| |
− | } else {
| |
− | break;
| |
− | }
| |
− | }
| |
− | | |
− | return $strDetailedInfo;
| |
− | }
| |
− | | |
− | ////////////////////////////////////////////////////////////////////////////////
| |
− | // Helpers
| |
− | ////////////////////////////////////////////////////////////////////////////////
| |
− | function getVar( $_strVarName, $_bAllowGet = false )
| |
− | {
| |
− | // If _POST var is set, return _POST var,
| |
− | // else, if _GET var is set and is allowed, return _GET var
| |
− | // else, requested var not found: return NULL
| |
− | if ( isset( $_POST[ $_strVarName ] ) )
| |
− | return $_POST[ $_strVarName ];
| |
− | else if ( isset( $_GET[ $_strVarName ] ) && ($_bAllowGet == true) )
| |
− | return $_GET[ $_strVarName ];
| |
− | else
| |
− | return NULL;
| |
− | }
| |
− | ?>
| |
− | </pre>
| |
− | | |
− | === dialing out ===
| |
− | This default dialplan snippet does a caller id lookup, and updates the callee name which will be visible on the local extension
| |
− | | |
− | <pre>
| |
− | <extension name="National_numbers">
| |
− | <condition field="destination_number" expression="^0([1-578]\d{8})$">
| |
− | <action application="set" data="effective_caller_id_number=${outbound_caller_id}"/>
| |
− | <action application="export" data="callee_id_name=${cidlookup(0031$1)}" />
| |
− | <action application="bridge" data="sofia/gateway/myLandLineProvider/31$1"/>
| |
− | </condition>
| |
− | </extension>
| |
− | </pre>
| |
− | | |
− | === incoming calls ===
| |
− | This public dialplan snippet somewhat at the top sets the number (if any) first, checks if it has an international prefix, does a lookup for incoming calls and will set the name accordingly.
| |
− | | |
− | The second part will strip any leading + sign
| |
− | | |
− | <pre>
| |
− | <extension name="fix_cidnam" continue="true">
| |
− | <!--make sure the module is loaded, or else loading it will kill our call!-->
| |
− | <!-- Simple case: name=number or name is empty -->
| |
− | <!-- and number is a 10digit (excluding optional leading 1), in nanpa nxx-nxx-xxxx form -->
| |
− | <!-- will skipurl lookup if not a 10digit # (don't lookup INTL), and instead just query the SQL -->
| |
− | <condition field="${module_exists(mod_cidlookup)}" expression="true"/>
| |
− | <condition field="caller_id_name" expression="^${caller_id_number}$|^$"/>
| |
− | <condition field="caller_id_number" expression="^(\+|00)(\d+)$">
| |
− | <action application="cidlookup" data="00$2"/>
| |
− | <anti-action application="cidlookup" data="${caller_id_number}"/>
| |
− | </condition>
| |
− | </extension>
| |
− | | |
− | <extension name="fix_cidnam_plus" continue="true">
| |
− | <!-- if the name starts with + followed by digits, strip the
| |
− | + and then pass the number -->
| |
− | <condition field="caller_id_name" expression="^\+(1[2-9]\d\d[2-9]\d{6})$">
| |
− | <action application="cidlookup" data="$1"/>
| |
− | </condition>
| |
− | </extension>
| |
− | </pre>
| |
− | | |
− | === todo ===
| |
− | items stored in the database will not be updated anymore. The only way to refresh the number's information is to remove the entry manually which will cause a new lookup the next time that number is requested.
| |
− | | |
− | == Simple intercom ==
| |
− | === dialplan snippet ===
| |
− | Upon dialing *<number>, this snippet will create a conference for the caller, and will try for 5 seconds to add the callee as <number>_intercom which is an auto-answer line 2 setup on the cisco phones containing a sip image.
| |
− | | |
− | <pre>
| |
− | <extension name="extension-intercom">
| |
− | <condition field="destination_number" expression="^\*(1[09]\d\d)$" break="on-false">
| |
− | <action application="set" data="dialed_extension=$1"/>
| |
− | <action application="sleep" data="300"/>
| |
− | </condition>
| |
− | | |
− | <condition>
| |
− | <action application="set" data="api_hangup_hook=conference 412 kick all"/>
| |
− | <action application="answer"/>
| |
− | <action application="export" data="sip_invite_params=intercom=true"/>
| |
− | <action application="export" data="sip_auto_answer=true"/>
| |
− | <action application="set" data="conference_auto_outcall_caller_id_name=$${effective_caller_id_name}"/>
| |
− | <action application="set" data="conference_auto_outcall_caller_id_number=$${effective_caller_id_number}"/>
| |
− | <action application="set" data="conference_auto_outcall_timeout=5"/>
| |
− | <action application="set" data="conference_auto_outcall_flags=mute"/>
| |
− | <action application="conference_set_auto_outcall" data="user/${dialed_extension}_intercom@${domain_name}"/>
| |
− | <action application="conference" data="412@intercom"/>
| |
− | | |
− | <!-- Shouldn't be needed -->
| |
− | <action application="conference" data="412 kick all"/>
| |
− | </condition>
| |
− | </extension>
| |
− | </pre>
| |
− | | |
− | === todo ===
| |
− | There is a auto_answer perl script that logs into the phone and changes the auto-answer setting: I might want to upload it here.
| |
− | | |
− | == Space state == | |
| This script sets the spacestate variable according to what the webservice API returns. | | This script sets the spacestate variable according to what the webservice API returns. |
| It then can be used in the dialplan to, for example, play a sound file or do call forwarding. | | It then can be used in the dialplan to, for example, play a sound file or do call forwarding. |
| Currently it is used to build a sound phrase for playing it as a greeting within our IVR | | Currently it is used to build a sound phrase for playing it as a greeting within our IVR |
| | | |
− | === spacestate.js ===
| + | View the dialplan at [[Telephone system:Space state]] |
− | <pre>
| |
− | // Checks the space state API: if "open" is not 'true',
| |
− | // it's assumed closed and plays a sound file
| |
− | | |
− | if (session.ready())
| |
− | {
| |
− | session.preAnswer();
| |
− | | |
− | var state = fetchUrl( "https://ackspace.nl/status.php" );
| |
− | if (state == false)
| |
− | console_log( 3, "could not fetch space state");
| |
− | else
| |
− | {
| |
− | // Remove newlines
| |
− | state = state.replace( /[\r\n]/g,"");
| |
− | | |
− | if( !state.match( /.*"open"[ \t]*:[ \t]*true.*/i ) )
| |
− | {
| |
− | console_log(4, "Space seems to be closed, or could not parse result.\n");
| |
− | session.setVariable("spacestate", "closed");
| |
− | } else {
| |
− | console_log(4, "Space is open!\n");
| |
− | session.setVariable("spacestate", "open");
| |
− | }
| |
− | }
| |
− | }
| |
− | </pre>
| |
− | | |
− | === dialplan and ivr ===
| |
− | The javascript is executed just before executing the IVR
| |
− | <action application="javascript" data="spacestate.js"/>
| |
− | <action application="ivr" data="ackspace_ivr"/>
| |
− | | |
− | and the corresponding IVR setting is:
| |
− | greet-long="phrase:ackspace_welcome:${spacestate}"
| |
− | | |
− | | |
− | | |
− | === phrase ===
| |
− | This snippet is put under lang/nl/IVR/ackspace.xml and checks the given variable whether it is set to 'open'
| |
− | <pre><macro name="ackspace_welcome">
| |
− | <input pattern="^(open)$">
| |
− | <match>
| |
− | <action function="play-file" data="ivr/welkom.wav"/>
| |
− | <action function="sleep" data="300"/>
| |
− | <action function="play-file" data="phrase:ackspace_welcome_short"/>
| |
− | </match>
| |
− | <nomatch>
| |
− | <action function="play-file" data="ivr/welkom.wav"/>
| |
− | <action function="sleep" data="300"/>
| |
− | <action function="play-file" data="ivr/gesloten.wav"/>
| |
− | <action function="sleep" data="2000"/>
| |
− | <action function="play-file" data="phrase:ackspace_welcome_short"/>
| |
− | </nomatch>
| |
− | </input>
| |
− | </macro>
| |
− | </pre>
| |
− | | |
− | == closing announcement ==
| |
− | While this script is not in use anymore, since we're a 24/7 space now, it still is fun to trigger announcements using cron jobs
| |
− | | |
− | it used to trigger on 9:30PM on weekdays, and 4:30PM on saturday.
| |
− | At first I tried to retrigger the events in the dialplan for the next occurrence, but cron jobs are way more reliable (and easier)
| |
− | | |
− | === crontab for freeswitch user ===
| |
− | 30 21 * * 1-5 /usr/local/freeswitch/bin/fs_cli -x "originate loopback/1399 closure"
| |
− | 30 16 * * 6 /usr/local/freeswitch/bin/fs_cli -x "originate loopback/1399 closure"
| |
− | | |
− | === paging.js ===
| |
− | This script takes the dialstring of all members withing call group 'intercom' and puts them as conference-auto-out-call separately.
| |
− | After that, the conference is started with the sound extension, and all parsed extensions will be called automatically (assuming that extension has auto-answer for that line)
| |
− | When the sound extension is done and hangs up, everyone is kicked out of the conference.
| |
− | | |
− | <pre>
| |
− | if (session.ready())
| |
− | {
| |
− | session.answer();
| |
− | | |
− | console_log(4, "building-wide paging\n");
| |
| | | |
− | session.execute("set","pageGroup=${group_call(intercom@${domain_name}+E)}\n");
| + | === Closing announcement === |
− | var pageGroup = session.getVariable("pageGroup");
| + | This collection of scripts was used to broadcast (closing) announcements using cron jobs |
− | var arrPageGroup = pageGroup.split( ":_:" );
| |
− | for ( var idx = 0; idx < arrPageGroup.length; idx++ )
| |
− | {
| |
− | var user = arrPageGroup[ idx ];
| |
− | user = user.replace( /\n/g, "" );
| |
− | user = user.replace( /\[[^\]]*\](.*)/g, "$1" );
| |
− | session.execute("conference_set_auto_outcall", user);
| |
− | }
| |
− | }
| |
− | </pre>
| |
| | | |
− | === dialplan ===
| + | View the scripts at [[Telephone system:Closing announcement]] |
− | The announcement consists of two parts: triggering a group-intercom and executing a 'closure' extension which played the appropriate sounds
| |
| | | |
− | <pre>
| + | === Betamax credit notification === |
− | <extension name="group_page">
| + | This collection of scripts is used to say the amount of credit left on one of the Betamax services (tested with VoipBuster and InterVoip). |
− | <condition field="destination_number" expression="^(1399)$">
| + | It is an altered version of a php script. |
− | <action application="set" data="api_hangup_hook=conference 412 kick all"/>
| |
− | <action application="answer"/>
| |
− | <action application="export" data="sip_invite_params=intercom=true"/>
| |
− | <action application="export" data="sip_auto_answer=true"/>
| |
− | <action application="set" data="conference_auto_outcall_caller_id_name=$${effective_caller_id_name}"/>
| |
− | <action application="set" data="conference_auto_outcall_caller_id_number=$${effective_caller_id_number}"/>
| |
− | <action application="set" data="conference_auto_outcall_timeout=5"/>
| |
− | <action application="set" data="conference_auto_outcall_flags=mute"/>
| |
− | <action application="javascript" data="paging.js"/>
| |
− | <action application="set" data="res=${sched_api +1 none conference 412 play tone_stream://path=${base_dir}/conf/beep.ttml}"/>
| |
− | <action application="conference" data="412@intercom"/>
| |
− | <action application="conference" data="412 kick all"/>
| |
− | </condition>
| |
− | </extension>
| |
| | | |
− | <extension name="closing announcement">
| + | View the scripts at [[Telephone system:Betamax credit]] |
− | <condition field="destination_number" expression="^closure|1398$" break="on-false">
| |
− | <action application="set" data="language=nl"/>
| |
− | <action application="answer"/>
| |
− | <action application="sleep" data="2000"/>
| |
− | <action application="set_audio_level" data="write -2"/>
| |
− | <action application="playback" data="../../../stationsbel.mp3"/>
| |
− | <action application="set_audio_level" data="write 0"/>
| |
− | <action application="playback" data="../../../nl/nl/xander/ivr/sluiten.wav"/>
| |
− | <action application="sleep" data="1000"/>
| |
− | <action application="set_audio_level" data="write -2"/>
| |
− | <action application="playback" data="../../../game_over.mp3"/>
| |
− | </condition>
| |
− | </extension>
| |
− | </pre>
| |