WebRequest в MT4 возвращает GetLastError() = 4060

 

Добрый день!

Для отправки данных в Telegram в MetaTrader 4 (билд 1147 от 16 Nov 2018) использую функцию WebRequest.

Код библиотеки пишу так (там 2 варианта функции отправки: TelegramSendMessage - через WebRequest, и TelegramSendMessage2 - через испорт "Wininet.dll", не работают обе):

//+------------------------------------------------------------------+
//|                                           TelegramMQLsoftBot.mq4 |
//|                Copyright 2018, Valery V. Chesnokov (MQLsoft.ru)  |
//|                                           http://www.mqlsoft.ru/ |
//+------------------------------------------------------------------+
#property library
#property copyright "Copyright 2018, Valery V. Chesnokov (MQLsoft.ru)"
#property link      "http://www.mqlsoft.ru/"
#property version   "1.00"
///#property strict

#import  "Wininet.dll"
   int InternetOpenW(string, int, string, string, int);
   int InternetConnectW(int, string, int, string, string, int, int, int); 
   int InternetOpenUrlW(int, string, string, int, int, int);
   int InternetReadFile(int, string, int, int& OneInt[]);
   int InternetCloseHandle(int); 
   int HttpOpenRequestW(int, string, string, string, string, string, int, int);
   bool HttpSendRequestW(int, string, int, string, int);
#import
#import "kernel32.dll"
int GetLastError(void);
#import

//+------------------------------------------------------------------+
//| Telegram Send Message Function v2                                                      |
//+------------------------------------------------------------------+
 int TelegramSendMessage2(string UserName, string Message) export
 {
   string headers = "Content-Type: application/x-www-form-urlencoded";
   string data = "";
   int HttpOpen = InternetOpenW(" ", 0, " ", "", 0);  
   int HttpConnect = InternetConnectW(HttpOpen, "https://mqlsoft.ru", 443, "", "", 3, 0, 0);
   int HttpRequest = HttpOpenRequestW(HttpConnect, "POST", "/api/tg/mqlsofttgcore/sendmess.php", "", "", data, 0, 0);   
   bool result = HttpSendRequestW(HttpRequest, headers, StringLen(headers), data, StringLen(data));
   Alert ("Last MSDN Error =: ", kernel32::GetLastError());
   int read[1];
   Print("This is the POST result: ", result);
   InternetCloseHandle(HttpOpen);
   InternetCloseHandle(HttpRequest);
   
   return (result);
 }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Telegram Send Message Function                                                      |
//+------------------------------------------------------------------+
 int TelegramSendMessage(string UserName, string Message) export
 {
   int    res;
   char   data[];
   char result[];
   string str = "";
   string params = 
      "&userlogin=" + UserName + 
      "&messtext=" + Message;
   
   StringToCharArray(params, data);
   
   res = WebRequest("POST", "https://mqlsoft.ru/api/tg/mqlsofttgcore/sendmess.php", NULL, 0, data, result, str);
   //string url = "https://mqlsoft.ru/api/tg/mqlsofttgcore/sendmess.php";
   //res = PostRequest(result, url, data, 10000);
   
   if(res == 200)
   {
      Print ("В бота @MQLsoftBot в Telegram успешно отправлен запрос");
      return (0);
   }
   else
   {
      Print ("Ошибка POST WEB запроса на сервер #" + (string)res + ", LastError="+(string)GetLastError());
      //Print ("result: " + CharArrayToString(result));
      return (res);
   }
 }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
int PostRequest(string &out,
                const string url,
                const string params,
                const int timeout=10000)
  {
   char data[];
   int data_size=StringLen(params);
   StringToCharArray(params,data,0,data_size);

   uchar result[];
   string result_headers;

   //--- application/x-www-form-urlencoded
   int res = WebRequest("POST",url,NULL,NULL,timeout,data,data_size,result,result_headers);
   //Print("WebRequest ",res," ",CharArrayToString(result,0,WHOLE_ARRAY,CP_UTF8),"/",ArraySize(result));
   if (res == 200)//OK
     {
      //--- delete BOM
      int start_index = 0;
      int size=ArraySize(result);
      for (int i=0; i<fmin(size,8); i++)
        {
         if(result[i]==0xef || result[i]==0xbb || result[i]==0xbf)
            start_index=i+1;
         else
            break;
        }
      //---
      out=CharArrayToString(result,start_index,WHOLE_ARRAY,CP_UTF8);
      return(res);
     }
   else
     {
      Print ("Ошибка POST WEB запроса на сервер #" + (string)res + ", LastError="+(string)GetLastError());
      Print ("result: " + CharArrayToString(result));
      return (res);
     }

   return(0);
  }
//+------------------------------------------------------------------+


И в тестовом индикаторе вызываю функцию отправки:

//+------------------------------------------------------------------+
//|                                             MQLTestIndicator.mq4 |
//|                Copyright 2018, Valery V. Chesnokov (MQLsoft.ru)  |
//|                                           http://www.mqlsoft.ru/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, Valery V. Chesnokov (MQLsoft.ru)"
#property link      "http://www.mqlsoft.ru/"
#property version   "1.00"
#property strict
#property indicator_chart_window

#include "..\Libraries\TelegramMQLsoftBot.mq4"

input int Counter = 20; // Counter

int curr_count = 0;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   TelegramSend();
   
//---
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| My Telegram function                              |
//+------------------------------------------------------------------+
  int TelegramSend()
  {
      ++curr_count;
      
      if (true)//curr_count >= 20) 
      {
         //curr_count = 0;
         
         string UserName = "vchesnokov";
         string Message = "Message from MQLTestIndicator";
         
         int result = TelegramSendMessage(UserName, Message);
         Alert ("TelegramSend return: ", result);
      }
      
      return curr_count;
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   TelegramSend();
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+


При этом в настройках терминала разрешил доступ к нужным URL домена:

Несмотря на выданные разрешения, вызов:

int res = WebRequest("POST",url,NULL,NULL,timeout,data,data_size,result,result_headers);

возвращает в GetLastError() код 4060.

При этом тестирование моего веб-сервиса через тестер https://resttesttest.com даёт успешную отправку POST запроса в Телеграм бота:



Прошу помочь с поиском причины ошибки и её устранением.

Не нашёл на сайте адреса, к сожалению, куда можно отправить ticket в support компании MetaQuotes с этом вопросом.

Прилагаю оба файла (библиотека TelegramMQLsoftBot.mq4 и индикатор MQLTestIndicator.mq4).

REST test test...
  • resttesttest.com
× Welcome! Use this simple page to poke around at the API. Specify HTTP method, URL and parameters, and click on Ajax Request. Note that this page requires a browser with HTML5 support.
Файлы:
 
В индикаторах сетевые функции запрещены, так как они неминуемо будут тормозить цикл обработки данных.
 
Renat Fatkhullin:
В индикаторах сетевые функции запрещены, так как они неминуемо будут тормозить цикл обработки данных.

Уважаемый Ренат, прошу подсказать корректную методику отправки уведомлений в Телеграм - для этого нужно исполнить POST Web запрос с передачей параметров.

Суть библиотеки (TelegramMQLsoftBot.mq4 в моём случае) в том, чтобы её можно было использовать в произвольном индикаторе или советнике для отправки уведомлений в Телеграм.

Или сетевые функции в советниках разрешены (запрещены только в индикаторах)?

 
Валерий Чесноков:

Или сетевые функции в советниках разрешены (запрещены только в индикаторах)?

Сетевые функции разрешены везде, кроме индикаторов.

 

Спасибо.

В советнике успешно получится вызов функции отправки сообщений в Телеграм:

//+------------------------------------------------------------------+
//|                                                MQLTestExpert.mq4 |
//|                Copyright 2018, Valery V. Chesnokov (MQLsoft.ru)  |
//|                                           http://www.mqlsoft.ru/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, Valery V. Chesnokov (MQLsoft.ru)"
#property link      "http://www.mqlsoft.ru/"
#property version   "1.00"
#property strict

#include "..\Libraries\TelegramMQLsoftBot.mq4"

input int Counter = 20; // Counter

int curr_count = 0;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   TelegramSend();
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   TelegramSend();
   
  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| My Telegram function                              |
//+------------------------------------------------------------------+
  int TelegramSend()
  {
      ++curr_count;
      
      if (true)//curr_count >= 20) 
      {
         //curr_count = 0;
         
         string UserName = "vchesnokov";
         string Message = "Message from MQLTestIndicator";
         
         int result = TelegramSendMessage(UserName, Message);
         Alert ("TelegramSend return: ", result);
      }
      
      return curr_count;
  }
//+------------------------------------------------------------------+


 
Валерий Чесноков:

Уважаемый Ренат, прошу подсказать корректную методику отправки уведомлений в Телеграм - для этого нужно исполнить POST Web запрос с передачей параметров.

Суть библиотеки (TelegramMQLsoftBot.mq4 в моём случае) в том, чтобы её можно было использовать в произвольном индикаторе или советнике для отправки уведомлений в Телеграм.

Или сетевые функции в советниках разрешены (запрещены только в индикаторах)?

А у вас провайдер не блокирует телеграм?  Было время, тоже думал, что проблема в вебреквесте, а оказалось блокировка провайдера. 

 
tyup:

А у вас провайдер не блокирует телеграм?  Было время, тоже думал, что проблема в вебреквесте, а оказалось блокировка провайдера. 

Вы знаете, Телеграм (тфу-тфу) работает исправно. Если его и пытаются блокировать, то совсем безуспешно :) Причём и на десктопе (один провайдер), и на мобильном инете (другой провайдер) Telegram успешно работает - молодцы его создатели.


Есть другой вопрос.

Мне удалось успешно из советника MetaTrader 4 передавать сообщения в Телеграм через штатную MQL4 функцию WebRequest в своего Telegram бота @MQLsoftBot:


НО. Одно но - в бота не доходят сообщения с кириллицей.

Только с латиницей и цифрами - т.е. думаю, что проходят сообщения с ANSI символами.

Отправку сообщений в Телеграм бота из своей MQL4 библиотеки делаю таким кодом:

//+------------------------------------------------------------------+
//| Telegram Send Message Function                                                      |
//+------------------------------------------------------------------+
 int TelegramSendMessage(string UserName, string Message) export
 {
   int    res;
   char   data[];
   char result[];
   string str = "";
   string params = 
      "&userlogin=" + UserName + 
      "&messtext=" + Message;
   
   StringToCharArray(params, data);
   
   res = WebRequest("POST", "https://mqlsoft.ru/api/<INSERT_YOUR_URL_HERE>", NULL, 0, data, result, str);
   
   if(res == 200)
   {
      Print ("В бота @MQLsoftBot в Telegram успешно отправлен запрос");
      return (0);
   }
   else
   {
      Print ("Ошибка POST WEB запроса на сервер #" + (string)res + ", LastError="+(string)GetLastError());
      //Print ("result: " + CharArrayToString(result));
      return (res);
   }
 }
//+------------------------------------------------------------------+

При этом тестирование POST HTTPS запроса, к примеру, на сервисе resttesttest.com, т.е. минуя MetaTrader 4, прекрасно отправляет в бота и сообщения с кириллицей.


Т.е. отправка с кириллицей не доходит до бота именно при вызове WebRequest из MT4.

Может, как-то нужно обернуть параметры POST запроса?

Причина обращения: