Настройка интеграции с Asterisk телефонией
Требуется астериск сервер 11 версии. В настройках пользователей (/etc/asterisk/manager.conf) добавьте нового пользователя (AMI), который будет использоваться внутренней программой.
[userw]
secret = **password**
deny=0.0.0.0/0.0.0.0
permit=127.0.0.1/255.255.255.0
read = system,call,log,verbose,command,agent,user,config,command,dtmf,reporting,cdr,dialplan,originate,message
write = system,call,log,verbose,command,agent,user,config,command,dtmf,reporting,cdr,dialplan,originate,message
writetimeout = 5000
Значение **password** поменяйте на свой пароль. Не забывайте, что пароль должен быть сложным. Если у вас сервер доступен из интернета и расшарен порт 5038, то обязательно следует ограничить доступность пользователя по маске IP. Имя пользователя userw
можете выбрать другое (что тоже желательно).
Зайдите в управление MySQL сервером (phpmyadmin), и создайте нового пользователя, и назначьте ему права на чтение, запись и изменение для таблицы asteriskcdrdb
на сервере, где работает астериск.
Далее потребуется в папке web сервера создать произвольную папку под файлы интеграции. Очень желательно, если это будет не простое название, а к примеру такое, как выделено: /var/www/html/idjwncei/
Создайте в той папке первый файл, который следует назвать asterisk_api.php
<?php
function get_list_ch() {
$str_ ="";
$manager_host = "localhost";
$manager_user = "userw";
$manager_pass = "**password**";
$manager_port = "5038";
$manager_connection_timeout = 30;
$fp = fsockopen($manager_host, $manager_port, $errno, $errstr, $manager_connection_timeout);
if (!$fp) {
$str_ = "(`channel_name` LIKE 'xxx-xxxE')";
} else {
$login = "Action: login\r\n";
$login .= "Username: $manager_user\r\n";
$login .= "Secret: $manager_pass\r\n";
$login .= "Events: Off\r\n";
$login .= "\r\n";
fwrite($fp,$login);
$manager_version = fgets($fp);
$cmd_response = fgets($fp);
$response = fgets($fp);
$blank_line = fgets($fp);
if (substr($response,0,9) == "Message: ") {
$loginresponse = trim(substr($response,9));
if (!$loginresponse == "Authentication Accepted") {
fclose($fp);
} else {
$checkpeer = "Action: Status\r\n";
$checkpeer .= "\r\n";
fwrite($fp,$checkpeer);
$line = trim(fgets($fp));
$str_ = "";
while($line != "Event: StatusComplete") {
$aa = strpos($line,"hannel:");
if ($aa == 1 ) $str_ .= "> \"".substr($line,9)."\"";
$line = trim(fgets($fp));
}
fclose($fp);
$str_ = substr($str_,4);
$str_ = "(".$str_.")";
}
} else {
$str_ = "(`channel_name` LIKE 'xxx-xxxE')";
fclose($fp);
}
}
return $str_;
}
function get_list_ach() {
$str_ ="";
$manager_host = "localhost";
$manager_user = "userw";
$manager_pass = "**password**";
$manager_port = "5038";
$manager_connection_timeout = 30;
$fp = fsockopen($manager_host, $manager_port, $errno, $errstr, $manager_connection_timeout);
if (!$fp) {
$str_ = "(`channel_name` LIKE 'xxx-xxxE')";
} else {
$login = "Action: login\r\n";
$login .= "Username: $manager_user\r\n";
$login .= "Secret: $manager_pass\r\n";
$login .= "Events: Off\r\n";
$login .= "\r\n";
fwrite($fp,$login);
$manager_version = fgets($fp);
$cmd_response = fgets($fp);
$response = fgets($fp);
$blank_line = fgets($fp);
if (substr($response,0,9) == "Message: ") {
$loginresponse = trim(substr($response,9));
if (!$loginresponse == "Authentication Accepted") {
fclose($fp);
} else {
$checkpeer = "Action: Status\r\n";
$checkpeer .= "\r\n";
fwrite($fp,$checkpeer);
$line = trim(fgets($fp));
$str_ = "";
while($line != "Event: StatusComplete") {
$str_ .= "> ".$line."\r\n";
$line = trim(fgets($fp));
}
fclose($fp);
$str_ = "".$str_."";
}
} else {
$str_ = "(`channel_name` LIKE 'xxx-xxxE')";
fclose($fp);
}
}
return $str_;
}
function set_new_line($from_,$to_) {
$str_ ="";
$manager_host = "localhost";
$manager_user = "userw";
$manager_pass = "**password**";
$manager_port = "5038";
$manager_connection_timeout = 30;
$response='-';
$file = fsockopen($manager_host, $manager_port, $errno, $errstr, $manager_connection_timeout);
fwrite($file, "Action: Login\r\n");
fwrite($file, "UserName: $manager_user\r\n");
fwrite($file, "Secret: $manager_pass\r\n");
$actionid=rand(000000000,9999999999);
fwrite($file, "ActionID: $actionid\r\n\r\n");
stream_set_timeout($file, 1);
$response = stream_get_contents($file);
fwrite($file, "Action: Redirect\r\n");
fwrite($file, "Channel: $from_\r\n");
fwrite($file, "Exten: $to_\r\n");
fwrite($file, "ExtraExten: $to_\r\n");
fwrite($file, "Context: default\r\n");
fwrite($file, "ExtraContext: default\r\n");
fwrite($file, "Priority: 1\r\n");
fwrite($file, "ExtraPriority: 1\r\n");
$actionid2=rand(000000000,9999999999);
fwrite($file, "ActionID: $actionid2\r\n\r\n");
fwrite($file, "Action: Logoff\r\n");
$actionid3=rand(000000000,9999999999);
fwrite($file, "ActionID: $actionid3\r\n\r\n");
$response = stream_get_contents($file);
fclose($file);
return $response;
}
function call_from_site($tel){
$manager_host = "localhost";
$manager_user = "userw";
$manager_pass = "**password**";
$manager_port = "5038";
$manager_connection_timeout = 30;
$strChannel = "Local/s@from-script-n";
$strContext = "from-script";
$strWaitTime = "60000";
$strPriority = "1";
$strCallerId = "n <$tel>";
$length = strlen($tel);
if ( ($length == 11) && (is_numeric($tel)) ) {
$file = fsockopen($manager_host, $manager_port, $errno, $errstr, $manager_connection_timeout) or die("Connection to host failed");
fwrite($file, "Action: Login\r\n");
fwrite($file, "UserName: $manager_user\r\n");
fwrite($file, "Secret: $manager_pass\r\n");
$actionid=rand(000000000,9999999999);
fwrite($file, "ActionID: $actionid\r\n\r\n");
stream_set_timeout($file, 1);
$response = stream_get_contents($file);
fwrite($file, "Action: originate\r\n");
fwrite($file, "Channel: $strChannel\r\n");
fwrite($file, "CallerID: $strCallerId\r\n");
fwrite($file, "Exten: $tel\r\n");
fwrite($file, "ExtraExten: $tel\r\n");
fwrite($file, "Context: $strContext\r\n");
fwrite($file, "ExtraContext: $strContext\r\n");
fwrite($file, "Priority: 1\r\n");
fwrite($file, "ExtraPriority: 1\r\n");
$actionid2=rand(000000000,9999999999);
fwrite($file, "ActionID: $actionid2\r\n\r\n");
fwrite($file, "Action: Logoff\r\n");
$actionid3=rand(000000000,9999999999);
fwrite($file, "ActionID: $actionid3\r\n\r\n");
$response = stream_get_contents($file);
fclose($file);
echo $response;
} else { echo 'error num! >> '.$tel.' | ';}
}
?>
И создайте второй файл, который нужно назвать get_call.php
.
<?php
require_once 'asterisk_api.php';
if (isset($_GET['get_ls_all'])){
$cn = $_GET['get_ls_all'];
if ($cn =="") return;
$a = get_list_ch();
echo $a;
}
if (isset($_GET['get_info1'])){
echo passthru("sensors");
}
if (isset($_GET['get_ls_all1'])){
$cn = $_GET['get_ls_all1'];
if ($cn =="") return;
$a = get_list_ach();
echo $a;
}
if (isset($_GET['redirect'])){
$from_ = $_GET['from'];
$to_ = $_GET['to'];
if ($from_ == "") return;
if ($to_ == "") return;
$a = set_new_line($from_,$to_);
echo $a;
}
if (isset($_GET['callto'])) {
$to_ = $_GET['callto'];
$from = $_GET['callfrom'];
$str_1 = 'asterisk -rx "channel originate SIP/'.$from.' ';
$str_2 = 'extension '.$to_.'@from-internal"';
exec($str_1.$str_2);
echo 'call_start';
}
if (isset($_GET['cfs'])){
$from = $_GET['cfs'];
call_from_site($from);
echo 'call_start';
}
// ******************************************************************
const DB_HOST = 'localhost'; //Имя хоста
const DB_NAME = 'asteriskcdrdb'; //Имя базы данных
const DB_USER = 'usersql'; //Имя пользователя
const DB_PASS = '**password**'; //Пароль пользователя
const DB_PORT = '3306'; //порт
if (isset($_GET['getinfocall'])) {
$i_ = $_GET['getinfocall'];
$connect = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT);
mysqli_query($connect, 'SET NAMES utf8');
$sql1 = 'SELECT * FROM `cdr` WHERE `uniqueid` LIKE "'.$i_.'" LIMIT 1 ;';
$query = mysqli_query($connect, $sql1);
if ($row = mysqli_fetch_array($query)) {
echo 'FROM:'.$row["src"].''.PHP_EOL;
echo 'CHN :'.$row["channel"].''.PHP_EOL;
echo 'DURT:'.$row["duration"].''.PHP_EOL;
echo 'BILL:'.$row["billsec"].''.PHP_EOL;
echo 'CNTX:'.$row["dcontext"].''.PHP_EOL;
echo 'RECF:'.$row["recordingfile"].''.PHP_EOL;
echo 'TO_D:'.$row["dst"].''.PHP_EOL;
echo 'DCHN:'.$row["dstchannel"].''.PHP_EOL;
}
}
if (isset($_GET['getrecord'])) {
$i_ = $_GET['getrecord'];
$connect = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT);
mysqli_query($connect, 'SET NAMES utf8');
$recfile='';
$sql1 = 'SELECT * FROM `cdr` WHERE `uniqueid` LIKE "'.$i_.'" LIMIT 1 ;';
$query = mysqli_query($connect, $sql1);
if ($row = mysqli_fetch_array($query)) {
$recfile = $row["recordingfile"];
}
if ($recfile != '') {
$a_rec = explode('-',$recfile);
$path_ = $a_rec[3];
$path = '/var/spool/asterisk/monitor/'.substr($path_,0,4).'/'.substr($path_,4,2).'/'.substr($path_,6,2).'/'.$recfile;
$download_rate = 200.5;
if(file_exists($path) && is_file($path)) {
header('Cache-control: private');
header('Content-Type: application/octet-stream');
header('Content-Length: '.filesize($path));
header('Content-Disposition: filename='.$recfile);
flush();
$file = fopen($path, "r");
while(!feof($file)) {
print fread($file, round($download_rate * 1024));
flush();
}
fclose($file);
}
}
}
if (isset($_GET['gethistory'])) {
$i_ = $_GET['gethistory'];
$a = substr($i_,0,1);
if ($a == '+') $i_ = substr($i_,1);
$a = substr($i_,0,1);
if ($a == '8') $i_ = substr($i_,1);
$a = substr($i_,0,1);
if ($a == '7') $i_ = substr($i_,1);
$connect = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT);
mysqli_query($connect, 'SET NAMES utf8');
$sql1 = 'SELECT * FROM `cdr` WHERE (`src` LIKE "%'.$i_.'") OR (`dst` LIKE "%'.$i_.'") ORDER BY `calldate` ASC;';
$query = mysqli_query($connect, $sql1);
while ($row = mysqli_fetch_array($query)) {
echo '>>' . $row["uniqueid"] . '>' . $row["src"] . '>' . $row["dst"] . '>' . $row["calldate"].'>' . $row["duration"].'>' . $row["billsec"].'>' . $row["recordingfile"].'>' . PHP_EOL;
}
}
if (isset($_GET['getchistory'])) {
$i_ = $_GET['getchistory'];
$a = substr($i_,0,1);
if ($a == '+') $i_ = substr($i_,1);
$a = substr($i_,0,1);
if ($a == '8') $i_ = substr($i_,1);
$a = substr($i_,0,1);
if ($a == '7') $i_ = substr($i_,1);
$connect = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT);
mysqli_query($connect, 'SET NAMES utf8');
$sql1 = 'SELECT COUNT(*) FROM `cdr` WHERE (`src` LIKE "%'.$i_.'") OR (`dst` LIKE "%'.$i_.'");';
$query = mysqli_query($connect, $sql1);
if ($row = mysqli_fetch_array($query)) {
echo $row[0];
} else { echo '0';}
}
if (isset($_GET['gethistoryday'])) {
$i_ = $_GET['gethistoryday'];
$connect = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT);
mysqli_query($connect, 'SET NAMES utf8');
$sql1 = 'SELECT * FROM `cdr` WHERE (`calldate` > \''.$i_.' 00:00:00\') AND (`calldate` < \''.$i_.' 23:59:59\') ORDER BY `calldate` ASC;';
$query = mysqli_query($connect, $sql1);
while ($row = mysqli_fetch_array($query)) {
echo '>>' . $row["uniqueid"] . '>' . $row["src"].'>' . $row["dst"] . '>' . $row["calldate"].'>' . $row["duration"] . '>' . $row["billsec"] . '>' . $row["recordingfile"] . '>'. PHP_EOL;
}
}
?>
Не забывайте указывать правильные пароли и логины.
После сохранения файлов, зайдите в FreePBX и сделайте применение настроек (к примеру открыть на правку внутренний номер, сохранить, и кнопка применения станет активной). Если не стоит FreePBX, то можно перезагрузить сервер. Можно и через консоль перезагрузить службу астериска, но в таком случае возможны некоторые ошибки при парсинге звонков (с чём связано - не знаем, первые 2 варианта 100% помогают).
Далее - очередь подключения Serv4 к настроенной телефонии.
В Serv4 откройте служебные настройки, вкладку Оповещения и выберите Astesisk Server. Укажите путь к get_call.php
файлу. Впишите адрес без указания http:// и без слеша и имени файла.
Нажмите кнопку "проверить", и если всё нормально, то должна стать активной кнопка "сохранить". Нажмите "сохранить".
Если возникла ошибка, то просмотрите логи apache2 на сервере на предмет ошибок. Если вы ввели неправильный пароль или где-то кавычку пропустили, то там будет видно место ошибки.
В служебных настройках перейдите на вкладку "Сотрудники", кликните 2-х раза в нужного сотрудника, и листайте вкладки в его настройках. Вам нужна вкладка "APP+" (обычно скрыта), и там вам нужно будет указать внутренний номер телефона для данного сотрудника. К примеру - номер "100".
Данный номер телефона нужен, чтобы телефония знала как работать с текущим сотрудником. К примеру при исходящем звонке клиенту - телефония вначале звонит менеджеру на телефон, и после звонок идёт клиенту.
Далее следует вернуться на вкладку "Оповещения", и перейти к "Операторы".
Укажите сотрудников, которым следует предоставить доступ к телефонии.
В результате всего телефония станет шикарным помощником для вашего сервисного центра!