telegram.mqh reply to msg

 

Hello,

I am currently coding an EA with telegram.mqh that send mt4 signals to my telegram.

What I'm trying to do now is to make updates about my trades when they hit a TP and send a 'TP hit' message in telegram.

This is no big deal but I was wondering if it was possible to link this 'TP hit' message with the BUY/SELL signal I send to my telegram channel earlier.


Is there a way for me to search for a specific message in my telegram channel, containing specific words and then, reply to it using telegram's 'Reply' fonction?

Thanks, have a great day!

 
tdbguy:

Hello,

I am currently coding an EA with telegram.mqh that send mt4 signals to my telegram.

What I'm trying to do now is to make updates about my trades when they hit a TP and send a 'TP hit' message in telegram.

This is no big deal but I was wondering if it was possible to link this 'TP hit' message with the BUY/SELL signal I send to my telegram channel earlier.


Is there a way for me to search for a specific message in my telegram channel, containing specific words and then, reply to it using telegram's 'Reply' fonction?

Thanks, have a great day!

Yes it is possible , you have to maintain data for your trades (so that you can store the original trade post message id ) so that you can provide tely with an id to reply to

#property strict
#include <Telegram\TelegramL.mqh>
input string channel_name="";//PRIVATE CHANNEL NAME (string)
input string channel_private_id_string="";//PRIVATE CHANNEL ID (string)
string InpToken="";//telegram input token
// to get private channel id
//Log into Telegram via web: https://web.telegram.org
//Find your channel and copy the URL. 
//You should have something like this: https://web.telegram.org/#/im?p=c**NUMBER**_number
//The numbers between "c" and "_" are the ID of your private channel.

//Now tell your bot to send the messages to chat_id=-100NUMBER

//mql code : 
/*
id in webtelegram c1334309342_1978467370643286368 >
1334309342 > 
-1001334309342 >
    string ids="-1001334309342";
    long idl=(long)StringToInteger(ids);
    bot.SendMessage(idl,messi,NULL,false,false);


*/
string private_channel_string_id="";
long private_channel_post_id=0,private_channel_prepost_id=0;
//id of last message for replies 
long last_message_id=-1;
/*
you can implement a solution where in your trades monitoring class 
you maintain the message id that was produced after the trade was posted in the telegram channel
for example ,you open a buy order ,you get its ticket ,you store it in your class array with your trades 
myTrades[x].ticket=ticket;
then after messaging the channel ,you can store the return id (the id of the message) in the same class array
myTrades[x].reply_message_id=last_message_id;

then when stop loss is hit for example you could : 
if(myTrades[x].reply_messge_id!=-1) > quote and message
*/
int OnInit()
  {
  last_message_id=-1;
  telegram_running=false;
  StartTelegramService();  
  //finding your channels id
    string ids="-100"+channel_private_id_string;
    private_channel_string_id=ids;
    long idl=(long)StringToInteger(ids);
    private_channel_prepost_id=(long)StringToInteger(channel_private_id_string);
    private_channel_post_id=idl;
    if(idl>=0) 
    {
    Alert("Invalid Private Channel ID");
    ExpertRemove();
    telegram_running=false;
    }
  //test message and its quote 
    string txt="This will be quoted";
    last_message_id=-1;
    int res=bot.SendMessageGetID(false,0,private_channel_post_id,txt,NULL,false,false,last_message_id);
                //if it was sent
                if(last_message_id!=-1)
                {
                Sleep(1000);
                //reply to it !
                txt="Reply test!";
                long reply_id=-1;
                bot.SendMessageGetID(true,last_message_id,private_channel_post_id,txt,NULL,false,false,reply_id);
                }  
  
  
  return(INIT_SUCCEEDED);
  }
  
  
//TELEGRAM STUFF 
class CMyBot: public CCustomBot
  {
private:
   int               m_radio_index;
   bool              m_lock_state;
   bool              m_mute_state;
public:
   //find chat id of private channel 
   long FindChannelChatId(string c_name,long normal_id,long post_id)
   {
   long returnio=-1;
   int total_chats=bot.ChatsTotal();
   for(int c=0;c<total_chats;c++)
    {
    CCustomChat chat=m_chats.GetNodeAtIndex(c);
    }
   return(returnio);
   }
   //find chat id of private channel ends here 
  };

