Кнопки под сообщением: inline

Вчерашние кнопки живут внизу экрана. Но бывают другие, которые висят прямо под конкретным сообщением. Открой любой нормальный бот и увидишь их: «Купить», «Подробнее», «Назад». Они называются inline-кнопки, и сегодня мы их сделаем.

После урока сможешь: объяснить тему «Кнопки под сообщением: inline» и выполнить связанный с ней учебный шаг без подсказки.

Чем inline отличается от reply

Reply-кнопка при нажатии присылает обычный текст. А inline-кнопка присылает не текст, а особый сигнал, который называют callback (читается «колбэк»). Пользователь в чате ничего не печатает, а бот понимает, какую кнопку нажали. Ловить нажатие будем не обычным обработчиком, а отдельным, для callback.

Показываем inline-кнопки

Сделаем команду /menu, которая покажет кнопки под сообщением.

@bot.message_handler(commands=['menu'])
def menu(message):
    keyboard = types.InlineKeyboardMarkup()
    keyboard.add(types.InlineKeyboardButton("Шутка", callback_data="joke"))
    keyboard.add(types.InlineKeyboardButton("Совет", callback_data="advice"))
    bot.send_message(message.chat.id, "Выбери, что прислать:", reply_markup=keyboard)

types.InlineKeyboardButton("Шутка", callback_data="joke") это кнопка с двумя кусочками: надпись, которую видит человек, и callback_data — тихое слово-метка, которое прилетит боту при нажатии. Человек его не видит, оно для программы. Метки joke и advice можешь назвать как удобно.

Ловим нажатие

@bot.callback_query_handler(func=lambda call: True)
def on_click(call):
    if call.data == "joke":
        bot.send_message(call.message.chat.id, "Программист заходит в лифт, а там кнопки 0 и 1.")
    elif call.data == "advice":
        bot.send_message(call.message.chat.id, "Не бойся ошибок. Бойся не сохраниться.")
    bot.answer_callback_query(call.id)
  • @bot.callback_query_handler(...) новая табличка на двери, ловит именно нажатия inline-кнопок. Внутрь прилетает не message, а call — информация о нажатии.
  • call.data это метка, которую мы задали. По ней через if понимаем, какую кнопку нажали. Адрес чата теперь call.message.chat.id.
  • bot.answer_callback_query(call.id) говорит Telegram «я принял нажатие». Без неё на кнопке крутятся часики, как будто бот завис.

Ловушка: часики висят, хотя answer_callback_query есть

Строчка bot.answer_callback_query на месте, а часики на кнопке всё равно крутятся? Знакомая ловушка. Дело почти всегда не в этой строке. Две частые причины: (1) ты дописал строку, но не перезапустил бота, и он работает по старому коду, где её ещё нет; (2) запущены две копии бота сразу, они мешают друг другу. И то, и другое лечится перезапуском: останови бота (Ctrl+C), проверь, что нигде больше он не запущен, и запусти файл заново. Часики оживут. Подробный разбор обеих ловушек — в уроке «Бот молчит? Чиним», причины 6 и 7.

Контрольный вопрос. У inline-кнопки есть тихая метка, которую бот получает при нажатии. Как называется параметр этой метки? Напиши одно слово.

Подсказка: types.InlineKeyboardButton(«Шутка», ____=»joke»)

Онлайн-проверка ответа появится позже

Задание. Сделай команду /menu с 2-3 inline-кнопками, на каждую свой ответ. Не забудь answer_callback_query, чтобы убрать часики. Пришли скриншот меню с кнопками под сообщением и ответа на нажатие.

Подсказка: InlineKeyboardMarkup + InlineKeyboardButton с callback_data, ловить callback_query_handler по call.data.

✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.

Онлайн-проверка ответа появится позже

Зачёт, если:
✅ команда /menu показывает 2-3 inline-кнопки под сообщением;
✅ на каждую кнопку свой ответ, часики после нажатия пропадают (есть answer_callback_query);
✅ прислан скриншот меню и ответа на нажатие.

Назад  ·  ↑ В начало урока  ·  ⌂ В начало курса  ·  Вперёд →

Школа Виктора Комлева