Говорят, лень - двигатель прогресса. Конечно, свою лень можно дисциплинировать до состояния «лень будет переделывать», но это уже попахивает автоматизацией. Автоматизация ведет к перфекционизму, когда все части механизма отлажены и работают как часы. А перфекционизм в свою очередь - к лишнему стрессу. Ведь если что-то и может сломаться, оно обязательно обвалится.
Что-то я немного увлекся с философией. Так вот, поговорим про лень и ошибки.
Бывала ли когда-то у вас ситуация, что вы набирали номер телефона и ошибались одной цифрой? Ну признавайтесь, было же. А бывало такое, что вам лень набирать номер каждый раз? А вот у руководителя наших менеджеров возник такой вопрос: как бы сделать так, чтобы человек не набирал каждый раз номер клиента, а звонок осуществлялся бы по одному клику.
Ну что же, давайте разбираться. В нашем распоряжении есть локальная АТС на Asterisk+Freepbx, золотые руки (вроде даже не из причинного места) и CRM система, в которой хранятся номера телефонов клиентов.
Для начала вспомним, что все удаленное управление Asterisk происходит через Asterisk AMI.
Asterisk AMI (Asterisk Manager Interface)
Это сетевой интерфейс, который позволяет разработчикам взаимодействовать с Asterisk, открытым IP PBX-системой. AMI обеспечивает управление и мониторинг системы в реальном времени через протокол TCP.
С помощью Asterisk AMI можно:
- Управлять звонками — запуск, завершение или передача звонков.
- Управлять пользователями — добавление, удаление или изменение статуса абонентов.
- Мониторить события - получение уведомлений о входящих/исходящих звонках.
Приступим к настройке нашего Asterisk.
Для начала, нам нужно установить плагин Asterisk AMI (если его нет) и включить. По умолчанию, AMI будет использовать порт tcp 5038, так что он должен быть открыт на фаерволле АТС.
Заходим через web на наш FreePBX в Settings -> Asterisk Manager Users и создаем учетную запись, через которую мы будем обращаться к нашей АТС
На данном этапе я предполагаю, что ваша АТС уже давно в работе, у вас настроены все маршруты и внутренние номера. Так что эту часть я пропущу.
Начинаем писать скрипт обращения к АТС
В работе мы будем использовать библиотеку asterisk-ami.
pip install asterisk-ami
- Импортируем из библиотеки модуль AMIClient и создаем подключение к АТС.
from asterisk.ami import AMIClient
client = AMIClient(address='192.168.1.170', port=5038, timeout=None)
client.login(username='Python_user', secret='strong_password')
Если все прошло успешно, то строка print(client) выдаст вам объект Ami client.
<asterisk.ami.client.AMIClient object at 0x73a5f4262a70>
- Для совершения какого-либо действия, нам понадобится модуль SimpleAction. Создадим объект звонка.
action = SimpleAction(
name='Originate',
Channel='SIP/101',
Exten='client_number',
Priority=1,
Context='ANY',
CallerID='Webcall',
)
call = client.send_action(action)
name - Обязательно 'Originate', так мы показываем Астериску, что мы хотим запустить звонок.
Channel - Номер, которому Астериск позвонит первым.
Exten - Номер, которому Астериск позвонит после того, как Channel поднимет трубку.
Context - Имя CustomContext, через который будет совершен звонок.
CallerID - Нужно для дальнейшей идентификации веб звонка, ни на что не влияет.
Важно: если в Channel, или Exten используется внутренний номер, он указывается в формате 'SIP/номер'
- Добавим немного больше логики: хотелось бы, чтобы при звонке использовался не случайный CustomContext, а тот, который привязан к Extension менеджера.
Для этого нам нужно отправить на Астериск команду 'SIPshowpeer'.
manager = 101
action = SimpleAction(
name='SIPshowpeer',
Peer=manager
)
ext = client.send_action(action)
context = ext.response.keys['Context']
На данном этапе мы уже можем вписывать номер менеджера и номер клиента, и совершать звонок.
Однако помним, мы должны получать эти номера от CRM. Договариваемся с программистами о том, что мы будем получать POST запрос и возвращать json объект о статусе звонка.
Подготавливаем среду для нашего веб звонка
- Устанавливаем nginx с cgi модулями.
- В /etc/nginx/conf.d создаем файл webcall.conf
server {
listen 80;
server_name example.com
location / {
gzip off;
root /var/www/webcalls;
fastcgi_pass unix:/var/run/fcgiwrap.socket;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME /var/www/webcalls$fastcgi_script_name;
}
}
- В папке /var/www создаем директорию webcalls и создаем в ней скрипт call.py
import cgi
form = cgi.FieldStorage()
internal_number = form.getvalue('manager')
client_number = form.getvalue('client')
Так мы ожидаем, что при обращении к нашему скрипту, передастся два параметра: manager и client.
Обращение должно быть по URL http://example.com/call.py?manager=[номер менеджера]&client=[номер клиента]
- В конец скрипта мы прописываем генерацию ответа нашего скрипта. Напомню, нам нужно отдавать json объект, так что импортируем в скрипт библиотеку json.
print("Content-type: application/json\n")
response = {'statusCode': status_code}
print(json.dumps(response))
- В нашем скрипте звонка добавляем проверку, был ли совершен звонок. Для этого после команды вызова звонка, добавляем получение его статуса.
call_status = call.response.status
if call_status == 'Success':
status_code = 1
else:
status_code = 0
- Собираем все это воедино и тестируем.
- Получаем похвалу от менеджеров, которым теперь достаточно кликнуть кнопку в CRM, и АТС сама позвонит и на их внутренний номер, и клиенту.