Не работают кнопки в телеграм боте
Проблема в том, что кнопки не работают — при нажатии на них ничего не происходит. Я добавил 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.