文章 "如何采用 MQL5 创建用于 Telegram 的 bots" - 页 31 1...242526272829303132333435363738...55 新评论 Marco vd Heijden 2020.06.26 21:34 #301 发送照片 该类通过两种应用方式提供了发送照片的机会。 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) 聊天号码 聊天号码 本地路径 <data folder>\MQL5\Files 文件夹的本地路径 照片 ID 上传到服务器的照片的标识符 标题 照片下方的签名文字 common_flag 所有客户端的公共文件夹中的文件位置标志 (Terminal\Common\Files 超时 以毫秒为单位的操作超时 发送照片有几种方法。 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)); 我看到你有一个减号。 你可以查看 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) { //--- 解析结果 CJAVal js(NULL,jtUNDEF); bool done=js.Deserialize(out); if(!done) return(ERR_JSON_PARSING); //--- 获取错误描述 bool ok=js["ok"].ToBool(); long err_code=js["error_code"].ToInt(); string err_desc=js["description"].ToStr(); } //--- 完成 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(); //--- 将文件复制到内存缓冲区 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); //--- 创建边界:(数据 -> base64 -> 1024 字节 -> 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[]; //--- 添加 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",数据); //--- 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)//确定 { //--- 删除 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; } //--- string out=CharArrayToString(result,start_index,WHOLE_ARRAY,CP_UTF8); //--- 解析结果 CJAVal js(NULL,jtUNDEF); bool done=js.Deserialize(out); if(!done) return(ERR_JSON_PARSING); //--- 获取错误描述 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); //Print(out); return(_LastError); } else { if(res>=100 && res<=511) { string out=CharArrayToString(result,0,WHOLE_ARRAY,CP_UTF8); //Print(out); 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(); //--- 将文件复制到内存缓冲区 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); //--- 创建边界:(数据 -> base64 -> 1024 字节 -> 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[]; //--- 添加 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",数据); //--- 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)//确定 { //--- 删除 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; } //--- string out=CharArrayToString(result,start_index,WHOLE_ARRAY,CP_UTF8); //--- 解析结果 CJAVal js(NULL,jtUNDEF); bool done=js.Deserialize(out); if(!done) return(ERR_JSON_PARSING); //--- 获取错误描述 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); //Print(out); return(_LastError); } else { if(res>=100 && res<=511) { string out=CharArrayToString(result,0,WHOLE_ARRAY,CP_UTF8); //Print(out); return(ERR_HTTP_ERROR_FIRST+res); } return(res); } } //--- return(0); } //+------------------------------------------------------------------+ 在 mqh 文件中可以看到 string name=StringTrim(_channel_name); if(StringGetCharacter(name,0)!='@') name="@"+name; 因此,您可以尝试做如下修改 string name = _channel_name; //if(StringGetCharacter(name,0)!='@') // name="@"+name; Keith Watford 2020.06.26 23:35 #302 tdbguy: 请勿重复发帖! 我会删除您的主题并将回复移到这里。 RedProviders 2020.06.29 13:18 #303 John Progton:Andrey Voytenko 基本上,我添加了您使用的文件,然后修改了脚本,以便在执行交易操作时发送到电报而不是电子邮件。除了在开仓交易时会多次发送信息外,这个方法还是有效的。 同样的问题 huwa 2020.07.07 21:03 #304 我确认,只需对 #46 号帖子中的代码稍作修改,代码就能在 MT5 上正常工作,向通道发送警报。 我还确认,向机器人发送用于控制 EA 的请求也能正常工作。 但有人成功地将机器人向 EA 发出的请求锁定在某个 "from_id "上吗? 这样机器人就只能监听来自特定 ID 的请求。 huwa 2020.07.11 19:14 #305 huwa:我确认,只需对 #46 号帖子稍作修改,代码就能在 MT5 上正常工作,向通道发送警报。我还确认,向控制 EA 的机器人发送请求也正常。但有人成功地将机器人向 EA 发出的请求锁定在某个 "from_id "上吗? 这样机器人就只能监听来自特定 ID 的请求。 如果想将机器人请求锁定在 Telegram 帐户 ID 上,请在 Telegram.mqh 中找到这一行: //--- 过滤器 //if(m_users_filter.Total()==0 || (m_users_filter.Total()>0 && m_users_filter.SearchLinear(msg.from_username)>=0)) //从代码中删除这一行 if(msg.from_id==??????????) //在代码中添加这一行,其中 ?????????? 是您的 Telegram 账户 ID ade kurniawan 2020.07.21 15:32 #306 感谢 Andrey Voytenko 分享您的知识,这对我这样的初学者很有帮助。 Telegram_Bot_EA 和 Telegram_Search_EA 运行得很好,但最后一个(Telegram_signal_EA)却不行。 我的频道没有信号。 我的做法是 - 制作一个机器人,添加到我的频道并设置为管理员 - 用我的指标更改您的代码 - 更改 Telegram.mqh 以创建私人频道 运行 Telegram_singal_EA 后,我可以看到我的机器人名称,但仍然没有收到任何信号。 每次勾选都 会出错: Telegram_Signal_EA GBPUSD,M1:错误:请求错误 Telegram_Signal_EA GBPUSD,M1: {"ok":false, "error_code":400, "description": "Bad Request: chat not found"} 您有任何建议吗? Discussion of article "How 创建 MQL5-Telegram 集成 EA 创建 MQL5-Telegram 集成 EA Andriy Voitenko 2020.07.21 16:10 #307 @ade kurniawan 在使用私人频道时应使用聊天 ID(而不是频道名称)。 Ade Kurniawan 2020.07.21 16:12 #308 Andrey Voytenko:@ade kurniawan 你应该使用图表 ID(而不是频道名称)来处理私人频道。 是的,我已经改了。还是同样的错误。即使我将所有内容都改为公共频道 Herman Makmur 2020.08.01 06:25 #309 我试过在信息中使用**粗体** __italic__ 和标记符,如下所示,但没有成功..."n**boldtext** __italictext__ Balance: $%s parse_mode=MARKDOWN" 结果是:**boldtext** __italictext__ 余额:$10056.21parse_mode=MARKDOWN Herman Makmur 2020.08.01 06:44 #310 没关系.... 我通过将 AsHTML 标志设置为 true 找到了答案... bot.SendMessage(InpTelegramId,"<b>Balance: $10056.21</b>",true); 抱歉... spottypegasus: 我试过在信息中使用 **bold** __italic__ 和 markdown,如下所示,但没有成功..."n**boldtext** __italictext__ Balance: $%s parse_mode=MARKDOWN" 结果是:**boldtext** __italictext__ 余额:$10056.21parse_mode=MARKDOWN 1...242526272829303132333435363738...55 新评论 您错过了交易机会: 免费交易应用程序 8,000+信号可供复制 探索金融市场的经济新闻 注册 登录 拉丁字符(不带空格) 密码将被发送至该邮箱 发生错误 使用 Google 登录 您同意网站政策和使用条款 如果您没有帐号,请注册 可以使用cookies登录MQL5.com网站。 请在您的浏览器中启用必要的设置,否则您将无法登录。 忘记您的登录名/密码? 使用 Google 登录
发送照片
该类通过两种应用方式提供了发送照片的机会。
发送照片有几种方法。
我看到你有一个减号。
你可以查看 Telegram.mqh 文件。
在 mqh 文件中可以看到
因此,您可以尝试做如下修改
请勿重复发帖!
我会删除您的主题并将回复移到这里。
Andrey Voytenko 基本上,我添加了您使用的文件,然后修改了脚本,以便在执行交易操作时发送到电报而不是电子邮件。除了在开仓交易时会多次发送信息外,这个方法还是有效的。
我确认,只需对 #46 号帖子中的代码稍作修改,代码就能在 MT5 上正常工作,向通道发送警报。
我还确认,向机器人发送用于控制 EA 的请求也能正常工作。
但有人成功地将机器人向 EA 发出的请求锁定在某个 "from_id "上吗? 这样机器人就只能监听来自特定 ID 的请求。
我确认,只需对 #46 号帖子稍作修改,代码就能在 MT5 上正常工作,向通道发送警报。
我还确认,向控制 EA 的机器人发送请求也正常。
但有人成功地将机器人向 EA 发出的请求锁定在某个 "from_id "上吗? 这样机器人就只能监听来自特定 ID 的请求。
如果想将机器人请求锁定在 Telegram 帐户 ID 上,请在 Telegram.mqh 中找到这一行:
每次勾选都 会出错:
Telegram_Signal_EA GBPUSD,M1:错误:请求错误
Telegram_Signal_EA GBPUSD,M1: {"ok":false, "error_code":400, "description": "Bad Request: chat not found"}
您有任何建议吗?
@ade kurniawan 在使用私人频道时应使用聊天 ID(而不是频道名称)。
@ade kurniawan 你应该使用图表 ID(而不是频道名称)来处理私人频道。
我试过在信息中使用**粗体** __italic__ 和标记符,如下所示,但没有成功...
"n**boldtext** __italictext__ Balance: $%s parse_mode=MARKDOWN"
**boldtext** __italictext__ 余额:$10056.21parse_mode=MARKDOWN结果是:
没关系....
我通过将 AsHTML 标志设置为 true 找到了答案...
bot.SendMessage(InpTelegramId,"<b>Balance: $10056.21</b>",true);
抱歉...
我试过在信息中使用 **bold** __italic__ 和 markdown,如下所示,但没有成功...
"n**boldtext** __italictext__ Balance: $%s parse_mode=MARKDOWN"
**boldtext** __italictext__ 余额:$10056.21parse_mode=MARKDOWN结果是: