ISP`s IT Аутсорсинг
Быстрый переход: Главная блога Главная сайта Форум
Если Вы чего то недопоняли или не нашли - задайте
вопрос на нашем форуме и мы попробуем Вам помочь.
Subnets.ru Регистрация IP и Автономных систем mega-net.ru

Архивные статьи в категории ‘Asterisk’

Добро пожаловать в блог! Надеемся, что Вы еще вернетесь.

Роботы все плотнее входят в нашу повседневную жизнь. То, что ранее было фантастикой, сегодня уже повседневка.
Роботы строят, работают на производствах, рулят и т.п. Недавно узнал, что уже есть полностью роботизированные отели. Наверно уже совсем скоро даже утюг будет роботом.
Но так ли будет удобно с ними, если они не будут вас понимать ? Т.е. если нельзя будет общаться с ними.

Сегодня в определённых сферах все только и говорят про роботов: промышленных, бытовых, текстовых чат-ботов. Роботы строят, работают на производствах, рулят и т.п. Недавно узнал, что уже есть полностью роботизированные отели. Наверно уже совсем скоро даже утюг будет роботом.

Гиганты и флагманы индустрии — Google, Amazon, Apple, Yandex демонстрируют своих виртуальных помощников и помощниц, одна другой краше и сообразительней. Большинство их привязано к нейросетям, для самообучения и демонстрации искусственного псевдо-интеллекта. Как тут не вспомнить Алана Тьюринга с его тестом?

Давно хотел попробовать использовать технологии синтеза речи и распознавание речи, но руки все не доходили… И вот, наконец, дошли 🙂
Принимаю участие в интересном проекте, назвали мы его «Оксана».
«Оксана» основана на TTS (Text-To-Speech) и системе распознавания голоса, которые предоставляет сервис от Яндекс — SpeechKit Cloud.

«Оксана» представлена в виде AGI скрипта, который исполняется IP-АТС Asterisk.
На данном этапе в проекте специально не используется никаких нейронных сетей, баз данных и т.п. Это НЕ искусственный интеллект и мы даже не пытаемся его создать.
«Оксана», не слишком умна (да и зачем ей большой ум? Диссертации писать?), её дело простое:
отвечать на одни и те же вопросы, принимать заказы, переводить звонок в техподдержку (если надо), записывать на стрижку/укладку.
«Оксана» может обрабатывать как входящие вызовы, так и совершать исходящие вызовы.
Что ещё? Всё что можно придумать и уложить в логику простого диалога с распознаванием речи, пере спросами, если не поняла или не расслышала
Поэтому говоря с «Оксаной» не стоит говорить «граф Дракула» в ответ на вопрос «Как вас зовут?» и «Хочу побрить сову» на вопрос «Какая услуга вас интересует ?».
«Оксана» это запрограммированные диалоги в определенном ключе для выполнения определенных задач.
Например задачи «секретарь», «оператор такси», «опрос» и тому подобные рутинные разговоры, которые проходят в одном и том же ключе.
Для каждого диалога предусмотрен свой конфиг файл, в котором и задается что будет говорить «Оксана» и что мы ожидаем в ответ, и что будем делать.

Логика такого диалога — простая конфигурация, но к ней надо подходить основательно. Лучше сразу нарисовать блок-схему, с ветвлением, с переходами по условиям если распознано , то => шаг Х, если же иное => шаг Y, и так далее.
Говорить «Оксана» может не только через TTS от Яндекс, но и через встроенный в Asterisk Festival, но Festival от Asterisk заметно хуже и сильно уступает сервису от Яндекс.

Простота конфигурации, печатанием всевозможных слов и выражений для воспроизведения речи, может заменяться заранее записанными аудио-файлами. Тогда становится реально труднее распознать, что вы общаетесь не с живым человеком! Особенно после некоторых опций — ключевых слов, которыми можно перебить искусственный разум, типа — «Замолчи!» и даже «Заткнись!».

Вот визуализация некоторых диалогов с «Оксаной»:

oksana_secretar

«Оксана» секретарь

 

oksana_taxi

«Оксана» оператор такси

 

oksana_doctor

«Оксана» доктор

 

Проект ещё находится на этапе разработки, но уже проходил (и успешно) испытания на людях, да и сейчас проходит.

P.S. При копировании статьи ссылка на источник ОБЯЗАТЕЛЬНА ! Пожалуйста, уважайте чужой труд.

Автор: Николаев Дмитрий (virus (at) subnets.ru)

Ничего не понялТак себе...Не плохоДовольно интересноОтлично ! То что нужно ! (Еще не голосовали)
Загрузка...
Отправить на почту Отправить на почту

enumer

Как описано в https://ru.wikipedia.org/wiki/ENUM

ENUM (или Enum, от E.164 NUmber Mapping) — набор протоколов для объединения системы нумерации телефонов E.164 с системой адресации интернет, а DNS при использовании косвенного метода поиска получает записи NAPTR. Записи хранятся в базе данных DNS. Логика создания такой базы вытекала из базовой (условной) стоимости звонков по протоколам VoIP стремящейся к нулю.

Функция поиска номера назначения при исходящем вызове на межгородские и международные соединения легко включала бы в себя запрос в единую базу номеров Enum, и, при наличии этого номера в базе, узел совершал бы вызов не по традиционным каналам PSTN, а напрямую к ресурсу, на котором зарегистрирован этот номер.

Понятно, что такой сценарий не очень устраивает традиционных консервативных операторов связи, которые по прежнему зарабатывают на услугах голосовой связи, игнорируя порой возможности новых технологий. Это облегчает вызов пользователя VoIP из IP сетей, но никак не из традиционных сетей.

По сути, ENUM также не является функцией VoIP, являясь лишь удобным дополнением. Диалектика развития нулевой стоимости вызовов для проекта Enum привела его к угасанию.

И только в последнее время появилось новое продолжение — ENUMER, та же самая функция идейно, но на новой технологической платформе — блокчейна Emercoin.

Зачем нужен ENUMER простому клиенту?

 

  • Публикуясь в ENUMER, вы даёте возможность миру позвонить себе бесплатно. Это полезно для организаций, кто принимает звонки, в особенности — владельцы 800-х номеров: служба заказов билетов, магазины, заводы и тп.;
  • Если у вас 800-ый (toll-free) номер — то это прямая экономия на расходах за принимаемые вызовы, которые оплачивает владелец номера;
  • ENUMER сокращает время установления соединения с примерно 2х sec PSTN до 0.3s ENUMER;
  • Повышенное качество сигнала и снижение задержек за счёт сокращения цепочки транскодинга;
  • Повышенное качество сигнала за счёт возможности использовать HD codec;
  • Возможность безопасного соединения за счёт SRTP/ZRTP;
  • Обход ограничения на кол-во линий E1/T1;

Как использовать ?

В Asterisk есть команда dialplan ENUMLOOKUP. Применив которую осуществляется DNS запрос в базу блокчейна.

exten => s,1,Set(ENUMER=${ENUMLOOKUP(${DIAL_NUMBER},sip,,1,enum.)})
exten => s,n,NoOp(ENUMLOOKUP is ${ENUMER})
exten => s,n,Dial(SIP/${ENUMER},30)
exten => s,n,Hangup()

Для осуществления DNS запроса в клиенте emercoin встроен DNS сервер, который необходимо включить в emercoin.conf.
Для более детального понимания читать  >>> https://habr.com/company/emercoin/blog/337034/
Ничего не понялТак себе...Не плохоДовольно интересноОтлично ! То что нужно ! (Еще не голосовали)
Загрузка...
Отправить на почту Отправить на почту

Интеграция Asterisk и Telegram

На одном из форумов посвященных Asterisk`у в очередной раз подняли тему «Как не терять звонки». Тему о том как уведомлять, себя любимого, да и не только себя, о пропущенных вызовах и/или совершенной переадресации. И в очередной раз был предложен метод с использованием СМС. Но ведь есть и другой способ, который на мой взгляд лучше — Telegram.

