Skip to the content.

Глава 17. AMI и файлы вызовов

Джон Малкович: я видел мир, который не должен видеть ни один человек! Крейг Шварц: Правда? Потому что для большинства людей это довольно приятный опыт. – Быть Джоном Малковичем

Интерфейс Asterisk Manager (Asterisk Manager Interface - AMI) - это интерфейс мониторинга и управления системой, предоставляемый Asterisk. Он позволяет в реальном времени отслеживать события, происходящие в системе, а также позволяет запрашивать Asterisk выполнение некоторых действий. Доступные действия имеют широкий диапазон и включают такие вещи, как возврат информации о состоянии или инициирование новых вызовов. На Asterisk было разработано много интересных приложений, использующих AMI в качестве основного интерфейса для Asterisk.

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

Файлы вызовов

Обычно для инициализации вызовов используется AMI, но во многих ситуациях проще использовать файлы вызовов. Файл вызова - это простой текстовый файл, описывающий вызов, который вы хотите совершить через Asterisk. Когда файл вызова помещается в каталог /var/spool/asterisk/outgoing, Asterisk немедленно обнаружит, что файл был помещен туда, и обработает вызов.

Asterisk поставляется с образцом файла вызова, который вы найдете в ~/src/asterisk-15.<TAB>/sample.call (или там, где находится корневой каталог исходников Asterisk).

Ваш первый файл вызова

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

Создайте в домашнем каталоге следующий файл:

$ vim ~/call-file

Channel: PJSIP/SOFTPHONE_A
Extension: 103
Context: sets

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

$ cp ~/call-file docall

Измените владельца файла docall на asterisk:

$ chown asterisk:asterisk docall

Переместите файл docall в каталог outgoing Asterisk.

$ sudo mv docall /var/spool/asterisk/outgoing

Иногда самый простой способ - лучший способ.

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

$ cp ~/call-file docall \
sudo chown asterisk:asterisk docall \
sudo mv docall /var/spool/asterisk/outgoing/

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

Предупреждение

Использование mv вместо cp здесь важно. Asterisk следит за тем, чтобы содержимое отображалось в каталоге spool. Если вы используете копирование - Asterisk может попытаться прочитать новый файл до того, как содержимое будет скопировано в него. Создание файла, а затем его перемещение позволяет избежать этой проблемы.

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

Заметки о файлах вызова

Компонент Channel файла вызова является обязательным. Обычно вызов, поступающий в Asterisk, инициируется конечной точкой (например, вы делаете вызов со своего телефона). В файле вызова это соединение должно происходить наоборот - Asterisk обращается к конечной точке, и только когда она отвечает, вызов может начаться. Планируйте соответственно.

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

Расширение, конечно, также должно быть указано. Обычно это номер телефона, по которому нужно позвонить, но, конечно, это может быть любой допустимый добавочный номер в Context.

Остальные параметры файла вызова являются необязательными и подробно описаны в файле ~/src/asterisk-15.<TAB>/sample.call и на веб-сайте Asterisk wiki.

AMI Быстрый старт

Этот раздел предназначен для того, чтобы как можно быстрее испачкать руки с помощью AMI. Во-первых, поместите следующую конфигурацию в /etc/asterisk/manager.conf:

; Включить AMI и указать ему принимать соединения только от localhost.
[general]
enabled = yes
webenabled = yes
bindaddr = 127.0.0.1

; Создайть аккаунт с именем "hello" и паролем "world"
[hello]
secret=world
read=all     ; Получать все типы событий
write=all    ; Разрешить этому пользователю выполнять все действия

Примечание

Этот пример конфигурации настроен так, чтобы разрешить только локальные подключения к AMI. Если вы собираетесь сделать этот интерфейс доступным по сети, настоятельно рекомендуется использовать только протокол TLS. Использование TLS более подробно рассматривается далее в этой главе.

Как только конфигурация AMI готова, включите встроенный HTTP-сервер, поместив следующее содержимое в /etc/asterisk/http.conf:

; Включить встроенный HTTP-сервер и слушайть только соединения на localhost.
[general]
enabled = yes
bindaddr = 127.0.0.1

Перезагрузите диспетчер и http-серверы из Asterisk CLI:

*CLI> manager reload

*CLI> module reload http

AMI через TCP

Существует несколько способов подключения к AMI, но наиболее распространенным является TCP-сокет. Мы будем использовать telnet для демонстрации подключения AMI. Для этого нам нужно будет установить telnet:

$ sudo yum -y install telnet

В этом примере показаны следующие шаги:

Вот как это сделать с помощью telnet:

$ telnet localhost 5038

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Asterisk Call Manager/4.0.3

Вы подключились, но он будет висеть на вас, если вы не подтвердите свою подлинность. Вставьте в окно telnet следующее:

Action: Login
Username: hello
Secret: world

Обратите внимание, что после команд должна быть пустая строка (нажмите Enter после вставки всего, если ничего не происходит).

Response: Success
Message: Authentication accepted

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

Action: Ping
Response: Success
Ping: Pong

Все идет нормально. Мы просто уберемся и выйдем сейчас.

Action: Logoff
Response: Goodbye
Message: Thanks for all the fish.
Connection closed by foreign host.

Вы убедились что AMI принимает соединения через TCP-соединение.

AMI через HTTP

Также можно использовать AMI через HTTP. Мы будем выполнять те же действия что и раньше, но через HTTP вместо собственного TCP-интерфейса к AMI. АMI через HTTP подробно описаны в “AMI через HTTP”.

Примечание

Учетные записи, используемые для подключения к AMI через HTTP, являются теми же учетными записями, настроенными в файле /etc/asterisk/manager.conf.

В этом примере показано, как получить доступ к AMI по протоколу HTTP, войти в систему, выполнить действие Ping и выйти из системы:

$ curl "http://localhost:8088/rawman?action=login&username=hello&secret=world" \
-c /tmp/tempcookie

Response: Success
Message: Authentication accepted
$ curl "http://localhost:8088/rawman?action=ping" -b /tmp/tempcookie

Response: Success
Ping: Pong
Timestamp: 1538871944.474131
$ curl "http://localhost:8088/rawman?action=logoff" -b /tmp/tempcookie

Response: Goodbye
Message: Thanks for all the fish.

Интерфейс HTTP для AMI позволяет интегрировать управление вызовами Asterisk в веб-службу.

Конфигурация

Раздел “AMI быстрый старт” показал очень простой набор конфигурационных файлов для начала работы. Существует много способов тонкой настройки конфигурации AMI.

manager.conf

Основной конфигурационный файл для AMI - это /etc/asterisk/manager.conf. Раздел [general] содержит параметры, управляющие общей работой AMI. Любые другие разделы в manager.conf определяют учетные записи для входа в систему и использования AMI. Пример файла содержит подробные объяснения различных параметров и может быть найден в ~/src/asterisk-15<TAB>/configs/samples/manager.conf.sample.

Предупреждение

Если вы собираетесь выставить свой AMI за пределы машины, на которой он работает, вам потребуется настроить подключение TLS.

Конфигурационный файл manager.conf также содержит конфигурацию учетных записей пользователей AMI. Вы создаете учетную запись, добавляя раздел с именем пользователя в квадратных скобках. В каждом разделе [username] есть параметры, которые могут быть установлены, которые будут применяться только к этой учетной записи. Файл ~/src/asterisk-15<TAB>/configs/samples/manager.conf.sample также содержит подробные объяснения каждого из этих параметров. Наш пользователь по имени [hello], имеет простейшую конфигурацию, которая позволяет все операции чтения и записи. Обычно следует создавать пользователей AMI, которые ограничены только действиями, необходимыми для их функционирования.

В разделе [username] параметры read и write определяют к каким действиям и событиям диспетчера имеет доступ конкретный пользователь. На данный момент есть 20 из них: all, system, call, log, verbose, agent, user, config, command, dtmf, reporting, cdr, dialplan, originate, agi, cc, aoc, test, security и message. Вы увидите что файл manager.conf.sample содержит ссылку на каждый из них, относящийся к вашему выпуску (и, если какие-либо из них добавлены, которые не были перечислены здесь, они будут в файле примера).

Предупреждение

Обратите особое внимание на разрешения system, command и originate. Эти разрешения предоставляют значительные полномочия всем приложениям, которые имеют право их использовать. Предоставляйте эти разрешения только приложениям, над которыми у вас есть полный контроль (и в идеале они работают в одном окне).

http.conf

Как мы уже видели, интерфейс Asterisk Manager может быть доступен как по протоколу HTTP, так и по протоколу TCP. Для этого в Asterisk встроен очень простой HTTP-сервер. Все параметры, относящиеся к AMI, находятся в разделе [general] файла /etc/asterisk/http.conf.

Примечание

Включение доступа к AMI по протоколу HTTP требует наличия /etc/asterisk/manager.conf и /etc/asterisk/http.conf. AMI должен быть включен в manager.conf с параметром enabled, установленным в yes и webenabled должен быть установлен в значение yes чтобы разрешить доступ по протоколу HTTP. Наконец, опция enabled в http.conf должна быть установлена в yes чтобы включить сам HTTP-сервер.

Доступные опции будут найдены в вашем файле ~/src/asterisk-15<TAB>/configs/samples/http.conf.sample.

Обзор протокола

В AMI есть два основных типа сообщений: события диспетчера и действия диспетчера.

События диспетчера - это односторонние сообщения, посылаемые Asterisk клиентам AMI для сообщения о том, что произошло в системе (Рисунок 17-1).

Рисунок 17-1. События диспетчера

Рисунок 17-1. События диспетчера

Действия диспетчера - это запросы от клиента к Asterisk для выполнения некоторого действия и возврата результата (Рисунок 17-2). Например, действие AMI инициирует запросы, чтобы Asterisk создал новый вызов, и, естественно, клиентскому приложению потребуются ответы от Asterisk, чтобы указать ход выполнения этого действия.

Рисунок 17-2. Действия диспетчера

Рисунок 17-2. Действия диспетчера

Другие действия менеджера - это запросы данных. Например, есть действие - получить список всех активных каналов в системе: сведения о каждом канале доставляются как событие. Когда список результатов будет завершен, будет отправлено окончательное сообщение о том, что цель достигнута. См. Рисунок 17-3 для графического представления клиента, отправляющего этот тип управляющего действия и получающего список ответов.

Рисунок 17-3. Действия диспетчера возвращающие список данных

Рисунок 17-3. Действия диспетчера возвращающие список данных

Кодировка сообщений

Все сообщения AMI, включая события, действия и ответы на действия, кодируются одинаково. Сообщения являются текстовыми, со строками, заканчивающимися возвратом каретки и символом перевода строки. Сообщение завершается пустой строкой:

Header1: This is the first header<CR><LF>
Header2: This is the second header<CR><LF>
Header3: This is the last header of this message<CR><LF>
<CR><LF>

Если вы запускаете тесты из telnet-клиента - это означает, что после последней строки инструкций вам нужно будет дважды нажать клавишу Enter.

События

События всегда имеют заголовок Event и заголовок Privilege. В заголовке Event указывается имя события, а в заголовке Privilege - уровни разрешений, связанные с данным событием. Любые другие заголовки, включенные в событие, являются специфичными для данного типа события. Вот вам пример:

Event: Hangup
Privilege: call,all
Channel: SIP/0004F2060EB4-00000000
Uniqueid: 1283174108.0
CallerIDNum: 2565551212
CallerIDName: Russell Bryant
Cause: 16
Cause-txt: Normal Clearing

CLI Asterisk включает в себя manager show events и manager show event <event>. Выполните эти команды в CLI Asterisk, чтобы получить список событий или узнать подробности конкретного события.

Не забывайте, что отличным справочником для всех вещей Asterisk, включая AMI, является официальная Asterisk wiki.

Действия

При выполнении действия необходимо включить заголовок Action. Заголовок Action определяет, какое действие выполняется. Остальные заголовки являются аргументами для действия и могут потребоваться или не потребоваться в зависимости от действия.

Чтобы получить список заголовков, связанных с определенным действием, введите в CLI Asterisk команду manager show command <Action>. Чтобы получить полный список действий, поддерживаемых используемой версией Asterisk, введите manager show commands.

Окончательный ответ на действие обычно представляет собой сообщение, содержащее заголовок Response. Значение заголовка Response будет Success, если действие было выполнено успешно. Если действие не было успешно выполнено, то значение заголовка ответа будет Error. Например:

Action: Login
Username: hello
Secret: world

Response: Success
Message: Authentication accepted

AMI через HTTP

Помимо собственного TCP-интерфейса, можно также получить доступ к AMI по протоколу HTTP. Программисты с имеющимся опытом написания приложений, использующие веб-API, скорее всего предпочтут его по сравнению с подключением TCP. В то время как интерфейс TCP предлагает только один тип структуры сообщений, AMI через HTTP предлагает несколько вариантов кодирования. Вы можете получать ответы в том же формате что и в TCP, в формате XML или в виде базовой HTML-страницы. Тип кодировки выбирается на основе поля в URL запросе. Варианты кодирования рассматриваются более подробно далее в этом разделе.

Аутентификация и обработка сессии

Существует два метода выполнения аутентификации против AMI через HTTP. Первый - это использование действия Login, аналогичного аутентификации с помощью собственного интерфейса TCP. Это метод, который использовался в Примере быстрого запуска, как показано в AMI через HTTP.

После успешной аутентификации Asterisk предоставит файл cookie, который идентифицирует аутентифицированный сеанс. Вот пример ответа на действие Login, которое включает в себя файл cookie сеанса от Asterisk:

$ curl -v "http://localhost:8088/rawman?action=login&username=hello&secret=world"

Второй вариант аутентификации - это HTTP-дайджест аутентификации. В этом примере запрошенный тип кодировки, основанный на URL-запросе, является rawman. Чтобы указать, что следует использовать дайджест аутентификацию HTTP, префикс типа кодировки в URL-адресе запроса должен содержать a:

$ curl -v --digest -u hello:world http://127.0.0.1:8088/arawman?action=ping

Кодирование /rawman (/arawman)

Тип кодирования rawman - это то, что до сих пор использовалось во всех примерах AMI через HTTP в этой главе. Ответы, полученные от запросов, использующих rawman, форматируются точно так же, как они были бы, если бы запросы были отправлены по прямому TCP-соединению к AMI.

curl -v "http://localhost:8088/rawman?action=login&username=hello&secret=world"

curl -v --digest -u hello:world http://127.0.0.1:8088/arawman?action=ping

Кодирование /manager (/amanager)

Тип кодировки manager предоставляет ответ в простой HTML-форме. Этот интерфейс в первую очередь полезен для экспериментов с AMI:

$ curl -v "http://localhost:8088/manager?action=login&username=hello&secret=world"

$ curl -v --digest -u hello:world http://localhost:8088/amanager?action=ping

Кодирование /mxml (/amxml)

Тип кодировки mxml предоставляет ответы на действия закодированные в XML:

$ curl -v "http://localhost:8088/mxml?action=login&username=hello&secret=world"

$ curl -v --digest -u hello:world http://localhost:8088/amxml?action=ping

События диспетчера

При подключении к собственному интерфейсу TCP для AMI события доставляются асинхронно. При использовании AMI через HTTP необходимо получить события путем опроса для них. Вы получаете события по протоколу HTTP, выполняя действие WaitEvent. В следующем примере показано, как события могут быть извлечены с помощью действия WaitEvent. Шаги такие:

  1. Запустите сеанс HTTP AMI с помощью действия Login.
  2. Зарегистрируйте SIP-телефон на Asterisk, чтобы создать событие.
  3. Извлеките событие с помощью действия WaitEvent.

Взаимодействие выглядит следующим образом:

$ wget --save-cookies cookies.txt \
> "http://localhost:8088/mxml?action=login&username=hello&secret=world" -O -

<ajax-response>
<response type='object' id='unknown'>
    <generic response='Success' message='Authentication accepted' />
</response>
</ajax-response>


$ wget --load-cookies cookies.txt \
< "http://localhost:8088/mxml?action=waitevent" -O -

<ajax-response>
<response type='object' id='unknown'>
    <generic response='Success' message='Waiting for Event completed.' />
</response>
<response type='object' id='unknown'>
    <generic event='PeerStatus' privilege='system,all'
             channeltype='SIP' peer='SIP/0000FFFF0004'
             peerstatus='Registered' address='172.16.0.160:5060' />
</response>
<response type='object' id='unknown'>
    <generic event='WaitEventComplete' />
</response>
</ajax-response>

Вам потребуется разработать механизмы в вашем приложении чтобы гарантировать что буферизованные события часто опрашиваются.

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

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

Инициирование вызова

AMI имеет действие Originate, которое можно использовать для инициирования вызова. Многие из принятых заголовков совпадают с параметрами, размещенными в файлах вызовов. В Таблице 17-1 перечислены заголовки, принятые действием Originate.

Таблица 17-1. Заголовки для действия Originate

Параметр Пример значения Описание
ActionID a3a58876-f7c9-4c28-aa97-50d8166f658d Этот заголовок принимается большинством действий AMI. Он используется для предоставления уникального идентификатора, который также будет включен во все ответы на действие. Это дает вам возможность определить с каким запросом связан ответ. Он важен, так как все действия, их ответы и события передаются по одному и тому же соединению (если только не используется AMI через HTTP).
Channel SIP/myphone Этот заголовок является критическим и обязательно должен быть указан. Он описывает исходящий вызов, который будет инициирован. Значение имеет тот же синтаксис, что и аргумент канала для приложения Dial() в диалплане.
Context default Этот заголовок используется для указания положения в диалплане, которое будет запущено после ответа на исходящий вызов. Заголовки Context, Exten и Priority должны быть использованы вместе. При использовании этих заголовков не следует использовать заголовки Application и Data.
Exten s Смотри документацию по заголовку Context.
Priority 1 Смотри документацию по заголовку Context.
Application ConfBridge Заголовки Application и Data можно использовать вместо заголовков Context, Exten и Priority. В этом случае исходящий вызов напрямую соединяется с одним приложением после ответа на вызов.
Data 500 Смотри документацию по заголовку Application.
Timeout 30000 Этот заголовок определяет, как долго (в миллисекундах) ждать ответа, прежде чем отказаться от исходящего вызова. Значение по умолчанию - 30000 миллисекунд (30 секунд).
CallerID Matthew Jordan <(555) 867-5309> Этот заголовок можно использовать для указания идентификатора вызывающего абонента, используемого для исходящего вызова.
Account someaccount Этот заголовок задает код учетной записи CDR для исходящего вызова.
Variable VARIABLE=VALUE или FUNCTION(arguments)=VALUE Заголовок Variable может использоваться для задания как переменных канала, так и функций канала на исходящем канале. Его можно задать несколько раз.
Codecs ulaw,alaw Этот параметр можно использовать для ограничения количества кодеков, разрешенных для исходящего вызова. Если этот параметр не указан, то набор кодеков, настроенных в файле конфигурации драйвера канала, будет по-прежнему учитываться.
EarlyMedia true Если этот заголовок указан и установлен в true, исходящий вызов будет подключен к указанному добавочному номеру или приложению, как только появится какой-либо медиапоток.
Async true Если этот заголовок задан и имеет значение true, то этот вызов будет инициирован асинхронно. Это позволит вам продолжить выполнение других действий на AMI-соединении во время обработки вызова.

Самый простой пример использования действия Originate через telnet:

$ telnet localhost 5038

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Asterisk Call Manager/4.0.3

Как только соединение установлено Вам необходимо войти в систему.

Action: Login
Username: hello
Secret: world
Response: Success
Message: Authentication accepted

Теперь вы готовы инициировать свой звонок. Мы делаем практически то же самое что и с файлом вызова, только на этот раз с помощью AMI:

Action: Originate
Channel: PJSIP/SOFTPHONE_A
Context: sets
Exten: 103
Priority: 1

Вы должны услышать звонок SOFTPHONE_A. Как только вы ответите на него, вызов будет сделан на SOFTPHONE_B.

AMI больше не участвует в том что происходит. Вы можете отключиться, и вызов будет продолжен (оставьте его в данный момент, так как мы собираемся работать с текущим вызовом далее).

Action: Logoff
Response: Goodbye
Message: Thanks for all the fish.
Connection closed by foreign host.

Если вы уже повесили трубку - это не проблема. Вам просто нужно будет восстановить вызов, что, конечно же, вы можете сделать, просто позвонив по одному номеру с другого (101-103 или как пожелаете).

Перенаправление вызова

Перенаправление (или transferring - передача) вызова из AMI - еще одна функция, заслуживающая упоминания. Действие AMI Redirect можно использовать для отправки одного или двух каналов на любой другой модуль в диалплане Asterisk. Если вам нужно перенаправить два канала, которые соединены вместе, сделайте это с обоими одновременно. В противном случае, как только один канал будет перенаправлен, другой будет отключен.

Важно понимать, что каналы Asterisk не существуют до тех пор, пока не будет выполнен вызов. Имя, которое мы все считаем именем канала (например, SOFTPHONE_A), на самом деле не является именем канала, а просто ссылкой на данные, которые используются для создания канала. Присвоение имени каналу происходит при возникновении вызова (то есть, когда канал фактически создан). Все это означает, что вы должны определить полное название канала, прежде чем сможете действовать на нем.

Инициируйте вызов, а затем просмотрите Event: Newchannel, и вы увидите имя канала под заголовком Channel:.

Action: Originate
Channel: PJSIP/SOFTPHONE_A
Context: sets
Exten: 103
Priority: 1
Response: Success
Message: Originate successfully queued
Event: Newchannel
Privilege: call,all
Channel: PJSIP/SOFTPHONE_A-00000013
ChannelState: 0
ChannelStateDesc: Down
CallerIDNum: 
CallerIDName: 
ConnectedLineNum: 
ConnectedLineName: 
Language: en
AccountCode:
Context: sets
Exten: s
Priority: 1
Uniqueid: 1538939479.29
Linkedid: 1538939479.29
</pre></code></p>

Событие Newchannel предоставит имя созданного канала, которое в данном примере является PJSIP/SOFTPHONE_A-00000013.

Вам нужно будет отслеживать эти имена каналов, если хотите правильно выполнять действия по текущим вызовам. Как только вызов заканчивается, канал уничтожается. Новому вызову, использующему ту же конечную точку, будет присвоено другое имя канала. Одно определение канала может поддерживать несколько вызовов (например, возможны несколько вызовов на телефон), и именно поэтому имя канала отличается от определения канала.

</td> </tr> </table> Вы можете перенаправить один канал (другой будет отключен): ``` Action: Redirect Channel: PJSIP/SOFTPHONE_A-00000013 Exten: 209 Context: sets Priority: 1 ``` Или можете перенаправить два канала: ``` Action: Redirect Channel: PJSIP/SOFTPHONE_A-00000015 Context: sets Exten: 209 Priority: 1 ExtraChannel: PJSIP/SOFTPHONE_B-00000016 ExtraContext: sets ExtraExten: 209 ExtraPriority: 1 ``` Функция перенаправления позволяет создавать мощные внешние приложения, которые могут управлять текущими вызовами. ## Разработка фреймворков Многие разработчики приложений пишут код, который напрямую взаимодействует с AMI. Однако существует ряд фреймворков, которые были созданы с целью облегчить разработку приложений AMI. Если вы ищете фреймворки Asterisk на популярном языке программирования по вашему выбору, вы, скорее всего, найдете один. На вас лежит ответственность за определение пригодности структуры, в которой вы заинтересованы. Некоторые вещи, которые вы должны искать в рамках включают в себя: **Зрелость** Этот проект существует уже несколько лет? Зрелый проект гораздо менее вероятно будет иметь серьезные ошибки в нем. **Поддержка** Проверьте возраст последнего обновления. Если проект не обновлялся в течение пяти лет - есть большая вероятность, что он был заброшен. Возможно, он еще пригодится, но вы будете предоставлены сами себе. Аналогично, как выглядит баг-трекер? Есть ли много важных ошибок, которые игнорируются? (Будьте проницательны здесь, так как часто реалии поддержки свободного проекта требуют дисциплинированной сортировки - не все функции будут добавлены.) **Качество кода** Это хорошо написанная структура? Если он не был хорошо спроектирован, вы должны знать об этом, когда решаете, стоит ли доверять ему свой проект. **Сообщество** Есть ли активное сообщество разработчиков, использующих этот проект? Вероятно, вам понадобится помощь; будет ли она доступна, когда вы в ней будете нуждаться? **Документация** Код должен быть хорошо прокомментирован, но в идеале необходима вики или другая официальная документация для поддержки библиотеки. В Таблице 17-2 перечислены некоторые структуры, которые, как мы обнаружили, на момент написания данной статьи соответствовали предыдущим критериям. Там могут быть и другие. _Таблица 17-2. Разработка фреймворков AMI_ | Фреймворк | Язык | | :--- | :--- | | Adhearsion | Ruby | | StarPy | Python | | Asterisk-Java | Java | | AsterNET | .NET | | ami-io | Node.js | | panoramisk | Python | ## Вывод AMI предоставляет API для мониторинга событий из системы Asterisk, а также запрашивает Asterisk выполнять широкий спектр действий. Был предоставлен интерфейс HTTP, и был разработан ряд фреймворков, которые облегчают разработку приложений. [Глава 16. Введение в интерактивное голосовое меню](/Definitive-Guide-5th-Edition/glava-16.html) | [Содержание](SUMMARY.md) | [Глава 18. AGI](/Definitive-Guide-5th-Edition/glava-18.html)