Discusión sobre el artículo "Cómo crear un bot para Telegram en el lenguaje MQL5" - página 31

 

EnviarFoto

La clase ha implementado la oportunidad de enviar fotos con dos formas de aplicación.

int SendPhoto(const long   chat_id,
              const string local_path,
              string       &photo_id,
              const string caption=NULL,
              const bool   common_flag=false,
              const int    timeout=10000)
chat_id número de chat
local_path ruta local a la carpeta en <carpeta de datos>\MQL5\Files
photo_id identificador de la foto subida al servidor
pie de foto texto de la firma debajo de la foto
bandera_común bandera de ubicación del archivo en la carpeta común de todos los terminales cliente \Terminal\Common\Files
tiempo de espera tiempo de espera de la operación en milisegundos

Hay varias formas de enviar una foto.

CCustomBot bot;

string token = "208375865:AAFnuOjlZ3Wsdan6PAjeqqUtBybe0Di1or8";

bot.Token(token);

string photo_id;
int result=bot.SendPhoto(198289825,"EURUSD1.gif",photo_id,"screenshot");
if(result==0)
   Print("Photo ID: ",photo_id);
else
   Print("Error: ",GetErrorDescription(result));

Veo que tienes un signo menos.

Puedes mirar en el archivo Telegram.mqh.

