В данной статье рассмотрим пример скрипта EAGI на FreePBX.
VOSK — бесплатный,офлайн движок для распознавания голоса, поставляется ввиде Docker-контейнера. В интернете есть много информации, как развернуть Докер-контейнеер с Воском.

EAGI — расширенный AGI, который работает звуковым потоком через файловый дескриптор-3. В FreePBX поставляется с библиотекой PHP-AGI, которая может работать с FD3.

Сам скрипт

#!/usr/bin/php -q                                                                                                                                                                                                                                                               
<?php                                                                                                                                                                                                                                                                           
/*                                                                                                                                                                                                                                                                              
 * @developed by asterisk-system.ru                                                                                                                                                                                                                                         
 */                                                                                                                                                                                                                                                                             
ob_implicit_flush(false);                                                                                                                                                                                                                                                       
set_time_limit(0);                                                                                                                                                                                                                                                              
error_reporting(0);                                                                                                                                                                                                                                                             

$VersionPath    = dirname(__FILE__);                                                                                                                                                                                                                                            
$LibPath        = $VersionPath.'/lib';                                                                                                                                                                                                                                          

//адрес Воск
$voskServer = 'ws://192.168.1.100:2700';                                                                                                                                                                                                                                         
$FD3 = 'php://fd/3';                                                                                                                                                                                                                                                            
require_once '/etc/freepbx.conf';                                                                                                                                                                                                                                               
require_once '/var/lib/asterisk/agi-bin/phpagi.php';                                                                                                                                                                                                                            

$module_name  = 'eagiVosk';

$dbh = \FreePBX::Database();                                                                                                                                                                                                                                                    
$outGoingPath = \FreePBX::Config()->get("ASTSPOOLDIR")."/outgoing";                                                                                                                                                                                                             
$monitorPath = \FreePBX::Config()->get("ASTSPOOLDIR")."/monitor";                                                                                                                                                                                                               

//поиск слов по этому массиву с Goto или Dial                                                                                                                                                                                                                                   
$word_arr = array(                                                                                                                                                                                                                                                              
                'тех' => 'ext-queues,8001,1',                                                                                                                                                                                                                                   
                'бухгалтер' => 'from-did-direct,102,1',                                                                                                                                                                                                                         
                'оператор' => 'ext-queues,800,1'                                                                                                                                                                                                                                
);                                                                                                                                                                                                                                                                              

$myagi = new AGI();                                                                                                                                                                                                                                                             
$myagi->answer(); 
require_once("/var/lib/asterisk/agi-bin/websocket-php-1.3.1/vendor/autoload.php");                                                                                                                                                                                         
use WebSocket\Client;                                                                                                                                                                                                                                                           
$client = new Client($voskServer, array('timeout' => 20,'fragment_size'=> 8192));                                                                                                                                                                                               
$client->send('{ "config" : { "sample_rate" : 8000 } }', 'text');                                                                                                                                                                                                               

// проигрываем                                                                                                                                                                                                                                                                  
$myagi->exec('PLAYBACK',array('/var/lib/asterisk/sounds/ru/hello-world'));                                                                                                                                                                                                      

$myText = array();                                                                                                                                                                                                                                                              
$totalText = '';                                                                                                                                                                                                                                                                
$mydata = fopen($FD3, "rb");                                                                                                                                                                                                                                                    
$previous_text = '';                                                                                                                                                                                                                                                            
while(!feof($mydata)) {                                                                                                                                                                                                                                                         
        $data = fread($mydata,8192);                                                                                                                                                                                                                                            
        $client->send($data, 'binary');                                                                                                                                                                                                                                         
        $receive = $client->receive();                                                                                                                                                                                                                                          

        $result = json_decode($receive, true);                                                                                                                                                                                                                                  
        if(!empty($result['partial'])) {                                                                                                                                                                                                                                        
                $myagi->verbose($result['partial'],3);                                                                                                                                                                                                                          
                if($previous_text != $result['partial']){                                                                                                                                                                                                                       
                        $previous_text = $result['partial'];                                                                                                                                                                                                                    
                        foreach ($word_arr as $word => $destination){                                                                                                                                                                                                           
                                if (preg_match('/'.$word.'/u', $previous_text , $matches) ){                                                                                                                                                                                    
                                        list($context,$ext,$priority) = explode(',',$destination);                                                                                                                                                                              
                                        $myagi->exec_dial('Local',$ext.'@'.$context);                                                                                                                                                                                           
                                        break;                                                                                                                                                                                                                                  
                                }                                                                                                                                                                                                                                               
                        }                                                                                                                                                                                                                                                       

                }                                                                                                                                                                                                                                                               

        }                                                                                                                                                                                                                                                                       
}                                                                                                                                                                                                                                                                               
$client->send("{\"eof\" : 1}");                                                                                                                                                                                                                                                 
$receive = $client->receive();                                                                                                                                                                                                                                                  
fclose($mydata);                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
$myagi->hangup();                                                                                                                                                                                                                                                               
?>

 

Скрипт называем eagiVOSK.php ложим в /var/lib/asterisk/agi-bin

так как мы работали под своим пользователем, то чтобы Asterisk мог с ними работать нужно поменять пользователя

chown -R asterisk:asterisk /var/lib/asterisk/agi-bin

Чтобы звонок попал в наш скрипт, создаем простой диаплан в extensions_custom.conf

[testEAGI]
exten => _X.,1,Answer()
same => n,EAGI(/var/lib/asterisk/agi-bin/eagiVOSK.php)
same => n,Hangup()