Здесь показаны различия между двумя версиями данной страницы.
Следующая версия | Предыдущая версия | ||
faq:dial_conf_extension_number [2020/10/13 13:49] Портнов Алексей создано |
faq:dial_conf_extension_number [2023/12/22 13:14] (текущий) Портнов Алексей |
||
---|---|---|---|
Строка 11: | Строка 11: | ||
- Укажем название комнаты "**Z-CONF-354233**" | - Укажем название комнаты "**Z-CONF-354233**" | ||
- Укажем внутренний номер "**354233**" | - Укажем внутренний номер "**354233**" | ||
- | - Опишем "**Приложение Dialplan**" | + | - Опишем "**Приложение Dialplan**" (см. [[:dialplan-applications|Приложения диалпланов]]) |
- Название "**Z-Worker-CONF**" | - Название "**Z-Worker-CONF**" | ||
- Номер для вызова "**2200101**" (может быть произвольным) | - Номер для вызова "**2200101**" (может быть произвольным) | ||
- | - | + | - Укажите тип кода "**PHP-AGI скрипт**" |
+ | - Код <code><?php | ||
+ | require_once 'Globals.php'; | ||
+ | use MikoPBX\Core\System\Util; | ||
+ | use MikoPBX\Core\Asterisk\AGI; | ||
+ | use MikoPBX\Core\Asterisk\AsteriskManager; | ||
+ | use MikoPBX\Core\System\Processes; | ||
+ | |||
+ | function checkStartConf(){ | ||
+ | $Z_DTMF = '354233'; | ||
+ | $Z_PROVIDER_ID = 'SIP-1692280724'; | ||
+ | $Z_DST = '84957776675'; | ||
+ | $asteriskCmd = Util::which('asterisk'); | ||
+ | $busyboxCmd = Util::which('busybox'); | ||
+ | |||
+ | $am = new AsteriskManager(); | ||
+ | $am->connect(); | ||
+ | |||
+ | $confEmpty = true; | ||
+ | $confChannelFound = false; | ||
+ | |||
+ | $result = shell_exec("$asteriskCmd -rx 'confbridge list $Z_DTMF' | $busyboxCmd grep default_menu | $busyboxCmd cut -f 1 -d ' '"); | ||
+ | foreach (explode(PHP_EOL, $result) as $channelData){ | ||
+ | if(empty($channelData)){ | ||
+ | continue; | ||
+ | } | ||
+ | $value = $am->GetVar($channelData, 'ZDTMF', null, false); | ||
+ | if(!empty($value)){ | ||
+ | // Это канал конференции. | ||
+ | $confChannelFound = true; | ||
+ | }else{ | ||
+ | // Есть канал конечного пользователя. | ||
+ | $confEmpty = false; | ||
+ | } | ||
+ | } | ||
+ | if($confChannelFound === false && $confEmpty === false){ | ||
+ | // Необходимо соединить с внешней конференцией. | ||
+ | $am->Originate( | ||
+ | 'Local/'.$Z_DTMF.'@z-meetme', | ||
+ | $Z_DST, | ||
+ | 'z-outgoing', | ||
+ | '1', | ||
+ | null, | ||
+ | null, | ||
+ | null, | ||
+ | "Conf <$Z_DTMF>", | ||
+ | "__ZDTMF={$Z_DTMF},__ZPROVIDERID={$Z_PROVIDER_ID},__ZDST={$Z_DST}}", | ||
+ | '0'); | ||
+ | |||
+ | }elseif ($confChannelFound === true && $confEmpty === true){ | ||
+ | Processes::mwExec("{$asteriskCmd} -rx 'confbridge kick {$Z_DTMF} all'"); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | $action = $argv[1]??''; | ||
+ | if($action === 'start'){ | ||
+ | $pid = Processes::getPidOfProcess(basename($argv[0])." start$", getmypid()); | ||
+ | if(!empty($pid)){ | ||
+ | $killCmd = Util::which('kill'); | ||
+ | Processes::mwExec("{$killCmd} {$pid}"); | ||
+ | } | ||
+ | while (true){ | ||
+ | checkStartConf(); | ||
+ | sleep(10); | ||
+ | } | ||
+ | }else{ | ||
+ | $agi = new AGI(); | ||
+ | $agi->answer(); | ||
+ | checkStartConf(); | ||
+ | $agi->hangup(); | ||
+ | } | ||
+ | </code> | ||
+ | - Правим файл "**/var/spool/cron/crontabs/root**" через меню [[:custom-files|Кастомизация системных файлов]] | ||
+ | - Добавляем задачу в конец файла: <code>*/1 * * * * /usr/bin/php -f /var/lib/asterisk/agi-bin/DIALPLAN-APP-EC12CFAE6783FE82FD34F16E40C7386B.php start > /dev/null 2> /dev/null</code> | ||
+ | - В данном примере "**DIALPLAN-APP-EC12CFAE6783FE82FD34F16E40C7386B**" - Это идентификатор созданного ранее приложения. ID можно подсмотреть в адресной строке браузера при редактировании приложения. | ||
+ | - Опишем дополнительные контексты через меню [[:custom-files|Кастомизация системных файлов]]. Править будем файл **extensions.conf**. Добавьте в конец файла следущий текст: <code> | ||
+ | [z-outgoing] | ||
+ | exten => _X!,1,Ringing() | ||
+ | same => n,Gosub(${ISTRANSFER}dial,${EXTEN},1) | ||
+ | same => n,Dial(PJSIP/${EXTEN}@${ZPROVIDERID},600,${DOPTIONS}TKU(z-dial-answer)b(dial_create_chan,s,1)) | ||
+ | same => n,ExecIf($["${ISTRANSFER}x" != "x"]?Gosub(${ISTRANSFER}dial_hangup,${EXTEN},1)) | ||
+ | same => n,Set(pt1c_UNIQUEID=${EMPTY_VALUE}) | ||
+ | same => n,ExecIf($["${BLINDTRANSFER}x" != "x"]?AGI(check_redirect.php,${BLINDTRANSFER})) | ||
+ | same => n,Hangup() | ||
+ | |||
+ | [z-dial-answer] | ||
+ | exten => s,1,NoOp(Answered send DTMF...) | ||
+ | same => n,Gosub(dial_answer,${EXTEN},1) | ||
+ | same => n,SendDTMF(${ZDTMF}) | ||
+ | same => n,return | ||
+ | |||
+ | [z-meetme] | ||
+ | exten => _X!,1,Answer() | ||
+ | same => n,Gosub(set-answer-state,${ZDTMF},1) | ||
+ | same => n,Set(CHANNEL(hangup_handler_wipe)=hangup_handler_meetme,s,1) | ||
+ | same => n,Set(CONFBRIDGE(bridge,record_file_timestamp)=false) | ||
+ | same => n,Set(CONFBRIDGE(bridge,record_conference)=yes) | ||
+ | same => n,Set(CONFBRIDGE(bridge,video_mode)=follow_talker) | ||
+ | same => n,Set(CONFBRIDGE(user,talk_detection_events)=yes) | ||
+ | same => n,Set(CONFBRIDGE(user,quiet)=yes) | ||
+ | same => n,Set(CONFBRIDGE(user,music_on_hold_when_empty)=yes) | ||
+ | same => n,ConfBridge(${ZDTMF}) | ||
+ | same => n,Hangup() | ||
+ | </code> | ||
+ | |||
+ | <note important>При звонке в конференцию по номеру **354233** автоматически будет подключаться внешний абонент с номером **84957776675**. Как только абонент ответи, будет произведен набор добавочного номера **354233**. Как только все "внутренние" участники покинули конференцию, внешний абонент будет отключен. </note> | ||
+ | |||
+ | <note important>Задача в крон нужна лишь для дополнительной "защиты", по сути это рестарт php скрипта каждую минуту</note> | ||
[[faq:|Обратно к инструкциям]] | [[faq:|Обратно к инструкциям]] |