JavaRush/Java блог/Random/Telegram Ability Bot: бот, умеющий вести диалог: Часть 2
Chundrik
35 уровень

Telegram Ability Bot: бот, умеющий вести диалог: Часть 2

Статья из группы Random
участников
ЧАСТЬ 1 Чтобы позже не запутаться в частях программы, я стараюсь всю логику разделять на отдельные классы. Собственно фразы, которыми будет отвечать бот, будут хранится в интерфейсе Constants. Создадим там строку:
String START_DESCRIPTION = "Hello";
Затем перейдем в класс TelegramBot и вставим следующий код:
public Ability replyToStart() {
    return Ability
        .builder()
        .name("start")
        .info(Constants.START_DESCRIPTION)
        .locality(ALL)
        .privacy(PUBLIC)
        .action(ctx ->  silent.send("Hello!", ctx.chatId()))
        .build();
}
Telegram Ability Bot: бот, умеющий вести диалог: Часть 2 - 1Теперь бот может приветствовать его клиентов в ответ на стандартную команду /start. Попробуйте запустить его: бот уже немного живой! Но, как и любому монстру Франкештейна, ему не хватает парочки конечностей.Telegram Ability Bot: бот, умеющий вести диалог: Часть 2 - 2

Использование встроенной клавиатуры

Чтобы бот смог построить с нами диалог, нам понадобятся еще два класса: MessageFactory и KeyboardFactory. Первый будет считывать ответы людей и генерировать сообщения, а второй — создавать кнопки с ответами.
public class KeyboardFactory {
    public static ReplyKeyboard startButtons() {
        InlineKeyboardMarkup inlineKeyboard = new InlineKeyboardMarkup();
        List<list<inlinekeyboardbutton>> rowsInline = new ArrayList<>();
        List<inlinekeyboardbutton> rowInline = new ArrayList<>();

       rowInline.add(new InlineKeyboardButton().setText("DISCUSSION").setCallbackData(Constants.DISCUSSION));
        rowInline.add(new InlineKeyboardButton().setText("SMALL TALK").setCallbackData(Constants.SMALL_TALK));

        rowsInline.add(rowInline);
        inlineKeyboard.setKeyboard(rowsInline);
        return inlineKeyboard;
    }
}
</inlinekeyboardbutton></list<inlinekeyboardbutton>
По пути добавим в Constants:
String START_REPLY = "Start using the telegram bot if you are lonely or bored";
String CHOOSE_OPTION = "Make a choice";
String DISCUSSION = "Let's discuss!";
String SMALL_TALK = "Let's talk!";
Теперь мы можем просто вызвать статический метод нашей фабрики, чтобы использовать встроенную клавиатуру. Самая важная часть кода — это setCallbackData(). Она распознает, какая кнопка была нажата пользователем. Переходим в MessageFactory:
public class MessageFactory {
    private final MessageSender sender; //используется для отправки сообщений обратно пользователю

    public MessageFactory(MessageSender sender) {
        this.sender = sender;
    }

    public void start (long chatId) {
        try {
            sender.execute(new SendMessage()
                    .setText(Constants.START_REPLY)
                    .setChatId(chatId));

            sender.execute(new SendMessage()
                    .setText(Constants.CHOOSE_OPTION)
                    .setChatId(chatId)
                    .setReplyMarkup(KeyboardFactory.startButtons()));


        } catch (TelegramApiException e) {
            e.printStackTrace();
        }
    }
}
Заменим код в методе Telegrambot.replyToStart():
public Ability replyToStart() {
        return Ability
                .builder()
                .name("start")
                .info(Constants.START_DESCRIPTION)
                .locality(ALL)
                .privacy(PUBLIC)
                .action(ctx ->  messageFactory.start(ctx.chatId()))
                .build();
    }
И еще одна поправка в том же классе — замена конструктора:
private TelegramBot(String botToken, String botUsername) {
        super(botToken, botUsername);
        messageFactory = new MessageFactory(sender);
    }
Попробуйте перезапустить ваш бот. Теперь он предложит встроенную клавиатуру в ответ на ваши действия.Telegram Ability Bot: бот, умеющий вести диалог: Часть 2 - 3Полезные лайфхаки для новичков: Если вы пользуетесь Идеей и хотите посмотреть документацию по классу, то выделите класс или метод и нажмите Ctrl+J на Mac или Ctrl+Q на Windows. Также можно сделать правой кнопкой мыши-> Go to-> Declaration of usages. Таким образом, к примеру, можно узнать, что наш AbilityBot на самом деле наследуется от стандартного TelegramLongPollingBot. Только в нем используются лямбды, что существенно сокращает код. В следующей (финальной) части будет развитие диалога и деплой на Heroku.
Комментарии (17)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Vitaliy_JV Student
12 февраля 2023, 11:41
Очень классно и конструктивно! Я уже запустил "полуживой" бот по этому руководству. Круто! Очень хочется следующую часть!
JavaCodeR
Уровень 1
29 августа 2022, 16:27
Блин, где продолжение? Самой важной части нету, я уже столько гуглю как построить систему диалогов в боте, ничего не нахожу
Alexey Finik
Уровень 14
17 мая 2022, 15:13
MessageFactory.java import org.telegram.abilitybots.api.sender.MessageSender; import org.telegram.telegrambots.meta.api.methods.send.SendMessage; import org.telegram.telegrambots.meta.api.objects.Message; import org.telegram.telegrambots.meta.api.objects.MessageEntity; import org.telegram.telegrambots.meta.exceptions.TelegramApiException; import java.util.List; public class MessageFactory { private final MessageSender sender; //используется для отправки сообщений обратно пользователю SendMessage message; SendMessage message2; public MessageFactory(MessageSender sender) { this.sender = sender; } public void start (long chatId) { try { message = new SendMessage(String.valueOf(chatId), Constants.START_REPLY); sender.execute(message); message2 = new SendMessage(String.valueOf(chatId), Constants.CHOOSE_OPTION); message2.setReplyMarkup(KeyboardFactory.startButtons()); sender.execute(message2); } catch (TelegramApiException e) { e.printStackTrace(); } } }
Alexey Finik
Уровень 14
17 мая 2022, 15:13
KeyBoardFactory.java import org.telegram.telegrambots.meta.api.objects.replykeyboard.InlineKeyboardMarkup; import org.telegram.telegrambots.meta.api.objects.replykeyboard.ReplyKeyboard; import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.InlineKeyboardButton; import java.util.ArrayList; import java.util.List; public class KeyboardFactory { public static ReplyKeyboard startButtons() { InlineKeyboardMarkup inlineKeyboard = new InlineKeyboardMarkup(); List<List<InlineKeyboardButton>> rowsInline = new ArrayList<>(); List<InlineKeyboardButton> rowInline = new ArrayList<>(); InlineKeyboardButton inlineKeyboardButton = new InlineKeyboardButton("DISCUSSION"); inlineKeyboardButton.setCallbackData(Constants.DISCUSSION); InlineKeyboardButton inlineKeyboardButton2 = new InlineKeyboardButton("SMALL TALK"); inlineKeyboardButton2.setCallbackData(Constants.SMALL_TALK); rowInline.add(inlineKeyboardButton); rowInline.add(inlineKeyboardButton2); rowsInline.add(rowInline); inlineKeyboard.setKeyboard(rowsInline); return inlineKeyboard; } }
Alexey Finik
Уровень 14
17 мая 2022, 15:12
Присоединяюсь к предыдущему комментатору частично. Вот пока довел бота до следующего состояния: TelegramBot.java import org.telegram.abilitybots.api.bot.AbilityBot; import org.telegram.abilitybots.api.objects.Ability; import org.telegram.abilitybots.api.objects.Locality; import org.telegram.abilitybots.api.objects.Privacy; import org.telegram.telegrambots.meta.api.objects.Update; import java.util.List; public class TelegramBot extends AbilityBot { public TelegramBot(){ this(Constants.BOT_TOKEN, Constants.BOT_USERNAME); } private TelegramBot(String botToken, String botUsername) { super(botToken, botUsername); //MessageFactory messageFactory = new MessageFactory(sender); } @Override public long creatorId() { return Constants.CREATOR_ID; } @Override public void onUpdatesReceived(List<Update> updates) { super.onUpdatesReceived(updates); } @Override public void onClosing() { super.onClosing(); } public Ability replyToStart() { return Ability .builder() .name("start") .info(Constants.START_DESCRIPTION) .locality(Locality.ALL) .privacy(Privacy.PUBLIC) .action(ctx -> new MessageFactory(sender).start(ctx.chatId())) .build(); } }
Oleg Viktorovich
Уровень 41
22 февраля 2021, 20:11
Очень ужасно все рассказано, нечего не получилось по этим 2м статьям, просто огрызки кода, переменные не инициализированны, типо догадывайтесь сами, нету финального кода по каждому классу как должно быть. Я не доволен.
Стас Пасинков Software Developer в Zipy Master
22 июля 2021, 21:47
финальный код у автора на гитхабе :) надеюсь, вы остались довольны :)
Alexey Finik
Уровень 14
17 мая 2022, 17:03
Сейчас он тоже не работает, вроде.
Стас Пасинков Software Developer в Zipy Master
17 мая 2022, 18:56
честно говоря, я его не запускал) а что именно "не работает"? проблемы с запуском? или с функционалом? просто, чаще всего у людей возникают проблемы с деплоем, а не с кодом. или же подключили не ту версию библиотеки в зависимостях - вот "старые" методы и не работают на новом апи :)
Алексей К.
Уровень 41
18 ноября 2020, 09:02
Когда будет продолжение? Очень жду.
Chundrik
Уровень 35
18 ноября 2020, 19:34
Обещаю дописать на этих выходных)
Александер
Уровень 20
11 сентября 2020, 11:05
Очень понравились статьи. Жду с нетерпением продолжения, особенно интересует деплой. Я до сих пор пишу небольшие вещи наподобие ботов для телеграмма, но запускаю их всегда под IDE. Вот как избавиться от этой зависимости и запускать готового бота под виндовсом или маком...? Не представляю...
Chundrik
Уровень 35
30 сентября 2020, 18:11
Большое спасибо!
Azazil47
Уровень 22
30 августа 2020, 13:32
Здравствуйте! Прочел обе Ваши статьи, я пока на 20 уровне и знаний наверное у меня еще мало.(Ранее программированием не увлекался) Мне бы очень хотелось написать бота, но боюсь, что наверное у меня не хватит навыков? P.S. Очень жду продолжение Вашей работы
Chundrik
Уровень 35
31 августа 2020, 19:23
Ух ты, это очень приятно, спасибо) Думаю со временем со всем разберетесь, удачи!
Alukard Vampire hunter в The Hellsing Expert
25 августа 2020, 22:32
Не знаю зачем я это прочел но выглядит круто!
Chundrik
Уровень 35
26 августа 2020, 11:43
Спасибо!