Почему Telegram ? Потому, что данный мессенджер удобен и у него много приятных фишек, например таких как боты.
Собственно с помощью бота можно не только отправлять себе что-то, но и получить обратную связь.
У нас уже был опыт подобной связи и мы уже использовали эту возможность для соединения нашего чата с Telegram, дабы иметь возможность общаться не только сидя перед компом.

Итак далее про интеграцию Asterisk и Telegram.
Чтобы показать пример отправки сообщения в Telegram я по быстрому зарегистрировал нового бота и создал небольшой PHP скрипт, который расположил тут: http://bot.subnets.ru/telegram/
Принцип работы такой:

  • устанавливаем приложение telegram на телефон или используем web версию telegram
  • находим бота (по имени пользователя) @msaster_bot
  • отправлям боту команду /start
  • запоминаем свой ID в Telegram, который бот выдаст в ответе на команду/start (или отправляем боту команду /me)
  • затем используя ссылку вида http://bot.subnets.ru/telegram/simple.php?user=<TELEGRAM ID>&msg=<MESSAGE TEXT>
    • где <TELEGRAM ID> — ваш ID в Telegram
    • где <MESSAGE TEXT> — текст для отправки

    пример ссылки: http://bot.subnets.ru/telegram/simple.php?user=12345&msg=testMessage

После чего наблюдаем отправленный вами текст на экране своего смартфона/компа.
Таким образом используя вAsterisk функцию CURL и/или другой скрипт вызываемый с помощью функции System, или AGI скрипт, вообщем все то что может обратиться к URL, мы можем отправлять себе сообщения прямо из dialplan Asterisk или консоли сервера.

И вот тут у меня проснулся интерес. Отправлять сообщения конечно здорово, но иметь обратную связь с Asterisk будет ещё лучше.
Как эту обратную связь использовать ? Да первое что мне пришло на ум это callback. Тыкаем в команду бота и тут же получаем callback от своего Asterisk.
Здорово, но мало 🙂 А что если реализовать возможность отправлять в Asterisk команды CLI прямо из Telegram и получать вывод этих команд ? Да, было бы не лишним.
Почему не лишним ? Да потому что ты не все время у компа и если вдруг что-то пойдет не так и тебе позвонят с работы «Ой, все упало !», то подобная прямая связь с Asterisk была бы кстати, т.к. очень быстро готова к использованию и прямо с мобилы.

Потратив некоторое время на разработку функционала самого бота и написав PHP клиента для связи с Asterisk я все же добился необходимого мне результата.

Я смог выполнить произвольную команду в CLI Asterisk. На скриншоте ниже это выполнение команды core show calls:

Интеграция Asterisk и Telegram

Asterisk и Telegram

Ну или даже вот так:

Asterisk и Telegram

Asterisk и Telegram

Вот такой получился интересный, на мой взгляд, проект.

Для скептиков:
Функции защиты всего это добра от использования сторонними людьми предусмотрены:

  • привязка к конкретному Telegram ID
  • идентификация по паролю в самом боте
  • контрольная подпись при отправке/получении данных между ботом и PHP клиентом
  • возможность ограничить доступ к PHP клиенту по IP-адресам
  • возможность указать какие команды Asterisk CLI будут доступны для исполнения

P.S. Если Вы так же хотите попробовать покомандовать своим Asterisk через Telegram, то я могу предоставить Вам такую возможность.
Для этого Вам будет необходимо:

  • ваше желание тестировать и сообщать об ошибках
  • иметь свой сервер с Asterisk
  • иметь установленный PHP (не ниже версии 5.6)
  • запущенный HTTP сервис (например apache), до которого можно достучаться извне
  • обратиться ко мне ( virus [СОБАЧКА-ГАВ-ГАВ] subnets.ru ) для получения паролей и явок 🙂
  • скачать и настроить PHP клиента для связи с Вашим Asterisk (PHP клиент НЕ обязательно должен быть расположен на сервере с Asterisk, он может находится и отдельно (например на Вашем WEB сервере))
  • выполнить настройки HTTP службы в Asterisk

P.S.S. При копировании статьи ссылка на источник ОБЯЗАТЕЛЬНА ! Уважайте чужой труд.

