TelegramBot. Die Grundfunktionalität. Fliegen getrennt, Schnitzel getrennt. (Teil 2)

Wir entwickeln die Grundfunktionalität für den Bot in Telegrammen weiter. In den vorangegangenen Abschnitten haben wir den Punkt besprochen, dass die Arbeit des Bots beim Empfangen, Verarbeiten und Senden von Nachrichten aufgeteilt werden sollte. Versuchen wir, die grundlegenden Java Core-Tools zu verwenden, um unseren Bot multithreading- und asynchron zu machen. Wir werden eine Aufgabe entwickeln, deren Bearbeitung viel Zeit in Anspruch nimmt. Mal sehen, wie die Befehle im Telegramm funktionieren und wie sie verarbeitet werden müssen.

Dies ist eine Fortsetzung des ersten Teils des Artikels über das Programmieren von Bots für Telegramme in Java
TelegramBot-Anweisungen zum Erstellen grundlegender Funktionen für den Bot. (Teil 1)
Für wen es weiter interessant ist, sind Sie herzlich willkommen…

Ich muss sofort sagen, dass in diesem Teil viel auf einmal hinzugefügt wurde und wir im Hintergrund alle Funktionen analysieren werden, die es dem Bot ermöglichten, Multithreading durchzuführen, und warum es überhaupt benötigt wird.

Wie üblich aus der Hauptsache:
Sie finden den fertigen Code für diesen Artikel im Zweig Part2-Handlers im Git-Repository.
Der Code ist voll funktionsfähig, es reicht aus, die Daten für die Autorisierung des Bots (Name und Token) zu ändern und die Hauptmethode in der App.class-Klasse auszuführen.

Bitte beachten Sie, dass diese Klasse eine Benachrichtigung an den Bot-Administrator sendet, wenn der Bot startet, dass der Bot gestartet wurde. Die Administrator-ID des Bots wird auch in der App.class-Klasse angegeben. Wenn Sie diese nicht ändern, versucht Ihr Bot, Nachrichten an mich zu senden :)

Und weiter unten werden wir die Änderungen analysieren, die nach der Veröffentlichung des ersten Teils aufgetreten sind.

Befehlsverarbeitung


Zunächst wollen wir uns mit diesem Konzept befassen, was ein Team im Allgemeinen in einem System zur Kommunikation mit einem Telegrammbot darstellt. Abhängig von den Einstellungen des Bots können entweder Nachrichten in einem beliebigen Format oder nur speziell gestaltete Befehle angezeigt werden. Was ist der Unterschied und
wo Sie diese Nachrichtenoptionen treffen können.

  1. Klartext, normale Nachrichten.
    In dieser Form erhält der Bot Nachrichten, wenn er in PM an ihn schreibt. Wenn jedoch in den Einstellungen des Bots der Datenschutzmodus in Gruppen deaktiviert ist, werden alle Nachrichten vom Bot vollständig angezeigt. Wenn diese Einstellung aktiviert ist, werden dem Bot beim Hinzufügen zur Gruppe nur die an ihn gerichteten Befehle angezeigt. Wie sie aussehen - siehe den zweiten Absatz
  2. Speziell entwickelte Teams
    Solche Befehle beginnen immer mit einem Schrägstrich: /
    Danach kommt das Team selbst. Der Befehlstext sollte keine Leerzeichen enthalten. Ein Beispiel:
    Ich fange an
    Mit diesem Befehl startet jeder Benutzer immer die Kommunikation mit Ihrem Bot. Daher muss nach den Regeln der guten Form die Reaktion auf diesen Befehl vorgeschrieben werden.

    Bei allen Befehlen, mit denen Ihr Bot umgehen kann, ist es ratsam, die Liste der Fähigkeiten in den Einstellungen Ihres Bot zu erweitern. Dies geschieht alles in einem Telegramm mit @BotFather.

    Wählen Sie mit dem Befehl / myBots Ihren Bot und dann die Schaltfläche „Bot bearbeiten“ aus
    Sie erhalten ein Fenster, in dem alle Parameter des Bots angezeigt werden. Anschließend können Sie die gesamte Benutzeroberfläche konfigurieren und angeben, mit welchen Befehlen Ihr Bot arbeiten kann.



    Sie sind in diesem Format festgelegt:



    Wenn Sie danach einen Befehl in Ihren Bot eingeben, wird die Hilfe mit einer Liste der aufgeführten Befehle angezeigt:



    Und es gibt noch eine Nuance. Eine Gruppe kann mehrere Bots enthalten. Wenn sie gemeinsame Befehle haben (und gemeinsame Befehle obligatorisch sind, werden in den meisten Bots derselbe Start und dieselbe Hilfe implementiert), wird dem Befehl selbst ein Teil hinzugefügt, der angibt, zu welchem ​​Bot dieser Befehl gehört. Und der Befehl sieht komplett so aus:
    / start @ test_habr_bot

