TelegramBot. Fungsionalitas dasar. Terbang secara terpisah, irisan daging secara terpisah. (Bagian 2)

Kami terus mengembangkan fungsionalitas dasar untuk bot di telegram. Di bagian sebelumnya, kami membahas titik bahwa bot bekerja untuk menerima pesan, memproses dan mengirim harus dibagi. Mari kita coba menggunakan alat Java Core dasar untuk membuat bot kita multithreaded dan asynchronous. Kami akan datang dengan tugas yang membutuhkan banyak waktu untuk diproses. Mari kita lihat bagaimana perintah dalam telegram bekerja dan bagaimana mereka perlu diproses.

Ini adalah kelanjutan dari bagian pertama artikel tentang pemrograman bot untuk telegram di Jawa
Instruksi TelegramBot untuk membuat fungsionalitas dasar untuk bot. (Bagian 1)
Untuk siapa ini lebih menarik, Anda dipersilakan ...

Saya harus mengatakan segera bahwa di bagian ini banyak semuanya ditambahkan sekaligus dan diam-diam kita akan menganalisis semua fungsi yang memungkinkan bot untuk dapat multithread dan mengapa itu diperlukan sama sekali.

Seperti biasa dari main:
Anda dapat menemukan semua kode yang sudah jadi untuk artikel ini di cabang Part2-Handlers di repositori git.
Kode berfungsi penuh, cukup untuk miring, mengubah data untuk otorisasi bot (nama dan token) dan menjalankan metode utama di kelas App.class.

Harap dicatat bahwa kelas ini mengirimkan pemberitahuan kepada administrator bot ketika bot mulai bahwa bot telah dimulai. ID admin bot juga ditentukan dalam kelas App.class dan jika Anda tidak mengubahnya, bot Anda akan mencoba mengirim pesan kepada saya :)

Dan lebih lanjut tentang poin-poin kami akan menganalisis perubahan-perubahan yang muncul setelah rilis bagian pertama.

Pemrosesan perintah


Untuk memulainya, mari kita berurusan dengan konsep ini tentang apa yang tim secara umum dalam sistem untuk berkomunikasi dengan bot telegram. Bergantung pada pengaturan bot, ia dapat melihat pesan dalam format apa pun atau hanya perintah yang dirancang khusus. Apa bedanya dan
di mana Anda dapat memenuhi opsi pesan ini.

  1. Teks biasa, pesan biasa.
    Dalam formulir ini, bot menerima pesan saat mereka menulis kepadanya di PM. Namun, jika dalam pengaturan bot mode privasi dalam grup dimatikan, bot mulai melihat semua pesan sepenuhnya. Jika pengaturan ini diaktifkan, saat ditambahkan ke grup, bot hanya melihat perintah yang ditujukan padanya. Bagaimana mereka terlihat - lihat paragraf kedua
  2. Tim yang dirancang khusus
    Perintah seperti itu selalu dimulai dengan garis miring: /
    Setelah itu muncul tim itu sendiri. Teks perintah harus tanpa spasi. Contoh:
    / mulai
    Dengan perintah ini, setiap pengguna selalu memulai komunikasi dengan bot Anda. Oleh karena itu, sesuai dengan aturan bentuk yang baik, respons terhadap perintah ini harus ditentukan.

    Semua perintah yang bot Anda tahu cara bekerja dengannya, disarankan untuk menambah daftar keterampilan dalam pengaturan bot Anda. Ini semua dilakukan dalam telegram dengan @BotFather.

    Dengan memanggil perintah / myBots, pilih bot Anda dan kemudian tombol "Edit Bot"
    Anda akan mendapatkan jendela di mana semua parameter bot akan ditampilkan dan kemudian Anda dapat mengkonfigurasi seluruh antarmuka dan menunjukkan perintah mana yang bisa digunakan oleh bot Anda.



    Mereka diatur dalam format ini:



    Dan setelah itu, ketika Anda mulai memasukkan perintah ke bot Anda, itu akan menunjukkan bantuan dengan daftar perintah yang terdaftar:



    Dan ada satu lagi nuansa. Sebuah grup dapat berisi beberapa bot, dan jika mereka memiliki perintah umum (dan perintah umum akan wajib, mulai dan bantuan yang sama diimplementasikan di sebagian besar bot), maka bagian akan ditambahkan ke perintah itu sendiri, memberi tahu bot yang mana milik perintah ini. Dan perintahnya akan terlihat seperti ini:
    / start @ test_habr_bot

Dan sekarang, mengetahui semua nuansa ini, mari kita buat dengan Anda opsi pemrosesan seperti itu yang harus memahami perintah yang dimulai dengan slash dan mengetahui bagaimana membedakan apakah perintah tersebut ditujukan khusus untuk bot Anda atau ke yang lain.

Buat paket yang akan berisi kelas yang bertanggung jawab untuk memproses perintah.
paket com.example.telegrambot.command

Di kelas Command, kami daftar semua perintah yang bot kami harus bisa mengerti.

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

Seperti yang Anda lihat sebelumnya, saya menunjukkan pada @BotFather bahwa bot saya harus dapat memahami 4 tim. Ini akan menjadi standar awal dan bantuan. Kami menambahkan satu id berguna. Dan satu lagi, beri tahu, yang akan saya bicarakan nanti. Dan dua tim NONE dan NOTFORME, yang akan memberi tahu kami bahwa pesan teks itu bukan perintah sama sekali, atau perintah ini bukan untuk bot kami.

Tambahkan kelas pembantu lain 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=""; } 

Tujuan utamanya adalah untuk menyimpan hasil parsing teks pada objek kelas ini. Ini hanya akan berisi tim itu sendiri dan semua teks yang datang setelah tim.

Dan kami akan menulis kelas terpisah yang akan mem-parsing tim kepada kami. Kelas Parser

 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); } } 

Singkatnya. Ketika menginisialisasi parser, kita harus memberikan nama bot kita di konstruktor sehingga parser dapat membedakan perintahnya dari orang asing.

Nah, kalau begitu kita sebut saja metode publik

 public ParsedCommand getParsedCommand(String text) 

Untuk yang kami sampaikan teks pesan dalam argumen, dan dia harus mengembalikan perintah kepada kami dan teks pesan datang setelah perintah.

Anda dapat melihat bagaimana parser bekerja di kelas tes .

Terbang secara terpisah, irisan daging secara terpisah


Sekarang kita perlu mengajarkan bot kita untuk secara terpisah menerima pesan, memproses dan mengirim tanggapan. Setelah serangkaian coba-coba, saya sampai pada logika aplikasi ini.
Bot kelas utama akan bekerja di utas utama aplikasi dan hanya akan sibuk dengan kenyataan bahwa semua pesan yang diterima akan dimasukkan ke dalam antrian khusus dan juga akan menjadi wadah untuk pesan yang kami rencanakan untuk dikirimkan kepada pengguna sebagai tanggapan.

Perubahan di kelas ini sangat kecil. Kami menambahkan dua antrian:

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

dan sedikit menulis ulang kode fungsi public void onUpdateReceived (Perbarui pembaruan)

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

Kenapa begitu Sekali lagi saya mencoba opsi yang berbeda. Dan masalah utama multithreading adalah bekerja dengan data bersama. Dan yang paling penting saya menyukai bagaimana implementasi antrian multi-threaded ConcurrentLinkedQueue <> () menangani ini.
Dan seperti yang Anda lihat, dalam kedua antrian kami akan menyimpan tipe data Object. Ini adalah penunjuk lain untuk masa depan. Dengan demikian, kami tidak terikat pada jenis pesan yang diterima. Dalam antrian yang masuk, kita dapat menambahkan tidak hanya objek dari jenis Pembaruan, tetapi juga beberapa objek lain yang kita butuhkan.

Hal yang sama dengan antrian untuk pengiriman. Karena kami dapat mengirim berbagai jenis pesan dan tidak memiliki induk yang sama - kami juga menggunakan tipe data umum - Objek.
Jika Anda menjalankan bot dalam formulir ini, itu akan berfungsi, tetapi tidak akan melakukan apa pun. Dia akan merekam semua pesan yang diterima di log dan dimasukkan ke dalam antrian.
Oleh karena itu, kita memerlukan semacam utas yang akan menerima pesan yang diterima dari antrian dan melakukan beberapa tindakan pada mereka dan menempatkan antrian sendQueue dalam hasil kerjanya.

Mari kita buat paket terpisah: layanan dan di dalamnya kita hanya akan memiliki 2 kelas:

MessageReciever - penangan pesan yang diterima
MessageSender adalah penangan antrian pesan untuk dikirim ke pengguna.

Kami akan mempertimbangkan pekerjaan mereka sedikit lebih rendah, tetapi untuk saat ini, kami akan menjelaskan penggunaannya di Aplikasi kelas awal kami

Setelah bot kami terhubung, kami memulai penangan kami di utas terpisah:

 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(); 

Untuk kedua utas, kami menentukan mode Daemon. Ini diperlukan agar utas dapat berfungsi selama utas utama berjalan dan untuk mengakhiri sendiri segera setelah utas berhenti bekerja.

Kami tidak ingin berurusan dengan penangan pesan yang masuk terlebih dahulu - mari kita lihat operasi kelas MessageSender .

Mari kita lihat apa yang bisa dia lakukan dan apa yang dia lakukan:

  • Biasanya, ini adalah warisan antarmuka untuk multithreading:
    mengimplementasikan runnable
    dan implementasi dari fungsi run

     @Override public void run() 

    Di sini kita memulai infinite loop, yang hanya sibuk dengan fakta bahwa ia memeriksa antrian send dan memanggil perintah send

     private void send(Object object) 

    jika sesuatu muncul dalam antrian.
  • Di konstruktor kelas, kita melewatkan objek kelas Bot, karena dari sana kita akan mengambil objek untuk mengirim pesan dan dengannya kita akan mengirimkannya.
  • Metode kirim menentukan jenis pesan yang akan dikirim dan menerapkan perintah yang sesuai.

Nah, sekarang mari kita lihat karya dari kelas MessageReciever

Dia, seperti MessageSender, harus multithreaded, di konstruktor menerima objek Bot kelas, di mana ia akan menerima pesan yang diterima dalam loop tak terbatas, memprosesnya dan menempatkannya dalam antrian untuk mengirim hasil karyanya.

Di sini kita menggunakan parser perintah yang dibuat sebelumnya. Dan kemudian kami menambahkan kemampuan untuk menggunakan berbagai jenis penangan untuk tim kami dan beberapa dari mereka akan kami buat multi-threaded.

Siklus kerjanya sangat sederhana:

 @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; } } } 

Periksa antrian. Jika ada sesuatu, jalankan alat analisa:

 private void analyze(Object object) 

Jika tidak ada apa-apa, kami menunggu.

Penganalisa memeriksa jenis objek. Jika dia tahu cara bekerja dengannya, dia memulai penganalisa berikutnya. Jika Anda tidak bisa - bersumpah :)

Kenapa begitu Sekali lagi, ini adalah penunjuk untuk masa depan dan, saya harap, saya akan mengungkapkannya di bagian selanjutnya dari seri artikel ini. Implementasi seperti itu akan memungkinkan kita untuk kemudian membentuk tugas kita sendiri untuk bot, membuat milis, tugas harian. Untuk ini, penerima harus dapat memproses tidak hanya objek dari jenis Pembaruan, tetapi juga sesuatu dari kita. Tetapi lebih lanjut tentang itu nanti :)

Mari kita pertimbangkan penganalisa untuk tipe Pembaruan secara lebih rinci:

 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); } } 

Ini mendefinisikan ID obrolan. Mendapat teks pesan. Menggunakan parser, itu menentukan apakah pesan adalah perintah dan menentukan penangan mana perintah ini harus diproses. Ini mulai memproses perintah dan jika pemrosesan perintah mengembalikan beberapa teks yang tidak kosong - itu membentuk pesan untuk dikirim ke pengguna dan memasukkannya ke dalam antrian.

Dan kemudian Anda harus memiliki pertanyaan: "Penangan seperti apa?". Tidak ada pembicaraan tentang dia sebelumnya, dan dia tidak disebutkan dalam kode. Baiklah Sekarang kita akan menganalisis fungsi ini.

Untuk melakukan ini, buat paket terpisah, yang akan menyimpan semua penangan kami. Sebut saja pawang
Mari kita membuat kelas abstrak 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); } 

Dia akan memiliki konstruktor dasar di mana kita lulus dengan objek Bot mana dia perlu berinteraksi. Dan fungsi abstrak untuk beroperasi dinyatakan, implementasi yang harus kita daftarkan di ahli waris kelas kita.

Dan segera kami akan mengimplementasikan handler yang paling sederhana yang tidak akan melakukan apa-apa dan kami akan menggunakannya ketika kami tidak dapat memahami jenis perintah apa yang diberikan kepada kami dan tidak ada respons yang diperlukan dari 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 ""; } } 

Bagaimana kita akan menerapkannya dan di mana kita akan mendapatkan hasil pekerjaannya - kita akan menganalisis sedikit kemudian.

Baris berikutnya adalah SystemHandler
Dia akan berurusan dengan perintah dasar, seperti start, help, dan kami juga akan menginstruksikan dia untuk mengeksekusi perintah id

Dasarnya terlihat seperti ini:

 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 ""; } 

Anda dapat melihat bagaimana respons terhadap perintah mulai dan bantuan terbentuk dalam kode :)
Kami membentuk pesan teks dan menempatkannya dalam antrian untuk dikirim. Tentang ini, pekerjaan pawang berhenti. Siapa dan bagaimana akan mengirim pesan-pesan ini - dia tidak peduli sama sekali.
Dan ingat, saya sebutkan sedikit di atas bahwa sebagai hasil dari handler, ia mengembalikan beberapa data teks. Dan jika baris ini tidak kosong, kita harus mengirim teks ini kepada pengguna. Ini persis fungsi yang kami gunakan saat mengerjakan perintah ID:

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

Handler akan mengembalikan teks dengan ID pengguna kepada orang yang memanggilnya dan sudah ada pesan yang akan dihasilkan untuk dikirim, yang kemudian akan masuk ke antrian.

Dan di awal artikel, saya menyebutkan bahwa kami menerapkan opsi ini untuk memproses pesan dari pengguna yang membutuhkan waktu untuk bekerja. Dan agar tidak mengganggu penangan kami, kami akan mengalokasikannya dalam aliran terpisah dan membiarkannya melanjutkan bisnisnya tanpa mengganggu sisanya.
Sebagai utas "kelas berat", saya datang dengan perintah notify. Prinsip pekerjaannya adalah ini.

Dengan mengirimkan bot perintah dari form:
/ beri tahu 300

Bot harus memberi tahu Anda bahwa tim memahami dan setelah 300 detik ia akan mengirimi Anda pemberitahuan bahwa 300 detik telah berlalu. Tim ini bahkan mungkin memiliki penggunaan praktis :)

Misalnya, Anda membuat pangsit terbakar dan Anda harus menghapusnya setelah 5 menit. Bot akan melakukan ini dengan sempurna dan akan mengirimkan pemberitahuan kepada Anda dalam obrolan bahwa waktunya sudah habis.

Atau mengambil tugas yang lebih serius. Anda pergi ke pertemuan penting dan Anda tahu bahwa ketika berkomunikasi dengan seseorang, Anda perlu menginterupsi pembicaraan. Untuk ini, mereka biasanya meminta teman untuk menelepon atau menulis pesan, yang akan menjadi motif untuk tidak mengalihkan perhatian dari percakapan untuk waktu yang lama dan mengambil tindakan. Tapi mengapa repot-repot teman ketika Anda memiliki bot? Setelah memintanya tugas terlebih dahulu dan menunjukkan waktu, Anda akan menerima pemberitahuan yang diperlukan di telegram. Tapi ini semua liriknya. Tugas dan perintah ini diciptakan hanya untuk menunjukkan kepada Anda bagaimana mengalokasikan dalam aliran terpisah sesuatu yang pekerjaannya dapat memakan waktu yang sangat lama.

Jadi, 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 ""; } } 

Kami memeriksa apakah waktu tunda diberikan kepada kami dalam teks. Jika tidak, kami bersumpah. Jika demikian, kami memulai utas baru, di mana kami melewati pengantar pada instruksi kami. Tugas ini akan ditangani oleh kelas Notify yang terpisah.
Fungsionalitasnya sangat sederhana. Dia tidur jumlah yang ditunjukkan detik. Tetapi dalam proses tidurnya, bot Anda dapat menerima pesan lain, berkomunikasi dengan Anda, dan meluncurkan pemberitahuan tambahan. Dan semua ini bekerja secara terpisah satu sama lain.

Dan untuk menyelesaikan secara keseluruhan kumpulan ini dengan penangan panggilan, mari kembali ke kelas MessageReciever kami dan lihat bagaimana kami memahami penangan mana yang kami butuhkan dan bagaimana kami menjalankannya.
Pawang yang diperlukan dikembalikan kepada kami dengan perintah
 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); } } 

Sekarang, jika Anda ingin menambahkan beberapa perintah lagi, Anda perlu melakukan hal berikut:

  1. Di kelas Command tambahkan sintaks perintah.
  2. Di penerima, dalam fungsi getHandlerForCommand, tentukan siapa yang akan bertanggung jawab untuk memproses perintah ini.
  3. Dan benar-benar menulis penangan ini.

Saya akan mengatakan sebelumnya bahwa proses penambahan tim baru dapat disederhanakan. Penangan yang bertanggung jawab dapat didaftarkan segera di kelas dengan daftar perintah. Tapi saya khawatir kode itu tidak mudah dimengerti. Teksnya sangat panjang. Tapi aku tidak bisa mengalahkannya. Tiga fungsi dasar bot dijelaskan di sini, yang hanya bekerja bersama dan tidak tepat untuk membicarakannya secara terpisah.

Apa yang akan kita bicarakan di bagian berikut?

Kita perlu memahami cara membentuk berbagai jenis pesan. Cara bekerja dengan keyboard dan tombol. Cara mengedit posting lama Anda. Cara bekerja dengan callback. Cara memberi tugas kepada bot untuk melakukan beberapa tindakan. Cara membuat pesan interaktif dengan bot dan banyak lagi. Semua bagian lebih lanjut terserah Anda dan aktivitas Anda.
Dalam komentar, saya menantikan umpan balik dan arahan Anda, yang akan kami pertimbangkan sebagai prioritas.

Jangan ragu untuk bertanya. Jika ada sesuatu yang tidak ditunjukkan dalam artikel atau pada titik tertentu tidak jelas - menulis kepada saya tentang hal itu. Saya pasti akan memperbaiki, mengedit, atau mengklarifikasi masalah kontroversial.

Program dengan senang hati dan semoga kekuatan dan kode yang indah datang bersama Anda :)

py.s.

Bot yang ditulis di bagian artikel ini berfungsi. Anda dapat menyiksanya di sini: @test_habr_bot
Anda juga dapat menyiksa perencana saya: @EventCheckPlanner_Bot
Dan penggemar film Cheeky : @FilmFanAmateurBot .

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


All Articles