Автор: Николаев Дмитрий (virus (at) subnets.ru

Ничего не понялТак себе...Не плохоДовольно интересноОтлично ! То что нужно ! (Еще не голосовали)
Загрузка...
Отправить на почту Отправить на почту

Как, надеюсь, вам уже известно в Asterisk`е есть:

  • Asterisk Gateway Interface (AGI) — запуск и исполнение любых скриптов на любом языке программирования из dialplan, а так же позволяет выполнять команды dialplan`а в этих скриптах
  • Asterisk Manager Interface (AMI) — позволяет «слушать» событие происходящие в Asterisk`е, а так же позволяет выполнять команды

Если вам они неизвестны, то подробнее вы сможете узнать из документации.

Начиная с версии Asterisk`а 12 в нем появился Asterisk REST Interface (ARI), который является воплощением соединения AMI и AGI:

ARI

Данные интерфейс позволяет внешнему приложению осуществлять управление вызовом, а так же имеет встроенный Websocket сервер.

Основное в ARI:

  • встроенный Websocket сервер
  • приложение для dialplan`а именуемое Stasis
  • управление вызовом через API
  • Websocket сервер передает информацию о происходящих событиях в приложении Stasis

Недавно нам потребовалось реализовать следующую задачу:

Необходимо иметь web-страницу, на которой будут в режиме online отображаться пользователи, которые вошли в конференцию или вышли из нее.

На сервере, где это надо было сделать уже стоял Asterisk 13.6.0

Если необходим online режим, когда страница отображает события происходящие внутри Asterisk непосредственно в момент когда они произошли, Websocket подходит как нельзя лучше.

Мы не использовали ранее ни 12 ни 13-ю версию Asterisk`а и потому опыта работы с ARI у нас до этого момента не было, но понимание принципов работы и применение Websocket на практике уже было. Подробнее о Websocket вы можете узнать на www.websocket.org 

Ближе к концу раб. дня ознакомились с немногочисленной документацией и по началу, было очень много вопросов и непоняток, но на следующее утро все, как говорится, встало на свои места. Посему мы решили попробовать реализовать все задуманное используя ARI.

Постараюсь в данной статье изложить суть и озвучить некоторые из вопросов, которые возникали и пояснить некоторые моменты.

Настройка ARI производится в ari.conf. Остановимся на некоторых пунктах настройки, на некоторых потому, что я считаю что не надо объяснять что если вы хотите использовать ARI, то нужно в enabled указывать yes.

allowed_origins — указание URL или URL`ов с которых позволено обращение к Websock`у.

Если указывается несколько URL`ов, то будьте внимательны, они должны разделяться запятой и БЕЗ пробелов.

Пример:

allowed_origins = http://my.domain.ru,http://ari.asterisk.org

Настройки пользователя ARI:

[username]
type = user
read_only = no
password = password
password_format = plain

В read_only указываем yes только в том случае если мы хотим чтобы внешняя система могла только получать уведомления от приложения, но НЕ могла управлять вызовом.

Работа ARI невозможна без встроенного в Asterisk HTTP сервера, а значит для работы нам необходимо его включить — правим настройки в http.conf

После этого заставляем Asterisk перечитать конфигурацию и смотрим на результат своих трудов по настройке:

*CLI> http show status
HTTP Server Status:
Prefix:
Server: AsteriskRU
Server Enabled and Bound to 127.0.0.1:8088

Enabled URI’s:
/httpstatus => Asterisk HTTP General Status
/phoneprov/… => Asterisk HTTP Phone Provisioning Tool
/amanager => HTML Manager Event Interface w/Digest authentication
/arawman => Raw HTTP Manager Event Interface w/Digest authentication
/manager => HTML Manager Event Interface
/rawman => Raw HTTP Manager Event Interface
/static/… => Asterisk HTTP Static Delivery
/amxml => XML Manager Event Interface w/Digest authentication
/mxml => XML Manager Event Interface
/ari/… => Asterisk RESTful API
/ws => Asterisk HTTP WebSocket

Не забудьте, что если вы указывали свой prefix в http.conf, то его необходимо будет использовать во всех URL`ах для обращения. Так же необходимо понимать что помимо ARI становятся доступными и остальные интерфейсы указанные в списке выше. Посему настоятельно НЕ рекомендуется там указывать:

bindaddr=0.0.0.0

Рекомендуется:

bindaddr=127.0.0.1

Итак ARI и WS (Websocket server) запущены. Что далее ? А далее познакомимся с возможностями ARI. Для этого разработчики создали документацию, которая доступна в JSON формате и которую можно получить обратившись на соответствующий URL.

Например: http://localhost:8088/ari/api-docs/resources.json

Если Вы, по отношению к серверу находитесь удаленно, то можно открыть данный URL консольным браузером (например lynx) или сделать проброс порта через SSH. Для этого выполняем:

# ssh myRealAsteriskIP -L8001:127.0.0.1:8088

После чего вы сможете обратиться по URL`у http://localhost:8001/ari/api-docs/resources.json прямо со своего компа.

Все это конечно здорово, но читать доку в Json формате не очень удобно, особенно если в ari.conf вы не указали pretty=yes. Но тут к вам на выручку придут разработчики Asterisk, которые для этих целей создали web-интерфейс ari.asterisk.org, который может подключится к вашему ARI:

ARI.web

И мы не только можем читать доку по всем командам ARI в удобоваримом виде, но и ПРОБОВАТЬ выполнять ARI команды прямо там же и не отходя от кассы:

ARI.web.2

За это разрабам просто низкий поклон и уважуха. Снимаю шляпу перед ними. Если бы этого инструмента не было, то вникать в ARI явно пришлось бы дольше.

Теперь настало время ознакомиться с самим приложением Stasis, чтобы нам было на чем тренироваться в вышеуказанном web-интерфейсе.

Читаем доку:

# asterisk -rx ‘core show application Stasis’

-= Info about application ‘Stasis’ =-

[Synopsis]
Invoke an external Stasis application.

[Description]
Invoke a Stasis application.
This application will set the following channel variable upon completion:
${STASISSTATUS}: This indicates the status of the execution of the Stasis application.
SUCCESS: The channel has exited Stasis without any failures in Stasis.
FAILED: A failure occurred when executing the Stasis The app registry
is not instantiated; The app application. Some (not all) possible reasons
for this: requested is not registered; The app requested is not active;
Stasis couldn’t send a start message.

[Syntax]
Stasis(app_name[,args])

[Arguments]
app_name
Name of the application to invoke.
args
Optional comma-delimited arguments for the application invocation.

Пример применения приложения Stasis в dialplan:

[default]
exten => 1000,1,NoOp()
same => n,Answer()
same => n,Stasis(hello)
same => n,Hangup()

В данном контексте мы наблюдаем вызов приложения Stasis и запуском вашего первого приложения hello, которое будет контролироваться вами через Stasis.

Вот тут стоит обязательно отметить что:

  • вы НЕ можете управлять каналом, который находится ВНЕ приложения Stasis
  • вы НЕ можете получать события по каналам, которые находятся ВНЕ приложения Stasis
  • во время исполнения приложения Stasis исполнение dialplan`а полностью прекращается и если ваше приложение не подает никаких ARI команд, то вызов (канал) будет просто висеть с тишиной в трубке
  • если к вашему приложению нет клиентов подключенных по Websocket, то такое приложение работать не будет и вызов (см. пример выше) уйдет по Hangup`у

Давайте ещё раз осознаем, что приложение Stasis позволяет управлять ВАШИМ приложением hello. Тавтология конечно, но не знаю как сказать по иному. Главное чтобы выпонимали разницу между двумя этими приложениями, одно это приложение dialplan`а (Stasis), а другое это ваше приложение (hello (конечно же название приложения может быть любым)).

Если вы все сделали правильно и создали страничку с Websocket`ом и коннектом на ws://127.0.0.1:8001/ws то открыв её вы в CLI увидите:

Activating Stasis app ‘hello’

Это сигнал к тому, что ваше приложение зарегистрировано в системе и вы уже можете приступать к изысканиям 🙂 Начать которые можно путем совершения вызова в контекст и exten где расположен запуск Stasis(hello). В примере выше это контекст default и exten 1000.

Набрав этот номер, как я уже и писал выше, вы ничего не услышите, но воспользовавшись web-интерфейсом вы легко это исправите. Как ?

Кликнем на ветке channels и раскроем первую же вкладку «GET /channels List all active channels in Asterisk», прочтем, вникнем и нажмем магическую кнопку «Try it out!».

После чего web-интерфейс обратиться к ARI по URL`у, который будет указан в «Request URL» и получит оттуда ответ, который будет указан в «Response Body». Если вы ещё не положили трубку, то ответом будет какие каналы сейчас подключены к вашему приложению hello. Далее … а о чем это мы … ах да, о пока тишине в трубке. Исправляем это дело. Копируем номер канала и разворачиваем вкладку «POST /channels/{channelId}/play Start playback of media». В ней вставляем в channelId номер нашего канала и нажмем магическую кнопку «Try it out!».

Можно поступить чуть по другому. ARI может получить команды от вас прямо из консоли сервера. Для этого вам необходим установленный CURL.

Пример команды:

[root@virus ~]# curl -v -u ari_username:ari_password -X POST «http://localhost:8088/ari/channels/1449506765.811/play?media=sound:hello-world»

После чего вы должны услышать в трубке знакомый многим голос, голос штатного приветствия hello-world.wav от Asterisk.

Думаю этих примеров уже достаточно чтобы вы могли начать развлекаться с этим далее уже самостоятельно и потому я не буду приводить других примеров, а перейду к другим важным замечаниям:

Если вы откроете ту же страницу с Websocket`ом с другого компа или просто другим браузером, то в CLI вы увидите:

Replacing Stasis app ‘hello’
== WebSocket connection from ‘XXX.XXX.XXX.XXX:YYYYY’ for protocol » accepted using version ’13’
Activating Stasis app ‘hello’

И после чего первый клиент ПЕРЕСТАНЕТ получат какие либо уведомления от ARI, а из будет получать только второй клиент. Почему так ?

Don’t access ARI directly from a web page
It’s very convenient to use ARI directly from a web page for development, such as using Swagger-UI, or even abusing the WebSocket echo demo to get at the ARI WebSocket.
But, please, do not do this in your production applications. This would be akin to accessing your database directly from a web page. You need to hide Asterisk behind your own application server, where you can handle security, logging, multi-tenancy and other concerns that really don’t belong in a communications engine.

Все это потому, что как вы могли заметить выше:

  • в каждой команде к ARI используется apy_key что является парой логин и пароль разделенные двоеточием, который указан в явном виде
  • если следовать рекомендациям, то HTTP служба Asterisk`а висит на 127.0.0.1, а это означает что она доступна только локально и соответственно внешний пользователь, который придет на страницу не сможет ничего получать от Websocket сервера

Вот тут мы начинаем осознавать, что без собственно application сервера нам ну никак не обойтись. Что это за зверь ?

Задача application сервера (Websocket сервера) быть подключенным к ARI (зарегистрировать ваше приложение), а так же подключать внешних клиентов и бродкастить им сообщения, которые он получает от ARI. Таким образом вы скроете не только пароль к ARI, но и не позволите ломать вас через остальные интерфейсы, которые предоставляет HTTP служба внутри Asterisk`а.

В кач-ве такого сервера мы остановили свой взор на довольно распространенной платформе nodeJS (Node.js® is a JavaScript runtime built on Chrome’s V8 JavaScript engine)

Именно nodejs может одновременнно выступать в роли сервера для внешних клиентов и в роле клиента по отношению к ARI.

На debian это ставится так:

# apt-get install nodejs
# apt-get install npm
# npm install ws

На FreeBSD нужно поставить порты:

# cd /usr/ports/www/node && make install clean
# cd /usr/ports/www/npm && make install clean

Затем перейти в папку, в которой мы планируем разместить скрипт сервера, например /usr/local/sbin/scripts/ari, и выполнить:

# cd /usr/local/sbin/scripts/ari
# npm install ws
# npm install require

После открываем документацию и вникаем в нее и приводимые там примеры, а так же вот эту документацию, которая вам позволит осознать как обратиться к ARI из JS.

Если вы все осознали, то у вас получится написать js файл, который мы и будем стартовать в кач-ве Websocket сервера из консоли.

Для debian:

# nodejs ws_server.js

Для FreeBSD это:

# node ws_server.js

Самый простой пример Websocket сервера, ws_server.js:

#!/usr/bin/env node

var WebSocket = require('ws');
var WebSocketServer = require('ws').Server;
var request = require('request');

var wss;
wss = new WebSocketServer({ port: 9088 });

wss.on('connection', function connection(server) {
    console.log('Web connected');
    server.on('message', function incoming(m) {
        console.log('received: %s', m);
        server.send( m );
        console.log('sended: %s', m);
    });
});

И если запустить ws_server.js и отправить ему какой либо текст, например «send to websocket server test message«, то мы увидим в консоли

Web connected
received: send to websocket server test message
sended: send to websocket server test message

В заключении:

Именно так мы реализовали исходную задачу. Средствами Stasis была создана конференция, ws_server.js подключается к ARI и регистрирует приложение team, которое обеспечивает создание конференции, проигрывания MOH, mute/unmute и kick, а web-страница все это показывает и позволяет всем этим управлять.

Но это уже материал для другой статьи, которую вероятно я когда нить тоже осилю 🙂

З.Ы. При копировании статьи ссылка на источник ОБЯЗАТЕЛЬНА ! Уважайте чужой труд.

З.Ы.Ы. Наш пример того что получилось можно посмотреть на github.

Автор: Николаев Дмитрий (virus (at) subnets.ru)

Ничего не понялТак себе...Не плохоДовольно интересноОтлично ! То что нужно ! (голосов: 2, среднее: 5,00 из 5)
Загрузка...
Отправить на почту Отправить на почту

Многие у кого в компании больше одного сервера Asterisk зачастую сталкиваются с задачей: экспорт состояния номеров на другом сервере

Например когда появляется желание мониторить состояние exten`а на другом сервере (BLF). Чтобы при том что ваш телефон подключен к одному Asterisk серверу, а второй телефон к другому. По научному это называется Distributed Device State.

Реализация подобной задачи возможна и самый распространенный путь это путь через Jabber (XMPP PubSub). Для этого соответственно вам будет необходим Jabber сервер, а так же настройка ваших Asterisk`ов.

Как то и сам я столкнулся с этой задачей. Понадобилось сделать BLF для нцать внутренних телефонов, которые находятся на другом сервере и как и следовало я углубился в доку.

Как выяснилось позднее — это не такая простая задача как может показаться на первый взгляд. У меня то ли лыжи не едут, то ли …

Делал несколько подходов к настройке данного безобразия, но нормально у меня это так и не заработало. Не буду углубляться в причины, т.к. речь в этой статье не о данном способе.

И вот не так давно на многим известном ресурсе asterisk.ru появляется очередная тема посвященная данному вопросу: Distributed Device State: SUBSCRIBE между двумя Астерисками

Как и водится начинается она как раз с выше обозначенного способа с XMPP, но затем пользователь litnimax высказывает следующую мысль:

Проблема не так просто решается.
На сегодня есть такие варианты (мне известные):
— Jabber сервер и res_xmpp для Asterisk: позволяет обмениваться состояниями, требует кучу времени на установку, жрет немерянно ресурсов (тяжелое Java приложение, зачем оно нужно на сервере телефонии?)
— PJSIP: в новом канале есть распределенные состояния (res_pjsip_pubsub.so), однако от примеров конфигов дымится моск.
— Ну и третий вариант — ØMQ модуль для астериск и скрипт ØMQ Asterisk Manager Interface (AMI) Broker — https://github.com/litnimax/zmq-ami-broker/

Автором третьего вариант является Ваш покорный слуга, который за#$% от того, что для связи двух и более серверов требуются какие-то индейские пляски.

После данного поста и почитав доку о ZMQ Broker меня прямо осенило ! Почему мой мозг так покорно уперся только в один единственный вариант с XMPP я объяснить не могу, но именно это привело к тому, что я не мыслил шире и сам не допетрил до подобной мысли, а именно собственный метод пересылки состояний. Ведь для этого у меня уже все есть:

  • возможность в Asterisk`е устанавливать Custom state для пира
  • Websocket сервер и Websocket клиент, которые создавались нами под другую задачу, но вполне могут быть применены и для этой задачи

А больше нам ничего и не надо. Точнее все же надо, но это уже другое, а именно светлая голова и прямые руки 🙂

Создадим тестовый стенд. Допишем в диалплан (файл extensions.conf) exten`ы с такими именами для наглядности:

[devstate_test]
exten => 1234,hint,Custom:mystate
exten => 1234,1,NoOp(Test custom state for exten 1234)
exten => set_inuse,1,Set(DEVICE_STATE(Custom:mystate)=INUSE)
exten => set_not_inuse,1,Set(DEVICE_STATE(Custom:mystate)=NOT_INUSE)
exten => check,1,NoOp(Custom:mystate is ${DEVICE_STATE(Custom:mystate)})

Затем инклюднем данный контекст в тот же контекст где ваш телефон и сделаем себе пару тестовых EXTEN для того чтобы вызывать set_inuse, set_not_inuse и check.

После чего можно будет набрать эти EXTEN`ы и смотреть в CLI, где будет нечто подобное:

-- Executing [set_inuse@devstate_test:1] Set("SIP/6003-00000f41", "DEVICE_STATE(Custom:mystate)=INUSE") in new stack
-- Executing [check@devstate_test:1] NoOp("SIP/6003-00000f43", "Custom:mystate is INUSE") in new stack
-- Executing [set_not_inuse@devstate_test:1] Set("SIP/6003-00000f44", "DEVICE_STATE(Custom:mystate)=NOT_INUSE") in new stack
-- Executing [check@devstate_test:1] NoOp("SIP/6003-00000f46", "Custom:mystate is NOT_INUSE") in new stack

Т.е. как мы видим все работает — состояние устанавливается. Теперь посмотрим что происходит с состоянием самого exten`а 1234, для которого и написан hint и создадим подписку (SUBSCRIBE) настроив свой телефонный аппарат путем настройки BLF на любой кнопке. После того как телефон подпишется на состояние 1234, то мы сможем это наблюдать в CLI:

*CLI> sip show subscriptions
172.16.10.12 6003 1800900375-6060 1234@users Idle dialog-info+xml <none> 000300

После чего снова вызовем set_inuse и посмотрим состояние снова:

  -- Executing [set_inuse@devstate_test:1] Set("SIP/6003-00000f6e", "DEVICE_STATE(Custom:mystate)=INUSE") in new stack
*CLI> sip show subscriptions
172.16.10.12 6003 1800900375-6060 1234@users InUse dialog-info+xml <none> 000300

Как мы можем видеть состояние изменилось на InUse и кнопка на моем телефоне покраснела.

Теперь вызовем set_not_inuse и снова посмотрим:

 -- Executing [set_not_inuse@devstate_test:1] Set("SIP/6003-00000f74", "DEVICE_STATE(Custom:mystate)=NOT_INUSE") in new stack
*CLI> sip show subscriptions
172.16.10.12 6003 1800900375-6060 1234@users Idle dialog-info+xml <none> 000300

Как мы видим состояние изменилось на Idle и кнопка на моем телефоне позеленела обратно.

Механизм работает, а значит пора приступать ко второй части — передачу состояния на другой сервер. Главное тут две вещи:

  • осознать как это должно работать
  • наладить канал поставки и импорта/экспорта состояний

Как это должно работать ? По такой схеме:

AMI <-> «Брокер» сервер А <-> «Брокер» сервер Б <-> AMI

Словами это можно представить так:

  • в AMI сервера А происходит событие изменения состояние exten
  • программный клиент, который подключен к AMI сервера А и слушает такие события передает их «Брокеру» сервера A
  • «Брокер» сервера A пересылает сообщения на «Брокер» сервера Б
  • «Брокер» сервера Б передает их программному клиенту, который в свою очередь подключен к AMI сервера Б
  • в AMI сервера Б исполняется команда

Соответственно в обратную сторону от сервера Б к серверу А все тоже самое.

Для экспорта состояния мы слушаем события в AMI, пример такого события:

Event: ExtensionStatus
Privilege: call,all
Exten: 1234
Context: devstate_test
Hint: Custom:inuse
Status: 0

Для импорта состояния в AMI мы выполняем команду Setvar:

Action: Setvar
Variable: DEVICE_STATE(Custom:ВАШ_EXTEN)
Value: ЗНАЧЕНИЕ

Где «ВАШ_EXTEN» это номер который мы мониторим, а «Значение» это состояние (inuse, not_inuse или иное).

В моем случае у меня Asterisk 1.8 и потому для меня есть несколько НО:

  • у него в AMI нет «Event DeviceStateChange«, у него есть «Event ExtensionStatus«, так же отсутствует presence state (оно появилось начиная с Asterisk 11)
  • «Event ExtensionStatus» приходит только по тому номеру НА который звонят, а по тому КТО звонит ничего нет, но это решаемо, решаемо через «Event Newstate«

После того как вы доставили сообщение к AMI сервера, вам остается сделать контекст, в котором и выполнять hint`ы для таких экстеншенов.

В виду того что символ @ в названии exten не стоит использовать, т.к. у парсера Asterisk`а сносит крышу от этого когда в строке появляется две @ 
Потому я  для себя (пока или на совсем не знаю) выбрал такой формат: НОМЕР*DNS_ИМЯ_СЕРВЕРА

[externalStates]
exten => _XXX*[a-z].,hint,Custom:${EXTEN}
exten => _XXX*[a-z].,1,NoOp(Call to ${CUT(EXTEN,*,1)} on ${CUT(EXTEN,*,2)})

После чего мы можем инклюднуть этот контекст туда где живет ваш же телефон и в настройках вашего телефона настроить BLF на подписку на exten НОМЕР*my.domain.ru.

И вуаля. При вызове НОМЕР на сервере Б, ваш телефон который подключен к серверу А теперь видит, что состояние НОМЕР изменилось и моргает вам лампочкой 🙂

Как я уже писал выше в кач-ве «брокера» я у себя использовал Websocket.

Таким образом задача была решена и с тех пор все работает как часы и без надстроек в виде XMPP.

З.Ы. При копировании статьи ссылка на источник ОБЯЗАТЕЛЬНА ! Уважайте чужой труд.

Автор: Николаев Дмитрий (virus (at) subnets.ru)

Ничего не понялТак себе...Не плохоДовольно интересноОтлично ! То что нужно ! (Еще не голосовали)
Загрузка...
Отправить на почту Отправить на почту