Und jetzt, da wir all diese Nuancen kennen, wollen wir mit Ihnen eine solche Verarbeitungsoption erstellen, die Befehle verstehen sollte, die mit einem Schrägstrich beginnen und zu unterscheiden wissen, ob der Befehl speziell an Ihren Bot oder an einen anderen gerichtet ist.

Erstellen Sie ein Paket, das die Klassen enthält, die für die Verarbeitung der Befehle verantwortlich sind.
package com.example.telegrambot.command

In der Command-Klasse listen wir alle Befehle auf, die unser Bot verstehen sollte.

public enum Command { NONE, NOTFORME, NOTIFY, START, HELP, ID } 

Wie du vorher gesehen hast, habe ich bei @BotFather darauf hingewiesen, dass der Bot 4 Teams verstehen sollte. Dies ist der Standardstart und die Standardhilfe. Wir fügen eine nützliche ID hinzu. Und noch eine, benachrichtige, worüber ich etwas später sprechen werde. Und zwei Teams, NONE und NOTFORME, die uns mitteilen, dass es sich bei der Textnachricht entweder gar nicht um einen Befehl handelt oder dass dieser Befehl nicht für unseren Bot bestimmt ist.

Fügen Sie eine weitere Hilfsklasse ParsedCommand hinzu

 import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @Getter @Setter @NoArgsConstructor @AllArgsConstructor public class ParsedCommand { Command command = Command.NONE; String text=""; } 

Der Hauptzweck ist das Speichern des Ergebnisses der Textanalyse in Objekten dieser Klasse. Es wird nur das Team selbst und den gesamten Text enthalten, der nach dem Team kommt.

Und wir werden eine separate Klasse schreiben, die die Teams für uns parsen wird. Parser- Klasse

 import javafx.util.Pair; import org.apache.log4j.Logger; public class Parser { private static final Logger log = Logger.getLogger(Parser.class); private final String PREFIX_FOR_COMMAND = "/"; private final String DELIMITER_COMMAND_BOTNAME = "@"; private String botName; public Parser(String botName) { this.botName = botName; } public ParsedCommand getParsedCommand(String text) { String trimText = ""; if (text != null) trimText = text.trim(); ParsedCommand result = new ParsedCommand(Command.NONE, trimText); if ("".equals(trimText)) return result; Pair<String, String> commandAndText = getDelimitedCommandFromText(trimText); if (isCommand(commandAndText.getKey())) { if (isCommandForMe(commandAndText.getKey())) { String commandForParse = cutCommandFromFullText(commandAndText.getKey()); Command commandFromText = getCommandFromText(commandForParse); result.setText(commandAndText.getValue()); result.setCommand(commandFromText); } else { result.setCommand(Command.NOTFORME); result.setText(commandAndText.getValue()); } } return result; } private String cutCommandFromFullText(String text) { return text.contains(DELIMITER_COMMAND_BOTNAME) ? text.substring(1, text.indexOf(DELIMITER_COMMAND_BOTNAME)) : text.substring(1); } private Command getCommandFromText(String text) { String upperCaseText = text.toUpperCase().trim(); Command command = Command.NONE; try { command = Command.valueOf(upperCaseText); } catch (IllegalArgumentException e) { log.debug("Can't parse command: " + text); } return command; } private Pair<String, String> getDelimitedCommandFromText(String trimText) { Pair<String, String> commandText; if (trimText.contains(" ")) { int indexOfSpace = trimText.indexOf(" "); commandText = new Pair<>(trimText.substring(0, indexOfSpace), trimText.substring(indexOfSpace + 1)); } else commandText = new Pair<>(trimText, ""); return commandText; } private boolean isCommandForMe(String command) { if (command.contains(DELIMITER_COMMAND_BOTNAME)) { String botNameForEqual = command.substring(command.indexOf(DELIMITER_COMMAND_BOTNAME) + 1); return botName.equals(botNameForEqual); } return true; } private boolean isCommand(String text) { return text.startsWith(PREFIX_FOR_COMMAND); } } 

