Интеграция AmoCRM и сервера телефонии на базе Asterisk

Интеграция Asterisk с Amocrm
Итак, наш отдел продаж пересел на очередную CRM. На этот раз выбор пал на AmoCRM.

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

На сайте Amocrm можно активировать виджет для интеграции с Asterisk. В его настройках есть ссылка на инструкцию и на скрипт для взаимодействия через API обеих систем.

Некоторые важные моменты в инструкции отсутствуют, поэтому я решил описать свой процесс настройки взаимодействия этих двух систем.

Итак, имеем: сервер IP телефонии на Ubuntu с настроенным Asterisk 11.7.0 (для более новых версий нужно внести изменения в скрипт) без веб-интерфейса и Интернет-шлюз на базе той же Ubuntu c внешним IP адресом. Внешние звонки у меня записываются и отображаются в настроенном Asterisk CDR Viewer Mod. Сами записи разговоров располагаются в папке /var/mp3/.

Нам нужно:
  1. Проверить настройки Asterisk и включить поддержку AJAM2
  2. Настроить web-сервер и опубликовать скрипт amocrm.php. Получить SSL сертификат и настроить https доступ к скрипту через внешний адрес sip.mysite.ru (для сотрудников работающих вне офиса).
  3. Перенастроить локальный DNS сервер для чтобы внутри нашей локальной сети запросы к адресу sip.mysite.ru перенаправлялись на локальный IP сервера с Астериском.
  4. На Интернет-шлюзе пробросить 443 порт на сервер с астером.
  5. Внести изменения в диалплан и amocrm.php


Включаем в астериске AJAM2 и проверяем работу

Открываем файл /etc/asterisk/manager.conf и добавляем секцию amocrm с такми содержанием:
[amocrm]
secret = your-password-is-here
deny = 0.0.0.0/0.0.0.0
permit = 127.0.0.1/255.255.255.0
read = cdr,reporting,originate
write = reporting,originate
Далее публикуем ajam интерфейс. Добавляем или редактируем секцию general в файле /etc/asterisk/http.conf
[general]
enabled=yes
enablestatic=yes
bindaddr=0.0.0.0
bindport=8088
prefix=asterisk
После чего открываем консоль астериска: asterisk -Rvvv
Перезапускаем астер и проверяем настройки:
core restart now 
http show status
на что получаем примерно следующее:
HTTP Server Status:
Prefix: /asterisk
Server Enabled and Bound to 0.0.0.0:8088

Enabled URI's:
/asterisk/httpstatus => Asterisk HTTP General Status
/asterisk/phoneprov/... => Asterisk HTTP Phone Provisioning Tool
/asterisk/amanager => HTML Manager Event Interface w/Digest authentication
/asterisk/arawman => Raw HTTP Manager Event Interface w/Digest authentication
/asterisk/manager => HTML Manager Event Interface
/asterisk/rawman => Raw HTTP Manager Event Interface
/asterisk/static/... => Asterisk HTTP Static Delivery
/asterisk/amxml => XML Manager Event Interface w/Digest authentication
/asterisk/mxml => XML Manager Event Interface
/asterisk/ws => Asterisk HTTP WebSocket

Enabled Redirects:
  None.
Далее открываем в браузере на ссылку типа http://asterisk-ip-adress:8088/asterisk/rawman?action=login&username=amocrm&secret=your-password-is-here

На что получаем следующий ответ:
Response: Success
Message: Authentication accepted
Если что-то не сработало, проверяйте еще раз все подробно.


Настраиваем web-сервер и вносим изменения в amocrm.php

Web-сервер у меня уже настроен т.к ранее был настроен Asterisk CDR Viewer, но в случае отсутствия можно установить LAMP (Linux-Apache-MySQL-PHP) простой командой:
sudo apt-get install lamp-server^
В процессе установки вводим пароль для mysql. Трудностей там нет.

Нам понадобится зарегистрированное доменное имя и SSL сертификат. Я создал поддомен на сайте своей организации: sip.mysite.ru и направил его на внешний адрес ЦОДа с сервером телефонии. Далее нам нужно получить SSL сертификат, это можно сделать бесплатно на сайте startssl.com, инструкций как это сделать полно. Файлы с сертификатами можно поместить, например, в папку /etc/apache2/ssl/

Создаем каталог /var/www/amocrm/ и копируем туда файл amocrm.php (скаченный по ссылке в начале статьи) и настраиваем апач:
Создаем хост. Не забываем внести свои поправки.
nano /etc/apache2/sites-available/sip.mysite.ru.ssl.conf

<IfModule mod_ssl.c>
        <VirtualHost sip.mysite.ru:443>
                ServerAdmin admin@mysite.ru
                ServerName sip.mysite.ru

                DocumentRoot /var/www/amocrm

                ErrorLog ${APACHE_LOG_DIR}/error.log
                TransferLog ${APACHE_LOG_DIR}/access_log
                CustomLog ${APACHE_LOG_DIR}/access.log combined

                SSLEngine on
                SSLProtocol all -SSLv2 -SSLv3
                SSLCipherSuite ALL:!DH:!EXPORT:!RC4:+HIGH:+MEDIUM:!LOW:!aNULL:!eNULL

                SSLCertificateChainFile /etc/apache2/ssl/1_root_bundle.crt
                SSLCertificateFile      /etc/apache2/ssl/2_sip.mysite.ru.crt
                SSLCertificateKeyFile /etc/apache2/ssl/ssl.key


                <FilesMatch "\.(cgi|shtml|phtml|php)$">
                                SSLOptions +StdEnvVars
                </FilesMatch>
                <Directory /usr/lib/cgi-bin>
                                SSLOptions +StdEnvVars
                </Directory>

                BrowserMatch "MSIE [2-6]" \
                                nokeepalive ssl-unclean-shutdown \
                                downgrade-1.0 force-response-1.0
                BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown

        </VirtualHost>
</IfModule>
Далее включаем модуль SSL в апаче, активируем созданный хост и заодно устанавим JSON:
a2enmod ssl
a2ensite sip.mysite.ru.ssl.conf
apt-get install php5-json
Кстати, чтобы не вводить каждый раз пароль на SSL сертификат при перезапуске апача, можно дешифровать ключ командой
openssl rsa -in ssl.key -out ssl.key
То же самое можно сделать на сайте startssl.com. В панели управления перейти в Tool Box, затем воспользоваться опцией Decrypt Private Key, далее ввести пароль и выбрать свой файл, на выходе получим расшифрованный сертификат. Не забудьте выставить права на файл (chmod 400, владелец root).
Если же вы хотите оставить пароль, можно создать простой скрипт и поместить его в а конец файла /etc/apache2/apache2.conf
nano /etc/apache2/echo
#!/bin/sh
/bin/echo тут_пароль
Делаем скрипт исполняемым:
chmod +x /etc/apache2/echo
добавляем в конец etc/apache2/apache2.conf следующую строчку:
SSLPassPhraseDialog exec:/etc/apache2/echo
Перезапустим апач:
service apache2 restart
Последний штрих, нам нужно, чтобы папка с записями звонков была также доступна через Интернет. Для этого я просто создал символическую ссылку:
ln -s /var/mp3 /var/www/amocrm/mp3
Не забываем о безопасности. При открытии ссылки https://sip.mysite.ru/mp3/ недоброжелатель получает список всех звонков. К тому же не лишним будет ограничить доступ к звонкам своей локальной подсетью. Создадим файл .htaccess в папке /var/mp3/ со следующим содержанием:
Order Deny,Allow
Deny from all
Allow from 192.168.1.
IndexIgnore * 
Чтобы директивы из .htaccess заработали, нужно включить использование этого файла в директории /var/www. Для этого в файле /etc/apache2/apache2.conf находим секцию
<Directory /var/www/> и меняем значение  AllowOverride None на AllowOverride All. У меня получилось так:
<Directory /var/www/>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
</Directory>
Далее перезапускаем apache:
service apache2 restart

Последний штрих. Проверим доступность скрипта:
https://sip.mysite.ru/amocrm.php?_login=amocrm&_secret=your-password-is-here&_action=status

Так как sip.mysite.ru ведет на внешний адрес шлюза моей сети, то из локально сети имя не доступно, поэтому пока вместо него введем локальный адрес астериска: 192.168.1.2. Для доступности из своей сети придется перенастроить локальный DNS сервер на шлюзе.


Перенаправление DNS запросов на локальный адрес.


В качестве DNS сервера я использую BIND, соответственно, настраиваю на своем примере.
Добавляем зону для домена третьего уровня в файл /etc/bind/named.conf.local
zone "sip.mysite.ru" {
        type master;
        file "/var/lib/bind/sip.mysite.ru";
};
Далее создаем файл с описанием новой зоны
nano /var/lib/bind/sip.mysite.ru 
со следующим содержанием:
$ORIGIN .
$TTL 86400      ; 1 day
sip.mysite.ru                IN SOA  gate.mysite.local. admin.mysite.local. (
                                20147503   ; serial
                                10800      ; refresh (3 hours)
                                3600       ; retry (1 hour)
                                604800     ; expire (1 week)
                                86400      ; minimum (1 day)
                                )
                        NS      gate.mysite.local.
$TTL 86400      ; 1 day
 A       192.168.1.2
Некоторые пояснения: у меня локальный домен называется mysite.local, а адрес сервера телефонии 192.168.1.2
Далее проверяем все ли правильно сконфигурировали:
named-checkconf -z
Если ошибок нет, перезапускаем BIND и проверяем перенаправление:
service bind9 restart
nslookup sip.mysite.ru
Результат должен получиться примерно такой:
nslookup sip.mysite.ru
Server:         192.168.1.1
Address:        192.168.1.1#53
Name:   sip.mysite.ru
Address: 192.168.1.2
Если что-то не сработало, проверяйте и изучайте BIND, вот ссылка на список команд:

Настраиваем проброс 443 порта на шлюзе на сервер с Asterisk


На шлюзе у меня используется iptables, порты пробросить просто. В переменной EXTIF у меня имя внешнего сетевого интерфейса:
iptables -A PREROUTING -t nat -i ${EXTIF} -p tcp --dport 443 -j DNAT --to-destination 192.168.1.2:443
iptables -A FORWARD -p tcp -d 192.168.1.2 --dport 443 -j ACCEPT


Корректировка диалплана астериска и скрипта amocrm.php 


Открываем диалплан и добавляем туда примерно следующее, меняя по своей ситуации:
nano /etc/asterisk/extensions.conf
; пример установки callerID, полученного от amocrm
[cidlookup]
include => cidlookupcustom
exten => cidlookup_2,1,Set(CURLOPT(httptimeout)=7)
exten =>
cidlookup_2,n,Set(CALLERID(name)=${CURL(https://<account>.amocrm.ru/private/acceptors/asterisk_new/?number=${CALLERID(number)}&USER_LOGIN=<login>&USER_HASH=<hash>)})
exten => cidlookup_2,n,Return()
exten => cidlookup_return,1,ExecIf($["${DB(cidname/${CALLERID(num)})}" !=
""]?Set(CALLERID(name)=${DB(cidname/${CALLERID(num)})}))
exten => cidlookup_return,n,Return()
Редактирование диалплана не так существенно, должно работать и без этого.

Теперь откорректируем файл /var/www/amocrm/amocrm.php
Сначала вносим изменения в начало файла:
ini_set('display_errors',0);
define('AC_HOST','localhost');
define('AC_PORT',8088);
define('AC_PREFIX','/asterisk/');
define('AC_TLS',false);
define('AC_DB_CS','mysql:host=localhost;port=3306;dbname=voip');
define('AC_DB_UNAME','mysql-user');
define('AC_DB_UPASS','mysql-password');
define('AC_TIMEOUT',0.75);
define('AC_RECORD_PATH','https://sip.mysite.ru/mp3/#');
/* define('AC_RECORD_PATH','https://sip.mysite.ru/mp3/%Y/%m/%d/#'); */
define('AC_TIME_DELTA',6); // hours. Ex. GMT+4 = 4
Вписываем туда имя и пароль для доступа к MySQL, указываем внешний адрес и меняем часовой пояс.
У меня контекст для исходящих звонков отдела продаж называется sales. Для того, чтобы продажники совершали исходящие звонки именно через него, я нашел и изменил значение контекста вот так:
'Context'=>'sale'
Возможно я что-то упустил, т.к. писал по памяти. Есть есть вопросы или уточнения - пишите в комментариях :)

2 комментария:

  1. все отлично, ни чего не пропустил

    ОтветитьУдалить
    Ответы
    1. Думаю, сегодня эта инструкция уже не актуальна. У AmoCRM изменился механизм работы с астериском, да и версия * 11.7 сейчас редко у кого еще используется.

      Удалить