Интеграция PBX Asterisk и Битрикс24 с помощью Asterisk Manager Interface (AMI)
Я хотел бы поделиться своим опытом интеграции бизнес-системы Битрикс24 и телефонной АТС Asterisk через AMI.
Эта интеграция позволяет автоматизировать обработку входящих и исходящих звонков, управлять клиентской базой и контролировать активности сотрудников.
AMI (Asterisk Manager Interface) - это интерфейс управления, который позволяет управлять Asterisk через программный интерфейс. В нашем случае, мы используем AMI для получения событий звонков, например, входящие и исходящие звонки, статусы звонков, и т.д.
Одно из главных преимуществ интеграции через AMI - это возможность получения информации о звонках в реальном времени. Например, когда звонит клиент, наша система получает информацию о его номере и имени, и мы можем автоматически идентифицировать его в Битрикс24 и связать звонок с этим контактом.
Еще одно преимущество интеграции через AMI - это возможность управления звонками непосредственно из Битрикс24. Мы можем перенаправлять звонки на нужного сотрудника, записывать разговоры и прослушивать их в Битрикс24, а также создавать звонки прямо из системы CRM.
Для интеграции через AMI будем использовать библиотеку panoramisk на Python, которая облегчает работу с AMI. Эта библиотека позволяет подключаться к AMI и получать события в реальном времени без вмешательства в диалплан.
В примере рассмотрим процесс подключения к AMI и получения событий с помощью panoramisk и дальнейшую оптправку данных о входящем звонке в Битрикс24:
1. Первое, что нужно сделать - это подключиться к AMI интерфейсу, используя учетные данные из файла manager.cof (Asterisk)
import asyncio
import requests, json
from panoramisk import Manager
# Подключение AMI
manager = Manager(loop=asyncio.get_event_loop(),
host='ip', port=5038, ssl=False,
encoding='utf8',
username='username',
secret='secret')
2. Для хранения данных о звонках будем использвоать ассоциативный массив
# Ассоциативный массив
calls_data = {}
# Ассоциативный массив
calls_data = {}
3. Следующий блок кода регистрирует обработчик события "Newchannel" с помощью manager.register_event()
. Если входящий вызов был успешно установлен, обработчик получит событие и проверит, что вызов не является внутренним (Exten не равен 's') и что его контекст равен 'from-trunk'. Затем обработчик сохраняет информацию о вызове в словарь calls_data
с использованием уникального идентификатора Linkedid
в качестве ключа. Кроме того, он выводит информацию о вызове в консоль.
# Подписка на события Новый вызов
@manager.register_event('Newchannel')
def NewchannelEvent(manager, message):
# Обработка событий входящего вызова
if message.Context == 'from-trunk' and message.Exten != 's':
call_id = message.Linkedid
calls_data[call_id] = {"phone_number": message.CallerIDNum, 'bitrix_user_id': None}
print('Входящий: ', call_id, calls_data[call_id])
Так выглядит само событие "Newchannel" данные из которого мы получаем:
Event: Newchannel
Privilege: call,all
Channel: SIP/trunk Tele2-700XXXXXXXX
ChannelState: 0
ChannelStateDesc: Down
CallerIDNum: +77058645543 (Номер мой)
CallerIDName: +77058645543
ConnectedLineNum: <unknown>
ConnectedLineName: <unknown>
Language: en
AccountCode:
Context: from-trunk
Exten: +700XXXXXXXX
Priority: 1
Uniqueid: 1677040396.2789
Linkedid: 1677040396.2789
4. Следующий код отвечает за обработку события BridgeEnter, которое происходит, когда оператор ответил на звонок.
В функции BridgeEnter происходит проверка, является ли вызов входящим (если это исходящий звонок, то функция не будет выполнять никаких действий).
Затем функция обновляет информацию о звонке в словаре calls_data, добавляя в него информацию об внутреннем номере оператора, ищет в Битрикс24 id пользователя по этому номеру, регистрирует звонок в Битрикс24 и сохраняет id звонка в словаре calls_data.
Наконец, функция выводит сообщение в консоль о том, что оператор ответил на звонок и печатает информацию о звонке из словаря calls_data.
@manager.register_event('BridgeEnter')
def BridgeEnter(manager, message):
# Для входящих вызовов
call_id = message.Linkedid
if message.ChannelStateDesc == 'Up' and message.Context == 'macro-dial-one':
calls_data[call_id]["internal_number"] = message.CallerIDNum
calls_data[call_id]["bitrix_user_id"] = find_user_id(message.CallerIDNum)
calls_data[call_id]["bitrix_call_id"] = register_call(calls_data[call_id]["bitrix_user_id"], calls_data[call_id]["phone_number"], 2)
print('Оператор ответил: ', call_id, calls_data[call_id])
Получаем продолжительность звонка:
manager.register_event('Cdr')
def CdrEvent(manager, message):
call_id = message.UniqueID
calls_data[call_id]["duration"] = message.Duration
6. Этот код отправляет POST-запрос на указанный адрес bitrix_url + finish
, чтобы завершить звонок в Битрикс24. Для этого используются данные из словаря calls_data
для конкретного call_id
, в котором содержится информация о звонке, включая идентификатор вызова в Битрикс24 bitrix_call_id
, идентификатор пользователя bitrix_user_id
, продолжительность звонка duration
и статус STATUS_CODE
.
В качестве параметров для POST-запроса передаются ключ-значение в виде словаря finish_param
. После отправки запроса на сервер Битрикс24, результат возвращается в виде ответа response_finish
, который затем выводится на экран с помощью функции print()
.
# Завершение звонка звонка в битрикс
finish_param = {
'CALL_ID': calls_data[call_id]["bitrix_call_id"],
'USER_ID': calls_data[call_id]["bitrix_user_id"],
'DURATION': calls_data[call_id]["duration"],
'STATUS_CODE': '200'
}
response_finish = requests.post(bitrix_url + finish, finish_param)
print(f"Response from finish: {response_finish.json()}")
В данной статье рассмотрен только один сценарий - "успешный" входящий звонок. Так же нет функции отправки записи разговора на сервер Битрикс24. Но это всё будет, если есть интерес :)
Comments 0
Login to leave a comment