Kurz gesagt. Beim Initialisieren des Parsers müssen wir den Namen unseres Bots im Konstruktor übergeben, damit der Parser seine Befehle von Fremden unterscheiden kann.

Dann rufen wir einfach die öffentliche Methode auf

 public ParsedCommand getParsedCommand(String text) 

An die wir den Nachrichtentext in den Argumenten übergeben, und er muss uns einen Befehl und den Nachrichtentext zurückgeben, der nach dem Befehl kommt.

Sie können sehen, wie der Parser in der Testklasse funktioniert.

Fliegen getrennt, Schnitzel getrennt


Jetzt müssen wir unserem Bot beibringen, Nachrichten separat zu empfangen, zu verarbeiten und Antworten zu senden. Nach einer Reihe von Versuchen bin ich zu dieser Logik der Anwendung gekommen.
Der Hauptklassen- Bot arbeitet im Haupt-Thread der Anwendung und ist nur damit beschäftigt, dass er alle empfangenen Nachrichten in eine spezielle Warteschlange stellt und auch ein Container für Nachrichten ist, die wir als Antwort an den Benutzer senden möchten.

Die Änderungen in dieser Klasse sind sehr gering. Wir haben zwei Warteschlangen hinzugefügt:

 public final Queue<Object> sendQueue = new ConcurrentLinkedQueue<>(); public final Queue<Object> receiveQueue = new ConcurrentLinkedQueue<>(); 

und den Funktionscode public void onUpdateReceived (Update update) leicht umgeschrieben

 @Override public void onUpdateReceived(Update update) { log.debug("Receive new Update. updateID: " + update.getUpdateId()); receiveQueue.add(update); } 

Warum so? Wieder habe ich verschiedene Optionen ausprobiert. Das Hauptproblem beim Multithreading ist das Arbeiten mit gemeinsam genutzten Daten. Und am meisten hat mir gefallen, wie die Implementierung von Multithread-Warteschlangen ConcurrentLinkedQueue <> () damit umgeht.
Und wie Sie sehen, werden in beiden Warteschlangen Objektdatentypen gespeichert. Dies ist ein weiteres Lesezeichen für die Zukunft. Wir sind also nicht an die Art der empfangenen Nachrichten gebunden. In der eingehenden Warteschlange können wir nicht nur Objekte vom Typ Update hinzufügen, sondern auch einige andere Objekte, die wir benötigen.

Das gleiche gilt für die Warteschlange zum Senden. Da wir verschiedene Arten von Nachrichten senden können und sie kein gemeinsames übergeordnetes Objekt haben, verwenden wir auch einen gemeinsamen Datentyp - Object.
Wenn Sie den Bot in dieser Form ausführen, wird es funktionieren, aber nichts tun. Er zeichnet alle empfangenen Nachrichten im Protokoll auf und stellt sie in die Warteschlange.
Aus diesem Grund benötigen wir einen Thread, der sich darum kümmert, empfangene Nachrichten aus der Warteschlange zu übernehmen, einige Aktionen auszuführen und die Ergebnisse seiner Arbeit in die sendQueue- Warteschlange zu stellen.

Lassen Sie uns ein separates Paket erstellen: service und darin werden wir nur 2 Klassen haben:

MessageReciever - Handler für empfangene Nachrichten
MessageSender ist der Message Queue Handler, der an den Benutzer gesendet werden soll.

