Дмитрий Рашевский
18.10.2019
6453

Библиотека ARI-PY для разработки модулей на PYTHON использующих подключение по ARI

Введение Установка библиотеки Методы библиотеки Пример использования Введение При интеграции Asterisk с различными системами возникают нестандартные решения и стандартные модули не всегда помогают. Для этого обычно разрабатываются дополнительные модули/коннекторы. Эти программы обычно «мониторят» состояние астериска, его каналов, управление звонками и т. д. Каждый в праве сам выбирать каким языком программирования пользоваться. Данная статья написана для разработчиков […]

  1. Введение
  2. Установка библиотеки
  3. Методы библиотеки
  4. Пример использования

Введение

При интеграции Asterisk с различными системами возникают нестандартные решения и стандартные модули не всегда помогают. Для этого обычно разрабатываются дополнительные модули/коннекторы. Эти программы обычно «мониторят» состояние астериска, его каналов, управление звонками и т. д. Каждый в праве сам выбирать каким языком программирования пользоваться.

Данная статья написана для разработчиков использующих язык программирования Python. И здесь будет описана библиотека ari-py. Эта библиотека используется как прослойка для подключения к Астериск через ARI.

Установка библиотеки

В данном разделе рассмотрим установку библиотеки на Centos 6.

Данная библиотека работает только с версией Python 2.7. Разработчик собирается добавить поддержку Python 3.

Итак, для установки библиотеки перейдем в директорию исходников командой cd и скачаем с github исходники командой.

git clone
cd /usr/src   git clone   https://github.com/asterisk/ari-py.git ari
cd /usr/src   git clone   https://github.com/asterisk/ari-py.git ari    

Теперь перейдем в скаченную директорию ari и выполним установку библиотеки командой

./setup.py install
cd ari/   ./setup.py install   

Во время установки также скачиваются и устанавливаются дополнительные библиотеки:

  • certifi — используется для проверки подлинности SSL-сертификатов
  • requests —  необходима для отправки HTTP запросов и получения ответов.
  • urllib3 — библиотека используемая как HTTP клиент

Ниже приведен список всех библиотек и их версий необходимых для работы ari-py.

certifi==2019.9.11
chardet==3.0.4
idna==2.8
requests==2.22.0
six==1.12.0
swaggerpy==0.2.1
urllib3==1.25.6
websocket-client==0.56.0

Методы библиотеки

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

Для создания экземпляра класса используется метод connect. Параметрами этого метода является адрес подключения, логин AMI, пароль AMI.

import ari # подключение модуля
ari_connection = ari.connect(‘http://127.0.0.0:8088/’, ‘admin’, ‘amp111’) #создание экземпляра класса

В свою очередь созданный экземпляр класса имеет несколько методов:

  • close
  • run
  • on_event
  • on_object_event
  • on_channel_event
  • on_bridge_event
  • on_playback_event
  • on_live_recording_event
  • on_stored_recording_event
  • on_endpoint_event
  • on_device_state_event

Рассмотрим подробнее каждый метод:

  • close  — Метод, не принимающий никаких значений, закрывает ARI соединение.
ari_connection.close()
  • run – подключается к web сокету и начинает обработку передаваемых сообщений, принимает 1 параметр — название ARI приложения. Типы передаваемых параметров STRING/LIST
ari_connection.run(apps='hello')
  • on_event – метод отслеживающий указанное в параметре событие и выполняющий определенные действия. Принимает 2 параметра: event_type (строковое значение названия отслеживаемого события) и event_cb (имя функции, в которой будет описаны необходимые вам действия).
def on_dtmf(channel, event): 
           digit = event['digit']
           if digit == '#':
                 channel.play(media='sound:goodbye')
                 channel.continueInDialplan()
           elif digit == '*':
                  channel.play(media='sound:asterisk-friend')
           else:
                  channel.play(media='sound:digits/%s' % digit)
def on_start(channel, event):
    channel.on_event('ChannelDtmfReceived', on_dtmf) 

Пример использования события on_event описаной в функции on_start. Данный пример отслеживает каналы, на которых происходит событие digit , то по нажатию определенных клавиш воспроизводится файл goodbye при нажатии #, при нажатой *  — asterisk-friend, при нажатых цифрах воспроизводит нажатые цифры.

  • on_object_event — принимает четыре параметра: event_type, event_cd, factory_fn, model_id. И отслеживает события указанные в параметре event_type, event_cb –  имя функции, в которой будут описаны необходимые вам действия. factory_fn – функция создающая объект из JSON.
   ari_connection.on_object_event('StasisStart',   self.noop, self.noop, 'Bridge')   
  • on_channel_event — “триггер” отслеживания события, указанного в параметре event_type с необходимыми правилами, записанными в передаваемой функции fn.
   ari_connection.on_channel_event('NewExten', on_needed_event)   
  • on_bridge_event — “триггер” отслеживания события на «бридже», указанного в параметре event_type с необходимыми правилами, записанными в передаваемой функции fn.
  • on_playback_event — Используется при воспроизведении аудио файла и отслеживает имя события переданного в параметре event_type и выполняет записанные правила в передаваемой функции fn.
  • on_live_recording_event — Используется при начале записи аудио файла и отслеживает имя события переданного в параметре event_type и выполняет записанные правила в передаваемой функции fn.
  • on_stored_recording_event — Используется при окончании записи аудио файла и отслеживает имя события переданного в параметре event_type и выполняет записанные правила в передаваемой функции fn.
  • on_device_state_event — Используется при изменении состояния устройства и отслеживает имя события переданного в параметре event_type и выполняет записанные правила в передаваемой функции fn.

Пример использования

В данном разделе разберем пример использования библиотеки ari-py.

Первым примером будет использование originate.

import requests
import ari
from requests import HTTPError

OUTGOING_ENDPOINT = "SIP/trunk"

ari_connection = ari.connect('http://localhost:8088/', 'admin', 'amp111')


bridges = [
                  b for b in client.bridges.list()
                  if b.json['bridge_type'] == 'holding']



if bridges:
    holding_bridge = bridges[0]
else:
    holding_bridge = client.bridges.create(type='holding')

def safe_hangup(channel):
      try:
            channel.hangup()
      except HTTPError as e:
             if e.response.status_code != requests.codes.not_found:
                 raise 

def on_start(incoming, event):
      if event['args'] != ['incoming']:
          return
      incoming.answer()
      incoming.play(media="sound:wait-call")
      holding_bridge.addChannel(channel=incoming.id)

      # Совершение Originate
      outgoing = client.channels.originate(
                         endpoint=OUTGOING_ENDPOINT, app="hello", appArgs="dialed")
      
      incoming.on_event('StasisEnd', lambda *args: safe_hangup(outgoing))

      outgoing.on_event('ChannelDestroyed', lambda *args: safe_hangup(incoming))

       def outgoing_on_start(channel, event):
             bridge = client.bridges.create(type='mixing')
             outgoing.answer()
             bridge.addChannel(channel=[incoming.id, outgoing.id])
             outgoing.on_event('StasisEnd', lambda *args: bridge.destroy())

       outgoing.on_event('StasisStart', outgoing_on_start)


ari_connection.on_channel_event('StasisStart', on_start)

ari_connection.run(apps="Originate")

Теперь подробнее разберем описанный выше пример.

Для начала занесем в переменную ari_connection данные подключения к ARI известным нам ранее методом  ari.connect. Далее в список b занесем значения имен бриджей с типом holding.

Ниже создаем функцию, safe_hangup. Она будет использоваться ниже, она нам необходима для разрыва канала. Разрываем канал, игнорируя 404 ошибки.

Далее создаем обработчик on_start. Когда появляется входящий канал, добавляет его в  holding_bridge

incoming.answer()
incoming.play(media="sound:pls-wait-connect-call") holding_bridge.addChannel(channel=incoming.id)

и вызывает новый канал

outgoing = client.channels.originate(
                   endpoint=OUTGOING_ENDPOINT, app="hello", appArgs="dialed") 

и соединяет с имеющимся.

В момент, когда вторичный канал отвечает объединяет в бридж оба канала.

bridge = client.bridges.create(type='mixing') outgoing.answer() bridge.addChannel(channel=[incoming.id, outgoing.id]) 
Подписаться
Уведомление о
guest
0 Комментарий
Inline Feedbacks
View all comments

Остались вопросы?

Я - Компаниец Никита, менеджер компании Voxlink. Хотите уточнить детали или готовы оставить заявку? Укажите номер телефона, я перезвоню в течение 3-х секунд.

VoIP оборудование

ближайшие курсы

ближайшие Вебинары

ONLINE

10 доводов в пользу Asterisk

Распространяется бесплатно.

Asterisk – программное обеспечение с открытым исходным кодом, распространяется по лицензии GPL. Следовательно, установив один раз Asterisk вам не придется дополнительно платить за новых абонентов, подключение новых транков, расширение функционала и прочие лицензии. Это приближает стоимость владения станцией к нулю.

Безопасен в использовании.

Любое программное обеспечение может стать объектом интереса злоумышленников, в том числе телефонная станция. Однако, сам Asterisk, а также операционная система, на которой он работает, дают множество инструментов защиты от любых атак. При грамотной настройке безопасности у злоумышленников нет никаких шансов попасть на станцию.

Надежен в эксплуатации.

Время работы серверов некоторых наших клиентов исчисляется годами. Это значит, что Asterisk работает несколько лет, ему не требуются никакие перезагрузки или принудительные отключения. А еще это говорит о том, что в районе отличная ситуация с электроэнергией, но это уже не заслуга Asterisk.

Гибкий в настройке.

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

Имеет огромный функционал.

Во многом именно Asterisk показал какой должна быть современная телефонная станция. За многие годы развития функциональность Asterisk расширилась, а все основные возможности по-прежнему доступны бесплатно сразу после установки.

Интегрируется с любыми системами.

То, что Asterisk не умеет сам, он позволяет реализовать за счет интеграции. Это могут быть интеграции с коммерческими телефонными станциями, CRM, ERP системами, биллингом, сервисами колл-трекинга, колл-бэка и модулями статистики и аналитики.

Позволяет телефонизировать офис за считанные часы.

В нашей практике были проекты, реализованные за один рабочий день. Это значит, что утром к нам обращался клиент, а уже через несколько часов он пользовался новой IP-АТС. Безусловно, такая скорость редкость, ведь АТС – инструмент зарабатывания денег для многих компаний и спешка во внедрении не уместна. Но в случае острой необходимости Asterisk готов к быстрому старту.

Отличная масштабируемость.

Очень утомительно постоянно возвращаться к одному и тому же вопросу. Такое часто бывает в случае некачественного исполнения работ или выбора заведомо неподходящего бизнес-решения. С Asterisk точно не будет такой проблемы! Телефонная станция, построенная на Asterisk может быть масштабируема до немыслимых размеров. Главное – правильно подобрать оборудование.

Повышает управляемость бизнеса.

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

Снижает расходы на связь.

Связь между внутренними абонентами IP-АТС бесплатна всегда, независимо от их географического расположения. Также к Asterisk можно подключить любых операторов телефонии, в том числе GSM сим-карты и настроить маршрутизацию вызовов по наиболее выгодному тарифу. Всё это позволяет экономить с первых минут пользования станцией.