Роботы, плагины и скрипты к чату MyChat. Разработка альтернативных клиентов и различных утилит. Технические вопросы по программированию, замечания и предложения по развитию API
СергейВБР
здрасте!
Скрипт пишу в первый раз, верно ли я себе представляю задуманное?
- формирую запрос mHTTPSendPostMessage на погодный сайт,
- результат обрабатываю с помощью строковых функций,
- вывожу в общий чат.
с курсом - аналогично.
Или есть другие варианты получения и вывода информации из HTML?
Может в чате реально отобразить HTML фрэйм?
Аватара пользователя
Алексей Пикуров
Добрый день.

Формально всё верно. HTML фрейм можно отобразить только в рекламном блоке внизу чата. Но только pure html, без javascript и css. Попробуйте, в админке это легко сделать через "Настройки", "Дополнительно", "Показывать рекламу на клиентах", если есть какой-то определённый линк на ваш web-сервер, например, с готовым html-файлом.

В тексте чата html с нормальным рендерингом вы не вставите, нужно парсить и кидать обычным текстом. CRLF поддерживаются.
СергейВБР
Примерно набросал запрос:
Код: Выделить всё
var sResult, s, sCurTemp: string; sCurWind:string; x: integer;
begin
  sResult := mHTTPSendPostMessage('https://www.ventusky.com/sumy', '', 'Accept-Language: ru,en-US;q=0.7,en;q=0.3'+ CRLF +'Accept: text/html,charset=windows-1251,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 2000);
  mLogScript(sResult, 'sResult');
//Current Weather
//temperature
  x := pos('<td class="temperature">',sResult);
  s := copy(sResult, x+24, 7);
  sCurTemp := GetNextSt(s,'<');
  mLogScript(sCurTemp, 'curTemp');
 //Wind
  x := pos('>Wind</span>',sResult);
  s := copy(sResult, x+41, 8);
  sCurWind := GetNextSt(s,'<');
  mLogScript(sCurWind, 'sCurWind');
end.

Вопрос: сервер отдает страничку в utf-8. в скрипте это отображается кракозяблами, как это исправить?
Аватара пользователя
Алексей Пикуров
Надо посмотреть, почему так, отвечу позже.
СергейВБР
С кириллицей явно проблемы.
Сделал парсинг данных о погоде через JSON, - всеравно руский шрифт в спарсенных данных отображается кракозяблами
Вложения
screenshot 2018-01-23 %c.png
screenshot 2018-01-23 %c.png (175.78 КБ) Просмотров: 7132
СергейВБР
Что в коде не так? После включения скрипта в OnPrivateMessage, - все ЛС перестают работать, кроме ЛС с Эльзой.
з.ы. разобрался, упустил result := true;
СергейВБР
Подскажите, сделать запрос из MyChat Script Language который мог бы пройти авторизацию и работать через это АПИ - не получится, верно я понял?
Каждый запрос, который нуждается в авторизации, сопровождается дополнительным заголовком, вида:

"Authorization: ключ_пользователя: подпись"

Ключи для авторизации необходимо получить в личном кабинете.

Подпись составляется по следующему алгоритму:
массив из передаваемых параметров (GET, POST, PUT, DELETE) сортируется по названию ключа по алфавиту;
из полученного массива формируется строка запроса (например, функция http_build_query в PHP), пример "from=DATEFROM&to=DATETO…";
и далее - соединяется по формуле:
строка = имя_метода строка_запроса md5( строка_запроса ),
где "имя_метода" - строка запроса, начиная от домена (с указанием версии АПИ), до начала перечисления параметров, например - /v1/sip/"
полученная строка хешируется по алгоритму sha1 с секретным ключом пользователя:
хеш = hash( строка, секретный_ключ )
и далее хеш кодируется в base64
подпись = base64_encode( хеш )

Пример на PHP:
ksort($params);
$paramsStr = http_build_query($params, null, '&', PHP_QUERY_RFC1738);
$sign = base64_encode(hash_hmac('sha1', $method . $paramsStr . md5($paramsStr), $secret));

$header = 'Authorization: ' . $userKey . ':' . $sign;
Аватара пользователя
Алексей Пикуров
Давайте по порядку. Я сначала отвечу на ваш первый вопрос, потом на остальные, когда разберусь.
Аватара пользователя
Алексей Пикуров
С кодировкой разобрались.

Ваш код выглядит теперь вот так:

scriptsource.png
scriptsource.png (90.11 КБ) Просмотров: 7088


Теперь давайте насчёт API. Я так понимаю, вам нужны функции для md5 и sha1 хешей. Их можно добавить. Но мне непонятна фраза
хеш = hash( строка, секретный_ключ )

Что за секретный ключ? Где увидеть пример работы алгоритма? Хеш считается от строки, секретного ключа там нет.
СергейВБР
Ваш код выглядит теперь вот так

Отлично!
Что за секретный ключ? Где увидеть пример работы алгоритма? Хеш считается от строки, секретного ключа там нет

Вся инфа расписана здесь https://zadarma.com/ru/support/api/
Но я думаю функции полезны будут и для других сервисов.
СергейВБР
в PHP это реализовано в функции http://php.net/manual/ru/function.hash-hmac.php
Вложения
screenshot 2018-01-29 %c.png
screenshot 2018-01-29 %c.png (58.74 КБ) Просмотров: 7083
Аватара пользователя
Алексей Пикуров
Сборку сервера могу дать вам сегодня. В личку.
Аватара пользователя
Алексей Пикуров
Отправил личкой ссылку на сборку сервера.
СергейВБР
Отправил личкой ссылку на сборку сервера.

Спасибо, проверил новые функции.
Кодировка utf-8 теперь отображается везде корректно.

С отправкой зашифрованного запроса - проблемка.
Если неправильный запрос формирую - получаю в sJSONResult - корректное сообщение об ошибке:
[sJSONResult] {"status":"error","message":"Not authorized"}

Когда начал использовать новые функции, сформировал все правильно, по инструкции, но в ответ теперь ошибки нету - просто в sJSONResult возвращается пустая строка.
Совсем не могу понять куда копать? Долбить поддержку задармы (АПИ которых должны вернуть значения), или может есть способы увидеть, что возвращает сервер после mHTTPSendPostMessage?
Код прилагаю, ключи все верные.
Код: Выделить всё
const
    sParam = '';
    sMetod = '/v1/info/balance/';
    sKey = '1ba2038c0831b3797198';
    sSekret = '7f274be71573ca3645f9';
var
  sJSONResult, sSign, status: string; 
begin
             sSign := EncodeBase64(StrToHex(HMAC_SHA1(sMetod + sParam + StrToHex(MD5(sParam)), sSekret)));
             sJSONResult := mHTTPSendPostMessage('https://api.zadarma.com' + sMetod, sParam, 'Authorization:' + sKey + ':' + sSign, 1000);
             mLogScript(sJSONResult, 'sJSONResult');
             JSONGetString(sJSONResult, 'status', status);
             mLogScript(status, 'status');
     
end.
СергейВБР
Поэкспериментировав, я понял что работает не с POST а с GET запросом.
Тогда возвращает JSON.
Здесь есть возможность отправить GET запрос?
Аватара пользователя
Алексей Пикуров
GET запрос мы не делали в API. А что, с POST никак?
Аватара пользователя
Алексей Пикуров
:) Я попробую для GET функцию сделать, позже.
Аватара пользователя
Алексей Пикуров
Странная строка:

Код: Выделить всё
sSign := EncodeBase64(StrToHex(HMAC_SHA1(sMetod + sParam + StrToHex(MD5(sParam)), sSekret)));

Зачем StrToHex от StrToHex делать?

Судя по документации от Zadarma, я бы написал sSign := EncodeBase64(HMAC_SHA1(sMetod + sParam + MD5(sParam), sSekret));

Я попробовал сделать GET метод, но у вас в коде скрипта Param пустой. Что туда нужно вставить для проверки? Сейчас я получаю на GET запрос:

Код: Выделить всё
{"status":"error","message":"Not authorized"}
Аватара пользователя
Алексей Пикуров
P.S. Получилось :) У вас всё Ок, это я накосячил в коде, когда пробовал.

Код: Выделить всё
{"status":"success","balance":10.2637,"currency":"USD"}

Получился такой код:
Код: Выделить всё
const
 sParam = '';
 sMetod = '/v1/info/balance/';
 sKey = '1ba2038c0831b3797198';
 sSekret = '7f274be71573ca3645f9';
var
  sJSONResult, sSign, status: string; 
begin
  sSign := EncodeBase64(StrToHex(HMAC_SHA1(sMetod + sParam + StrToHex(MD5(sParam)), sSekret)));
  sJSONResult := mHTTPSendGetMessage('https://api.zadarma.com' + sMetod, 'Authorization:' + sKey + ':' + sSign, 1000);
  mLogScript(sJSONResult, 'sJSONResult');
  JSONGetString(sJSONResult, 'status', status);
  mLogScript(status, 'status');
end.


https://nsoft-s.com/forum/viewtopic.php?p=29403#p29403

Ссылку на сборку сервера бросил вам личкой.
СергейВБР
Клас! Все работает! Теперь такое можно сделать .... [smilie=good.gif]

А у меня еще есть идеи, которые не реализованы - можно вам подбрасывать или уже хватит? [smilie=dance4.gif]
СергейВБР
А, ещё вопросик
при настройке скрипта на OnPrivateMessage, получается след. ситуация, я отправляю кодовое слово - и ответ в чат приходит раньше кодового слова... См скрин...
Как это упорядочить? Раньше можно было удалить последнее сообщение, сча - нельзя, какой выход?
з.ы. с этим разобрался, увидел примеры с bFlag := false;
Последний раз редактировалось СергейВБР Пт фев 02, 2018 1:19 pm, всего редактировалось 1 раз.
Аватара пользователя
Алексей Пикуров
А у меня еще есть идеи, которые не реализованы - можно вам подбрасывать или уже хватит?

Подбрасывайте :) Отдельными темами только.