Asterisk and Truecaller. Determining the name of an unknown subscriber for incoming calls

TrueCaller is a service for determining the name of a subscriber for incoming calls, as well as blocking spam. On smartphones with CyanogenOS 12.1, it is sewn into a regular dialer. You can also install TrueDialler / TrueCaller with GooglePlay / AppStore / BlackBerryWorld / WindowsPhoneStore.

If you activated this functionality in your smartphone, then your contact book is completely merged into Truecaller's servers? You can check if your number is in the database using the link, for example: https://www.truecaller.com/en/74996813210 (authentication is required).
 
At the moment, the service has 1.6 billion numbers worldwide. You can write your number from the database at https://www.truecaller.com/unlist .

We fasten Truecaller to Asterisk


On the Truecaller website, it is possible to determine the name of the subscriber by phone number. Entrance to the site is possible only through third-party services and social networks. For authentication, I chose Vkontakte (Oauth protocol).

1. Manually log into truecaller.com using a previously registered VKontakte account to allow access.
2. It is necessary to create an internal database to store contacts that have already called once. This is necessary so that every time you do not access the truecaller service.
3. Write a script for authentication on the truecaller.com website via the VKontakte network, as well as a function for checking numbers for the presence of a subscriber name.
 
The script is written in PHP for ease of implementation under the AGI and general readability.

Create a database in MySQL:

USE asterisk;
CREATE TABLE asterisk.phonebook (
  id int(11) NOT NULL AUTO_INCREMENT,
  create_date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  number varchar(20) NOT NULL,
  name varchar(80) NOT NULL,
  temporary_contact tinyint(1) NOT NULL DEFAULT 1,
  PRIMARY KEY (id)
)
ENGINE = INNODB
AUTO_INCREMENT = 9
AVG_ROW_LENGTH = 8192
CHARACTER SET utf8
COLLATE utf8_general_ci;

PHP script /var/lib/asterisk/agi-bin/phonebook.php (for those who do it through PHP-AGI, do not forget to uncomment the corresponding lines, you will get the result in the channel variable CID_NAME):

#!/usr/bin/php -q
 "логин_вконтакте", "password"=> "пароль_вконтакте");
