Почему callback_query_handler в telebot не работает?
Вот сам inline вызывается:
keyboard = InlineKeyboardMarkup()
keyboard.add(InlineKeyboardButton(text='Показать аномалии', callback_data="show_anom"))
keyboard.add(InlineKeyboardButton(text='Показать сотрудников', callback_data="show_empl"))
keyboard.add(InlineKeyboardButton(text='Показать предметы', callback_data="show_items"))
bot.send_message(message.from_user.id, f'Инвентарь: \nКоличество аномалий: {str(len(json.loads(log_info(message, 4))))}\nКоличество сотрудников: {str(len(json.loads(log_info(message, 3))))}\nКоличество амуниции: {str(len(json.loads(log_info(message, 5))))}', reply_markup=keyboard)
bot.delete_message(message.chat.id, message.message_id)
А вот декоратор, который почему то не работает (даже банальный print(1) не показывает):
@bot.callback_query_handler(func=lambda callback: True)
def callback_query_handler(callback):
print(1)
message: Message
if callback.data == 'show_anom':
bot.send_message(message.chat.id, f'Список аномалий: ...')
elif callback.data == 'show_empl':
bot.send_message(message.chat.id, f'Список сотрудников: ...')
elif callback.data == 'show_items':
bot.send_message(message.chat.id, f'Список предметов: ...')
bot.answer_callback_query(callback.id)
Проблема с callback_query_handler в telebot обычно возникает из-за неправильной регистрации обработчика, конфликтов с другими обработчиками или ошибок в сигнатуре функции. Код вашего декоратора выглядит синтаксически правильно, но есть несколько распространенных проблем, которые могут вызывать такое поведение.
Содержание
- Основные причины неработающего callback_query_handler
- Проверка регистрации обработчиков
- Анализ вашего кода и ошибки
- Решение проблемы
- Дополнительные проверки
- Пример рабочего кода
- Источники
Основные причины неработающего callback_query_handler
Callback_query_handler в telebot может не работать по нескольким причинам:
- Неправильная регистрация обработчика - обработчик может быть зарегистрирован после начала polling
- Конфликты с другими обработчиками - другие обработчики могут перехватывать callback-запросы
- Ошибки в сигнатуре функции - функция-обработчик должна принимать правильные параметры
- Проблемы с answering callback - неотвеченные callback-запросы могут вызывать проблемы
- Версия библиотеки - некоторые версии pyTelegramBotAPI имеют известные ошибки
Как указано в документации pyTelegramBotAPI, callback-запросы требуют правильной обработки и ответа.
Проверка регистрации обработчиков
Убедитесь, что ваш callback_query_handler зарегистрирован до начала polling:
# Регистрируем обработчик ДО начала polling
@bot.callback_query_handler(func=lambda callback: True)
def callback_query_handler(callback):
print(1) # Для отладки
if callback.data == 'show_anom':
bot.send_message(callback.message.chat.id, 'Список аномалий: ...')
elif callback.data == 'show_empl':
bot.send_message(callback.message.chat.id, 'Список сотрудников: ...')
elif callback.data == 'show_items':
bot.send_message(callback.message.chat.id, 'Список предметов: ...')
bot.answer_callback_query(callback.id)
# Начинаем polling ПОСЛЕ регистрации всех обработчиков
bot.polling(none_stop=True)
Как объясняют в стеке, обработчики должны быть зарегистрированы в правильном порядке.
Анализ вашего кода и ошибки
В вашем коде есть несколько критических ошибок:
- Несуществующая переменная
message:
# НЕПРАВИЛЬНО - переменная message не определена
bot.send_message(message.chat.id, f'Список аномалий: ...')
# ПРАВИЛЬНО - используйте callback.message
bot.send_message(callback.message.chat.id, f'Список аномалий: ...')
- Отсутствие обработки ошибок - добавьте try-except для отладки:
@bot.callback_query_handler(func=lambda callback: True)
def callback_query_handler(callback):
try:
print(f"Callback получен: {callback.data}")
# ваш код
except Exception as e:
print(f"Ошибка в callback_handler: {e}")
Как показано в примере на GitHub, правильное использование callback-запросов включает обработку ошибок.
Решение проблемы
Вот исправленная версия вашего кода:
@bot.callback_query_handler(func=lambda callback: True)
def callback_query_handler(callback):
try:
print(1) # Проверяем, что обработчик вызывается
if callback.data == 'show_anom':
bot.send_message(callback.message.chat.id, f'Список аномалий: ...')
elif callback.data == 'show_empl':
bot.send_message(callback.message.chat.id, f'Список сотрудников: ...')
elif callback.data == 'show_items':
bot.send_message(callback.message.chat.id, f'Список предметов: ...')
# Обязательно отвечаем на callback, чтобы убрать "часики"
bot.answer_callback_query(callback.id, text="Обработка...")
except Exception as e:
print(f"Ошибка в callback_handler: {e}")
bot.answer_callback_query(callback.id, text="Ошибка!")
Также убедитесь, что ваш обработчик зарегистрирован правильно и нет конфликтов с другими обработчиками.
Дополнительные проверки
- Проверьте версию библиотеки:
import telebot
print(telebot.__version__)
- Добавьте логирование для отслеживания callback-запросов:
import logging
# Настройка логирования
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
@bot.callback_query_handler(func=lambda callback: True)
def callback_query_handler(callback):
logger.info(f"Получен callback: {callback.data} от {callback.from_user.id}")
# остальной код
- Проверьте конфликты обработчиков - убедитесь, что у вас нет других обработчиков, которые могут перехватывать callback-запросы.
Как отмечено в обсуждении на GitHub, правильная настройка обработчиков важна для корректной работы inline-кнопок.
Пример рабочего кода
Вот полный пример рабочего кода с callback_query_handler:
import telebot
from telebot import types
import json
bot = teleBot('YOUR_TOKEN_HERE')
@bot.message_handler(commands=['start'])
def start_command(message):
# Создаем клавиатуру
keyboard = types.InlineKeyboardMarkup()
keyboard.add(types.InlineKeyboardButton(text='Показать аномалии', callback_data="show_anom"))
keyboard.add(types.InlineKeyboardButton(text='Показать сотрудников', callback_data="show_empl"))
keyboard.add(types.InlineKeyboardButton(text='Показать предметы', callback_data="show_items"))
bot.send_message(message.chat.id, 'Инвентарь:', reply_markup=keyboard)
@bot.callback_query_handler(func=lambda callback: True)
def callback_query_handler(callback):
try:
print(f"Callback получен: {callback.data}")
if callback.data == 'show_anom':
bot.send_message(callback.message.chat.id, 'Список аномалий: ...')
elif callback.data == 'show_empl':
bot.send_message(callback.message.chat.id, 'Список сотрудников: ...')
elif callback.data == 'show_items':
bot.send_message(callback.message.chat.id, 'Список предметов: ...')
# Отвечаем на callback, чтобы убрать индикатор загрузки
bot.answer_callback_query(callback.id, text="Обработка завершена")
except Exception as e:
print(f"Ошибка в callback_handler: {e}")
bot.answer_callback_query(callback.id, text="Произошла ошибка")
# Запускаем бота
bot.polling(none_stop=True)
Источники
- Официальная документация pyTelegramBotAPI - CallbackQuery
- Stack Overflow - Why is my Telegram Bot callback query handler not working?
- GitHub Discussion - Callback query handler don’t work
- GitHub Issue - How we should set callback query handler for inline buttons?
- Stack Overflow - PyTelegrambotApi — @callback_query_handler does not work
Заключение
Основные проблемы с callback_query_handler в telebot обычно связаны с:
- Неправильным использованием переменных - всегда используйте
callback.messageвместоmessage - Отсутствием ответа на callback - обязательно вызывайте
bot.answer_callback_query() - Неправильной регистрацией обработчиков - регистрируйте все обработчики до начала polling
- Отсутствием обработки ошибок - добавляйте try-except блоки для отладки
После исправления этих проблем ваш callback_query_handler должен работать корректно. Если проблема остается, проверьте версию библиотеки и добавьте подробное логирование для отладки.