DEV Community

Cover image for Telegram bot. Добавим интерактивности
Stanislav Karol
Stanislav Karol

Posted on

Telegram bot. Добавим интерактивности

В этой заметке я писал о том, как по команде бота выдаётся случайное фото, а если добавить параметр к команде, то будет целенаправленный выбор темы.
У меня в том боте, который я неспешно сейчас пишу, есть нечто подобное: по команде выбирается случайный канал и из него достаются картинки. Если указали канал, то выбор идёт из указанного. До какого-то момента это меня устраивало, пока список каналов не стал подходить к 10. И тогда я задумал сделать такую возможность: дать пользователю выбрать канал по нажатию на кнопку.

Вот примерно как это сделано у меня.
Не важно, что вы используете в качестве библиотеки обращения к api, важно понимание этого самого api. Мы будем работать с методом sendMessage

    this.bot.sendMessage(chatId, "Выберите канал:", {
      reply_markup: {
        resize_keyboard: true,
        inline_keyboard: [
          [{ text: "Случайно", callback_data: "random" }],
          [{ text: "Спорт", callback_data: "sport" }],
          [{ text: "Кино", callback_data: "cinema" }],
          [{ text: "Музыка", callback_data: "music" }],
        ],
      },
    });
Enter fullscreen mode Exit fullscreen mode

Результат:
Результат
Здесь у нас каждый массив с объектом- это строка с кнопкой. Можно и по-другому сделать, например так:

    this.bot.sendMessage(chatId, "Выберите канал:", {
      reply_markup: {
        resize_keyboard: true,
        inline_keyboard: [
          [{ text: "Случайно", callback_data: "random" }],
          [
            { text: "Спорт", callback_data: "sport" },
            { text: "Кино", callback_data: "cinema" },
            { text: "Музыка", callback_data: "music" },
          ],
        ],
      },
    });
Enter fullscreen mode Exit fullscreen mode

Alt Text

Осталось добавить обработчик нажатия на кнопку. В библиотеке node-telegram-bot-api можно это сделать используя функцию on - первый параметр задаёт событие бота, на которое реагировать, второй параметр- обработчик этого события.

// После инициализации бота, задать обработчик 
   this.bot.on("callback_query", this.callbackQuery); 
// обработчик нажатия на кнопки
  callbackQuery = async (callbackQuery) => {
    const msg = callbackQuery.message;
    // Спрятать клавиатуру (оптимально)
    // await this.removeHisKeyboard(callbackQuery);
    // См. ниже пояснения
    await this.bot.answerCallbackQuery(callbackQuery.id);
    const { data = "" } = callbackQuery;
    //..
  };
  /**
   * Удалить вывод клавиатуры
   */
  removeHisKeyboard = (callbackQuery) => {
    const messageText = callbackQuery.message.text;
    const messageId = callbackQuery.message.message_id;
    return this.bot
      .editMessageText(messageText, {
        message_id: messageId,
        chat_id: callbackQuery.from.id,
        reply_markup: {
          inline_keyboard: [],
        },
      })      
  };
Enter fullscreen mode Exit fullscreen mode

Про callbackQuery написано в документации по api - там же объясняется, почему нужно вызывать answerCallbackQuery . Функция removeHisKeyboard здесь может и не нужна, но если Вы хотите скрыть клавиатуру, после того, как сделан выбор, то можно ей воспользоваться. Здесь бот редактирует своё сообщение с интерактивным выбором,- он просто очищает inline_keyboard.

Top comments (1)

Collapse
 
ohbob profile image
Roberts Ozoliņš

Спосибо, интересно