//---



//---
CMyBot bot;
int getme_result;

//user structure - for signals 
long telegram_chat_ids[];
int telegram_chats_total=0;
int telegram_chats_size=0;
int telegram_chats_step=10;
bool telegram_running=false,must_hide_keyboard=false;

//start telegram service and get id's 
  void StartTelegramService()
  {
  telegram_running=true;
  must_hide_keyboard=false;
//--- set token
  bot.Token(InpToken);
//--- check token
  getme_result=bot.GetMe();
  if(getme_result!=0) telegram_running=false;
  //if(telegram_running) Alert("Bot Name : "+bot.Name);
  if(telegram_running==false)
   {
   Alert("Could not start telegram service!");
   ExpertRemove();
   }
  }
//start telegram service and get id's ends here 

//TELEGRAM STUFF ENDS HERE 

use this include : (dont overwrite the original telegram.mqh) 

Files:
TelegramL.mqh  75 kb
 

wow thank you Lorentzos

I found no info on google and started to think it wasnt possible.

 
tdbguy:

wow thank you Lorentzos

I found no info on google and started to think it wasnt possible.

You are welcome . 

 

I passed all morning on it and I come across an issue,


2020.07.24 12:06:50.629 Mt4 - Telegram - 3TP GBPUSD,M1: Error: JSON parsing not OK
2020.07.24 12:06:50.629 Mt4 - Telegram - 3TP GBPUSD,M1: {"ok":false,"error_code":400,"description":"Bad Request: reply message not found"}

What I'm doing is making last_message_id = OrderTicket(); in

int res=bot.SendMessageGetID(false,0,-1001061351629 ,message,NULL,false,false,last_message_id);

and since the orderticket is the same when I close the trade, I'm thinking that it should recognise the message in telegram and replies to it right? so when a trade close

long replies = OrderTicket();

int res=bot.SendMessageGetID(true,replies,-1001061351629 ,message,NULL,false,false,reply_id);


-------------------

also I'm not sure to understand if reply_id is important here, I'm guessing it is only here to identify this reply in case I would want to reply to it later on.

but maybe I'm wrong?

 
tdbguy:

I passed all morning on it and I come across an issue,



What I'm doing is making last_message_id = OrderTicket(); in

and since the orderticket is the same when I close the trade, I'm think that it should recognise the message in telegram and replies to it right? so when a trade close

long replies = OrderTicket();

No , the last_message_id is what the SendMessageGetID returns to you (its passed as reference if you noticed , you are giving the function a long variable to write the id to). Its the Id of the message in the channel so you can quote it. Lets Call the ID it "TradeIdInTelegramChannel"

What you have to do is create arrays and associate  "TradeIdInTelegramChannel"  with OrderTicket() , so your system (not mt4 ,not telegram) knows that order with ticket x was posted in telegram with  "TradeIdInTelegramChannel" .

Thats the id you have to send to be quoted .

also I'm not sure to understand if reply_id is important here "
its not , its a placeholder and wont be used as you cant stack replies (like in reddit)  on telegram
 

Oh my god ,messy answer ,sorry(just having coffee)

Let me simplify

  1. Your ea opens a buy order with ticket 16425
  2. You now know that ticket because the trade went through .
  3. What you want to do now is post to your channel about the opening of this trade
  4. You form a message and call SendMessageGetID 
  5. The SendMessageGetID function , provides an ID -fills in- variable last_message_id (if the function fails it fills it with -1)
  6. So after the post for your trade is done in the channel, last_message_id (if not -1) has the position of the message in the channel (essentially)
  7. So your trade is posted in the channel succesfully and if you read last_message_id its 55 ,which means the thing you just posted is post #55 in the channel
  8. What your ea has to do is remember (log/save) that Buy order with MT4 Ticket 16425 is tethered/linked/related to post #55 in the channel 
  9. When order 16425 is closed ,you reply to message #55 (quoting it) .


 

Thanks but don't worry I understood your initial message ^^

Come to think of it, it was obvious that my way wasn't good because why would you ask to store values of messages if it was that simple to make replies.

I just wanted to make it work before coming back to you.


edit:

this is working well;

And for people that are stuck for storing datas and who needs to re use them later (to reply to old messages in telegram),

Lorentzos have a solution for you here ;

https://www.mql5.com/en/forum/347475

Read File - return value of variable
Read File - return value of variable
  • 2020.07.24
  • www.mql5.com
Hello, I'm writing values inside a file,line by line, like : OrderTicket1=value1 OrderTicket2=value2 OrderTicket3=value3...
 
tdbguy:

Thanks but don't worry I understood your initial message ^^

Come to think of it, it was obvious that my way wasn't good because why would you ask to store values of messages if it was that simple to make replies.

I just wanted to make it work before coming back to you.

Great , no worries ,that last sentence is how coders evolve :) 

 

I tried to send photo with TelegramL.mqh but I'm getting an error :

int res=bot.SendPhotoGetID(true,-1001061381629,urlphoto,photo_id,false,reply_id);

'SendPhotoGetID' - wrong parameters count


I don't find any documentation on TelegramL.mqh so I'm guessing it is your code.

I went into the file and altered SendMessageGetID() function with SendPhoto()  :

   
int SendPhotoGetID(bool replying_to_message,
                 long message_id_replying_to,
                 const long   _chat_id,
                 string  _text,
                 const string _photo_id,
                 const string _caption,
                 string  _reply_markup,
                        bool    _as_HTML,
                        bool    _silently,
                        long &return_id)
     {
      if(m_token==NULL)
         return(ERR_TOKEN_ISEMPTY);

      string out;
      string url=StringFormat("%s/bot%s/sendMessage",TELEGRAM_BASE_URL,m_token);
      string params=StringFormat("chat_id=%lld&photo=%s",_chat_id,_photo_id);
      if(_caption!=NULL)
         params+="&caption="+UrlEncode(_caption);

      int res=PostRequest(out,url,params,WEB_TIMEOUT);
      if(res!=0)
        {
         //--- parse result
         CJAVal js(NULL,jtUNDEF);
         bool done=js.Deserialize(out);
         if(!done)
            return(ERR_JSON_PARSING);

         //--- get error description
         bool ok=js["ok"].ToBool();
         long err_code=js["error_code"].ToInt();
         string err_desc=js["description"].ToStr();
        }
      if(!replying_to_message) params=StringFormat("chat_id=%lld&text=%s",_chat_id,UrlEncode(_text));
      if(replying_to_message)
        {
        params=StringFormat("chat_id=%lld&&reply_to_message_id=%lld&text=%s",_chat_id,message_id_replying_to,UrlEncode(_text));
        //params+="&reply_to_message_id="+IntegerToString(message_id_replying_to);
        }
      if(_reply_markup!=NULL)
         params+="&reply_markup="+_reply_markup;
      if(_as_HTML)
         params+="&parse_mode=HTML";
      if(_silently)
         params+="&disable_notification=true";

        //get message id for user to quote later if they want to
        return_id=-1;
        //--- parse result
        CJAVal js(NULL,jtUNDEF);
        bool done=js.Deserialize(out);
        if(!done) return(ERR_JSON_PARSING);
        //--- get error description
        bool ok=js["ok"].ToBool();
        if(!ok) return(ERR_JSON_NOT_OK);
        return_id=(long)js["result"]["message_id"].ToInt();
      return(res);
     } 

I'm not sure what is wrong with my code, isn't it possible to reply to a photo ?

 
tdbguy:

I tried to send photo with TelegramL.mqh but I'm getting an error :



I don't find any documentation on TelegramL.mqh so I'm guessing it is your code.

I went into the file and altered SendMessageGetID() function with SendPhoto()  :

I'm not sure what is wrong with my code, isn't it possible to reply to a photo ?

Oh , nice . 

You modified SendPhoto or SendMessageGetID ?

Reason: