В данной статье рассмотрим пример скрипта 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()