Найти в Дзене
Дети Свифта

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

Предыстория В одной из своих предыдущих статей я уже делилась с читателями первым опытом создания и развёртывании на сервере telegram-бота на java. При разработке бота были выбраны такие способы взаимодействия пользователя с ботом как: За 4 месяца самостоятельной жизни моего первого бота стало понятно, что пользователям не хочется что-либо вводить в поле сообщения. Что значительно удобней было бы просто нажимать на очередную кнопку при выборе формы документа. Иными словами, в целях упрощения взаимодействия с ботом необходимо минимизировать возможность использовать обычную клавиатуру смартфона или ПК. И такая возможность есть, если применить InlineKeyboard – вариант кнопок (за которыми скрыт необходимый функционал), прикрепленных непосредственно к сообщению от бота. Применить такую клавиатуру я решила при разработке другого бота. Однако столкнулась с тем, что ни в документации Telegram bot Api, ни в статьях / разборах, размещенных в Интернет, нет прозрачного пошагового пояснения всей
Найдено на просторах интернета
Найдено на просторах интернета

Предыстория

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

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

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

За 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;
}

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

-4

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

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 не так и много. Надеюсь, этот разбор кому-нибудь поможет при разработке своих телеграмм ботов.

Если интересно, как это реализовано в моем последнем телеграмм боте (усовершенствованная и усложненная версия бота Сам себе галерист), то милости прошу: Игра "Викторина".

О.Блас

-5