Динамические конференции на Asterisk 16 + FreePBX 14
В порядке рабочей необходимости поставилась задача по реализации динамических конференций на FreePBX. Из функционала должна быть возможность перевода активного разговора в конференцию, возможность приглашать новых участников в созданную динамическую конференцию находясь в ней, а так же возможность самостоятельному подключения к активной динамической конференции.
В интернете есть несколько примеров реализации подобного рода задачи, но я решил реализовать по своему и так как мне нужно. Итак все ниже описанные действия производились на Asterisk 16 + FreePBX 14 + phpAGI.
[stextbox id=’info’]ИНФОРМАЦИЯ. По-умолчанию phpAGI задействован в FreePBX и дополнительных манипуляций по его настройки не требуется. Если ниже описанные действия будут применяться к голому Asterisk, то как настроить на нем phpAGI можно прочитать из этой статьи.[/stextbox]
- В активном разговоре нажать
*7
— создание и перевод участников разговора в конференцию. - В конференции нажать
*7
— после гудка набрать номер кого хотим пригласить в конференцию и нажимаем#
. - Набрать внутренний номер с префиксом
*7
(прим.*71100
) — если конференция с набранным номером (прим.1100
) существует, то будет присоединение к ней, в противном случае будет создана новая конференция.
Создаем скрипт /var/lib/asterisk/agi-bin/conference.php
со следующим содержанием:
#!/usr/bin/php -q <?php require('phpagi.php'); // ------------------------------------------------// // Dymanic Conf module by Jakonda© 2020 // // web - https://jakondo.ru // // ------------------------------------------------// // Подключение phpAGI / AGI_AsteriskManager $agi = new AGI(); $asm = new AGI_AsteriskManager(); $asm->connect(); debug(".::: Starting scrypt (/var/lib/asterisk/agi-bin/cenference.php) :::."); $action = $argv[1]; $confnum = $argv[2]; switch ($action) { case "NEW": newconf(); break; case "ADD": inviteconf(); break; case "MANUAL": manualconf(); break; default: } // Функция создания динамической конференции из активного разговора function newconf() { global $agi,$asm,$debug; $CL = $agi->get_variable('CHANNEL'); $BP = $agi->get_variable('BRIDGEPEER'); $CN = $agi->get_variable('DYNAMIC_WHO_ACTIVATED'); $CL = $CL['data']; $BP = $BP['data']; $CN = $CN['data']; // Получение информации кто активировал DTMF код $CN = substr($CN, strpos($CN, "/") + 1, strpos($CN, "-") - 4); $asm->send_request('Setvar',array('Channel'=>"$CL",'Variable'=>"CONFNUM",'Value'=>"$CN")); $asm->send_request('Setvar',array('Channel'=>"$BP",'Variable'=>"CONFNUM",'Value'=>"$CN")); debug("Number [$CN] activated DTMF"); debug("Source channel [$CL]"); debug("Bridged channel [$BP]"); // Проверяем если номер внутренний, то разрешаем создать динамическую // конференцию из текущего разговора if (strlen($CN) == 4) { debug("Allow"); } else { debug("Deny"); break; } // Перебрасываем собеседников в конференцию $asm->send_request('Redirect',array('Channel'=>"$CL",'ExtraChannel'=>"$BP",'Context'=>"dynamic-conference",'Exten'=>"CONF",'Priority'=>"1")); } // Функция добавления новых участник в динамически созданную активную конференцию function inviteconf() { global $agi,$asm,$confnum,$debug; // Ожидаем ввода номера для добавления в конференцию $result = $agi->get_data('beep', 4000, 11); $res = $result['result']; debug("Invite [$res] to dynamic conference [$confnum]"); // Приглашаем набранный номер в конференцию if (strlen($res) == 4) { $asm->send_request('Originate',array('Channel'=>"SIP/$res",'Context'=>"dynamic-conference",'Exten'=>"CONF",'Priority'=>"1",'CallerID'=>"PBX Conference $confbum <$confnum>",'Variable'=>"CONFNUM=$confnum")); } else { $asm->send_request('Originate',array('Channel'=>"Local/$res@from-internal-additional",'Context'=>"dynamic-conference",'Exten'=>"CONF",'Priority'=>"1",'Variable'=>"CONFNUM=$confnum")); } } // Функция ручного управления. Создание динамической конференции и подключения к активной динамической конференции function manualconf() { global $agi,$asm,$debug; $CL = $agi->get_variable('CHANNEL'); $EX = $agi->get_variable('EXTEN'); $CL = $CL['data']; $EX = substr($EX['data'],2); debug("$CL"); debug("$EX"); $asm->send_request('Setvar',array('Channel'=>"$CL",'Variable'=>"CONFNUM",'Value'=>"$EX")); $asm->send_request('Redirect',array('Channel'=>"$CL",'Context'=>"dynamic-conference",'Exten'=>"CONF",'Priority'=>"1")); } // Функция вывода DEBUG информации в консоль // -- полезно для отладки работы скрипта function debug($string) { global $agi; $agi->verbose("$string"); } ?>
Выдаем права на чтение и запуск для asterisk:
chown asterisk:asterisk /var/lib/asterisk/agi-bin/conference.php chmod 755 /var/lib/asterisk/agi-bin/conference.php
Прописываем динамическую функцию запуска скрипта, по нажатию комбинации *7
из активного разговора. В файл /etc/asterisk/features_applicationmap_custom.conf
добавляем:
conference=>*7,self,AGI(/var/lib/asterisk/agi-bin/conference.php,NEW)
Объявляем прописанную динамическую функцию в глобальные переменные. В файл /etc/asterisk/globals_custom.conf
добавляем:
DYNAMIC_FEATURES=conference
Модифицируем параметры конференции, добавим возможность приглашать новых участников, по нажатию комбинации *7
в активной конференции. В файл /etc/asterisk/confbridge_custom.conf
добавляем:
[dynamic_user] type = user talk_detection_events=yes dsp_drop_silence=yes announce_only_user=no [dynamic_menu] type = menu *7=dialplan_exec(dynamic-conference,INVITE,1)
Описываем работу динамических конференций в диалплане. В файл /etc/asterisk/extensions_custom.conf
добавляем:
[from-internal-custom] include => dynamic-conference [dynamic-conference] ; ----------------------------------------------------------------------------------------------------------------- ; Динамические конференции. При активном разговоре, сотрудник может перевести разговор в конференцию, которая будет ; создана динамически(номер конференции будет присвоен такой же как и внутренний номер сотрудника). Сотрудник может ; добавить участников в созданную конференцию. Сотрудники могут подключиться к динамической конференции без ; приглашения, а так же создать свою новую динамическую конференцию. ; ; -- Инструкция: ; - В активном разговоре нажать *7 - создание и перевод участников разговора в конференцию ; - В конференции нажать *7 - после гудка набрать номер кого хотим пригласить в конференцию и нажимаем # ; - Набрать внутренний номер с префиксом *7 (прим. *71100) - если конференция с набранным номером (прим. 1100) ; существует, то будет присоединение к ней, в противном случае будет создана новая конференция. ; ----------------------------------------------------------------------------------------------------------------- ; exten => CONF,1,NoOp(Dynamic Conference) exten => CONF,n,ConfBridge(${CONFNUM},,dynamic_user,dynamic_menu) exten => INVITE,1,NoOp(Conference Invite ${CONFNUM}) exten => INVITE,n,AGI(/var/lib/asterisk/agi-bin/conference.php,ADD,${CONFNUM}) exten => _*7XXXX,1,NoOp(Create/Connect Dynamic Conference) exten => _*7XXXX,n,AGI(/var/lib/asterisk/agi-bin/conference.php,MANUAL)
[stextbox id=’info’]ИНФОРМАЦИЯ. Номерной план само собой может отличаться от моего (4-х значного), поэтом строку _*7XXXX
адаптируйте под свой номерной план.[/stextbox]
Перечитываем диалплан и можно проверять работу динамических конференций:
asterisk -rx 'dialplan reload'
А как можно запустить это скрипт на FreePBX 17 asterisk 21 ну и конечно же PJsip
модернизировав его под актуальные версии..
Добрый день!
Не удается запустить скрипт на голом астериск.
Получаю ошибку:
AGI Tx >> agi_request: /var/lib/asterisk/agi-bin/conference1.php
AGI Tx >> agi_channel: PJSIP/111001-00000002
AGI Tx >> agi_language: ru
AGI Tx >> agi_type: PJSIP
AGI Tx >> agi_uniqueid: 1658495905.2
AGI Tx >> agi_version: 16.2.1~dfsg-2ubuntu1
AGI Tx >> agi_callerid: 111001
AGI Tx >> agi_calleridname: 111001
AGI Tx >> agi_callingpres: 0
AGI Tx >> agi_callingani2: 0
AGI Tx >> agi_callington: 0
AGI Tx >> agi_callingtns: 0
AGI Tx >> agi_dnid: *7000
AGI Tx >> agi_rdnis: unknown
AGI Tx >> agi_context: from-internal
AGI Tx >> agi_extension: *7000
AGI Tx >> agi_priority: 2
AGI Tx >> agi_enhanced: 0.0
AGI Tx >> agi_accountcode:
AGI Tx >> agi_threadid: 140293074446080
AGI Tx >> agi_arg_1: MANUAL
AGI Tx >>
— AGI Script /var/lib/asterisk/agi-bin/conference1.php completed, returning 0
в чем может быть проблема?
У вас используется PJSIP, а на момент написания статьи я использовал ChanSIP.