Эту проблему сложно решить.При исходящих вызовах 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, и все готово!