Die Erstellung des Bots für Telegram in der Sprache MQL5
Andriy Voitenko | 24 Juni, 2016
Einführung
Am 12. April 2016 auf der Konferenz F8 in San Francisco hat das Unternehmen Facebook die Einführung des API für Bots in seinem Messenderer angekündigt. Am selben Tag kam eine große Upgrade für den Plattform Telegram Bot Platform. Die Version 2.0 hat mit den neuen Funktionen gefreut. Es scheint, dass für die gut vergessenen alten Dinge, nämlich für Bots, wieder Interessen erwachen, die in der Ära der ICQ beliebt waren. In der neuen Entwicklungsphase wird den Bots besser gedachte Funktionalität, eine offene Interface für die Programmierung, Multimedia-Unterstützung gegeben. Im Allgemeinen haben sie jetzt alles, damit sie nicht ersetzbar sein könnten, wenn Sie etwas finden, sehen oder kaufen möchten.
Dieser Artikel wurde als eine Anleitung gedacht, um Schritt um Schritt Bots für Telegramm in MQL5 zu erstellen. Was ist denn das ein Bot? Ein Bot (Kurzform für "Roboter") – ein Sonderprofil im Telegram, für das die Möglichkeit vorgesehen ist, um die Nachrichten über Software auszutauschen. Der Bot läuft auf Ihrer (Client) Seite und interagiert mit dem Telegramm-Server über einen speziellen Satz von Befehlen, die in Bot API enthalten sind. Bevor wir anfangen, den Bot direkt zu erstellen, bitte installieren Sie Telegramm und melden Sie sich an diesem Server an. Die Anmeldung wird mit Handynummer verbunden, aber zusätzlich können Sie einen Spitznamen @username haben, dass man Sie durch den Namen finden kann. Jetzt ist es die Zeit, den Ordner aller Bots kennen zu lernen.
Die Registrierung eines neuen Bots
Für die Registrierung und Einstellung der Bots ist ein besonderer Bot @BotFather verantwortlich. Wir finden ihn über die Suche. Nach dem Hinzufügen zur Kontakt-Liste beginnen wir mit ihm zur unternehmen, durch den Befehl/start. Als Reaktion darauf wird er eine Liste aller verfügbaren Befehle senden, wie es in Abbildung 1 dargestellt ist.
.
Abb.1. Die Befehle-Liste @BotFather.
Mit dem Befehl/newbot beginnen wir den neuen Bot zu registrieren. Es müssen zwei Namen ausgedacht werden. Der erste – Name (name) des Bots, den Sie in Ihrer Muttersprache eingeben können. Der zweite - der Name vom Bot-Benutzer (username) auf lateinisch, der mit dem Präfix “bot” endet. Als Ergebnis erhalten wir einen Token - der Zugriffsschlüssel für die Arbeit mit dem Bot durch die API. Das Beispiel der Registrierung wurde in Abbildung 2 aufgeführt.
Abb.2. Die Registrierung eines neuen Bots.
Einige Einstellungen können nach freiem Ermessen geändert werden. Die Inline-Modus-Einstellungen würde ich nicht berühren. Unsere Bots werden mit ihm nicht zusammenarbeiten. Ich empfehle nur die kosmetischen Eigenschaften zu setzen:- /setcommands – die Referenzliste der unterstützten Befehle. Diese Liste wird Benutzer in einem Popup-Fenster angezeigt, wenn Sie das Zeichen "/" im Chat-Fenster eingeben.
- /setuserpic – die Einstellung des Profilbildes. Ohne Foto sieht ein Bot würdelos aus.
- /setdescription – Der Text, der als Gruß erscheinen wird, wenn Sie einen Bot zum Messenger hinzufügen werden. Normalerweise zeigt man hier in wenigen Sätzen den Zweck des Bots.
Also, so wird der Bot registriert. Lassen Sie uns jetzt darüber reden, in welchen Modi er verwendet werden kann.
Bots Modi
Das Telegramm hat drei Schema der Interaktion zwischen Bots und den Benutzern. Erstens - es sind private Chats. Jeder Benutzer kommuniziert mit dem Bot in einem Anfrage-Antwort-Modus unabhängig voneinander, wie es in Abbildung 3 dargestellt ist.
Abb.3. Bot und private Chats.
Benutzer senden eine Nachricht an den Bot. Diese Nachrichten bleiben auf dem Server nicht länger als ein Tag gespeichert, und dann werden sie entfernt. Der Bot hat Zeit, diese Nachrichten anzufordern und auf sie zu reagieren. Dies ist der Hauptmodus, in dem unsere Bots arbeiten.
Der zweite Modus - sind Gruppen-Chats. Hier sind die Nachrichten, die von einem der Mitglieder der Gruppe geschickt wurden, die sehen alle (Abbildung 4).
Abb.4. Der Bot im Gruppen-Chat.
Bezüglich der Bots, sie dürfen durch den Befehl / setjoingroups in der Gruppe beitreten. Wenn der Bot zu der Gruppe hinzugefügt wurde, dann kann ihm durch den Befehl/setprivacy die Option ermöglicht werden, entweder alle Nachrichten empfangen zu können oder nur diejenigen, die mit dem Symbol "/" Tag-Team beginnen. Ehrlich gesagt, es ist mir gelungen, nur einen Zweck für den Bot in diesem Modus auszudenken - eben die Statistiken der Meldungen für die spätere Analyse zu sammeln.
Der dritte Modus - das ist die Arbeit auf dem Kanal. Die Kanäle im Telegramm - es sind die Accounts für die Broadcast der Nachrichten an ein großes Publikum, die eine unbegrenzte Anzahl von Abonnenten unterstützen. Ein wichtiges Merkmal des Kanals ist die Unfähigkeit der Nutzer, Kommentare und Daumen im den Nachrichten-Kanal hinterzulassen (nur einseitige Kommunikation). Die Nachrichten im Kanal dürfen nur Administratoren des Kanals hinterlassen (siehe Abbildung 5).
Abb.5. Bot als Kanal-Administrator.
Zu der Liste der Administratoren kann man auch Bots hinzufügen. So macht es vom Kanal ein perfektes Werkzeug für die Verteilung der Handelssignalen. Später werden wir einen einfachen Bot schreiben, der die Signale vom standarten MACD-Indikator veröffentlichen wird. Die Erstellung eines neuen öffentlichen Kanals ist über das Menü "Neuer Kanal" des Messengers möglich. Vergessen Sie nicht, Ihren Bot zur Liste der Administratoren des Kanals hinzufügen. Dies wird durch die Kanal-Eigenschaften durchgeführt. Damit sind die Vorbereitungen abgeschlossen, und wir können mit der Programmierung beginnen.
Die Verarbeitung der Nachrichten
Während des Schreibens dieses Artikels hatte ich die Aufgabe, eine Klasse zu erstellen, welche die Verarbeitungsroutine der Nachrichten übernimmt und ermöglicht Ihnen auf die Arbeitslogik des Bots zu konzentrieren. Dadurch wurde die Klasse CCustomBot geschrieben, welche die minimale benötigte Funktionalität für die Arbeit realisiert.
Die Kommunikation mit dem Server erfolgt über POST-Anfragen mit der Funktion WebRequst. Für jeder Befehl ist seine eigene URL vorgesehen:
https://api.telegram.org/bot< TOKEN >/ METHOD_NAME
wo, TOKEN – das Token des registrierten Bots; METHOD_NAME — eine Liste der unterstützten Methoden.
Die Antworten kommen aus dem Server im JSON-Format, deswegen wurde einen guten JSON-Parser benötigt. Ich verwendete einen nativen Parser JSON Serialization and Deserialization. Ich möchte Alexei, (sergeev) für seine Arbeit bedanken. Das Feld wurde auch für die Anzeige einige Parameter verwendet. Die Klasse CComment, die aus Codebase ist, passte zu dieser Aufgabe. Für die Universalität der öffentlichen Klassenmethoden wurden die Namen aus der Dokumentation für die Bot-API gelehnt. Die Liste der Methoden, die in der Klasse realisiert wurden, ist unten dargestellt:
Wir betrachten gründlicher die Programmierung, um zu verstehen, wie man diese Funktionen verwenden soll.
GetMe
Da das Token bei jeder Anfrage gesendet wird, wurde vor allem die Funktion GetMe realisiert, die ihn auf Echtheit überprüft. Diese Überprüfung soll beim Start des EAs durchgeführt werden, und falls ein Fehler auftritt, muss der Benutzer darüber informiert werden.
int GetMe() | |
Rückgabewert | Der Code des Fehlers |
Falls alles erfolgreich läuft, setzt GetMe 0 zurück, und durch die Methode Name() kann man den Name des Bots (username) erfahren. Dieser Name wird in der Arbeit nicht teilnehmen. Jedoch wird es auf dem Bildschirm als Information angezeigt. Eine solche Adresse wie telegram.me/ <botname> ermöglicht Ihnen die Web-Version des Messengers zu verwenden, und es wird als Werbungslink für Ihren Bot dienen. Der Expert mit der Tokens Überprüfung in der OnInit kann folgendermaßen aussehen:
//+------------------------------------------------------------------+ //| Telegram_GetMe.mq5 | //| Copyright 2014, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2014, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" #property strict #include <Telegram.mqh> input string InpToken="177791741:AAH0yB3YV7ywm80af_-AGqb7hzTR_Ud9DhQ";//Token CCustomBot bot; int getme_result; //+------------------------------------------------------------------+ //| OnInit | //+------------------------------------------------------------------+ int OnInit() { //--- set token bot.Token(InpToken); //--- check token getme_result=bot.GetMe(); //--- run timer EventSetTimer(3); OnTimer(); //--- done return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| OnDeinit | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { Comment(""); } //+------------------------------------------------------------------+ //| OnTimer | //+------------------------------------------------------------------+ void OnTimer() { //--- show error message end exit if(getme_result!=0) { Comment("Error: ",GetErrorDescription(getme_result)); return; } //--- show bot name Comment("Bot name: ",bot.Name()); //---{ insert your code here } } //+------------------------------------------------------------------+
GetUpdates
Die Hauptfunktion GetUpdates liest eine Reihe von Nachrichten, die auf dem Server gespeichert bleiben. Die muss über Timeframe aufgerufen werden. Die Aktualisierungszeit des Timers ist besser, nicht weniger als 1 Sekunde zu setzen, um den Server nicht zu belasten.
int GetUpdate() | |
Rückgabewert | Der Code des Fehlers |
Betrachten wir besser den Inhalt dieser Funktion. Wenn sie aufgerufen wird, werden alle ungelesenen Nachrichten von Benutzern gelesen und analysiert. Ein Beispiel einer dieser Nachrichten wird unten dargestellt:
{ "ok":true, "result":[ { "update_id":349778698, "message":{ "message_id":2, "from":{ "id":198289825, "first_name":"Andriy", "last_name":"Voitenko", "username":"avaticks" }, "chat":{ "id":198289825, "first_name":"Andriy", "last_name":"Voitenko", "username":"avaticks", "type":"private" }, "date":1459775817, "text":"\/start" } } ] }
Der Benutzer mit dem Nickname avaticks hat dem Bot den Befehl / start gegeben. Das Ziel ist, solche Nachrichten zu halten, und weiter auf sie zu reagieren. Dabei ist diese eindeutige Nummer des Charts chat[id] ist der Identifikator. Der gleiche Benutzer, der mit dem Bot durch verschiedene Geräte kommuniziert, hat unterschiedliche Chats-Identifikator. Diese Einstellung passt als eindeutiger Schlüssel für die Erstellung der Chat-Liste. Während der Arbeit wird der Bot eine Reihe von Chats speichern und bei jedem von ihnen die letzte gesendete Nachricht aktualisieren. Wenn wir darauf reagieren, wird diese Nachricht als bearbeitete angenommen und er wird durch die Flagge done gekennzeichnet. Der Typ des Chats ist ebenfalls bekannt. Es kann entweder ein privates Chart (privat) sein, oder ein Gruppen-Chart (Gruppe).
Um einen eigenen Bot zu schreiben, sollten wir nur CCustomBot fortsetzen und in seiner Klasse die virtuelle Funktion ProcessMessage neu zu definieren, die dafür vorgesehen ist, um Ihren eigenen Logik da zu realisieren. Ein kompletter Bot nach der Telegramms Dokumentation muss in der Lage sein, auf zwei Befehle "/start" und "/help" zu reagieren. Lassen Sie uns den ersten Bot schreiben, der auf diese Befehle reagieren wird.
//+------------------------------------------------------------------+ //| Telegram_GetUpdates.mq5 | //| Copyright 2014, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2014, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" #property strict #include <Telegram.mqh> //+------------------------------------------------------------------+ //| CMyBot | //+------------------------------------------------------------------+ class CMyBot: public CCustomBot { public: void ProcessMessages(void) { for(int i=0; i<m_chats.Total(); i++) { CCustomChat *chat=m_chats.GetNodeAtIndex(i); //--- if the message is not processed if(!chat.m_new_one.done) { chat.m_new_one.done=true; string text=chat.m_new_one.message_text; //--- start if(text=="/start") SendMessage(chat.m_id,"Hello, world! I am bot. \xF680"); //--- help if(text=="/help") SendMessage(chat.m_id,"My commands list: \n/start-start chatting with me \n/help-get help"); } } } }; //--- input string InpToken="177791741:AAH0yB3YV7ywm80af_-AGqb7hzTR_Ud9DhQ";//Token //--- CMyBot bot; int getme_result; //+------------------------------------------------------------------+ //| OnInit | //+------------------------------------------------------------------+ int OnInit() { //--- set token bot.Token(InpToken); //--- check token getme_result=bot.GetMe(); //--- run timer EventSetTimer(3); OnTimer(); //--- done return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| OnDeinit | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { Comment(""); } //+------------------------------------------------------------------+ //| OnTimer | //+------------------------------------------------------------------+ void OnTimer() { //--- show error message end exit if(getme_result!=0) { Comment("Error: ",GetErrorDescription(getme_result)); return; } //--- show bot name Comment("Bot name: ",bot.Name()); //--- reading messages bot.GetUpdates(); //--- processing messages bot.ProcessMessages(); } //+------------------------------------------------------------------+Das Ergebnis seiner Arbeit wurde in Abb.6. dargestellt.
Abb.6. Der Bot mit einem minimalen Satz von Befehlen.
Die Arbeit mit der Tastatur
Für die interaktive Kommunikation mit dem Benutzer wurde für Bots eine "Tastatur" ausgedacht. Bei der Sendung einer Nachricht kann man für jedes Chat eine “Tastatur” mit einem vorgegebenen Satz von Buchstaben anzeigen. Durch das Drücken auf die Taste sendet der Benutzer eine Nachricht mit dem Text. So wird die Interaktion zwischen einem Bot und einem Benutzer viel einfacher.
Die Klasse hat drei Funktionen für die Arbeit mit der Tastatur. Die erste erzeugt ein Tastatur-Objekt.
string ReplyKeyboardMarkup(const string keyboard, const bool resize, const bool one_time) | |
keyboard | die Zeile, die die Anordnung der Tasten bestimmt |
resize | die Erlaubnis für die Änderung der Tasten-Größe |
one_time | zeigt die Tastatur nur einmal. Nach dem Drücken auf die Taste verschwindet die Tastatur. |
Rückgabewert | Die Zeile (JSON Objekt), die als Parameter reply_markup bei der Sendung der Nachricht mit SendMessage gesendet werden muss |
Die zweite Funktion verbirgt die Tastatur.
string ReplyKeyboardHide() | |
Rückgabewert | Die Zeile (JSON Objekt), die als Parameter reply_markup bei der Sendung der Nachricht mit SendMessage gesendet werden muss |
Die dritte Funktion ermöglicht eine kleines Feld zu schicken, deren Form anzeigt, dass der Bot von Ihnen in Textform auf eine Antwort wartet (Die Tastatur wird nicht gezeigt).
string ForceReply() | |
Rückgabewert | Die Zeile (JSON Objekt), die als Parameter reply_markup bei der Sendung der Nachricht mit SendMessage gesendet werden muss |
Wir wenden jetzt betrachten, wie man diese Funktionen verwenden soll.
SendMessage
Die Tastatur kann in nicht sich selbst angezeigt oder verborgen werden. Die Aktion wird zusammen mit der Nachricht gesendet. Die Funktion SendMessage für die Sendung der Nachricht ins Chat sieht so aus:
int SendMessage(const long chat_id, const string text, const string reply_markup=NULL) | |
chat_id | Die Nummer des Chats |
text | Nachricht |
reply markup | Tastatur (JSON Objekt) |
Rückgabewert | Der Code des Fehlers |
In diesem Fall ist die Tastatur optional. Wir können einfache Textnachrichten von unseren MMS-Programmen senden. Meiner Meinung nach ist diese Funktion noch interessanter als die native SendNotification. Zum einen können wir Nachrichten häufiger senden (etwa einmal pro Sekunde). Zweitens wird das HTML-Format unterstützt. Ebenfalls ist wichtig der Vorteil, Icons zu senden.
Der Telegramm unterstützt eine große Anzahl von Icons (Emoji), deren Tabelle man hier sehen kann. Wie Sie sehen können, die überwiegende Mehrheit von Icons Codes ist im Bereich von (1F300 - 1F700) zu sehen. Ihre Fähigkeit geht über die Double-Byte-Zeichenketten, die in MQL5 angenommen sind. Wenn Sie die oberen Bits entfernen, so dass nur eine Zwei-Byte-Zahl bleibt, dann wird der resultierende Bereich (F300 - F700) in den Bereich (E000- F8FF) fällt, der in der Unicode-Tabelle für den privaten Verbrauch reserviert ist. Somit hindert uns nichts, für die Sendung der Icons, die beiden Bytes zu verwenden. Die Meldungszeile mit dem klassischen Smiley-Gesicht und mit dem Code U + 1F642 kann folgendermaßen aussehen:
string text="Have a nice day.\xF642";//Der Text der Nachricht mit dem Smiley U+1F642
Dasselbe gilt für Taten, da sie im wesentlichen ein Text sind. Nichts hindert uns, die Icons auf den Tasten zu verwenden. Lassen Sie uns ein Beispiel schreiben, das drei Tasten mit Ereignisverarbeiter angezeigt.
//+------------------------------------------------------------------+ //| Telegram_SendMessage.mq5 | //| Copyright 2014, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2014, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" #property strict #include <Telegram.mqh> //+------------------------------------------------------------------+ //| CMyBot | //+------------------------------------------------------------------+ class CMyBot: public CCustomBot { private: string m_button[3]; public: //+------------------------------------------------------------------+ void CMyBot::CMyBot(void) { m_button[0]="Button #1"; m_button[1]="Button #2"; m_button[2]="Button #3"; } //+------------------------------------------------------------------+ string GetKeyboard() { return("[[\""+m_button[0]+"\"],[\""+m_button[1]+"\"],[\""+m_button[2]+"\"]]"); } //+------------------------------------------------------------------+ void ProcessMessages(void) { for(int i=0;i<m_chats.Total();i++) { CCustomChat *chat=m_chats.GetNodeAtIndex(i); if(!chat.m_new_one.done) { chat.m_new_one.done=true; string text=chat.m_new_one.message_text; //--- start or help commands if(text=="/start" || text=="/help") bot.SendMessage(chat.m_id,"Click on the buttons",bot.ReplyKeyboardMarkup(GetKeyboard(),false,false)); //--- on click event int total=ArraySize(m_button); for(int k=0;k<total;k++) { if(text==m_button[k]) bot.SendMessage(chat.m_id,m_button[k],bot.ReplyKeyboardMarkup(GetKeyboard(),false,false)); } } } } }; input string InpToken="177791741:AAH0yB3YV7ywm80af_-AGqb7hzTR_Ud9DhQ";//Token CMyBot bot; int getme_result; //+------------------------------------------------------------------+ //| OnInit | //+------------------------------------------------------------------+ int OnInit() { //--- set token bot.Token(InpToken); //--- check token getme_result=bot.GetMe(); //--- run timer EventSetTimer(1); OnTimer(); //--- done return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| OnDeinit | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { Comment(""); } //+------------------------------------------------------------------+ //| OnTimer | //+------------------------------------------------------------------+ void OnTimer() { //--- show error message end exit if(getme_result!=0) { Comment("Error: ",GetErrorDescription(getme_result)); return; } //--- show bot name Comment("Bot name: ",bot.Name()); //--- reading messages bot.GetUpdates(); //--- processing messages bot.ProcessMessages(); } //+------------------------------------------------------------------+
Als Ergebnis erhalten wir eine Nachricht von der Tastatur, wie in Abb. 7 gezeigt ist.
Abb.7. Eine Nachricht mit der Tastatur.
//+------------------------------------------------------------------+ //| Telegram_SendMessage.mq5 | //| Copyright 2014, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2014, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" #property strict #include <Telegram.mqh> #define MUTE_TEXT "Mute" #define UNMUTE_TEXT "Unmute" #define LOCK_TEXT "Lock" #define UNLOCK_TEXT "Unlock" #define RADIO_SELECT "\xF518" #define RADIO_EMPTY "\x26AA" #define MUTE_CODE "\xF515" #define UNMUTE_CODE "\xF514" #define LOCK_CODE "\xF512" #define UNLOCK_CODE "\xF513" //+------------------------------------------------------------------+ //| CMyBot | //+------------------------------------------------------------------+ class CMyBot: public CCustomBot { private: string m_radio_button[3]; int m_radio_index; bool m_lock_state; bool m_mute_state; public: //+------------------------------------------------------------------+ void CMyBot::CMyBot(void) { m_radio_button[0]="Radio Button #1"; m_radio_button[1]="Radio Button #2"; m_radio_button[2]="Radio Button #3"; m_radio_index=0; m_lock_state=false; m_mute_state=true; } //+------------------------------------------------------------------+ string GetKeyboard() { //--- string radio_code[3]={RADIO_EMPTY,RADIO_EMPTY,RADIO_EMPTY}; if(m_radio_index>=0 && m_radio_index<=2) radio_code[m_radio_index]=RADIO_SELECT; //--- string mute_text=UNMUTE_TEXT; string mute_code=UNMUTE_CODE; if(m_mute_state) { mute_text=MUTE_TEXT; mute_code=MUTE_CODE; } //--- string lock_text=UNLOCK_TEXT; string lock_code=UNLOCK_CODE; if(m_lock_state) { lock_text=LOCK_TEXT; lock_code=LOCK_CODE; } //--- //Print(m_lock.GetKey()); return(StringFormat("[[\"%s %s\"],[\"%s %s\"],[\"%s %s\"],[\"%s %s\",\"%s %s\"]]", radio_code[0],m_radio_button[0], radio_code[1],m_radio_button[1], radio_code[2],m_radio_button[2], lock_code,lock_text, mute_code,mute_text)); } //+------------------------------------------------------------------+ void ProcessMessages(void) { for(int i=0;i<m_chats.Total();i++) { CCustomChat *chat=m_chats.GetNodeAtIndex(i); if(!chat.m_new_one.done) { chat.m_new_one.done=true; string text=chat.m_new_one.message_text; //--- start if(text=="/start" || text=="/help") { bot.SendMessage(chat.m_id,"Click on the buttons",bot.ReplyKeyboardMarkup(GetKeyboard(),false,false)); } //--- Click on a RadioButton int total=ArraySize(m_radio_button); for(int k=0;k<total;k++) { if(text==RADIO_EMPTY+" "+m_radio_button[k]) { m_radio_index=k; bot.SendMessage(chat.m_id,m_radio_button[k],bot.ReplyKeyboardMarkup(GetKeyboard(),false,false)); } } //--- Unlock if(text==LOCK_CODE+" "+LOCK_TEXT) { m_lock_state=false; bot.SendMessage(chat.m_id,UNLOCK_TEXT,bot.ReplyKeyboardMarkup(GetKeyboard(),false,false)); } //--- Lock if(text==UNLOCK_CODE+" "+UNLOCK_TEXT) { m_lock_state=true; bot.SendMessage(chat.m_id,LOCK_TEXT,bot.ReplyKeyboardMarkup(GetKeyboard(),false,false)); } //--- Unmute if(text==MUTE_CODE+" "+MUTE_TEXT) { m_mute_state=false; bot.SendMessage(chat.m_id,UNMUTE_TEXT,bot.ReplyKeyboardMarkup(GetKeyboard(),false,false)); } //--- Mute if(text==UNMUTE_CODE+" "+UNMUTE_TEXT) { m_mute_state=true; bot.SendMessage(chat.m_id,MUTE_TEXT,bot.ReplyKeyboardMarkup(GetKeyboard(),false,false)); } } } } };
Als Ergebnis erhalten wir ein Fenster in dieser Form (in Abb.8).
Abb.8. Die Steuerungselementen RadioButton und CheckBox
Wie Sie sehen können, geben hier Icons größere Sichtbarkeit an Einstellungen. Zusätzlich zu diesen Steuerungselementen können wir auch leicht ein hierarchisches Menü mit der Navigation in jedem Untermenü. In der Regel hängt alles von der Funktionalität ab, die Sie ausdenken und realisieren möchten.
Wenn wir eine Nachricht im Kanal veröffentlichen wollen, dann gibt es dafür eine zweite Variante SendMessage.
int SendMessage(const string channel_name, const string text) | |
channel_name | Der Kanal-Name in Form von @name |
text | Der Text der Meldung. Es werden Tegs HTML unterstützt. |
Rückgabewert | Der Code des Fehlers |
Das Ergebnis der Arbeit dieser Funktion wird in Abb.9. dargestellt
Die Arbeit mit Multimedia
Die Bots sind in der Lage, Bilder, Audio- und Videodateien, sowie Sprachnachrichten , Aufkleber und Standortkoordinaten auszutauschen. Im Moment des Schreibens dieses Artikels wurde eine neue Version des Bot-API 2.0 veröffentlicht, welche die Möglichkeit hat, die Kontaktinformationen und Einladungen zu einem Treffen auszutauschen. Von der gesamten Liste ist für unsere Bots aktuell, nur mit Fotografien auszutauschen.
SendPhoto
In der Klasse wurde die Möglichkeit realisiert, die Fotos mit den zwei Anwendungsfällen zu senden.
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 | Die Nummer des Chats |
local_path | der lokale Weg zur Datei in Ordner <Datenverzeichnis>\MQL5\Files |
photo_id | Der Identifikator der Fotos, die im Server geladen sind |
caption | Die Textunterschrift unter dem Foto |
common_flag | Die Flagge des Speicherorts in einem öffentlichen Ordner für alle Client-Terminals \Terminal\Common\Files |
timeout | Der Timeout der Operationen in Millisekunden |
Das Beispielcode, das ein Foto sendet:
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));
Ich denke, Sie werden Gelegenheiten haben, wenn Sie ein Foto an mehreren Benutzern senden müssen oder das gleiche Foto immer wieder senden. In diesem Fall ist es sinnvoll, ein Foto einmal hochzuladen und für die wiederholende Sendung den Identifikator photo_id zusammen mit der zweiten Variante der Funktion SendPhoto zu verwenden:
int SendPhoto(const long chat_id, const string photo_id, const string caption=NULL) | |
chat_id | Die Nummer des Chats |
photo_id | Der Identifikator der Fotos, die im Server geladen sind |
caption | Die Textunterschrift unter dem Foto |
SendChartAction
Stellen Sie sich vor, dass Sie eine Antwort vom Benutzer verarbeiten, und sind schon bereit, ihm das Ergebnis zu geben. Aber für die Erstellung der Antwort haben Sie ein paar Sekunden verbracht. Es wäre brav, den Benutzer zu warnen, dass Sie im Prozess sind. Dafür gibt es ein Ereignis. Zum Beispiel, während das Screenshot des Charts sich bildet, um dies dem Benutzer zu senden, können Sie das Ereignis senden "Foto Senden". Das wird mit SendChatAction durchgeführt.
int SendChatAction(const long chat_id, const ENUM_CHAT_ACTION actiona) | |
chat_id | Die Nummer des Chats |
action | Der Identifikator des Ereignis |
Bots Beispiele
Der erste Bot Telegram_Bot_EA ermöglicht die Information über das Konto zu bekommen, auch über Notierungen und Screenshots der Chats. Seine Arbeit ist in diesem Video gezeigt.
Der zweite Bot Telegram_Search_EA sendet die Suchergebnisse auf der Web-Seite MQL5.com. Sicherlich wird es Ihnen interessant sein, wie es im folgenden Video arbeiten wird.
Der dritte Bot Telegram_Signal_EA veröffentlicht auf dem Kanal die Signale vom standarten Indikator MACD. Ich denke, man kann leicht den MACD-Indikator um seinen Lieblingsindikator ersetzen und diesen Code für sich selbst verwenden.
//+------------------------------------------------------------------+ //| Telegram_Signal_EA_v1.mq4 | //| Copyright 2014, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2014, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" //+------------------------------------------------------------------+ //| Includes | //+------------------------------------------------------------------+ #include <Telegram.mqh> //--- Input parameters input string InpChannelName="@forexsignalchannel";//Channel Name input string InpToken="177791741:AAH0yB3YV7ywm80af_-AGqb7hzTR_Ud9DhQ";//Token //--- Global variables CCustomBot bot; int macd_handle; datetime time_signal=0; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { time_signal=0; //--- set token bot.Token(InpToken); //--- get an indicator handle macd_handle=iMACD(NULL,0,12,26,9,PRICE_CLOSE); if(macd_handle==INVALID_HANDLE) return(INIT_FAILED); //--- done return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- get time datetime time[1]; if(CopyTime(NULL,0,0,1,time)!=1) return; //--- check the signal on each bar if(time_signal!=time[0]) { //--- first calc if(time_signal==0) { time_signal=time[0]; return; } double macd[2]={0.0}; double signal[2]={0.0}; if(CopyBuffer(macd_handle,0,0,2,macd)!=2) return; if(CopyBuffer(macd_handle,1,0,2,signal)!=2) return; time_signal=time[0]; //--- Send signal BUY if(macd[1]>signal[1] && macd[0]<=signal[0]) { string msg=StringFormat("Name: MACD Signal\nSymbol: %s\nTimeframe: %s\nType: Buy\nPrice: %s\nTime: %s", _Symbol, StringSubstr(EnumToString(_Period),7), DoubleToString(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits), TimeToString(time[0])); int res=bot.SendMessage(InpChannelName,msg); if(res!=0) Print("Error: ",GetErrorDescription(res)); } //--- Send signal SELL if(macd[1]<signal[1] && macd[0]>=signal[0]) { string msg=StringFormat("Name: MACD Signal\nSymbol: %s\nTimeframe: %s\nType: Sell\nPrice: %s\nTime: %s", _Symbol, StringSubstr(EnumToString(_Period),7), DoubleToString(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits), TimeToString(time[0])); int res=bot.SendMessage(InpChannelName,msg); if(res!=0) Print("Error: ",GetErrorDescription(res)); } } } //+------------------------------------------------------------------+
Als Ergebnis erhalten Sie die Meldung, die in Abbildung 9 gezeigt ist.
Abb.9. Die Signale des Indikators MACD.
Fazit
Für diejenige, welche die Analyse basierend auf Yandex.AppMetrika für seinen Bot beteiligen wollen, können die Ressource Botan verwenden. Das Wesen des Dienstes ist, dass man an ihnen von Benutzern empfangen Nachrichten senden kann, und solche Indikatoren wie Segmentierung, Tracking, Kohortenanalyse und vieles mehr verlangen. Es gibt keine Notwendigkeit, das Messenger-Ökosystem zu verlassen, da die Statistik durch einen speziellen Bot in Form von Charts gesendet wird und ein mehr detaillierter Bericht wird in der Website erreichbar.
Ich hoffe, dieser Artikel wird Sie ermutigen, den Telegramm im Handeln zu verwenden. Ich hatte kein Ziel, ins Detail zu gehen, weil sie schon gut in der API-Dokumentation für den Bot beschrieben sind. Die Codes, die zum Artikel hinzugefügt wurden, wurden auf beiden Plattformen - und MetaTrader 4 und MetaTrader 5 angepasst.