Wir werden ihre Arbeit etwas niedriger betrachten, aber im Moment werden wir ihre Verwendung in unserer Startklasse- App beschreiben

Nachdem sich unser Bot verbunden hat, starten wir unsere Handler in separaten Threads:

 MessageReciever messageReciever = new MessageReciever(test_habr_bot); MessageSender messageSender = new MessageSender(test_habr_bot); test_habr_bot.botConnect(); Thread receiver = new Thread(messageReciever); receiver.setDaemon(true); receiver.setName("MsgReciever"); receiver.setPriority(PRIORITY_FOR_RECEIVER); receiver.start(); Thread sender = new Thread(messageSender); sender.setDaemon(true); sender.setName("MsgSender"); sender.setPriority(PRIORITY_FOR_SENDER); sender.start(); 

Für beide Threads geben wir den Daemon-Modus an. Dies ist erforderlich, damit die Threads funktionieren, solange der Haupt-Thread ausgeführt wird, und sich selbst beenden, sobald er seine Arbeit beendet.

Wir möchten uns nicht zuerst mit dem Handler für eingehende Nachrichten befassen - schauen wir uns die Funktionsweise der MessageSender- Klasse an.

Werfen wir einen Blick darauf, was er kann und was er tut:

  • Dies ist natürlich eine Vererbung der Schnittstelle für Multithreading:
    geräte lauffähig
    und Implementierung der Run- Funktion

     @Override public void run() 

    Hier starten wir die Endlosschleife, die nur damit beschäftigt ist, dass sie die Sendewarteschlange überprüft und den Sendebefehl aufruft

     private void send(Object object) 

    wenn etwas in der Warteschlange erscheint.
  • Im Klassenkonstruktor übergeben wir das Objekt der Bot-Klasse, weil von ihm werden wir Objekte zum Versenden von Nachrichten nehmen und mit ihm werden wir sie senden.
  • Die send-Methode bestimmt den Typ der zu sendenden Nachricht und wendet den entsprechenden Befehl darauf an.

Nun schauen wir uns die Arbeit der MessageReciever- Klasse an

Er muss, wie MessageSender, Multithreading-fähig sein, im Konstruktor ein Objekt der Klasse Bot erhalten, in dem er empfangene Nachrichten in einer Endlosschleife aufnimmt, verarbeitet und in die Warteschlange stellt, um die Ergebnisse seiner Arbeit zu senden.

Hier verwenden wir den zuvor erstellten Befehlsparser. Und dann fügen wir die Möglichkeit hinzu, verschiedene Arten von Handlern für unsere Teams zu verwenden, und einige von ihnen werden Multi-Thread-fähig sein.

Der Arbeitszyklus ist sehr einfach:

 @Override public void run() { log.info("[STARTED] MsgReciever. Bot class: " + bot); while (true) { for (Object object = bot.receiveQueue.poll(); object != null; object = bot.receiveQueue.poll()) { log.debug("New object for analyze in queue " + object.toString()); analyze(object); } try { Thread.sleep(WAIT_FOR_NEW_MESSAGE_DELAY); } catch (InterruptedException e) { log.error("Catch interrupt. Exit", e); return; } } } 

Überprüfen Sie die Warteschlange. Wenn es etwas gibt, führen Sie den Analysator aus:

 private void analyze(Object object) 

Wenn es nichts gibt, warten wir.

Der Analysator überprüft den Objekttyp. Wenn er weiß, wie er mit ihm arbeiten soll, startet er den nächsten Analysator. Wenn Sie nicht können - schwört :)

Warum so? Auch dies ist ein Lesezeichen für die Zukunft und ich hoffe, dass ich es in den nächsten Teilen dieser Artikelserie veröffentlichen werde. Eine solche Implementierung ermöglicht es uns, eigene Aufgaben für den Bot zu erstellen, Mailinglisten zu erstellen und Tagesaufgaben zu erledigen. Dazu muss der Empfänger nicht nur Objekte vom Typ Update verarbeiten können, sondern auch etwas von uns. Aber dazu später mehr :)

