نواصل تطوير الوظائف الأساسية للروبوت في البرقيات. في الأجزاء السابقة ، ناقشنا النقطة التي مفادها أنه يجب تقسيم عمل الروبوت في تلقي الرسائل والمعالجة والإرسال. دعونا نحاول استخدام أدوات Java Core الأساسية لجعل روبوتنا متعدد مؤشرات الترابط وغير متزامن. سنأتي بمهمة تستغرق الكثير من الوقت للمعالجة. دعونا نرى كيف تعمل الأوامر في البرق وكيف تحتاج إلى معالجتها.
هذا هو استمرار للجزء الأول من المقالة حول برامج روبوت البرمجة للبرقيات في Java
تعليمات TelegramBot لإنشاء الوظائف الأساسية للروبوت. (الجزء الأول)لمن يهمك الأمر أكثر ، فأنت مرحب بك ...
يجب أن أقول على الفور أنه في هذا الجزء تمت إضافة الكثير من كل شيء في وقت واحد وبهدوء سنقوم بتحليل جميع الوظائف التي سمحت للبوت لتكون قادرة على تعدد العمليات والسبب في الحاجة إليها على الإطلاق.
كالعادة من الرئيسي:
يمكنك العثور على جميع التعليمات البرمجية الجاهزة لهذه المقالة في فرع
Part2-Handlers في مستودع git.
تعمل الشفرة بشكل كامل ، وهي كافية لإمالة وتغيير البيانات للحصول على إذن للبوت (الاسم والرمز) وتشغيل الطريقة الرئيسية في فئة App.class.
يرجى ملاحظة أن هذه الفئة ترسل إخطارًا إلى مسؤول البوت عندما يبدأ البوت ببدء البوت. معرف المسؤول bot محدد أيضًا في فئة App.class وإذا لم تقم بتغييره ، فسيحاول الروبوت الخاص بك إرسال رسائل إلي :)علاوة على النقاط التي سنقوم بتحليلها تلك التغييرات التي ظهرت بعد إصدار الجزء الأول.
معالجة الأوامر
بادئ ذي بدء ، دعنا نتعامل مع هذا المفهوم حول ما هو فريق بشكل عام في نظام للتواصل مع الروبوت برقية. اعتمادًا على إعدادات برنامج الروبوت ، يمكن أن يرى أي رسائل بأي تنسيق أو أوامر مصممة خصيصًا فقط. ما هو الفرق و
حيث يمكنك تلبية خيارات الرسائل هذه.
- نص عادي ، رسائل عادية.
في هذا النموذج ، يتلقى الروبوت رسائل عندما يكتبون له في PM. ومع ذلك ، إذا تم إيقاف تشغيل وضع الخصوصية في المجموعات في إعدادات الروبوت ، يبدأ الروبوت في رؤية جميع الرسائل بالكامل. إذا تم تمكين هذا الإعداد ، عند إضافته إلى المجموعة ، فإن الروبوت لا يرى سوى الأوامر الموجهة إليه. كيف تبدو - انظر الفقرة الثانية - فرق مصممة خصيصا
تبدأ هذه الأوامر دائمًا بشرطة مائلة: /
بعد ذلك يأتي الفريق نفسه. يجب أن يكون نص الأمر بدون مسافات. مثال:
/ ابدأ
باستخدام هذا الأمر ، يبدأ أي مستخدم دائمًا في التواصل مع برنامج الروبوت الخاص بك. لذلك ، وفقًا لقواعد الشكل الجيد ، يجب تحديد الاستجابة لهذا الأمر.

جميع الأوامر التي يعرفها bot الخاص بك كيف تعمل ، يُنصح بإضافتها إلى قائمة المهارات في إعدادات bot الخاصة بك. يتم كل ذلك في برقية معBotFather.
عن طريق استدعاء الأمر / myBots ، حدد الروبوت الخاص بك ثم الزر "تحرير بوت"
ستتلقى نافذة تظهر فيها جميع معلمات bot ، وبعد ذلك يمكنك تهيئة واجهته بالكامل والإشارة إلى الأوامر التي يمكن أن يعمل معها الروبوت.

تم ضبطها بهذا التنسيق:

وبعد ذلك ، عندما تبدأ في إدخال أمر إلى برنامج الروبوت الخاص بك ، ستظهر لك المساعدة في قائمة الأوامر المدرجة:

وهناك فارق بسيط آخر. قد تحتوي المجموعة على العديد من برامج الروبوت ، وإذا كانت لديها أوامر مشتركة (وستكون الأوامر العامة إلزامية ، يتم تنفيذ نفس البداية والمساعدة في معظم برامج الروبوت) ، ثم ستتم إضافة جزء إلى الأمر نفسه ، لإخبار أي روبوت ينتمي إليه هذا الأمر. وسيظهر الأمر تمامًا مثل هذا:
/ start @ test_habr_bot
والآن ، ومع معرفة كل هذه الفروق الدقيقة ، فلننشئ معك خيار المعالجة هذا الذي يجب أن يفهم الأوامر التي تبدأ بشرطة مائلة ومعرفة كيفية التمييز بين ما إذا كان الأمر موجهًا بالتحديد إلى روبوتك أم إلى أخرى.
قم بإنشاء حزمة تحتوي على الفئات المسؤولة عن معالجة الأوامر.
الحزمة com.example.telegrambot.commandفي فئة الأوامر ، نسرد جميع الأوامر التي يجب أن يفهمها الروبوت.
public enum Command { NONE, NOTFORME, NOTIFY, START, HELP, ID }
كما رأيت سابقًا ، أشرت فيBotFather إلى أن الروبوت الذي يجب أن أكون قادرًا على فهمه هو 4 فرق. وستكون هذه البداية القياسية والمساعدة. نضيف واحد معرف واحد مفيد. وأبلغ واحدًا آخر ، والذي سأتحدث عنه لاحقًا بعد قليل. وفريقان لا شيء و NOTFORME ، والذي سيخبرنا أن الرسالة النصية إما ليست أمراً على الإطلاق ، أو أن هذا الأمر ليس بالنسبة لبوتنا.
إضافة فئة أخرى مساعد
ParsedCommand 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=""; }
الغرض الرئيسي منه هو تخزين نتيجة تحليل النص في كائنات هذه الفئة. سوف يحتوي فقط على الفريق نفسه وكل النص الذي يأتي بعد الفريق.
وسنكتب فصلًا منفصلاً سيقوم بتحليل الفرق إلينا. فئة
المحلل 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); } }
باختصار. عند تهيئة المحلل اللغوي ، يجب أن نمرر اسم روبوتنا في المنشئ حتى يتمكن المحلل اللغوي من التمييز بين أوامره وبين الغرباء.
حسنًا ، نحن نسمي الطريقة العامة
public ParsedCommand getParsedCommand(String text)
الذي نقوم بتمرير نص الرسالة إليه في الوسيطات ، ويجب عليه إعادة أمر إلينا ونص الرسالة الذي يأتي بعد الأمر.
يمكنك أن ترى كيف يعمل المحلل اللغوي في
فصل الاختبار .
الذباب بشكل منفصل ، شرحات بشكل منفصل
الآن نحن بحاجة إلى تعليم الروبوت لدينا لتلقي الرسائل بشكل منفصل ومعالجة وإرسال الردود. بعد سلسلة من التجربة والخطأ ، جئت إلى هذا المنطق للتطبيق.
ستعمل الفئة الرئيسية
Bot في الخيط الرئيسي للتطبيق وستكون مشغولة فقط بحقيقة أن جميع الرسائل المستلمة سيتم وضعها في قائمة انتظار خاصة وستكون أيضًا حاوية للرسائل التي نخطط لإرسالها إلى المستخدم ردًا على ذلك.
التغييرات في هذا الفصل بسيطة للغاية. أضفنا قائمتين:
public final Queue<Object> sendQueue = new ConcurrentLinkedQueue<>(); public final Queue<Object> receiveQueue = new ConcurrentLinkedQueue<>();
وإعادة كتابة رمز الوظيفة
العامة بشكل خاطئ onUpdateReceived (تحديث التحديث) @Override public void onUpdateReceived(Update update) { log.debug("Receive new Update. updateID: " + update.getUpdateId()); receiveQueue.add(update); }
لماذا هذا مرة أخرى حاولت خيارات مختلفة. والمشكلة الرئيسية في multithreading تعمل مع البيانات المشتركة. والأهم من ذلك كله أنني أحببت كيف يعالج تنفيذ طوابير متعددة الخيوط
ConcurrentLinkedQueue <> () هذا.
وكما ترى ، في كلتا الطابورتين ، سنخزن أنواع بيانات الكائنات. هذا هو إشارة مرجعية أخرى للمستقبل. وبالتالي ، نحن لسنا ملتصقين بأنواع الرسائل المستلمة. في قائمة الانتظار الواردة ، يمكننا إضافة ليس فقط كائنات من نوع التحديث ، ولكن أيضًا بعض الكائنات الأخرى التي نحتاجها.
نفس الشيء مع قائمة الانتظار للإرسال. نظرًا لأنه يمكننا إرسال أنواع مختلفة من الرسائل وليس لها أصل مشترك - نستخدم أيضًا نوع بيانات شائع - كائن.
إذا قمت بتشغيل برنامج الروبوت في هذا النموذج ، فستعمل ، ولكن لن تفعل أي شيء. سيقوم بتسجيل جميع الرسائل المستلمة في السجل ووضعها في قائمة الانتظار.
لذلك ، نحن بحاجة إلى نوع من
سلاسل الرسائل التي تهتم بأخذ الرسائل المستلمة من قائمة الانتظار وتنفيذ بعض الإجراءات عليها ووضع نتائج عملها في قائمة انتظار
sendQueue .
لنقم بإنشاء حزمة منفصلة:
خدمة وفيها سيكون لدينا فئتان فقط:
MessageReciever - تلقى رسالة معالج
MessageSender هو معالج قائمة انتظار الرسائل لإرسالها إلى المستخدم.
سوف نعتبر عملهم أقل قليلاً ، ولكن في الوقت الحالي ، سنصف استخدامهم في تطبيقنا فئة الانطلاق
بعد اتصال bot الخاص بنا ، نبدأ معالجاتنا في خيوط منفصلة:
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();
لكل من المواضيع ، نحدد وضع الخفي. يعد ذلك ضروريًا حتى تعمل مؤشرات الترابط طالما كان مؤشر الترابط الرئيسي قيد التشغيل وإنهاء عملها بمجرد توقفها عن العمل.
لا نود التعامل مع معالج الرسائل الواردة أولاً - دعنا ننظر إلى تشغيل فئة
MessageSender .
دعونا نلقي نظرة على ما يمكن أن يفعله وما يفعله:
حسنًا ، دعنا الآن
ننظر إلى عمل فئة
MessageRecieverيجب أن يكون ، مثل MessageSender ، متعدد مؤشرات الترابط ، في المُنشئ يتلقى كائنًا من الفئة Bot ، حيث سيتلقى الرسائل المستلمة في حلقة لا نهائية ، ويعالجها ويضعه في قائمة الانتظار لإرسال نتائج عمله.
هنا نستخدم محلل الأمر الذي تم إنشاؤه مسبقًا. ثم نضيف القدرة على استخدام أنواع مختلفة من المعالجات لفرقنا وبعضهم سنقوم بعمل خيوط متعددة.
دورة العمل بسيطة جدا:
@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; } } }
تحقق من قائمة الانتظار. إذا كان هناك شيء ما ، فقم بتشغيل المحلل:
private void analyze(Object object)
إذا لم يكن هناك شيء ، نحن في انتظار.
يتحقق المحلل من نوع الكائن. إذا كان يعرف كيفية العمل معه ، يبدأ المحلل التالي. إذا كنت لا تستطيع - يقسم :)
لماذا هذا مرة أخرى ، هذه إشارة مرجعية للمستقبل وآمل أن أكشف عنها في الأجزاء التالية من هذه السلسلة من المقالات. سيسمح لنا هذا التطبيق بتشكيل مهامنا الخاصة بالبوت ، وإنشاء قوائم بريدية ، ومهام يومية. لهذا الغرض ، يجب أن يكون جهاز الاستقبال قادرًا على معالجة ليس فقط كائنات من النوع Update ، ولكن أيضًا شيء خاص بنا. ولكن المزيد عن ذلك في وقت لاحق :)
دعونا ننظر في محلل لنوع التحديث بمزيد من التفاصيل:
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); } }
يحدد معرف الدردشة. الحصول على نص الرسالة. باستخدام المحلل اللغوي ، فإنه يحدد ما إذا كانت الرسالة أمر ويحدد المعالج الذي يجب معالجة هذا الأمر. يبدأ في معالجة الأمر ، وإذا كانت معالجة الأمر تُرجع بعض النصوص غير الفارغة - فهي تُشكل رسالة لإرسالها إلى المستخدم وتضعها في قائمة الانتظار.
ثم يجب أن يكون لديك سؤال: "أي نوع من معالج؟". لم يكن هناك حديث عنه من قبل ، ولم يرد ذكره في الكود. كل الحق. الآن سوف نقوم بتحليل هذه الوظيفة.
للقيام بذلك ، قم بإنشاء حزمة منفصلة ، والتي ستقوم بتخزين جميع معالجاتنا. نسميها
معالجدعونا إنشاء فئة مجردة
AbstractHandler 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); }
سيكون لديه مُنشئ أساسي نمر فيه مع كائن Bot الذي سيحتاج إلى التفاعل معه. وتم الإعلان عن وظيفة مجردة
للعمل ، والتي سيتعين علينا تسجيلها في ورثة فئتنا.
وسننفذ على الفور أبسط معالج لن يفعل أي شيء وسنستخدمه عندما لا نستطيع أن نفهم نوع الأمر الذي تلقيناه وليس هناك استجابة مطلوبة من الروبوت.
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 ""; } }
كيف سنطبقها وأين نحصل على نتائج عملها - سنحلل لاحقًا.
التالي في الخط هو
SystemHandlerسيتعامل مع الأوامر الأساسية ، مثل start ، help ، وسوف نطلب منه أيضًا تنفيذ أمر id
أساس ذلك يشبه هذا:
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 ""; }
يمكنك أن ترى كيف تتشكل الاستجابة لأمر start and help في الكود :)
نقوم بتكوين رسائل نصية ووضعها في قائمة انتظار للإرسال. في هذا ، يتوقف عمل المعالج. من وكيف سوف ترسل هذه الرسائل - وقال انه لا يهتم على الإطلاق.
وتذكر أنني ذكرت قليلاً أعلاه أنه نتيجة للمعالج ، فإنه يعرض بعض البيانات النصية. وإذا كان هذا الخط غير فارغ ، فيجب أن نرسل هذا النص إلى المستخدم. هذه بالضبط هي الوظيفة التي استخدمناها عند العمل على الأمر ID:
case ID: return "Your telegramID: " + update.getMessage().getFrom().getId();
سيقوم المعالج بإرجاع النص بمعرف المستخدم إلى الشخص الذي قام بالاتصال به وهناك بالفعل سيتم إنشاء رسالة للإرسال ، والتي ستنتقل بعد ذلك إلى قائمة الانتظار.
وفي بداية المقال ، ذكرت أننا ننفذ هذا الخيار لمعالجة رسالة من مستخدم يحتاج إلى وقت للعمل. وبحيث لا تتداخل مع معالجاتنا ، سنقوم بتخصيصها في جدول منفصل وندع نشاطها التجاري بدون تشتيت الباقي.
على هذا النحو موضوع "الوزن الثقيل" ، خطرت لي أمر الإخطار. مبدأ عملها هو هذا.
عن طريق إرسال bot أمر من النموذج:
/ إخطار 300يجب أن يعلمك الروبوت بأن الفريق قد فهم وبعد 300 ثانية سوف يرسل لك بعض الإشعارات بأن 300 ثانية قد مرت. قد يكون لهذا الفريق حتى استخدام عملي :)
على سبيل المثال ، تضع النار على الزلابية وتحتاج إلى إزالتها بعد 5 دقائق. سيقوم الروبوت بذلك بشكل مثالي وسيرسل إخطارًا إليك في الدردشة بأن الوقت قد انتهى.
أو خذ مهمة أكثر جدية. تذهب إلى اجتماع مهم وأنت تعلم أنه عند التواصل مع شخص ما ، ستحتاج إلى مقاطعة المحادثة. لهذا ، يطلبون عادة من الأصدقاء إما الاتصال أو كتابة رسالة ، والتي ستكون دافعًا لعدم صرف الانتباه عن المحادثة لفترة طويلة واتخاذ بعض الإجراءات. ولكن لماذا تزعج الأصدقاء عندما يكون لديك روبوت؟ بعد أن تطلب منه مهمة مسبقًا مع الإشارة إلى الوقت ، ستتلقى الإشعار اللازم في البرقيات. ولكن هذا هو كل كلمات. تم اختراع المهمة وهذا الأمر فقط لتوضيح كيفية تخصيص شيء يمكن أن يستغرق عمله فترة طويلة جدًا في دفق منفصل.
لذلك ،
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 ""; } }
نتحقق مما إذا كان قد تم إعطاء وقت التأخير لنا في النص. إذا لم يكن كذلك ، فإننا نقسم. إذا كان الأمر كذلك ، فإننا نبدأ سلسلة جديدة ، حيث نقوم بتمرير المقدمة في تعليماتنا. ستتم معالجة هذه المهمة بواسطة فصل
إعلام منفصل.
وظيفة بسيطة للغاية. ينام عدد الثواني المشار إليه. ولكن في عملية نومه ، يستطيع الروبوت الخاص بك استلام أي رسائل أخرى والتواصل معك وإطلاق إعلامات إضافية. وكل هذا يعمل بشكل منفصل عن بعضها البعض.
ولإكمال هذه المجموعة برمتها منطقياً مع معالجات الاتصال ، دعنا نعود إلى صف
MessageReciever الخاص بنا ونرى كيف نفهم المعالج الذي نحتاج إليه وكيف
نديرهم .
يتم إرجاع المعالج الضروري إلينا بواسطة الأمر
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); } }
الآن ، إذا كنت تريد إضافة المزيد من الأوامر ، فستحتاج إلى القيام بما يلي:
- في فئة الأوامر ، أضف جملة الأمر.
- في جهاز الاستقبال ، في وظيفة getHandlerForCommand ، حدد من سيكون المسؤول عن معالجة هذا الأمر.
- وبالفعل كتابة هذا المعالج.
سأقول مقدمًا أنه يمكن تبسيط عملية إضافة فرق جديدة. يمكن تسجيل المعالجات المسؤولة على الفور في الفصل مع قائمة بالأوامر. لكن أخشى أن الكود ليس من السهل فهمه. النص طويل جدا لكنني لا أستطيع ضربه إلى قطع. يتم وصف ثلاث وظائف بوت أساسية هنا ، والتي تعمل معًا فقط وليس من الصواب التحدث عنها بشكل فردي.
ما الذي سنتحدث عنه في الأجزاء التالية؟
نحن بحاجة إلى فهم كيفية تشكيل أنواع مختلفة من الرسائل. كيفية العمل مع لوحة المفاتيح والأزرار. كيفية تعديل مشاركاتك القديمة. كيفية العمل مع عمليات الاسترجاعات. كيفية إعطاء المهام للبوت لأداء بعض الإجراءات. كيفية إنشاء رسالة تفاعلية مع الروبوت وأكثر من ذلك بكثير. جميع الأجزاء الأخرى متروك لك ونشاطك.
في التعليقات ، أتطلع إلى تعليقاتك وتوجيهاتك ، والتي سننظر إليها كأولوية.
لا تتردد في طرح الأسئلة. إذا لم تتم الإشارة إلى شيء ما في المقالة أو في مرحلة ما ، فليس من الواضح - اكتب لي عن ذلك. سأقوم بالتأكيد بتصحيح أو تعديل أو توضيح القضايا المثيرة للجدل.
برنامج في السرور وقد تأتيك القوة والرمز الجميل معك :)
py.sy.
يعمل الروبوت المكتوب في هذا الجزء من المقالة. يمكنك عذابه هنا:
@ test_habr_botيمكنك أيضًا عذاب
مخططي :
EventCheckPlanner_Botومروحة فيلم Cheeky :
FilmFanAmateurBot .