Не работают кнопки в телеграм боте

Проблема в том, что кнопки не работают — при нажатии на них ничего не происходит. Я добавил CallbackQueryHandler для обработки callback-запросов, но обработчик не вызывается.

Вот пример кода:

import asyncio
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import Application, CommandHandler, ContextTypes, CallbackQueryHandler

TOKEN = "="

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    chat_id = update.effective_chat.id
    keyboard = [[InlineKeyboardButton("Нажми меня", callback_data="press_me")]]
    reply_markup = InlineKeyboardMarkup(keyboard)
    await context.bot.send_message(
        chat_id=chat_id,
        text="Нажми на кнопку ниже!",
        reply_markup=reply_markup
    )

async def button_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
    print("Обработчик кнопки вызван!") 
    query = update.callback_query
    await query.answer()
    data = query.data
    if data == "press_me":
        await query.edit_message_text("Кнопка нажата!")

def main():
    app = Application.builder().token(TOKEN).build()

    app.add_handler(CommandHandler("start", start))
    app.add_handler(CallbackQueryHandler(button_handler, pattern="^press_me$"))

    app.run_polling()

if __name__ == "__main__":
    main()

Ожидаемое поведение:
После нажатия кнопки "Нажми меня" текст сообщения должен измениться на "Кнопка нажата!", а в консоли должно появиться сообщение "Обработчик кнопки вызван!".

Фактическое поведение:
Кнопка появляется, но при нажатии ничего не происходит — ни в Telegram, ни в консоли.

Версия Python: 3.10
Версия python-telegram-bot: 20.7

В чём может быть проблема? Возможно, я неправильно регистрирую обработчик или что-то не так с настройкой бота?


Ответы (1 шт):

Автор решения: ʏʊքɨ

Ну вообще лучше использовать другие библиотеки, например aiogram или telebot. Они более удобны для написания телеграм ботов в ассинхронном виде.

Не знаю как на telegram-bot, но вот код на telebot:

import logging, asyncio
from telebot.async_telebot import AsyncTeleBot
from telebot.types import InlineKeyboardButton, InlineKeyboardMarkup

TOKEN = ''
bot = AsyncTeleBot(TOKEN)

# Настройка логирования
logging.basicConfig(
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    level=logging.INFO
)
logger = logging.getLogger(__name__)


@bot.message_handler(commands=['start'])
async def send_welcome(message):
    try:
        keyboard = InlineKeyboardMarkup()
        keyboard.add(InlineKeyboardButton(
            "Нажми меня", callback_data="press_me"))

        await bot.send_message(
            chat_id=message.chat.id,
            text="Нажми на кнопку ниже!",
            reply_markup=keyboard
        )
    except Exception as e:
        logger.error(f"Ошибка в send_welcome: {e}")


@bot.callback_query_handler(func=lambda call: True)
async def handle_button_click(call):
    try:
        logger.info(f"Обработчик вызван с данными: {call.data}")

        if call.data == "press_me":
            await bot.answer_callback_query(call.id, "Кнопка нажата!")
            await bot.edit_message_text(
                chat_id=call.message.chat.id,
                message_id=call.message.message_id,
                text="Кнопка нажата!"
            )
    except Exception as e:
        logger.error(f"Ошибка в handle_button_click: {e}")

if __name__ == '__main__':
    logger.info("Бот запущен")
    asyncio.run(bot.polling())

requirements.txt

telebot==0.0.5
aiohttp==3.11.16

Или на aiogram:

from aiogram import Bot, Dispatcher, types
from aiogram.filters import Command
from aiogram.utils.keyboard import InlineKeyboardBuilder
import logging, asyncio

# Инициализируем логгер
logger = logging.getLogger(__name__)

TOKEN = ''

bot = Bot(token=TOKEN)
dp = Dispatcher()


@dp.message(Command("start"))
async def cmd_start(message: types.Message):
    builder = InlineKeyboardBuilder()
    builder.button(text="Нажми меня", callback_data="press_me")
    await message.answer(
        "Нажми на кнопку ниже!",
        reply_markup=builder.as_markup()
    )


@dp.callback_query(lambda c: c.data == "press_me")
async def handle_callback(callback: types.CallbackQuery):
    # Добавляем запись в лог
    logger.info("Обработчик кнопки вызван!")

    await callback.answer("Кнопка нажата!", show_alert=False)
    await callback.message.edit_text("Кнопка нажата!")


async def main():
    # Настройка логирования
    logging.basicConfig(
        level=logging.INFO,
        format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
    )
    await dp.start_polling(bot)

if __name__ == "__main__":
    asyncio.run(main())

requirements.txt

aiogram==3.19.0
aiohttp==3.11.16

Для логгирования лучше использовать конечно loguru, но logging тоже годится. Как на обычном python-telegram-bot сделать не знаю, но данные мной решения работают по задуманной логике.

И понятно дело, нужно получить токен для бота в @BotFather.

→ Ссылка