Betrachten Sie den Analyzer für den Aktualisierungstyp genauer:

 private void analyzeForUpdateType(Update update) { Long chatId = update.getMessage().getChatId(); String inputText = update.getMessage().getText(); ParsedCommand parsedCommand = parser.getParsedCommand(inputText); AbstractHandler handlerForCommand = getHandlerForCommand(parsedCommand.getCommand()); String operationResult = handlerForCommand.operate(chatId.toString(), parsedCommand, update); if (!"".equals(operationResult)) { SendMessage message = new SendMessage(); message.setChatId(chatId); message.setText(operationResult); bot.sendQueue.add(message); } } 

Es definiert die Chat-ID. Ruft den Nachrichtentext ab. Mit dem Parser wird bestimmt, ob es sich bei der Nachricht um einen Befehl handelt und welcher Handler für diesen Befehl verwendet werden soll. Die Verarbeitung des Befehls wird gestartet, und wenn bei der Verarbeitung des Befehls nicht leerer Text zurückgegeben wird, wird eine Nachricht zum Senden an den Benutzer erstellt und in die Warteschlange eingereiht.

Und dann sollten Sie eine Frage haben: "Was für ein Handler?". Es wurde vorher nicht über ihn gesprochen, und er wurde im Kodex nicht erwähnt. Alles ist richtig. Nun werden wir diese Funktionalität analysieren.

Erstellen Sie dazu ein separates Paket, in dem alle unsere Handler gespeichert werden. Nennen Sie es Handler
Lassen Sie uns eine abstrakte Klasse AbstractHandler erstellen

 import com.example.telegrambot.bot.Bot; import com.example.telegrambot.command.ParsedCommand; import org.telegram.telegrambots.api.objects.Update; public abstract class AbstractHandler { Bot bot; AbstractHandler(Bot bot) { this.bot = bot; } public abstract String operate(String chatId, ParsedCommand parsedCommand, Update update); } 

Er wird einen grundlegenden Konstruktor haben, in dem wir übergeben, mit welchem ​​Bot-Objekt er interagieren muss. Und es wird eine abstrakte Funktion deklariert, deren Implementierung wir bei den Erben unserer Klasse registrieren müssen.

Und sofort werden wir den einfachsten Handler implementieren, der nichts tut, und wir werden ihn verwenden, wenn wir nicht verstehen können, welche Art von Befehl uns gegeben wurde und keine Antwort vom Bot erforderlich ist.

DefaultHandler.java

 import com.example.telegrambot.bot.Bot; import com.example.telegrambot.command.ParsedCommand; import org.apache.log4j.Logger; import org.telegram.telegrambots.api.objects.Update; public class DefaultHandler extends AbstractHandler { private static final Logger log = Logger.getLogger(DefaultHandler.class); public DefaultHandler(Bot bot) { super(bot); } @Override public String operate(String chatId, ParsedCommand parsedCommand, Update update) { return ""; } } 

Wie wir es anwenden werden und wo wir die Ergebnisse seiner Arbeit erhalten werden, werden wir etwas später analysieren.

Als nächstes folgt SystemHandler
Er wird sich mit grundlegenden Befehlen wie start, help befassen und wir werden ihn auch anweisen, den Befehl id auszuführen

Die Basis sieht so aus:

 import com.example.telegrambot.bot.Bot; import com.example.telegrambot.command.Command; import com.example.telegrambot.command.ParsedCommand; import org.apache.log4j.Logger; import org.telegram.telegrambots.api.methods.send.SendMessage; import org.telegram.telegrambots.api.objects.Update; public class SystemHandler extends AbstractHandler { private static final Logger log = Logger.getLogger(SystemHandler.class); private final String END_LINE = "\n"; public SystemHandler(Bot bot) { super(bot); } @Override public String operate(String chatId, ParsedCommand parsedCommand, Update update) { Command command = parsedCommand.getCommand(); switch (command) { case START: bot.sendQueue.add(getMessageStart(chatId)); break; case HELP: bot.sendQueue.add(getMessageHelp(chatId)); break; case ID: return "Your telegramID: " + update.getMessage().getFrom().getId(); } return ""; } 

Sie können sehen, wie die Antwort auf den Start- und Hilfebefehl im Code gebildet wird :)
Wir bilden Textnachrichten und stellen sie zum Versenden in eine Warteschlange. Daraufhin stoppt die Arbeit des Handlers. Wer und wie wird diese Nachrichten senden - es interessiert ihn überhaupt nicht.
Und denken Sie daran, ich habe ein wenig darüber erwähnt, dass der Handler einige Textdaten zurückgibt. Und wenn diese Zeile nicht leer ist, müssen wir diesen Text an den Benutzer senden. Dies ist genau die Funktionalität, die wir beim Ausarbeiten des ID-Befehls verwendet haben:

 case ID: return "Your telegramID: " + update.getMessage().getFrom().getId(); 

Der Handler gibt den Text mit der Benutzer-ID an die Person zurück, die ihn angerufen hat, und bereits dort wird eine Nachricht zum Senden generiert, die dann in die Warteschlange eingereiht wird.

Und am Anfang des Artikels erwähnte ich, dass wir diese Option implementieren, um eine Nachricht von einem Benutzer zu verarbeiten, der Zeit zum Arbeiten benötigt. Und damit es unsere Handler nicht stört, werden wir es in einem separaten Stream zuordnen und es seinem Geschäft überlassen, ohne den Rest abzulenken.
Als solch ein "Schwergewichts" -Thread habe ich mir den Befehl notify ausgedacht. Das Prinzip ihrer Arbeit ist dies.

Durch Senden eines Befehls des Formulars an den Bot:
Ich benachrichtige 300

Der Bot sollte Sie darüber informieren, dass das Team es verstanden hat. Nach 300 Sekunden erhalten Sie eine Benachrichtigung, dass 300 Sekunden vergangen sind. Dieses Team kann sogar einen praktischen Nutzen haben :)

Zum Beispiel setzen Sie Knödel in Brand und Sie müssen sie nach 5 Minuten entfernen. Der Bot macht das perfekt und benachrichtigt Sie im Chat, dass die Zeit abgelaufen ist.

Oder nehmen Sie eine ernstere Aufgabe. Sie gehen zu einem wichtigen Meeting und wissen, dass Sie bei der Kommunikation mit jemandem das Gespräch unterbrechen müssen. Zu diesem Zweck bitten sie Freunde in der Regel, entweder anzurufen oder eine Nachricht zu schreiben. Dies ist ein Motiv, um das Gespräch nicht über einen längeren Zeitraum hinweg abzulenken und Maßnahmen zu ergreifen. Aber warum Freunde stören, wenn Sie einen Bot haben? Nachdem Sie ihn zuvor um eine Aufgabe gebeten und die Uhrzeit angegeben haben, erhalten Sie die erforderliche Benachrichtigung in Form von Telegrammen. Aber das ist alles der Text. Die Aufgabe und dieser Befehl wurden nur erfunden, um Ihnen zu zeigen, wie Sie in einem separaten Stream etwas zuordnen, dessen Arbeit einen sehr langen Zeitraum in Anspruch nehmen kann.

Also, NotifyHandler :

 import com.example.telegrambot.ability.Notify; import com.example.telegrambot.bot.Bot; import com.example.telegrambot.command.ParsedCommand; import org.apache.log4j.Logger; import org.telegram.telegrambots.api.objects.Update; public class NotifyHandler extends AbstractHandler { private static final Logger log = Logger.getLogger(NotifyHandler.class); private final int MILLISEC_IN_SEC = 1000; private String WRONG_INPUT_MESSAGE = "Wrong input. Time must be specified as an integer greater than 0"; public NotifyHandler(Bot bot) { super(bot); } @Override public String operate(String chatId, ParsedCommand parsedCommand, Update update) { String text = parsedCommand.getText(); if ("".equals(text)) return "You must specify the delay time. Like this:\n" + "/notify 30"; long timeInSec; try { timeInSec = Long.parseLong(text.trim()); } catch (NumberFormatException e) { return WRONG_INPUT_MESSAGE; } if (timeInSec > 0) { Thread thread = new Thread(new Notify(bot, chatId, timeInSec * MILLISEC_IN_SEC)); thread.start(); } else return WRONG_INPUT_MESSAGE; return ""; } } 

Wir prüfen, ob uns die Verspätungszeit im Text mitgeteilt wurde. Wenn nicht, schwören wir. Wenn ja, starten wir einen neuen Thread, in dem wir die Einleitung zu unserer Anleitung weitergeben. Diese Aufgabe wird von einer separaten Notify- Klasse erledigt.
Die Funktionalität ist sehr einfach. Er schläft die angegebene Anzahl von Sekunden. Während des Schlafens kann Ihr Bot jedoch andere Nachrichten empfangen, mit Ihnen kommunizieren und zusätzliche Benachrichtigungen auslösen. Und das alles funktioniert getrennt voneinander.

Um diesen ganzen Haufen mit aufrufenden Handlern logisch zu vervollständigen, kehren wir zu unserer MessageReciever- Klasse zurück und sehen, wie wir verstehen, welche Handler wir benötigen und wie wir sie ausführen.
Der erforderliche Handler wird uns vom Befehl zurückgesandt
 private AbstractHandler getHandlerForCommand(Command command) { if (command == null) { log.warn("Null command accepted. This is not good scenario."); return new DefaultHandler(bot); } switch (command) { case START: case HELP: case ID: SystemHandler systemHandler = new SystemHandler(bot); log.info("Handler for command[" + command.toString() + "] is: " + systemHandler); return systemHandler; case NOTIFY: NotifyHandler notifyHandler = new NotifyHandler(bot); log.info("Handler for command[" + command.toString() + "] is: " + notifyHandler); return notifyHandler; default: log.info("Handler for command[" + command.toString() + "] not Set. Return DefaultHandler"); return new DefaultHandler(bot); } } 

Wenn Sie nun weitere Befehle hinzufügen möchten, müssen Sie folgende Schritte ausführen:

  1. Fügen Sie in der Command- Klasse die Befehlssyntax hinzu.
  2. Geben Sie im Empfänger in der Funktion getHandlerForCommand an, wer für die Verarbeitung dieses Befehls verantwortlich sein soll.
  3. Und tatsächlich diesen Handler schreiben.

Ich werde im Voraus sagen, dass der Prozess des Hinzufügens neuer Teams vereinfacht werden kann. Verantwortliche Bearbeiter können sofort mit einer Liste von Befehlen in der Klasse registriert werden. Ich befürchte jedoch, dass der Code nicht einfach zu verstehen ist. Der Text ist sehr lang. Aber ich kann ihn nicht in Stücke schlagen. Hier werden drei grundlegende Bot-Funktionen beschrieben, die nur zusammenarbeiten und über die nicht einzeln gesprochen werden darf.

Worüber werden wir in den folgenden Abschnitten sprechen?

Wir müssen verstehen, wie man verschiedene Arten von Nachrichten formt. So arbeiten Sie mit Tastatur und Tasten. So bearbeiten Sie Ihre alten Beiträge. So arbeiten Sie mit Rückrufen. Wie man dem Bot Aufgaben gibt, um einige Aktionen auszuführen. So erstellen Sie eine interaktive Nachricht mit einem Bot und vielem mehr. Alle weiteren Teile liegen bei Ihnen und Ihrer Tätigkeit.
In den Kommentaren freue ich mich auf Ihr Feedback und Ihre Anweisungen, die wir als Priorität betrachten werden.

Fühlen Sie sich frei, Fragen zu stellen. Wenn etwas in dem Artikel nicht angegeben ist oder irgendwann nicht klar ist - schreiben Sie mir darüber. Ich werde auf jeden Fall kontroverse Themen korrigieren, bearbeiten oder klären.

Programmiere mit Vergnügen und möge die Kraft und der schöne Code mit dir kommen :)

py.s.

Der in diesem Teil des Artikels beschriebene Bot funktioniert. Du kannst ihn hier quälen: @test_habr_bot
Sie können auch meinen Planer quälen: @EventCheckPlanner_Bot
Und der freche Filmfan : @FilmFanAmateurBot .

Source: https://habr.com/ru/post/de481354/


All Articles