В итоге решение проблемы нашлось не без везения — методом быстрого гугления наткнулись в GitHub на готовое решение от Жени Гостькова, который, дописав обработку изменившихся сообщений, «научил» работать Perl c Asterisk 16+. Как показала практика, в том числе и с 18 версией. Проблему решили.
2. Изменение некоторых событий и как следствие — наши скрипты не принимали и не знали, как работать с новыми событиями.
Изменились не только имена, но и наполнение событий. Взгляните на самый явный пример.
Это событие Bridge, 11 версия Asterisk:
Event: Bridge
Bridgestate: <value>
Bridgetype: <value>
Channel1: <value>
Channel2: <value>
Uniqueid1: <value>
Uniqueid2: <value>
CallerID1: <value>
CallerID2: <value>
И вот, что оно из себя представляет уже в 18 версии:
Event: BridgeEnter
BridgeUniqueid: <value>
BridgeType: <value>
BridgeTechnology: <value>
BridgeCreator: <value>
BridgeName: <value>
BridgeNumChannels: <value>
Channel: <value>
ChannelState: <value>
ChannelStateDesc: <value>
CallerIDNum: <value>
CallerIDName: <value>
ConnectedLineNum: <value>
ConnectedLineName: <value>
Language: <value>
AccountCode: <value>
Context: <value>
Exten: <value>
Priority: <value>
Uniqueid: <value>
Linkedid: <value>
SwapUniqueid: <value>
Кроме того, изменилось также и поведение некоторых событий. Если раньше событие Bridge вызывалось один раз на два канала одновременно, то теперь заменившее его событие BridgeEnter вызывается два раза за звонок и на каждый канал. Нам пришлось изучить все подобные изменившиеся события и переписать их обработку.
3. Приложение Queue.
Третья проблема состояла в том, что глубоко под капотом у нас используется приложение диалплана Queue, и оно между 11 и 18 версией также претерпело немало изменений. У нас нарушилась логика при переводе звонка между очередями нашего кол-центра: наши Asterisk перестали понимать, что звонок ушел из очереди. По всей видимости, ранее в приложении существовал баг, который служил нам ориентиром, сигнализирующим о том, что звонок покидает очередь. Возможно, с выходом новых версий баг был устранен, из-за чего этого ориентира мы лишились.
Мы посмотрели исходники приложения, решили, что не будем их править, а вместо этого реализуем логику при переводе звонка из одной очереди в другую на базе UserEvent, имена которых не зависят от версии Asterisk.
UserEvent — это приложение диалплана, которое позволяет создать кастомизированное AMI-событие с необходимыми нам параметрами, которые могут состоять, например, из текущих переменных канала.
Пример из диалплана:
[redirect]
exten => 1, Verbose (Перевод звонка)
.. .
.. .
same => n, UserEvent (Redirect, MemberFrom:\ ${MEMBER_FROM}, MemberTo:\ ${MEMBER_TO})
.. .
.. .
Как мы им воспользовались? Помимо приложения Queue, наш кол-центр реализован за счет диалплана и различных скриптов, что позволяет нам легко конфигурировать любой этап звонка. На примере перевода звонка: когда оператор совершает его, вызываем в диалплане соответствующий UserEvent, который отлавливается нашим слушателем AMI-сообщений и обрабатывается соответствующим скриптом. А в этом скрипте фиксируется статистика по разговору с текущим оператором и останавливается запись разговора с ним.