Процедура tel1_МаршрутизироватьВызовМанго(call_id, ВнутреннийНомер, НаименованиеКонтакта = "") Экспорт
СоответствиеЗаголовки = Новый Соответствие;
СоответствиеЗаголовки.Вставить("From/display-name", НаименованиеКонтакта);
Соответствие = Новый Соответствие;
Соответствие.Вставить("command_id", Строка(Новый УникальныйИдентификатор));
Соответствие.Вставить("call_id", call_id);
Соответствие.Вставить("to_number", ВнутреннийНомер);
Если НЕ ПустаяСтрока(НаименованиеКонтакта) Тогда
Соответствие.Вставить("sip_headers", СоответствиеЗаголовки);
КонецЕсли;
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, Соответствие);
json = ЗаписьJSON.Закрыть();
НастройкиТелефонии = ПолучитьНастройкиТелефонии();
sign = ПолучитьSign(НастройкиТелефонии.vpbx_api_key, json, НастройкиТелефонии.vpbx_api_salt);
ПараметрыТела = Новый Массив;
ПараметрыТела.Добавить("vpbx_api_key=" + НастройкиТелефонии.vpbx_api_key);
ПараметрыТела.Добавить("sign=" + sign);
ПараметрыТела.Добавить(КодироватьСтроку("json=" + json, СпособКодированияСтроки.URLВКодировкеURL));
URL = КорневойАдресАТС() + "commands/route";
СтруктураURI = ОбщегоНазначенияКлиентСервер.СтруктураURI(URL);
HTTPЗапрос = Новый HTTPЗапрос();
HTTPЗапрос.АдресРесурса = СтруктураURI.ПутьНаСервере;
HTTPЗапрос.Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded");
HTTPЗапрос.УстановитьТелоИзСтроки(СтрСоединить(ПараметрыТела, "&"),
КодировкаТекста.UTF8,
ИспользованиеByteOrderMark.НеИспользовать);
Прокси = ПолучениеФайловИзИнтернета.ПолучитьПрокси(СтруктураURI.Схема);
HTTPСоединение = Новый HTTPСоединение(СтруктураURI.Хост, СтруктураURI.Порт,,, Прокси, 20, Новый ЗащищенноеСоединениеOpenSSL);
HTTPОтвет = HTTPСоединение.ВызватьHTTPМетод("POST", HTTPЗапрос);
ЗаписьЖурналаРегистрации(
ТелефонияПереопределяемый.СобытиеЖурналаРегистрации() + "./commands/route",
УровеньЖурналаРегистрации.Примечание,,,
json + Символы.ПС + НСтр("ru='Код состояния HTTP ответа: '") + HTTPОтвет.КодСостояния + Символы.ПС + HTTPОтвет.ПолучитьтелоКакСтроку());
КонецПроцедуры
Процедура ОбработатьВходящийЗвонокIVR(ДанныеЗвонка, call_id) Экспорт
ДанныеКлиента = ТелефонияСервер.ПолучитьДанныеКлиента(ДанныеЗвонка.НомерКонтакта);
Если ДанныеКлиента <> Неопределено Тогда
Если Не ПустаяСтрока(ДанныеКлиента.ВнутреннийНомерОтветственного) Тогда
ТелефонияСервер.tel1_МаршрутизироватьВызовМанго(call_id, ДанныеКлиента.ВнутреннийНомерОтветственного, ДанныеКлиента.Представление);
КонецЕсли
КонецЕсли;
КонецПроцедуры
//--
Процедура ЖдатьНаСервереВФоновомЗадании(Знач Таймаут) Экспорт
Ключ = Строка(Новый УникальныйИдентификатор());
Наименование = "Фоновое ожидание";
МассивПараметров = Новый Массив;
МассивПараметров.Добавить(Таймаут);
МассивПараметров.Добавить(Ключ);
МассивПараметров.Добавить(Наименование);
ФЗ = ФоновыеЗадания.Выполнить("ТелефонияСервер.ЖдатьЗавершенияФонового", МассивПараметров, Ключ, Наименование);
ФЗ.ОжидатьЗавершения();
КонецПроцедуры
Процедура ЖдатьЗавершенияФонового(Таймаут,Ключ,Наименование) Экспорт
Попытка
ФоновыеЗадания.ПолучитьФоновыеЗадания(Новый Структура("Наименование,Ключ", Наименование, Ключ))[0].ОжидатьЗавершения(Таймаут);
Исключение
КонецПопытки;
КонецПроцедуры
//--
Функция mangoEventsCallPOST(Запрос) Экспорт
ИмяСобытияДляЖурналаРегистрации = "/events/call";
Если Не ПолучитьФункциональнуюОпцию("ИспользоватьОблачнуюТелефонию") Тогда
Возврат СообщениеОбОшибке(
500,
ИмяСобытияДляЖурналаРегистрации,
НСтр("ru='Использование телефонии Манго отключено в настройках'"));
КонецЕсли;
ТелоЗапроса = РаскодироватьСтроку(Запрос.ПолучитьТелоКакСтроку(), СпособКодированияСтроки.КодировкаURL);
ТелефонияПереопределяемый.ЗаписатьЗапросВЖурналРегистрации(ИмяСобытияДляЖурналаРегистрации, ТелоЗапроса);
ПараметрыТела = СтроковыеФункцииКлиентСервер.ПараметрыИзСтроки(ТелоЗапроса, "&");
УстановитьПривилегированныйРежим(Истина);
Если Не ТелефонияСервер.КорректнаяПодписьЗапроса(Перечисления.ДоступныеАТС.MangoOffice, ПараметрыТела.sign, ПараметрыТела) Тогда
Возврат СообщениеОбОшибке(
400,
ИмяСобытияДляЖурналаРегистрации,
СтрШаблон(НСтр("ru='Неверно указана подпись запроса sign=%1'"), ПараметрыТела.sign));
КонецЕсли;
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(ПараметрыТела.json);
МассивИмен = Новый Массив;
МассивИмен.Добавить("timestamp");
ПараметрыЗапроса = ПрочитатьJSON(ЧтениеJSON,,,,"ВосстановлениеJSON",ТелефонияСервер,,МассивИмен);
ЧтениеJSON.Закрыть();
ОбязательныеПараметры = Новый Массив;
ОбязательныеПараметры.Добавить("entry_id");
ОбязательныеПараметры.Добавить("call_id");
ОбязательныеПараметры.Добавить("timestamp");
ОбязательныеПараметры.Добавить("seq");
ОбязательныеПараметры.Добавить("call_state");
ОбязательныеПараметры.Добавить("location");
ОбязательныеПараметры.Добавить("to");
ОбязательныеПараметры.Добавить("from");
Для Каждого ОбязательныйПараметр Из ОбязательныеПараметры Цикл
Если Не ПараметрыЗапроса.Свойство(ОбязательныйПараметр) Тогда
Возврат СообщениеОбОшибке(
400,
ИмяСобытияДляЖурналаРегистрации,
СтрШаблон(НСтр("ru='Отсутствует обязательный параметр %1.'"), ОбязательныйПараметр));
КонецЕсли;
КонецЦикла;
Попытка
Если НРег(ПараметрыЗапроса.location) = "abonent" Тогда
Если ПараметрыЗапроса.call_state = "Appeared" Тогда
Если ПараметрыЗапроса.from.Свойство("extension") И ПараметрыЗапроса.to.Свойство("number") Тогда
ДанныеЗвонка = ТелефонияСервер.НовыйДанныеЗвонка();
ДанныеЗвонка.ИдентификаторЗвонкаВАТС = ПараметрыЗапроса.entry_id;
ДанныеЗвонка.НомерКонтакта = ПараметрыЗапроса.to.number;
ДанныеЗвонка.Пользователь.ВнутреннийНомер = ПараметрыЗапроса.from.extension;
ДанныеЗвонка.ДатаНачалаЗвонка = ПараметрыЗапроса.timestamp;
ТелефонияСервер.ОбработатьИсходящийЗвонок(ДанныеЗвонка);
ИначеЕсли ПараметрыЗапроса.from.Свойство("number") И ПараметрыЗапроса.to.Свойство("extension")
И НЕ ПараметрыЗапроса.Свойство("command_id") Тогда
ДанныеЗвонка = ТелефонияСервер.НовыйДанныеЗвонка();
ДанныеЗвонка.ИдентификаторЗвонкаВАТС = ПараметрыЗапроса.entry_id;
ДанныеЗвонка.НомерКонтакта = ПараметрыЗапроса.from.number;
ДанныеЗвонка.Пользователь.ВнутреннийНомер = ПараметрыЗапроса.to.extension;
ДанныеЗвонка.ДатаНачалаЗвонка = ПараметрыЗапроса.timestamp;
Если ПараметрыЗапроса.to.Свойство("line_number") Тогда
ДанныеЗвонка.НомерОрганизации = ПараметрыЗапроса.to.line_number;
КонецЕсли;
ТелефонияСервер.ОбработатьВходящийЗвонок(ДанныеЗвонка, Истина);
КонецЕсли;
// переадресация на группу если на звонок не ответил пользователь
Если ПараметрыЗапроса.from.Свойство("taken_from_call_id")
И НЕ ПараметрыЗапроса.to.Свойство("acd_group")
Тогда
ТелефонияСервер.ЖдатьНаСервереВФоновомЗадании(20);
НастройкиТелефонии = ТелефонияСервер.ПолучитьНастройкиТелефонии();
Если НастройкиТелефонии.МаршрутизироватьВходящиеНаОтветственных Тогда
ТелефонияСервер.tel1_МаршрутизироватьВызовМанго(ПараметрыЗапроса.call_id, "100");
КонецЕсли;
КонецЕсли;
ИначеЕсли ПараметрыЗапроса.call_state = "Connected" Тогда
Если ПараметрыЗапроса.to.Свойство("extension") Тогда
Пользователь = ПараметрыЗапроса.to.extension;
ИначеЕсли ПараметрыЗапроса.from.Свойство("extension") Тогда
Пользователь = ПараметрыЗапроса.from.extension;
КонецЕсли;
ДанныеЗвонка = ТелефонияСервер.НовыйДанныеЗвонка();
ДанныеЗвонка.ИдентификаторЗвонкаВАТС = ПараметрыЗапроса.entry_id;
ДанныеЗвонка.Пользователь.ВнутреннийНомер = Пользователь;
ДанныеЗвонка.ДатаНачалаРазговора = ПараметрыЗапроса.timestamp;
ТелефонияСервер.ОбработатьИзменениеЗвонка(ДанныеЗвонка);
ИначеЕсли ПараметрыЗапроса.call_state = "Disconnected" Тогда
Пользователь = Неопределено;
Если ПараметрыЗапроса.to.Свойство("extension") Тогда
Пользователь = ПараметрыЗапроса.to.extension;
ИначеЕсли ПараметрыЗапроса.from.Свойство("extension") Тогда
Пользователь = ПараметрыЗапроса.from.extension;
КонецЕсли;
ДанныеЗвонка = ТелефонияСервер.НовыйДанныеЗвонка();
ДанныеЗвонка.ИдентификаторЗвонкаВАТС = ПараметрыЗапроса.entry_id;
ДанныеЗвонка.Пользователь.ВнутреннийНомер = Пользователь;
ДанныеЗвонка.ДатаЗавершенияРазговора = ПараметрыЗапроса.timestamp;
ДанныеЗвонка.ОпределятьНеотвеченный = Истина;
ТелефонияСервер.ОбработатьЗавершениеЗвонка(ДанныеЗвонка);
КонецЕсли;
ИначеЕсли НРег(ПараметрыЗапроса.location) = "ivr"
И ПараметрыЗапроса.call_state = "Appeared" Тогда
НастройкиТелефонии = ТелефонияСервер.ПолучитьНастройкиТелефонии();
Если НастройкиТелефонии.МаршрутизироватьВходящиеНаОтветственных Тогда
Если ПараметрыЗапроса.from.Свойство("number") Тогда
ДанныеЗвонка = ТелефонияСервер.НовыйДанныеЗвонка();
ДанныеЗвонка.ИдентификаторЗвонкаВАТС = ПараметрыЗапроса.entry_id;
ДанныеЗвонка.НомерКонтакта = ПараметрыЗапроса.from.number;
ДанныеЗвонка.ДатаНачалаЗвонка = ПараметрыЗапроса.timestamp;
ТелефонияСервер.ОбработатьВходящийЗвонокIVR(ДанныеЗвонка, ПараметрыЗапроса.call_id);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Исключение
Возврат СообщениеОбОшибке(
500,
ИмяСобытияДляЖурналаРегистрации,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
Ответ = Новый HTTPСервисОтвет(200);
Возврат Ответ;
КонецФункции
Функция СообщениеОбОшибке(КодСостояния, ВложенноеИмяСобытия, Комментарий = Неопределено, Заголовки = Неопределено)
ЗаписьЖурналаРегистрации(
ТелефонияПереопределяемый.СобытиеЖурналаРегистрации() + "." + ВложенноеИмяСобытия,
УровеньЖурналаРегистрации.Ошибка,,,
Комментарий);
Возврат НовыйHTTPСервисОтвет(КодСостояния, Заголовки);
КонецФункции
Функция НовыйHTTPСервисОтвет(КодСостояния, Заголовки = Неопределено)