MT5 build 5100 causes problems with my code

 

Hey guys,

I use a scanner and when certain situations in the market happen, this scanner saves a screenshot with lines and annotiations and copies it into my own Telegram channel which is just for me.
Unfortunately I have absolutely no idea how this Telegram API code works. I just found it freely available on a forum some time ago and added it to my own code. Everything worked fine in the last years but with the new MT5 build 5100 this part of the code doesn't work anymore. Luckily I only did the update on my Desktop MT5 but not on the MT5 on my server. So the same code works on the old version of MT5 but not on the new one. How can that be?

I attached a screenshot of the errors and the Telegram API code. Maybe it's just a new syntax or maybe I need a completely new code. Can somebody advise? Thank you.

const string TelegramBotToken = "";
const string ChatId           = "";
const string TelegramApiUrl   = "https://api.telegram.org"; // Add this to allow URLs
const int    UrlDefinedError  = 4014; // Because MT4 and MT5 are different

bool SendTelegramMessage( string url, string token, string chat, string text,
                          string fileName = "" ) {
   string headers    = "";
   string requestUrl = "";
   char   postData[];
   char   resultData[];
   string resultHeaders;
   int    timeout = 5000; // 1 second, may be too short for a slow connection

   ResetLastError();

   if ( fileName == "" ) {
      requestUrl =
         StringFormat( "%s/bot%s/sendmessage?chat_id=%s&text=%s", url, token, chat, text );
   }
   else {
      requestUrl = StringFormat( "%s/bot%s/sendPhoto", url, token );
      if ( !GetPostData( postData, headers, chat, text, fileName ) ) {
         return ( false );
      }
   }

   ResetLastError();
   int response =
      WebRequest( "POST", requestUrl, headers, timeout, postData, resultData, resultHeaders );

   switch ( response ) {
   case -1: {
      int errorCode = GetLastError();
      Print( "Error in WebRequest. Error code  =", errorCode );
      if ( errorCode == UrlDefinedError ) {
         //--- url may not be listed
         PrintFormat( "Add the address '%s' in the list of allowed URLs", url );
      }
      break;
   }
   case 200:
      //--- Success
      //Print( "The message has been successfully sent" );
      Print(sym+" "+strTF+" has been sent to Telegram");
      break;
   default: {
      string result = CharArrayToString( resultData );
      PrintFormat( "Unexpected Response '%i', '%s'", response, result );
      break;
   }
   }

   return ( response == 200 );
}

bool GetPostData( char &postData[], string &headers, string chat, string text, string fileName ) {

   ResetLastError();

   if ( !FileIsExist( fileName ) ) {
      PrintFormat( "File '%s' does not exist", fileName );
      return ( false );
   }

   int flags = FILE_READ | FILE_BIN;
   int file  = FileOpen( fileName, flags );
   if ( file == INVALID_HANDLE ) {
      int err = GetLastError();
      PrintFormat( "Could not open file '%s', error=%i", fileName, err );
      return ( false );
   }

   int   fileSize = ( int )FileSize( file );
   uchar photo[];
   ArrayResize( photo, fileSize );
   FileReadArray( file, photo, 0, fileSize );
   FileClose( file );

   string hash = "";
   AddPostData( postData, hash, "chat_id", chat );
   if ( StringLen( text ) > 0 ) {
      AddPostData( postData, hash, "caption", text );
   }
   AddPostData( postData, hash, "photo", photo, fileName );
   ArrayCopy( postData, "--" + hash + "--\r\n" );

   headers = "Content-Type: multipart/form-data; boundary=" + hash + "\r\n";

   return ( true );
}

void AddPostData( uchar &data[], string &hash, string key = "", string value = "" ) {

   uchar valueArr[];
   StringToCharArray( value, valueArr, 0, StringLen( value ) );

   AddPostData( data, hash, key, valueArr );
   return;
}

void AddPostData( uchar &data[], string &hash, string key, uchar &value[], string fileName = "" ) {

   if ( hash == "" ) {
      hash = Hash();
   }

   ArrayCopy( data, "\r\n" );
   ArrayCopy( data, "--" + hash + "\r\n" );
   if ( fileName == "" ) {
      ArrayCopy( data, "Content-Disposition: form-data; name=\"" + key + "\"\r\n" );
   }
   else {
      ArrayCopy( data, "Content-Disposition: form-data; name=\"" + key + "\"; filename=\"" +
                          fileName + "\"\r\n" );
   }
   ArrayCopy( data, "\r\n" );
   ArrayCopy( data, value, ArraySize( data ) );
   ArrayCopy( data, "\r\n" );

   return;
}

void ArrayCopy( uchar &dst[], string src ) {

   uchar srcArray[];
   StringToCharArray( src, srcArray, 0, StringLen( src ) );
   ArrayCopy( dst, srcArray, ArraySize( dst ), 0, ArraySize( srcArray ) );
   return;
}

string Hash() {

   uchar  tmp[];
   string seed = IntegerToString( TimeCurrent() );
   int    len  = StringToCharArray( seed, tmp, 0, StringLen( seed ) );
   string hash = "";
   for ( int i = 0; i < len; i++ )
      hash += StringFormat( "%02X", tmp[i] );
   hash = StringSubstr( hash, 0, 16 );

   return ( hash );
}
Files:
errors.jpg  143 kb
 
ArrayCopy is already protected mql5 function maybe change its name.

Check elements of AddPostData they don't match 
 
Rajesh Kumar Nait #:
ArrayCopy is already protected mql5 function maybe change its name.

Check elements of AddPostData they don't match 

I thought the same. But look at this screenshot. This is from the older version of MT5 running on the server. At the color of the name you see that the function ArrayCopy() was already protected then and the code worked fine before.

Files:
Untitled.png  335 kb
 
Marbo #:

I thought the same. But look at this screenshot. This is from the older version of MT5 running on the server. At the color of the name you see that the function ArrayCopy() was already protected then and the code worked fine before.

you have two AddPostData, but you should not have two function with same name.
void AddPostData( uchar &data[], string &hash, string key, uchar &value[], string fileName = "" ) {

your AddPostData function contains 5 parameters but you call this function with only 4 parameter?

AddPostData( postData, hash, "caption", text );
Compiler is confused with your code which AddPostData to call? Fix it.
 
Rajesh Kumar Nait #:
you have two AddPostData, but you should not have two function with same name.

your AddPostData function contains 5 parameters but you call this function with only 4 parameter?

Compiler is confused with your code which AddPostData to call? Fix it.

You are absolutely right. The code confuses me and honestly I don't understand what it is doing. Therefore it's hard for me to fix it. I just wonder why the compiler of the last MT5 version didn't cause any problems.

 
Rajesh Kumar Nait # :
you have two AddPostData, but you should not have two function with same name.

we can have the same function or method name several times as long as the signatures are different
It's called an overload

besides, many functions do this
all the same name, but the signature

Example

Call by the first position and the number of required elements

 int    CopyRates (
   string            symbol_name,       // symbol name 
   ENUM_TIMEFRAMES   timeframe,         // period 
   int               start_pos,         // start position 
   int               count,             // data count to copy 
   MqlRates          rates_array[]       // target array to copy 
   );

Call by the start date and the number of required elements

 int    CopyRates (
   string            symbol_name,       // symbol name 
   ENUM_TIMEFRAMES   timeframe,         // period 
   datetime          start_time,         // start date and time 
   int               count,             // data count to copy 
   MqlRates          rates_array[]       // target array to copy 
   );

Call by the start and end dates of a required time interval

 int    CopyRates (
   string            symbol_name,       // symbol name 
   ENUM_TIMEFRAMES   timeframe,         // period 
   datetime          start_time,         // start date and time 
   datetime          stop_time,         // end date and time 
   MqlRates          rates_array[]       // target array to copy 
   );
 
Marbo #:

You are absolutely right. The code confuses me and honestly I don't understand what it is doing. Therefore it's hard for me to fix it. I just wonder why the compiler of the last MT5 version didn't cause any problems.

because in mt5 5xxx version uchar is now char


const string TelegramBotToken = "";
const string ChatId           = "";
const string TelegramApiUrl   = "https://api.telegram.org"; // Add this to allow URLs
const int    UrlDefinedError  = 4014; // Because MT4 and MT5 are different
string sym,strTF;

bool SendTelegramMessage( string url, string token, string chat, string text,
                          string fileName = "" ) {
   string headers    = "";
   string requestUrl = "";
   char   postData[];
   char   resultData[];
   string resultHeaders;
   int    timeout = 5000; // 1 second, may be too short for a slow connection

   ResetLastError();

   if ( fileName == "" ) {
      requestUrl =
         StringFormat( "%s/bot%s/sendmessage?chat_id=%s&text=%s", url, token, chat, text );
   }
   else {
      requestUrl = StringFormat( "%s/bot%s/sendPhoto", url, token );
      if ( !GetPostData( postData, headers, chat, text, fileName ) ) {
         return ( false );
      }
   }

   ResetLastError();
   int response =
      WebRequest( "POST", requestUrl, headers, timeout, postData, resultData, resultHeaders );

   switch ( response ) {
   case -1: {
      int errorCode = GetLastError();
      Print( "Error in WebRequest. Error code  =", errorCode );
      if ( errorCode == UrlDefinedError ) {
         //--- url may not be listed
         PrintFormat( "Add the address '%s' in the list of allowed URLs", url );
      }
      break;
   }
   case 200:
      //--- Success
      //Print( "The message has been successfully sent" );
      Print(sym+" "+strTF+" has been sent to Telegram");
      break;
   default: {
      string result = CharArrayToString( resultData );
      PrintFormat( "Unexpected Response '%i', '%s'", response, result );
      break;
   }
   }

   return ( response == 200 );
}

bool GetPostData( char &postData[], string &headers, string chat, string text, string fileName ) {

   ResetLastError();

   if ( !FileIsExist( fileName ) ) {
      PrintFormat( "File '%s' does not exist", fileName );
      return ( false );
   }

   int flags = FILE_READ | FILE_BIN;
   int file  = FileOpen( fileName, flags );
   if ( file == INVALID_HANDLE ) {
      int err = GetLastError();
      PrintFormat( "Could not open file '%s', error=%i", fileName, err );
      return ( false );
   }

   int   fileSize = ( int )FileSize( file );
   char photo[];
   ArrayResize( photo, fileSize );
   FileReadArray( file, photo, 0, fileSize );
   FileClose( file );

   string hash = "";
   AddPostData( postData, hash, "chat_id", chat );
   if ( StringLen( text ) > 0 ) {
      AddPostData( postData, hash, "caption", text );
   }
   AddPostData1( postData, hash, "photo", photo, fileName );
   ArrayCopy1( postData, "--" + hash + "--\r\n" );

   headers = "Content-Type: multipart/form-data; boundary=" + hash + "\r\n";

   return ( true );
}

void AddPostData( char &data[], string &hash, string key = "", string value = "" ) {

   char valueArr[];
   StringToCharArray( value, valueArr, 0, StringLen( value ) );

   AddPostData1( data, hash, key, valueArr );
   return;
}

void AddPostData1( char &data[], string &hash, string key, char &value[], string fileName = "" ) {

   if ( hash == "" ) {
      hash = Hash();
   }

   ArrayCopy1( data, "\r\n" );
   ArrayCopy1( data, "--" + hash + "\r\n" );
   if ( fileName == "" ) {
      ArrayCopy1( data, "Content-Disposition: form-data; name=\"" + key + "\"\r\n" );
   }
   else {
      ArrayCopy1( data, "Content-Disposition: form-data; name=\"" + key + "\"; filename=\"" +
                          fileName + "\"\r\n" );
   }
   ArrayCopy1( data, "\r\n" );
   ArrayCopy( data, value, ArraySize( data ) );
   ArrayCopy1( data, "\r\n" );

   return;
}

void ArrayCopy1( char &dst[], string src ) {

   char srcArray[];
   StringToCharArray( src, srcArray, 0, StringLen( src ) );
   ArrayCopy( dst, srcArray, ArraySize( dst ), 0, ArraySize( srcArray ) );
   return;
}

string Hash() {

   uchar  tmp[];
   string seed = IntegerToString( TimeCurrent() );
   int    len  = StringToCharArray( seed, tmp, 0, StringLen( seed ) );
   string hash = "";
   for ( int i = 0; i < len; i++ )
      hash += StringFormat( "%02X", tmp[i] );
   hash = StringSubstr( hash, 0, 16 );

   return ( hash );
}
 
Rajesh Kumar Nait #:

because in mt5 5xxx version uchar is now char


It works perfect again. Thank you so much!

 
Marbo #:

It works perfect again. Thank you so much!

Glad to know it helped
 
Gerard William G J B M Dinh Sy #:
es o

you are right its like we can have 

string X(int x) {return NULL;};
string X(string z) {return NULL;};

however i avoid using same name to avoid confusions with my personal coding style.