//+------------------------------------------------------------------+
   int SendPhoto(const long   _chat_id,
                 const string _photo_id,
                 const string _caption=NULL)
     {
      if(m_token==NULL)
         return(ERR_TOKEN_ISEMPTY);

      string out;
      string url=StringFormat("%s/bot%s/sendPhoto",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)
        {
         //--- resultado del análisis
         CJAVal js(NULL,jtUNDEF);
         bool done=js.Deserialize(out);
         if(!done)
            return(ERR_JSON_PARSING);

         //--- obtener descripción del error
         bool ok=js["ok"].ToBool();
         long err_code=js["error_code"].ToInt();
         string err_desc=js["description"].ToStr();
        }
      //--- hecho
      return(res);
     }

   //+------------------------------------------------------------------+
   int SendPhoto(string &_photo_id,
                 const string _channel_name,
                 const string _local_path,
                 const string _caption=NULL,
                 const bool _common_flag=false,
                 const int _timeout=10000)
     {
      if(m_token==NULL)
         return(ERR_TOKEN_ISEMPTY);

      string name=StringTrim(_channel_name);
      if(StringGetCharacter(name,0)!='@')
         name="@"+name;

      if(m_token==NULL)
         return(ERR_TOKEN_ISEMPTY);

      ResetLastError();
      //--- copia el archivo en el buffer de memoria
      if(!FileIsExist(_local_path,_common_flag))
         return(ERR_FILE_NOT_EXIST);

      //---
      int flags=FILE_READ|FILE_BIN|FILE_SHARE_WRITE|FILE_SHARE_READ;
      if(_common_flag)
         flags|=FILE_COMMON;

      //---
      int file=FileOpen(_local_path,flags);
      if(file<0)
         return(_LastError);

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

      //--- create boundary: (data -> base64 -> 1024 bytes -> md5)
      uchar base64[];
      uchar key[];
      CryptEncode(CRYPT_BASE64,photo,key,base64);
      //---
      uchar temp[1024]={0};
      ArrayCopy(temp,base64,0,0,1024);
      //---
      uchar md5[];
      CryptEncode(CRYPT_HASH_MD5,temp,key,md5);
      //---
      string hash=NULL;
      int total=ArraySize(md5);
      for(int i=0;i<total;i++)
         hash+=StringFormat("%02X",md5[i]);
      hash=StringSubstr(hash,0,16);

      //--- WebRequest
      uchar result[];
      string result_headers;

      string url=StringFormat("%s/bot%s/sendPhoto",TELEGRAM_BASE_URL,m_token);

      //--- 1
      uchar data[];

      //--- añadir chart_id
      ArrayAdd(data,"\r\n");
      ArrayAdd(data,"--"+hash+"\r\n");
      ArrayAdd(data,"Content-Disposition: form-data; name=\"chat_id\"\r\n");
      ArrayAdd(data,"\r\n");
      ArrayAdd(data,name);
      ArrayAdd(data,"\r\n");

      if(StringLen(_caption)>0)
        {
         ArrayAdd(data,"--"+hash+"\r\n");
         ArrayAdd(data,"Content-Disposition: form-data; name=\"caption\"\r\n");
         ArrayAdd(data,"\r\n");
         ArrayAdd(data,_caption);
         ArrayAdd(data,"\r\n");
        }

      ArrayAdd(data,"--"+hash+"\r\n");
      ArrayAdd(data,"Content-Disposition: form-data; name=\"photo\"; filename=\"lampash.gif\"\r\n");
      ArrayAdd(data,"\r\n");
      ArrayAdd(data,photo);
      ArrayAdd(data,"\r\n");
      ArrayAdd(data,"--"+hash+"--\r\n");

      // SaveToFile("debug.txt",data);

      //---
      string headers="Content-Type: multipart/form-data; boundary="+hash+"\r\n";
      int res=WebRequest("POST",url,headers,_timeout,data,result,result_headers);
      if(res==200)//OK
        {
         //--- borrar lista de materiales
         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;
           }

         //---
         string out=CharArrayToString(result,start_index,WHOLE_ARRAY,CP_UTF8);

         //--- resultado del análisis
         CJAVal js(NULL,jtUNDEF);
         bool done=js.Deserialize(out);
         if(!done)
            return(ERR_JSON_PARSING);

         //--- obtener descripción del error
         bool ok=js["ok"].ToBool();
         if(!ok)
            return(ERR_JSON_NOT_OK);

         total=ArraySize(js["result"]["photo"].m_e);
         for(int i=0; i<total; i++)
           {
            CJAVal image=js["result"]["photo"].m_e[i];

            long image_size=image["file_size"].ToInt();
            if(image_size<=file_size)
               _photo_id=image["file_id"].ToStr();
           }

         return(0);
        }
      else
        {
         if(res==-1)
           {
            string out=CharArrayToString(result,0,WHOLE_ARRAY,CP_UTF8);
            //Imprimir(fuera);
            return(_LastError);
           }
         else
           {
            if(res>=100 && res<=511)
              {
               string out=CharArrayToString(result,0,WHOLE_ARRAY,CP_UTF8);
               //Imprimir(fuera);
               return(ERR_HTTP_ERROR_FIRST+res);
              }
            return(res);
           }
        }
      //--- 
      return(0);
     }

   //+------------------------------------------------------------------+
   int SendPhoto(string &_photo_id,
                 const long _chat_id,
                 const string _local_path,
                 const string _caption=NULL,
                 const bool _common_flag=false,
                 const int _timeout=10000)
     {
      if(m_token==NULL)
         return(ERR_TOKEN_ISEMPTY);

      ResetLastError();
      //--- copia el archivo en el buffer de memoria
      if(!FileIsExist(_local_path,_common_flag))
         return(ERR_FILE_NOT_EXIST);

      //---
      int flags=FILE_READ|FILE_BIN|FILE_SHARE_WRITE|FILE_SHARE_READ;
      if(_common_flag)
         flags|=FILE_COMMON;

      //---
      int file=FileOpen(_local_path,flags);
      if(file<0)
         return(_LastError);

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

      //--- create boundary: (data -> base64 -> 1024 bytes -> md5)
      uchar base64[];
      uchar key[];
      CryptEncode(CRYPT_BASE64,photo,key,base64);
      //---
      uchar temp[1024]={0};
      ArrayCopy(temp,base64,0,0,1024);
      //---
      uchar md5[];
      CryptEncode(CRYPT_HASH_MD5,temp,key,md5);
      //---
      string hash=NULL;
      int total=ArraySize(md5);
      for(int i=0;i<total;i++)
         hash+=StringFormat("%02X",md5[i]);
      hash=StringSubstr(hash,0,16);

      //--- WebRequest
      uchar result[];
      string result_headers;

      string url=StringFormat("%s/bot%s/sendPhoto",TELEGRAM_BASE_URL,m_token);

      //--- 1
      uchar data[];

      //--- añadir chart_id
      ArrayAdd(data,"\r\n");
      ArrayAdd(data,"--"+hash+"\r\n");
      ArrayAdd(data,"Content-Disposition: form-data; name=\"chat_id\"\r\n");
      ArrayAdd(data,"\r\n");
      ArrayAdd(data,IntegerToString(_chat_id));
      ArrayAdd(data,"\r\n");

      if(StringLen(_caption)>0)
        {
         ArrayAdd(data,"--"+hash+"\r\n");
         ArrayAdd(data,"Content-Disposition: form-data; name=\"caption\"\r\n");
         ArrayAdd(data,"\r\n");
         ArrayAdd(data,_caption);
         ArrayAdd(data,"\r\n");
        }

      ArrayAdd(data,"--"+hash+"\r\n");
      ArrayAdd(data,"Content-Disposition: form-data; name=\"photo\"; filename=\"lampash.gif\"\r\n");
      ArrayAdd(data,"\r\n");
      ArrayAdd(data,photo);
      ArrayAdd(data,"\r\n");
      ArrayAdd(data,"--"+hash+"--\r\n");

      // SaveToFile("debug.txt",data);

      //---
      string headers="Content-Type: multipart/form-data; boundary="+hash+"\r\n";
      int res=WebRequest("POST",url,headers,_timeout,data,result,result_headers);
      if(res==200)//OK
        {
         //--- borrar lista de materiales
         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;
           }

         //---
         string out=CharArrayToString(result,start_index,WHOLE_ARRAY,CP_UTF8);

         //--- resultado del análisis
         CJAVal js(NULL,jtUNDEF);
         bool done=js.Deserialize(out);
         if(!done)
            return(ERR_JSON_PARSING);

         //--- obtener descripción del error
         bool ok=js["ok"].ToBool();
         if(!ok)
            return(ERR_JSON_NOT_OK);

         total=ArraySize(js["result"]["photo"].m_e);
         for(int i=0; i<total; i++)
           {
            CJAVal image=js["result"]["photo"].m_e[i];

            long image_size=image["file_size"].ToInt();
            if(image_size<=file_size)
               _photo_id=image["file_id"].ToStr();
           }

         return(0);
        }
      else
        {
         if(res==-1)
           {
            string out=CharArrayToString(result,0,WHOLE_ARRAY,CP_UTF8);
            //Imprimir(fuera);
            return(_LastError);
           }
         else
           {
            if(res>=100 && res<=511)
              {
               string out=CharArrayToString(result,0,WHOLE_ARRAY,CP_UTF8);
               //Imprimir(fuera);
               return(ERR_HTTP_ERROR_FIRST+res);
              }
            return(res);
           }
        }
      //--- 
      return(0);
     }
   //+------------------------------------------------------------------+

Si miras en el archivo mqh puedes ver

      string name=StringTrim(_channel_name);
      if(StringGetCharacter(name,0)!='@')
         name="@"+name;

Así que en tu caso puedes probar una modificación como esta

      string name = _channel_name;
      //if(StringGetCharacter(nombre,0)!='@')
      // name="@"+nombre;
 
tdbguy:

¡No hagas doble post!

Borraré tu tema y moveré las respuestas aquí.

 
John Progton:

Andrey Voytenko básicamente he añadido los archivos que utiliza y luego modificado el script que tengo que enviar a telegram en lugar de correo electrónico cuando se ejecuta una acción comercial. Eso funciona, excepto cuando se abre un comercio que enviará el mensaje varias veces

Los mismos problemas
 

Confirmo que con la pequeña modificación del post #46, el código funciona correctamente en MT5 para enviar alertas a los canales.

Confirmo también que el envío de peticiones al bot para el control del EA está funcionando.

Pero, ¿alguien ha conseguido bloquear las peticiones del bot al EA en un solo "from_id" para que el bot solo escuche las peticiones de un ID especifico?

 
huwa:

Confirmo que con la pequeña modificación del post #46, el código funciona correctamente en MT5 para enviar alertas a los canales.

Confirmar también que enviar solicitudes al bot para EA de control está funcionando.

Pero, ¿alguien ha conseguido bloquear las peticiones del bot al EA en un solo "from_id" para que el bot solo escuche las peticiones de un ID especifico?

Para aquellos que quieran bloquear las peticiones del bot al ID de cuenta de Telegram, encontrar esta línea en Telegram.mqh :


//--- filtro
   //if(m_users_filter.Total()==0 || (m_users_filter.Total()>0 && m_users_filter.SearchLinear(msg.from_username)>=0)) //Eliminar esta línea del código
   if(msg.from_id==??????????)   /Agrega esta línea al código donde ?????????? es el ID de tu cuenta de Telegram


 
Wow gracias Andrey Voytenko por compartir tus conocimientos, es muy útil para principiantes como yo

Telegram_Bot_EA y Telegram_Search_EA funcionan muy bien, pero no con el último ( Telegram_signal_EA ).
No me daba señal en mi canal.

Lo que hice es:
- Hacer un bot, añadirlo a mi canal y ponerlo como administrador.
- Cambiar su código con mi indicador
- Cambiar Telegram.mqh para hacer canal privado

Después de ejecutar Telegram_singal_EA, puedo ver el nombre de mi bot pero sigo sin recibir señal.


Cada tick me da error:

Telegram_Signal_EA GBPUSD,M1: Error:Bad Request

Telegram_Signal_EA GBPUSD,M1: {"ok":false, "error_code":400, "description": "Bad Request: chat not found"}


¿Tienes alguna sugerencia?

 

@ade kurniawan deberías trabajar con canales privados usando el ID del chat (no el nombre del canal).

 
Andrey Voytenko:

@ade kurniawan deberías trabajar con canales privados usando el ID del gráfico (no el nombre del canal).

Sí, ya lo he cambiado. Todavía con el mismo error. Incluso cambio todo a canal público
 

¿Alguien ha probado las fuentes BOLD o ITALIC usando esta librería?
He probado **bold** __italic__ con markdown en el mensaje como sigue pero no hay...


"n**boldtext** __italictext__ Balance: $%s parse_mode=MARKDOWN"

El resultado es:

**boldtext** __italictext__ Saldo: $10056.21 parse_mode=MARKDOWN
 

No importa....

Encontré la respuesta poniendo la bandera AsHTML a true...

bot.SendMessage(InpTelegramId,"<b>Balance: $10056.21</b>",true);

Lo siento...


spottypegasus:

¿Alguien ha probado las fuentes BOLD o ITALIC usando esta librería?
He probado **bold** __italic__ con markdown en el mensaje como sigue pero no hay manera...


"n**boldtext** __italictext__ Balance: $%s parse_mode=MARKDOWN"

El resultado es:

**boldtext** __italictext__ Saldo: $10056.21 parse_mode=MARKDOWN