Требуется вход Go login page
Вернуться к списку

Настройка интеграции с 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".

Данный номер телефона нужен, чтобы телефония знала как работать с текущим сотрудником. К примеру при исходящем звонке клиенту - телефония вначале звонит менеджеру на телефон, и после звонок идёт клиенту.

Далее следует вернуться на вкладку "Оповещения", и перейти к "Операторы".

Укажите сотрудников, которым следует предоставить доступ к телефонии.

В результате всего телефония станет шикарным помощником для вашего сервисного центра!