Динамические конференции на Asterisk 16 + FreePBX 14
В порядке рабочей необходимости поставилась задача по реализации динамических конференций на FreePBX. Из функционала должна быть возможность перевода активного разговора в конференцию, возможность приглашать новых участников в созданную динамическую конференцию находясь в ней, а так же возможность самостоятельному подключения к активной динамической конференции.
В интернете есть несколько примеров реализации подобного рода задачи, но я решил реализовать по своему и так как мне нужно. Итак все ниже описанные действия производились на Asterisk 16 + FreePBX 14 + phpAGI.
Техническое задание:
- В активном разговоре нажать
*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)
Перечитываем диалплан и можно проверять работу динамических конференций.
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.