|
Помогите с запросом к api Mango office WinHttp.WinHttpRequest | ☑ | ||
---|---|---|---|---|
0
ILNIK19
30.08.17
✎
17:17
|
Добрый день.
Уже несколько дней бьюсь над проблемой. Нужно сделать запрос к api АТС Манго офис. Надо получить статистику по звонкам, для этого сделать первый запрос с требуемыми параметрами статистики, потом api возвращает ключ, и ты делаешь второй запрос с этим ключом, для получения данных. В принципе он срабатывает, но есть проблема. Когда в ключе есть символ "+", то при отправке он превращается в пробел. Т.е. я в отладке вижу, что отправляю ключ и в нем есть знак "+", а тех поддержка видит ,что в отсылаемом им ключе вместо "+" стоит пробел. Если ключ не содержит "Плюсов", то все срабатывает как надо, без ошибок. Т.е. запрос статистики срабатывает через раз ,если повезет и не будет в ключе плюса, то ок, иначе ошибка 401. {"name":"Unauthorized","message":"You are requesting with an invalid credential.","code":0,"status":401} В чем может быть дело? Пример запроса с плюсом: vpbx_api_key=УнКод&sign=sign&json={ "key": "dMSffJ+si2a/44IqQrN22ugkjW1IuSBXEf76rmmqSFyY5kGYr/pu/4fOJu+2zK7IJTqcdyiSgybRpXOeDJZnkg==" } Текст запроса данных: Ключ = ОтправитьЗапросНаСтатитистикуИПолучитьКлюч(); УнКод = "МойКод"; УнКлюч = "МойКлюч"; data = Новый Структура; data.Вставить("key", Ключ); ЗаписьJSON = Новый ЗаписьJSON(); ЗаписьJSON.УстановитьСтроку(); ЗаписатьJSON(ЗаписьJSON, data); СтрокаJson = ЗаписьJSON.Закрыть(); Хеширование = Новый ХешированиеДанных(ХешФункция.SHA256); Хеширование.Добавить(УнКод); // vpbx_api_key Хеширование.Добавить(СтрокаJson); // json Хеширование.Добавить(УнКлюч);// vpbx_api_salt sign = Хеширование.ХешСумма; sign = СтрЗаменить(НРЕГ(sign), " ", ""); postdata = Новый Соответствие; postdata.Вставить("vpbx_api_key", УнКод); postdata.Вставить("sign", sign); postdata.Вставить("json", СтрокаJson); post = "vpbx_api_key=" + postdata.Получить("vpbx_api_key") + "&" + "sign=" + postdata.Получить("sign") + "&" + "json=" + postdata.Получить("json"); Сообщить(post); WinHttp = Неопределено; Попытка WinHttp = Новый COMОбъект("WinHttp.WinHttpRequest.5.1"); WinHttp.Option(2, "CESU-8"); WinHttp.Open("POST", "https://app.mango-office.ru/vpbx/stats/result",0); //Пробовал еще такое добавлять. Также пробовал ставить кодировку utf-8 //WinHttp.SetRequestHeader("Accept-Language", "en"); //WinHttp.SetRequestHeader("Accept-Charset","utf-8"); //WinHttp.setRequestHeader("Content-Language", "en"); //WinHttp.setRequestHeader("Content-Charset", "utf-8"); WinHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=CESU-8"); WinHttp.Send(post); ТекстОтвета = WinHttp.ResponseText(); ТекстПредупреждения = ТекстОтвета; Исключение ТекстПредупреждения = ОписаниеОшибки(); КонецПопытки; |
|||
1
ILNIK19
30.08.17
✎
17:18
|
Вот пример на PHP из их руководства
$api_key = '<YOUR_API_KEY>'; $api_salt = '<YOUR_API_SALT>'; $url = 'https://app.mango-office.ru/vpbx/stats/result'; $data = array( "key" => "<REQUEST_KEY>" ); // json = {"key":"<REQUEST_KEY>"} $json = json_encode($data); // sign = 515069b8c079df62f408e36dd7933912b8e86d833c5927ee77eb4b68d766c4f5 $sign = hash('sha256', $api_key . $json . $api_salt); /* array ( 'vpbx_api_key' => '<YOUR_API_KEY>', 'sign' => '515069b8c079df62f408e36dd7933912b8e86d833c5927ee77eb4b68d766c4f5', 'json' => '{"key":"<REQUEST_KEY>"}', ) */ $postdata = array( 'vpbx_api_key' => $api_key, 'sign' => $sign, 'json' => $json ); // post = vpbx_api_key=%3CYOUR_API_KEY%3E&sign=515069b8c079df62f408e36dd7933912b8e86d833c5927ee77eb4b68d766c4f5&json=%7B%22key%22%3A%22%3CREQUEST_KEY%3E%22%7D $post = http_build_query($postdata); /************ Отправка с использованием file_get_contents ************/ $opts = array( 'http' => array( 'method' => 'POST', 'header' => 'Content-type: application/x-www-form-urlencoded', 'content' => $post ) ); $context = stream_context_create($opts); $response = file_get_contents($url, false, $context); /************ Отправка с использованием cUrl ************/ $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $post); $response = curl_exec($ch); curl_close($ch); |
|||
2
Филиал-msk
30.08.17
✎
17:39
|
(1) > 'header' => 'Content-type: application/x-www-form-urlencoded',
Как думаешь, что это означает? |
|||
3
ILNIK19
30.08.17
✎
19:17
|
(2) Это формат для кодирования пар ключ-значение с возможностью дублирования ключей. Каждая пара ключ-значение отделяется символом &, ключ отделён от значения символом = . В ключах и значениях пробелы заменяются на знак +, и затем, используя URL-кодирование, заменяются все не буквенно-цифровые символы.
|
|||
4
ILNIK19
30.08.17
✎
19:20
|
(2) Хэш выходит в виде хх хх хх хх... и тд. Я удаляю пробелы. Может из-за этого?
Но вряд ли api примет хэш с пробелами |
|||
5
Филиал-msk
30.08.17
✎
19:31
|
(4) > ...и затем, используя URL-кодирование, заменяются все не буквенно-цифровые символы
И? |
|||
6
ILNIK19
30.08.17
✎
19:47
|
(5) вы можете сказать, что нужно конкретно сделать? Или будем играть в загадки?
|
|||
7
Филиал-msk
30.08.17
✎
20:20
|
(6) Мне надо чтобы ты заебался и задумался. А тебе надо готового кода и поиграться. Ок.
При отправке http запроса необходимо согласовать с сервером кодировку данных. В силу того, что http поточный протокол, информация о методе кодирования данных отправляется раньше, в заголовках. Поэтому, для нормальной работы необходимо передать тело запроса в соответствующем виде. Твоя очередь. Ебись (: |
|||
8
Филиал-msk
30.08.17
✎
23:00
|
А сейчас выскочит Serginio1 и даст ссылку на Ъ (:
|
|||
9
Lexey_
30.08.17
✎
23:30
|
(0)а зачем WinHttpRequest? Есть же HTTPЗапрос
|
|||
10
Lexey_
30.08.17
✎
23:37
|
+(9) да ещё и стаж 10 лет, че за фетиш такой на WinHttpRequestы?
|
|||
11
Лодырь
31.08.17
✎
05:01
|
(10) Ну вот он и вспомнил времена старинные, когда HTTPЗапроса не было, а приходилось использовать WinHTTP.
|
|||
12
ILNIK19
31.08.17
✎
07:31
|
(10) (11) я уже с этой задачей и так время от времени занимаюсь пару недель.
httpЗапрос пробовал разными вприантами. Манго возвращает ошибку аутентификации, хотя у них полность открытый доступ к api и никакой лог н и пароль не нужен. Пустой прокси прописывал. Защищенное соединение тоже пробовал. ВинРеквест работает, осталось только допилить чуток. Я правильно понимаю, что ошибка не в ключе, а в заголовке? Надосюла копать? |
|||
13
Филиал-msk
31.08.17
✎
07:39
|
(10) Меня вот больше интересует биологическая особенность, которая проявляется у всех со временем стажа, после обвешивания себя сертификатами и прочими регалиями. У людей напрочь отрубается способность читать написанное, даже то, что они написали своими руками. Пост (2) тому явный пример.
|
|||
14
Филиал-msk
31.08.17
✎
07:40
|
Пост (3), промахнулся.
|
|||
15
Филиал-msk
31.08.17
✎
07:44
|
Вот так вот пару недель на одной задаче, пару на другой - вот и 10 лет стажа. Удобно!
|
|||
16
ILNIK19
31.08.17
✎
08:59
|
(15) Предлагаю не захламлять тему бесполезными постами. Никому не интересны домыслы разных "спецов", считающих себя самыми умными. Если нечего сказать по делу, то, пожалуйста, не умничайте и не отвлекайте других.
Занимаюсь этой темой пару недель, потому что есть основная работа с тремя активными проектами. А данная задача является факультативом в свободное время |
|||
17
ILNIK19
31.08.17
✎
09:03
|
(15) Все знать невозможно. 1сники со стажем могут заменить и бухгалтера и кадровика и узких специалистов в разных предметных областях вместе взятых. Всегда будет что-то новое. Есть задача, есть разные пути решения. И ни одно решение не является истиной. Так что ваши потуги под...ать других людей не красят вас. Всегда найдется область в которой вы будете профаном, а другой человек обставит вас в два счета
|
|||
18
Lexey_
31.08.17
✎
09:23
|
Функция ВыполнитьЗапрос(АдресРесурса, ПараметрыЗапроса)
ЗаписьJSON = Новый ЗаписьJSON; ЗаписьJSON.УстановитьСтроку(Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет); ЗаписатьJSON(ЗаписьJSON, ПараметрыЗапроса); СтрокаJSON = ЗаписьJSON.Закрыть(); ХД = Новый ХешированиеДанных(ХешФункция.SHA256); ХД.Добавить(ApiKey); ХД.Добавить(СтрокаJSON); ХД.Добавить(ApiSalt); Sign = НРег(СтрЗаменить(ХД.ХешСумма, " ", "")); HTTPСоединение = Новый HTTPСоединение("app.mango-office.ru", 443,,,,, Новый ЗащищенноеСоединениеOpenSSL()); СтрокаЗапроса = СтрШаблон("vpbx_api_key=%1&sign=%2&json=%3", ApiKey, Sign, СтрокаJSON); ЗаголовкиHTTP = Новый Соответствие; ЗаголовкиHTTP.Вставить("Content-type", "application/x-www-form-urlencoded"); HTTPЗапрос = Новый HTTPЗапрос(АдресРесурса, ЗаголовкиHTTP); HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаЗапроса); Возврат HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос); КонецФункции пример вызова: ПараметрыЗапроса = Новый Структура; ПараметрыЗапроса.Вставить("key", key); HTTPОтвет = ВыполнитьЗапрос("vpbx/stats/result", ПараметрыЗапроса); |
|||
19
Филиал-msk
31.08.17
✎
09:33
|
(18) Не взлетит. Будет ровно та же самая ошибка.
|
|||
20
Lexey_
31.08.17
✎
09:36
|
(19) уже несколько месяцев исправно летает
|
|||
21
Филиал-msk
31.08.17
✎
09:39
|
(17) Я, кажется, понял. При подготовке к обвешиванию сертификатами применяется подход, который намертво вшивается в подкорку - зазубрить шаблоны примеров и попытаться применить их, надеясь на удачу.
В последующем, ровно такой же подход применяется специалистом и в разработке - программирование методом тыка наудачу. Чтобы отстали. Скопировать кусок руководства из интернета, ответить им на сарказм... Чтоб прочувствовали, а то ишь! Думать и читать скопированное совсем не обязательно. И даже вредно для сертифицированных специалистов. |
|||
22
Филиал-msk
31.08.17
✎
09:41
|
(20) добавь в тело запроса с такими заголовками, например, русские буквы.
|
|||
23
Филиал-msk
31.08.17
✎
09:47
|
(22) хотя можно и показательнее. Добавь в передаваемые данные, например, знак равенства.
|
|||
24
ILNIK19
31.08.17
✎
09:58
|
(18) Не работает. Даже когда плюса нет
|
|||
25
ILNIK19
31.08.17
✎
10:02
|
{"name":"Unauthorized","message":"You are requesting with an invalid credential.","code":0,"status":401}
|
|||
26
Lexey_
31.08.17
✎
10:20
|
(23) да, забыл КодироватьСтроку(СтрокаJSON, СпособКодированияСтроки.КодировкаURL)
|
|||
27
Lexey_
31.08.17
✎
10:21
|
СтрокаЗапроса = СтрШаблон("vpbx_api_key=%1&sign=%2&json=%3", ApiKey, Sign, КодироватьСтроку(СтрокаJSON, СпособКодированияСтроки.КодировкаURL));
|
|||
28
ILNIK19
31.08.17
✎
10:35
|
(27) vpbx_api_key=Мойkey&sign=Мойsign&json=%7B%0D%0A%22key%22%3A%20%22T9OyJplIzuuUwYXo7SHmNYnTHG3EPAdo0q4TH0yomf0uhXTCWvUhLWTaNFJ7refCr4%2FB5R6d3NTvL4f5W9tTlw%3D%3D%22%0D%0A%7D
{"name":"Unauthorized","message":"You are requesting with an invalid credential.","code":0,"status":401} |
|||
29
Lexey_
31.08.17
✎
10:40
|
(28) Мойkey и Мойsign тоже кодируй, проверил, всё работает
Функция ВыполнитьЗапрос(АдресРесурса, ПараметрыЗапроса) СтрокаJSON = ОбщегоНазначенияКлиентСервер.СтруктураВJSON(ПараметрыЗапроса, Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет)); ХД = Новый ХешированиеДанных(ХешФункция.SHA256); ХД.Добавить(МангоАТСПовтИсп.ApiKey()); ХД.Добавить(СтрокаJSON); ХД.Добавить(МангоАТСПовтИсп.ApiSalt()); sign = НРег(СтрЗаменить(ХД.ХешСумма, " ", "")); HTTPСоединение = Новый HTTPСоединение(МангоАТСПовтИсп.ApiServer(), 443,,,,, Новый ЗащищенноеСоединениеOpenSSL()); СтрокаЗапроса = СтрШаблон("vpbx_api_key=%1&sign=%2&json=%3", КодироватьСтроку(МангоАТСПовтИсп.ApiKey(), СпособКодированияСтроки.КодировкаURL), КодироватьСтроку(sign, СпособКодированияСтроки.КодировкаURL), КодироватьСтроку(СтрокаJSON, СпособКодированияСтроки.КодировкаURL)); ЗаголовкиHTTP = Новый Соответствие; ЗаголовкиHTTP.Вставить("Content-type", "application/x-www-form-urlencoded"); HTTPЗапрос = Новый HTTPЗапрос(АдресРесурса, ЗаголовкиHTTP); HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаЗапроса); Возврат HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос); КонецФункции |
|||
30
Lexey_
31.08.17
✎
10:42
|
Функция ВыполнитьЗапрос(АдресРесурса, ПараметрыЗапроса)
ЗаписьJSON = Новый ЗаписьJSON; ЗаписьJSON.УстановитьСтроку(Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет); ЗаписатьJSON(ЗаписьJSON, ПараметрыЗапроса); СтрокаJSON = ЗаписьJSON.Закрыть(); ХД = Новый ХешированиеДанных(ХешФункция.SHA256); ХД.Добавить(ApiKey); ХД.Добавить(СтрокаJSON); ХД.Добавить(ApiSalt); Sign = НРег(СтрЗаменить(ХД.ХешСумма, " ", "")); HTTPСоединение = Новый HTTPСоединение("app.mango-office.ru", 443,,,,, Новый ЗащищенноеСоединениеOpenSSL()); СтрокаЗапроса = СтрШаблон("vpbx_api_key=%1&sign=%2&json=%3", КодироватьСтроку(ApiKey, СпособКодированияСтроки.КодировкаURL), КодироватьСтроку(sign, СпособКодированияСтроки.КодировкаURL), КодироватьСтроку(СтрокаJSON, СпособКодированияСтроки.КодировкаURL)); ЗаголовкиHTTP = Новый Соответствие; ЗаголовкиHTTP.Вставить("Content-type", "application/x-www-form-urlencoded"); HTTPЗапрос = Новый HTTPЗапрос(АдресРесурса, ЗаголовкиHTTP); HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаЗапроса); Возврат HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос); КонецФункции |
|||
31
Филиал-msk
31.08.17
✎
11:20
|
Вот так вот сертифицированный специалист получил ещё один фрагмент кода, не приходя в сознание. Позже он попробует применить его в изменившемся окружении, фрагмент не сработает и он вернётся к нам с тем же вопросом и топаньем ножками (:
|
|||
32
ILNIK19
31.08.17
✎
11:21
|
(30) Спасибо большое за помощь.
Пробую ваш код, все равно не получается Ключ = ПрисланныйКлюч; ПараметрыЗапроса = Новый Структура; ПараметрыЗапроса.Вставить("key", Ключ); HTTPОтвет = ВыполнитьЗапрос("vpbx/stats/result", ПараметрыЗапроса); Сообщить(HTTPОтвет.ПолучитьТелоКакСтроку("UTF-8")); Функция ВыполнитьЗапрос(АдресРесурса, ПараметрыЗапроса) ApiKey = "МойАпиКей"; ApiSalt = "МойпиСалт"; ЗаписьJSON = Новый ЗаписьJSON; ЗаписьJSON.УстановитьСтроку(Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет)); ЗаписатьJSON(ЗаписьJSON, ПараметрыЗапроса); СтрокаJSON = ЗаписьJSON.Закрыть(); ХД = Новый ХешированиеДанных(ХешФункция.SHA256); ХД.Добавить(ApiKey); ХД.Добавить(СтрокаJSON); ХД.Добавить(ApiSalt); Sign = НРег(СтрЗаменить(ХД.ХешСумма, " ", "")); HTTPСоединение = Новый HTTPСоединение("app.mango-office.ru", 443,,,,, Новый ЗащищенноеСоединениеOpenSSL()); //СтрокаЗапроса = СтрШаблон("vpbx_api_key=%1&sign=%2&json=%3", ApiKey, Sign, СтрокаJSON); //Включен режим совместимости 8.3.5 СтрокаЗапроса = "vpbx_api_key="+КодироватьСтроку(ApiKey, СпособКодированияСтроки.КодировкаURL)+"&sign=" + КодироватьСтроку(Sign, СпособКодированияСтроки.КодировкаURL) + "&json=" + КодироватьСтроку(СтрокаJSON, СпособКодированияСтроки.КодировкаURL) + ""; //СтрокаЗапроса = "vpbx_api_key="+ApiKey+"&sign=" + Sign + "&json=" + СтрокаJSON + ""; Сообщить(СтрокаЗапроса); ЗаголовкиHTTP = Новый Соответствие; ЗаголовкиHTTP.Вставить("Content-type", "application/x-www-form-urlencoded"); HTTPЗапрос = Новый HTTPЗапрос(АдресРесурса, ЗаголовкиHTTP); HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаЗапроса); Возврат HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос); КонецФункции Отправляю запрос: vpbx_api_key=МойАпиКей&sign=МойСигн&json=%7B%22key%22%3A%22npBHqNSot%2B56LITtFLmXBntHtRW0UieuljXQzda%2BRcKfOkJMaj%2B70w7VDMjbK2eullwcsAlL7Oq4okP9wzN64Q%3D%3D%22%7D Ответ: {"name":"Unauthorized","message":"You are requesting with an invalid credential.","code":0,"status":401} |
|||
33
ILNIK19
31.08.17
✎
11:23
|
(31) Не мешай, раз не знаешь, как сделать
|
|||
34
Филиал-msk
31.08.17
✎
12:21
|
(33) Я переживаю. Как оно там, работает?
|
|||
35
ILNIK19
31.08.17
✎
12:34
|
Общаюсь с ТП Манго:
Проверьте пожалуйста сейчас: Ключ v494KPOUaKTGH8ZmV/3PMrD/Db/tOHqr4edKmUgI/NiQxyxbWWJK3JS43MKKZsZxixtUQOkVslg95rOCLjmrLQ== Запрос такой vpbx_api_key=МойApiKey&sign=МойSign&json=%7B%22key%22%3A%22v494KPOUaKTGH8ZmV%2F3PMrD%2FDb%2FtOHqr4edKmUgI%2FNiQxyxbWWJK3JS43MKKZsZxixtUQOkVslg95rOCLjmrLQ%3D%3D%22%7D {"name":"Unauthorized","message":"You are requesting with an invalid credential.","code":0,"status":401} Ответ ТП: Вы получили {"key":"v494KPOUaKTGH8ZmV\/3PMrD\/Db\/tOHqr4edKmUgI\/NiQxyxbWWJK3JS43MKKZsZxixtUQOkVslg95rOCLjmrLQ=="} Вы прислали {"key":"v494KPOUaKTGH8ZmV/3PMrD/Db/tOHqr4edKmUgI/NiQxyxbWWJK3JS43MKKZsZxixtUQOkVslg95rOCLjmrLQ=="} Плюс еще нуль символ в параметре перед буквой v в самом начале ?vpbx_api_key": "МойApi" |
|||
36
ILNIK19
31.08.17
✎
12:36
|
Символ слэша \ пропадает
|
|||
37
ILNIK19
31.08.17
✎
14:29
|
Короче победил.
Если используется кодировка UTF-8 при отправке запроса, то в начале контента 1с принудительно записывает BOM. Нужно это отключить: HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаЗапроса, "UTF-8", ИспользованиеByteOrderMark.НеИспользовать); И все взлетело. Большое спасибо Lexey. Подал идею кодировки запроса в URL |
|||
38
Филиал-msk
31.08.17
✎
15:22
|
(37) > Подал идею кодировки запроса в URL
Примерно 20 часов потребовалось сертифицированному специалисту, чтобы разобрать и понять собственные каракули из (3). Это успех! Поздравляю! |
|||
39
ILNIK19
31.08.17
✎
15:46
|
(38) Задача решена, какая разница сколько времени это заняло? Я занимаюсь этим параллельно другими задачи.
Когда я сдавал сертификаты 10 лет назад, этих объектов и в помине не было. В следующий раз сделаю эту задачу за 10 минут. А ты 20 часов только троллишь и мешаешь другим. Ну продолжай в том же духе... Беспричинное унижение других людей в интернете говорит о твоих проблемах в жизни и твоих комплексах. У меня нет времени на то, чтобы ублажать твое эго! Тебе с этим жить... |
|||
40
oleg_km
31.08.17
✎
17:55
|
(39) Мда, доктор бы тебя так вылечил: кинул клич по форумам, кто-то что-то посоветовал, быстренько попробовал, ура поциент не умер.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |