Простыми словами об InlineKeyboard в Телеграмм ботах на java

—

от автора

Предыстория 

В своей статье на Хабре я уже делилась с читателями первым опытом создания и развёртывании на сервере telegram-бота на java. При разработке бота были выбраны такие способы взаимодействия пользователя с ботом как:

 — ReplyKeyboardMarkup – клавиатура, которая показывается вместо основной и не привязана ни к какому сообщению. Представляет собой шаблоны сообщений (варианты ответа), которые выбираются путем нажатия на готовую кнопку. Боту в качестве сообщения отправляется то, что написано на кнопке;

— получение от пользователя запроса посредством введения в поле сообщения конкретной команды либо набора определенного сообщения.

За 4 месяца самостоятельной жизни моего первого бота стало понятно, что пользователям не хочется что-либо вводить в поле сообщения. Что значительно удобней было бы просто нажимать на очередную кнопку при выборе формы документа. Иными словами, в целях упрощения взаимодействия с ботом необходимо минимизировать возможность использовать обычную клавиатуру смартфона или ПК.

И такая возможность есть, если применить InlineKeyboard – вариант кнопок (за которыми скрыт необходимый функционал), прикрепленных непосредственно к сообщению от бота.

Применить такую клавиатуру я решила при разработке другого бота. Однако столкнулась с тем, что ни в документации Telegram bot Api, ни в статьях / разборах, размещенных в Интернет, нет прозрачного пошагового пояснения всей цепочки процессов. Разобравшись для себя с взаимосвязями вызовов в InlineKeyboard я решила этим поделиться с другими разработчиками. 

Как оно устроено

Для создания встроенной клавиатуры необходимо работать со следующими классами:

— InlineKeyboardMarkup – объект, представляющий собой встроенную клавиатуру,

— InlineKeyboardButton — объект одной кнопки встроенной клавиатуры. Кнопка или набор кнопок располагается сразу под сообщением от бота. Объект принимает, помимо прочего, такие параметры как: text (отображается на кнопке, обязательный параметр, поддерживает текст и эмодзи), url (адрес на который будет перенаправлен пользователь), callback_data (строка 1-64 символа, которая будет передана боту через объект CallbackQuery).

В своем проекте, основной функционал которого заключается в отправке пользователю картинок с изображением работ художника, которого пользователь выбирает на встроенной клавиатуре, я реализовала InlineKeyboard следующим образом.

1. Сами встроенные клавиатуры я создавала в отдельных классах через методы, возвращающие объект типа SendMessage:

public static SendMessage hermitageInlineKeyboardAb (long chat_id) {  // создаем объект сообщения         SendMessage message = new SendMessage();         message.setChatId(chat_id);         message.setText(«Чтобы увидеть картины, нажми на фамилию художника или перейди в полную коллекцию на сайте музея»);  // создаем объект встроенной клавиатуры         InlineKeyboardMarkup markupInline = new InlineKeyboardMarkup();  // создаем список списков кнопок, который впоследствии объединит ряды кнопок         List<List<InlineKeyboardButton>> rowsInline = new ArrayList<>();  // создаем список с кнопками для первого ряда         List<InlineKeyboardButton> rowInline1 = new ArrayList<>();  // создаем первую кнопку для в ряду         InlineKeyboardButton inlineKeyboardButton1 = new InlineKeyboardButton();   // устанавливаем параметр текста на кнопке          inlineKeyboardButton1.setText(«Аврезе»);           // устанавливаем параметр callback_data          inlineKeyboardButton1.setCallbackData(«АВРЕЗЕ»);   // создаем по аналогии вторую кнопку в ряду                 InlineKeyboardButton inlineKeyboardButton2 = new InlineKeyboardButton();         inlineKeyboardButton2.setText(«Аликс»);         inlineKeyboardButton2.setCallbackData(«АЛИКС»);  // добавляем кнопки в первый ряд в том порядке,  // какой нам необходим. В рассматриваемом случае ряд будет содержать 2 кнопки,  // размер которых будет одинаково пропорционально растянут по ширине сообщения,  // под которым клавиатура располагается         rowInline1.add(inlineKeyboardButton1);         rowInline1.add(inlineKeyboardButton2);  // если необходимо в кнопку запрограммировать переход на адрес  // Интернет страницы, такой параметр устанавливается через setUrl(String s).  // При этом в приведенном примере ряд кнопок будет состоять всего из одной кнопки         InlineKeyboardButton inlineKeyboardButton21 = new InlineKeyboardButton();         inlineKeyboardButton21.setText(«Переход на внешний сайт»);                     inlineKeyboardButton21.setUrl(«https://collections.hermitagemuseum.org»);   // устанавливаем url, указывая строковый параметр с адресом страницы         inlineKeyboardButton21.setCallbackData(«ПЕРЕХОД НА ВНЕШНИЙ САЙТ»);          rowInline11.add(inlineKeyboardButton21);  // настраиваем разметку всей клавиатуры         rowsInline.add(rowInline1);         rowsInline.add(rowInline2); …         rowsInline.add(rowInline11);  // добавляем встроенную клавиатуру в сообщение         markupInline.setKeyboard(rowsInline);         message.setReplyMarkup(markupInline); 

Отдельно необходимо остановиться на таком параметре как CallbackData. Это обязательный идентификатор, который позволяет боту понять, какая кнопка была нажата. У каждой кнопки – свой индивидуальный идентификатор (фактически id кнопки). Когда пользователь нажимает на кнопку, такой id передается боту, а бот в свою очередь понимает, какая из кнопок была нажата, и впоследствии совершает для пользователя определенные действия (в моем случае – высылает картинку).

Получаем итоговый код метода:

public static SendMessage hermitageInlineKeyboardAb (long chat_id) {          SendMessage message = new SendMessage();         message.setChatId(chat_id);         message.setText(«Чтобы увидеть картины, нажми на фамилию художника или перейди в полную коллекцию на сайте музея»);          InlineKeyboardMarkup markupInline = new InlineKeyboardMarkup();          List<List<InlineKeyboardButton>> rowsInline = new ArrayList<>();          List<InlineKeyboardButton> rowInline1 = new ArrayList<>();         InlineKeyboardButton inlineKeyboardButton1 = new InlineKeyboardButton();         inlineKeyboardButton1.setText(«Аврезе»);         inlineKeyboardButton1.setCallbackData(«АВРЕЗЕ»);         InlineKeyboardButton inlineKeyboardButton2 = new InlineKeyboardButton();         inlineKeyboardButton2.setText(«Аликс Ив»);         inlineKeyboardButton2.setCallbackData(«АЛИКС»);         rowInline1.add(inlineKeyboardButton1);         rowInline1.add(inlineKeyboardButton2);          List<InlineKeyboardButton> rowInline2 = new ArrayList<>();         InlineKeyboardButton inlineKeyboardButton3 = new InlineKeyboardButton();         inlineKeyboardButton3.setText(«Амелин»);         inlineKeyboardButton3.setCallbackData(«АМЕЛИН»);         InlineKeyboardButton inlineKeyboardButton4 = new InlineKeyboardButton();         inlineKeyboardButton4.setText(«Арстер»);         inlineKeyboardButton4.setCallbackData(«АРСТЕР»);         rowInline2.add(inlineKeyboardButton3);         rowInline2.add(inlineKeyboardButton4);          … // иные необходимые ряды кнопок по вышеуказанной аналогии          List<InlineKeyboardButton> rowInline11 = new ArrayList<>();         InlineKeyboardButton inlineKeyboardButton21 = new InlineKeyboardButton();         inlineKeyboardButton21.setText(«Переход на внешний сайт»);         inlineKeyboardButton21.setUrl(«https://collections.hermitagemuseum.org»);         inlineKeyboardButton21.setCallbackData(«ПЕРЕХОД НА ВНЕШНИЙ САЙТ»);         rowInline11.add(inlineKeyboardButton21);          rowsInline.add(rowInline1);         rowsInline.add(rowInline2);      …          rowsInline.add(rowInline11);          markupInline.setKeyboard(rowsInline);         message.setReplyMarkup(markupInline);          return message;      } 

В боте это визуализируется следующим образом:

Некоторые разработчики пишут, что экспериментальным путем они выяснили ограничения по количеству кнопок встроенной клавиатуры: не более восьми в ряд и не более ста всего. При этом количество рядов хоть и не ограничено, но в совокупности больше ста кнопок не получается.

2. Обработка действий пользователя при нажатии кнопок встроенной клавиатуры:

В классе, где переопределен метод onUpdateReceived(), прописываем обработку событий, связанных с встроенными клавиатурами. В такой обработке обязательно проводим как минимум 2 проверки того, что пришло от пользователя – текст или CallbackData (то самое id кнопки, что мы устанавливали при создании клавиатур). Без указанных проверок ответных действий от встроенной клавиатуры не последует:

@SneakyThrows @Override     public void onUpdateReceived(Update update) {          if (update.hasMessage() && update.getMessage().hasText()) {             message_text = update.getMessage().getText();             long chat_id = update.getMessage().getChatId();  // если получен соответствующий текст,              if (message_text.equals(«А-Б»)) {   //то отправляем пользователю нужную встроенную клавиатуру                 execute(HermitageInlineKeyboardAb.hermitageInlineKeyboardAb(chat_id));             }   // если же пользователь передал не текст,  // а некое значение - id кнопки (CallbackData)           } else if (update.hasCallbackQuery()) {  // то бот совершает определенные действия // (в моем случае – отправляет пользователю картинки  // или перенаправляет его на страницу в Интернете)              String call_data = update.getCallbackQuery().getData();             long chat_id = update.getCallbackQuery().getMessage().getChatId(); String path = «D:\\testBot\\testing\\src\\main\\resources\\page.jpg»;              if (call_data.equals(«АВРЕЗЕ»)) {                 execute(Sender.sendPhoto(chat_id, path));             } else if (call_data.equals(«ПЕРЕХОД НА ВНЕШНИЙ САЙТ»)) {                                 execute(Sender.sendMessage(chat_id, ""));             }

Итого

Статей и разъясняющих материалов про встроенные клавиатуры телеграмм ботов с одной стороны предостаточно, однако примеров именно для java не так и много. Надеюсь, этот разбор и реализация InlineKeyboard в проекте, код которого выложен на GitHub, кому-нибудь поможет при разработке своих телеграмм ботов.

Если интересно, как работает мой последний телеграмм бот, то милости прошу: Сам себе галерист.


ссылка на оригинал статьи https://habr.com/ru/articles/746370/