Asterisk AmoCRM интеграция

На текущий момент работает:
– Входящие через Asterisk виден Менеджеру в AmoCRM (всплывает окно, видно в карточке клиента)
– Исходящий со страницы AmoCRM выполняется. (см. amocrm.php п.5)
– Записанные звонки проигрываются.
– CDR-загружаются в AmoCRM. (Загадочное место, не нашел внятных объяснений поставщика)

Настройка

Web сервер на Вашем хосте

К нему обращается AmoCRM, HTTPS на Web-сервере обязателен для AmoCRM!

Asterisk

/etc/asterisk/manager.conf

[general]
enabled = yes
port = 5038
bindaddr = 127.0.0.1 ; Нет смысла писать 0.0.0.0 если подключение локальное 
webenabled = yes ; НЕ ЗАБЫТЬ
httptimeout = 60 ;
debug = on; при необходимости

[amocrm]
secret = SECRET
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

Ваш extention для входящих звонков
Для работы потребуется USER_HASH из AmoCrm.
Берем его в AmoCrm: Settings -> Api (требуется расширенный пакет)

Пример с моей конфигурации, для Вашей потребуется адаптация

# ВХОДЯЩИЕ ЗВОНКИ 
[ukrtelecom-income]
exten => _0441234567,1,Noop()
 same => n,Set(CALLTYPE=in)
 ; Ищем имя звонящего по AmoCRM
 same => n,Set(CALLERID(name)=${SHELL(wget -O - --quiet "https://domain.amocrm.ru/private/acceptors/asterisk_new/?number=${CALLERID(num)}[email protected]&USER_HASH=555" | cut -d "|"
 ; звоним ответственному менеджеру
 same => n,Set(TOEXT=${SHELL(wget -O - --quiet "https://domain.amocrm.ru/private/acceptors/asterisk_new/?redirect=Y&number=${CALLERID(num)}[email protected]&USER_HASH=555")}).
 ; запись разговора
 same => n,Gosub(sub-mixmonitor,${EXTEN},1)
 same => n,Dial(SIP/${TOEXT},,tTr)
 same => n,HangUp()

Проверка настройки

Проверьте подключение к AMI

https://note.wdm.net.ua/asterisk-test-connection-to-ami-by-telnet/

Проверьте внешние запросы к Web-сервису на Вашем хосте

# Запрос 1:
https://asterisk.domain.com/amocrm.php?_login=amocrm&_secret=SECRET&_action=test_cdr
# Ответ:
asterisk_cb({"status":"ok","data":"connection ok"});
 
# Запрос 2:
https://asterisk.domain.com/blabla.php?_login=amocrmuser&_secret=SECRET&_action=status
# Ответ:
asterisk_cb({"status":"ok","action":"status","data":[]});
# Могут быть данные в массиве data

Решение проблем

amocrm.php
1. AmoCRM допускает ввести вот такой телефонный номер: +38050[440А99*30.
Исправим.

elseif ($action === 'call') {
//...
$to = strval($_GET['to']);
$to = preg_replace("/[^0-9]/", '', $to);

$params=array(
'action'=>'Originate',
'channel'=>'SIP/'.$from),
'Exten'=> $to,

2. Если у Пользователя не указан Внутренний номер в настройки Интеграции – AmoCRM не гнушается позвонить с него. Мы не будем передавать такие запросы в Asterisk.

elseif ($action === 'call') {
//...
        $from=intval($_GET['from']);

        // не передали значение from - не будем даже отдавать на Asterisk
        if ($from == 0) {
            answer(array('status'=>'error','data'=>array('message'=>'No From Number')));
        }

        $params=array(
                'action'=>'Originate',
                'channel'=>'SIP/'.$from,
                'Exten'=> $to,

3. Нужно указать свой CONTEXT

elseif ($action === 'call') {
//...
$params=array(
'action'=>'Originate',^M
'channel'=>'SIP/'.intval($_GET['from']),^M
'Exten'=>strval($_GET['to']),^M
'Context'=>'from-internal', .// ТУТ НАДО УКАЗАТЬ СВОЕ ЗНАЧЕНИЕ
'priority'=>'2',
'Callerid'=>'"'.strval($_GET['as']).'" <'.intval($_GET['from']).'>',
'Async'=>'Yes',

4.При отдаче CDR – скрипт корректирует время события, на установленную в начале файла ДЕЛЬТУ:

} elseif ($action==='cdr'){ // fetch call history
//...
foreach ($r as $k=>$v) $r[$k]['calldate']=date('Y-m-d H:i:s',strtotime($v['calldate'])-AC_TIME_DELTA*3600);
//...
}

5. Исходящие звонки в CDR
Суть проблемы:
Amocrm.php выгружает в CDR поля, SRC и DST. В SRC при выполнении звонка по внешнему SIP провайдера подставляется внешний городской номер, то есть запись выглядит вот так:

{"calldate":"2017-05-31 06:54:46","src":"0442901234","dst":"050123456","duration":"16","billsec":"16"

Предполагаю, что такую запись AmoCRM не может подтянуть, ибо номер ей не известен.
В нашей конфигурации Asterisk-а мы кладем в CDR реальный номер звонящего внутреннего абонента.
Немного подправив amocrm.php получим такой результат:

{"calldate":"2017-05-31 06:54:46","src":"999","dst":"050123456","duration":"16","billsec":"16"

Asterisk