$mysql = array("hostname" => "localhost", "login"=> "root", "password"=> "пароль_mysql", "database"=> "asterisk");
if (!is_null($num))
{
	$callerid_name=get_num($num,$vk,$mysql,$cookie_file,true);
	return $callerid_name;
}
else
{
	echo "Номер телефона не задан\n";
	//$agi->set_variable("CID_NAME", "");
	return false;
}
// поиск номера на сервисе truecaller
function get_num($num,$vk,$mysql,$cookie_file,$isauth)
{
	// ищем в своей базе
	mysql_connect($mysql['hostname'],$mysql['login'],$mysql['password']); 
	mysql_select_db($mysql['database']) or die(mysql_error());
	mysql_query("SET NAMES 'utf8'"); mysql_query("SET CHARACTER SET 'utf8'"); mysql_query("SET SESSION collation_connection = 'utf8_general_ci'");
	$query = "SELECT * FROM phonebook WHERE `number`=$num";
	$res = mysql_query($query);
	$count = mysql_num_rows($res);
	if ($count>0)
	while ($row=mysql_fetch_array($res)) 
	{ 
		$name=$row['name'];
		echo "Найден контакт в MySQL '".$name."'\n";
		//$agi->set_variable("CID_NAME", "$name");
		return $name;
	}
	mysql_close();
	// ищем в truecaller
	if ($isauth)
	{
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, 'http://www.truecaller.com/ru/'.$num ); 
		curl_setopt($ch, CURLOPT_HEADER, 1);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
		curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
		curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);
		curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);	
		$data = curl_exec($ch);
		curl_close($ch);	
		if (preg_match("/You need to sign in to view the result/i", $data)) {
		    echo "Необходима аутентификация TC\n";
		  	$isauth = oauth_vk($vk, $cookie_file);
		  	get_num($num,$vk,$mysql,$cookie_file,$isauth);
		} else {
		    preg_match("/
\n\s*(.+)\s\n\s*<\/div>/i", $data, $matches); if (count($matches)>0) { $name=$matches[1]; echo "Найден контакт в TC '".$name."'\n"; mysql_connect($mysql['hostname'],$mysql['login'],$mysql['password']); mysql_select_db($mysql['database']) or die(mysql_error()); mysql_query("SET NAMES 'utf8'"); mysql_query("SET CHARACTER SET 'utf8'"); mysql_query("SET SESSION collation_connection = 'utf8_general_ci'"); $query = "INSERT INTO phonebook (`name`,`number`) VALUE ('".$name."','".$num."')"; $res = mysql_query($query); mysql_close(); //$agi->set_variable("CID_NAME", "$name"); return $name; } else { echo "Совпадения в TC не найдены\n"; //$agi->set_variable("CID_NAME", ""); return false; } } } else { echo "Аутентификация TC не была пройдена, попробуйте в следующий раз\n"; //$agi->set_variable("CID_NAME", ""); return false; } } // авторизация через кнопку "зайти через вконтакте" function oauth_vk($vk, $cookie_file) { unlink($cookie_file); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://oauth.vk.com/authorize?client_id=4951501&scope=friends%2Coffline&redirect_uri=http%3A%2F%2Fwww.truecaller.com%2Fsign-in%2Fvk&response_type=code&state=KKoLuT0vbWEOXfqIW9C0yAvoX7uoEDszIrVOxYSr'); curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file); // сохранять куки в файл curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file); $data = curl_exec($ch); curl_close($ch); preg_match("/
/i", $data, $matches); if (count($matches)>0) $action=$matches[1]; preg_match("//i", $data, $matches); if (count($matches)>0) $origin=$matches[1]; preg_match("//i", $data, $matches); if (count($matches)>0) $ip_h=$matches[1]; preg_match("//i", $data, $matches); if (count($matches)>0) $lg_h=$matches[1]; preg_match("//i", $data, $matches); if (count($matches)>0) $to=$matches[1]; if (isset($action) && isset($origin) && isset($ip_h) && isset($lg_h) && isset($to)) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $action ); curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file); curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, array( '_origin'=>$origin, 'ip_h'=>$ip_h, 'lg_h'=>$lg_h, 'to'=>$to, 'email'=>$vk['login'], 'pass'=>$vk['password'] )); $data = curl_exec($ch); curl_close($ch); preg_match('/Location: (http\:\/\/www\.truecaller\.com\/sign\-in\/vk\?code\=.+)\&state.+/', $data, $matches); if (count($matches)>0) $location=$matches[1]; if (isset($location)) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $location); curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file); curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file); $data = curl_exec($ch); curl_close($ch); if (preg_match("/\Signed In \| Truecaller\<\/title\>/i", $data)) { echo "Аутентификация VK пройдена успешно\n"; return true; } else { echo "Ошибка при прохождении авторизации через VK / не найдена строка о успешной авторизации\n"; return false; } } else { echo "Ошибка при прохождении авторизации через VK / переменная location не получена\n"; return false; } } else { echo "Ошибка при прохождении авторизации через VK / не все переменные получены action='".$action."', origin='".$origin."', ip_h='".$ip_h."', lg_h='".$lg_h."', to='".$to."'\n"; return false; } } ?>

I have a dial plan on LUA, so in extensions.lua:

local call = {}
call.cid_num = channel["CALLERID(num)"]:get()
call.cid_name = ""
-- ищем телефонный номер в базе
local handle = io.popen("/var/lib/asterisk/agi-bin/phonebook.php "..call.cid_num)
local founded_name = handle:read("*a")
handle:close()
app.Noop(founded_name)
_, _, call.cid_name = string.find(founded_name,"Найден%sконтакт%sв.+%s'(.+)'")
channel["CALLERID(name)"]:set(call.cid_name)

In this script, there is no account for blocking spam contacts. This article is described as an overview of the possible integration of such a wonderful Truecaller service with your PBX.

Also popular now: