Нужна помощь в получении Twilio X-Twilio-CallSid или X-Twilio-RecordingSid на исходящие звонки - PullRequest
0 голосов
/ 03 января 2019

Мы записываем вызовы вместе с записывающими Sid Twilio в базу данных, и поскольку Asterisk выставляет sip-заголовки Twilio только на план набора по запросу (в отличие от ответов), мы не можем получить заголовки X-Twilio-CallSid и X-Twilio-RecordingSid на дальнем конце канала.

При вызове, который был инициирован локальным добавочным номером Twilio и прерван исходящим добавочным номером, откуда сообщение BYE приходит от нас локально, все, что Asterisk когда-либо видит, это ответы SIP.

Может кто-нибудьпомочь сделать CallSid или RecordingSid доступными через план набора номера или PHP AGI-скрипт?

Мы пытались вставить подпрограмму gosub на вызываемом канале (дальний конец), что позволило нам получить доступ к переменным на этом канале, ноЗаголовки SIP доступны только от ПРИГЛАШЕНИЯ от Asterisk.Ни один из заголовков ответов Twilio не раскрывается.UNLESS Twilio отправляет запрос BYE, и в этом случае обработчик отбоя выставит CallSid и RecordingSid.Однако, если Asterisk вешает вызов, сообщение BYE, сгенерированное Asterisk, запускает обработчик отбоя до того, как требуемые заголовки ответа Twilio SIP будут получены звездочкой.

PHP AGI DialScript с подпрограммой gosub.

$agi->exec("Dial", "SIP/twilio-out/+1$call->dnid,180,rU(far-channel-hangup-hook,".$call->calllog_listid.")"); 

Настройка Dial-Plan (extensions.conf)

[far-channel-hangup-hook]
exten => s,1,Set(calllog_listid=${ARG1})
exten => s,n,Set(CHANNEL(hangup_handler_push)=far-channel-hangup,s,1)
exten => s,n,Return()

[far-channel-hangup]
exten => _.!,1,AGI(log_sid.php)
exten => _.!,n,Return()

Ответы [ 2 ]

0 голосов
/ 04 января 2019

Это можно сделать без изменения источника.

Для этого вы должны использовать действие iptables NLOG.

Как-то так

iptables -I INPUT -p udp --dport 5060 -m string --string "X-Twilio-" --algo bm -j NFLOG

После этого вам нужночитать по сценарию nflog, анализировать, сохранять где-то записи и перехватывать их.

tcpdump -i nflog -s0 -vvv -n|script here

Скрипт может сохранять результаты в memcached или mysql, используя callid в качестве ключа, после чего вы можете перехватить его в вашей схеме набора звездочек.

Не забудьте документ решения в вики вашего проекта.Мой опыт говорит, что такие изменения (особенно в источниках звездочек) легко пропустить при восстановлении из резервной копии.

0 голосов
/ 03 января 2019

Эту проблему сложно решить.При исходящих вызовах Twilio сначала предоставляет CallSid в ответе 200 OK на ваше первоначальное сообщение INVITE.Поскольку это всего лишь ответ, Asterisk не позволит вам получить доступ к заголовку SIP через SIP_HEADER ().

Вы правы: если Asterisk инициирует вызов, вы можете установить обработчик отбоя, который будет срабатывать при завершении вызова, и если Twilio отправит сообщение BYE, у вас будет полный доступ к "X-Заголовки Twilio "в вашем обработчике, но НЕ, если Asterisk завершает вызов своим собственным BYE.Тем не менее, если вы когда-нибудь в течение жизни диалога можете вывести Twilio-CallSid из Asterisk, вы можете использовать cURL в вашем обработчике зависания , чтобы получить дополнительную информацию о записанном вызове на основе CallSid.

Документация Twilio объясняет, что вы можете отправить HTTP-запрос GET с CallSid в их API-интерфейс для записей и получить информацию о записи.

curl -X GET -https://video.twilio.com/v1/Recordings/RMXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' -u ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:your_auth_token

В вашем PHPAGIкод, вы можете сделать что-то вроде этого:

    $recording_object = NULL;
    $accountsid = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
    $auth_token = "xxxxxxxxxxxxxxxxxxx"; // Your API access auth token
    $cidurl = "https://api.twilio.com/2010-04-01/Accounts/$accountsid/Calls/$CallSid/Recordings.json";
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $cidurl);
    curl_setopt($ch, CURLOPT_USERPWD, "$accountsid:$auth_token");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $retval = curl_exec($ch);
    $obj = json_decode($retval);
    curl_close($ch);
    if ($obj) {
        if (property_exists($obj, "recordings")) {
            $recording_object = $obj->recordings;
        }
    }

И вы сможете получить доступ к RecordingSid и RecordingDuration через:

    $recording_object->sid

и

    $recording_object->duration

(Если $ recording_object не равен NULL)

Теперь, чтобы на самом деле получить X-Twilio-CallSid ранее в вызове (диалог SIP), нужно еще больше хитрости.

Я всегда строюЗвездочка из источника.Это очень просто.Есть даже сценарии для установки зависимостей для вас на основе репозитория вашего Linux Distro.

Вот пример для CentOS .

Вот что я сделал срешить эту проблему.В настоящее время есть два драйвера SIP-канала, которые поставляются с Asterisk "chan_sip" и "chan_pjsip".Я использую chan_sip, более старый (зрелый, проверенный и верный) драйвер канала.Это работает хорошо.

Если вы загружаете исходный код для Asterisk и, прежде чем выполнить действия, описанные в руководстве, указанном выше, найдите файл "chan_sip.c".Обычно он находится в каталоге / channel

Редактировать файл.

Внутри файла есть функция с именем handle_response () .

/*! \brief Handle SIP response in dialogue
    \note only called by handle_incoming */
static void handle_response(struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, uint32_t seqno)

Поиск этой функции.

Внутри этой функции найдите первый оператор switch , а затем следуйте коду, где находится ваш «case 200».: "condition.

Это должно выглядеть примерно так:

    case 200:   /* 200 OK */ 
        p->authtries = 0;   /* Reset authentication counter */
        if (sipmethod == SIP_INVITE) {
            handle_response_invite(p, resp, rest, req, seqno);
        } else if (sipmethod == SIP_REGISTER) {
            handle_response_register(p, resp, rest, req, seqno);
        } else if (sipmethod == SIP_SUBSCRIBE) {
            ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
            handle_response_subscribe(p, resp, rest, req, seqno);
        } else if (sipmethod == SIP_BYE) {      /* Ok, we're ready to go */
            pvt_set_needdestroy(p, "received 200 response");
            ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
        }
        break;

Измените его следующим образом:

    case 200:   /* 200 OK */ 
        p->authtries = 0;   /* Reset authentication counter */
        if (sipmethod == SIP_INVITE) {
            const char *twilio_callsid = sip_get_header(req, "X-Twilio-CallSid");
            if (twilio_callsid) {
                ast_verb(1, "** Setting channel variable 'twiliocallsid' to '%s'\n", twilio_callsid);
                pbx_builtin_setvar_helper(owner, "twiliocallsid", twilio_callsid);
            }
            handle_response_invite(p, resp, rest, req, seqno);
        } else if (sipmethod == SIP_REGISTER) {
            handle_response_register(p, resp, rest, req, seqno);
        } else if (sipmethod == SIP_SUBSCRIBE) {
            ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
            handle_response_subscribe(p, resp, rest, req, seqno);
        } else if (sipmethod == SIP_BYE) {      /* Ok, we're ready to go */
            pvt_set_needdestroy(p, "received 200 response");
            ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
        }
        break;

Сохраните файл.Затем выполните шаги для сборки и установки Asterisk.

Теперь, как только Twilio ответит на INVITE и отправит 200 OK , который будет содержать X-Twilio-CallSid chan_sip установит егокак канальная переменная , называемая "twiliocallsid", и она будет доступна из абонентской группы ИЛИ вашего скрипта PHPAGI.Вы можете получить CallSid и использовать его в своем запросе cURL к Twilio, чтобы получить информацию о записи и сохранить ее на свое усмотрение.

Я не совсем уверен в этом, но если вы уже установили Asterisk, вы может по-прежнему сможет выключить его, перейти в каталог с исходным кодом и запустить "make install".Кто-то еще может внести свой вклад в это, но когда вы собираете и устанавливаете его из исходного кода, это все, что нужно.Вы можете изменить исходный код так, как вам нужно, и скомпилировать то, что было изменено, с помощью «make install».

Затем остановите, перезапустите Asterisk, и все готово!

...