Difference between revisions of "Telephone scripts"
(Created page with "== lookup.php == This script returns some information about the caller, preferrably the name. It uses a local MySQL database and fetches info from some sites.") |
(added number lookup script) |
||
| Line 1: | Line 1: | ||
| − | == lookup.php == | + | == Number lookup == |
| + | We make use of the mod_cidlookup for ease of use, but not all features are functional in our implementation. | ||
| + | Every request is done via HTTP requests to a php script that will check if the number: | ||
| + | * is an extension (and returns the name for that) | ||
| + | * 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: | ||
| + | <param name="url" value="http://webserviceprovider/lookup.php?number=${caller_id_number}"/> | ||
| + | |||
| + | === lookup.php === | ||
This script returns some information about the caller, preferrably the name. | This script returns some information about the caller, preferrably the name. | ||
It uses a local MySQL database and fetches info from some sites. | It uses a local MySQL database and fetches info from some sites. | ||
| + | |||
| + | <pre> | ||
| + | <?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" ); | ||
| + | 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. | ||
Revision as of 13:31, 23 June 2012
Number lookup
We make use of the mod_cidlookup for ease of use, but not all features are functional in our implementation. Every request is done via HTTP requests to a php script that will check if the number:
- is an extension (and returns the name for that)
- 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:
<param name="url" value="http://webserviceprovider/lookup.php?number=${caller_id_number}"/>
lookup.php
This script returns some information about the caller, preferrably the name. It uses a local MySQL database and fetches info from some sites.
<?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" );
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;
}
?>
dialing out
This default dialplan snippet does a caller id lookup, and updates the callee name which will be visible on the local extension
<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>
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
<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>
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.