Почему callback_query_handler в библиотеке telebot не работает? Я создал inline-клавиатуру с кнопками, имеющими callback_data, но обработчик callback-запросов не срабатывает. Вот код создания 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)
А вот мой обработчик callback-запросов, который почему-то не работает (даже простая команда 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-запросов в telebot?
Ваш код содержит несколько распространенных ошибок, которые приводят к неработоспособности callback_query_handler. Основная проблема находится в обработчике callback-запросов - вы используете неопределенную переменную message, а также допустили другие ошибки в структуре кода.
Содержание
- Основная проблема в коде
- Правильная реализация callback_query_handler
- Полный исправленный код
- Дополнительные возможные причины неработоспособности
- Рекомендации по отладке
- Лучшие практики при работе с inline-клавиатурами
Основная проблема в коде
Главная ошибка в вашем обработчике - использование переменной message, которая не определена внутри функции callback_query_handler. Вместо этого вы должны использовать объект callback, который содержит всю информацию о callback-запросе, включая callback.message.chat.id.
# НЕПРАВИЛЬНО (ваш код)
bot.send_message(message.chat.id, f'Список аномалий: ...')
# ПРАВИЛЬНО
bot.send_message(callback.message.chat.id, f'Список аномалий: ...')
Правильная реализация callback_query_handler
Вот как должен выглядеть исправленный обработчик callback-запросов:
@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, 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'Список предметов: ...')
bot.answer_callback_query(callback.id)
Полный исправленный код
from telebot import types
# Создание inline-клавиатуры
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.from_user.id,
f'Инвентарь: \nКоличество аномалий: {str(len(json.loads(log_info(message, 4))))}\n'
f'Количество сотрудников: {str(len(json.loads(log_info(message, 3))))}\n'
f'Количество амуниции: {str(len(json.loads(log_info(message, 5))))}',
reply_markup=keyboard
)
# Удаление предыдущего сообщения
bot.delete_message(message.chat.id, message.message_id)
# Обработчик callback-запросов
@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, 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'Список предметов: ...')
bot.answer_callback_query(callback.id)
Дополнительные возможные причины неработоспособности
Если после исправления основной проблемы обработчик все равно не работает, проверьте следующие моменты:
-
Импорт типов: Убедитесь, что вы правильно импортировали
typesиз telebot:pythonfrom telebot import types -
Инициализация бота: Проверьте, что ваш бот запущен с использованием
bot.polling():pythonif __name__ == '__main__': bot.polling(none_stop=True) -
Конфликт обработчиков: Убедитесь, что нет других обработчиков, которые могут перехватывать callback-запросы.
-
Права бота: Проверьте, что у бота есть необходимые права для отправки сообщений и удаления сообщений в чате.
-
Версия библиотеки: Убедитесь, что вы используете актуальную версию telebot. Рекомендуется использовать версию 0.0.4 или новее.
Рекомендации по отладке
Для диагностики проблемы добавьте больше отладочной информации:
@bot.callback_query_handler(func=lambda callback: True)
def callback_query_handler(callback):
print(f"Callback получен! Data: {callback.data}")
print(f"Chat ID: {callback.message.chat.id}")
print(f"Message ID: {callback.message.message_id}")
try:
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'Список предметов: ...')
bot.answer_callback_query(callback.id)
except Exception as e:
print(f"Ошибка в обработчике: {e}")
bot.answer_callback_query(callback.id, "Произошла ошибка")
Лучшие практики при работе с inline-клавиатурами
-
Используйте статические callback_data: Для простых случаев лучше использовать статические строки в
callback_data, как вы и делаете. -
Обрабатывайте все callback-запросы: Всегда используйте
bot.answer_callback_query()для ответа на callback, чтобы убрать “часики” у кнопки. -
Удаляйте сообщения при необходимости: Как в вашем коде, удаление старого сообщения с клавиатурой - хорошая практика.
-
Обрабатывайте ошибки: Добавьте обработку исключений в ваш callback-обработчик.
-
Используйте редактирование сообщений: Вместо отправки нового сообщения можно редактировать существующее:
pythonbot.edit_message_text(text='Новое сообщение', chat_id=callback.message.chat.id, message_id=callback.message.message_id)
После исправления основной проблемы (использование callback.message.chat.id вместо message.chat.id) ваш код должен начать работать корректно.