Как исправить неработающие кнопки в Telegram-боте на Python?

Я добавил в бота миниигру "кубик". После вывода сообщения с описанием игры, под ним отображаются две кнопки. Хотя сообщение и кнопки выводятся, кнопки не реагируют на нажатия, и в консоли не возникает ошибок. Если я отключаю функцию "list", которая расположена в начале кода, бот начинает реагировать только на кнопку "да", в то время как на другую кнопку и на кнопки из последующих сообщений реакции нет. Я пытался убрать функцию "list", так как в коде всего три функции с декоратором "callback_query_handler": это она и ещё две нижеуказанные функции. <br/><br/><pre><code class="python">@bot.callback_query_handler(func=lambda call: True) def list(call): if call.data == 'users': conn = sqlite3.connect('Gok.sql') cur = conn.cursor() cur.execute('SELECT * FROM users') users = cur.fetchall() info = '' for el in users: info += f'Имя: {el[1]}, очки: {el[2]}\n' cur.close() conn.close() bot.send_message(call.message.chat.id, info) @bot.message_handler(commands=['cube']) def cube_game(message): markup = types.InlineKeyboardMarkup() YB = types.InlineKeyboardButton('Да', callback_data='go_play') NB = types.InlineKeyboardButton('Нет', callback_data='dont_play_cube') markup.row(YB, NB) bot.send_message(message.chat.id, 'Игра называется кубик, бот бросает кубик после чего' 'выпадает случайное число от 1 до 6, дальше ход переходит вам, хотите сыграть?', reply_markup=markup) @bot.callback_query_handler(func=lambda call: True) def game_processing(call): if call.data == 'go_play': markup = types.InlineKeyboardMarkup()
  • 3 ноября 2024 г. 18:22
Ответы на вопрос 2
Ваша проблема может быть связана с тем, что у вас несколько декораторов `@bot.callback_query_handler(func=lambda call: True)`, и они могут конфликтовать друг с другом. Поскольку декоратор `@bot.callback_query_handler(func=lambda call: True)` обрабатывает все callback-запросы, после его определения управление будет передаваться первой обработанной функции (в данном случае — функции, которая обрабатывает все callback'и), и, следовательно, другие функции не будут вызываться по их условиям.

Вот несколько шагов, чтобы улучшить ваш код и убедиться, что все функции работают правильно:

1. **Объедините логику обработки нажатий кнопок в одну функцию**: Вместо того, чтобы иметь несколько декораторов для обработки `callback_query`, используйте один обработчик и внутри него различайте действия в зависимости от `call.data`.

2. **Посмотрите на порядок декораторов**: Убедитесь, что обработчики для разных кнопок четко определяют, какой именно `call.data` они должны обработать.

Вот пример того, как вы можете изменить свой код:

```python
import sqlite3
from telebot import TeleBot, types

bot = TeleBot("YOUR_BOT_TOKEN")

@bot.callback_query_handler(func=lambda call: True)
def handle_query(call):
    if call.data == 'users':
        conn = sqlite3.connect('Gok.sql')
        cur = conn.cursor()
        cur.execute('SELECT * FROM users')
        users = cur.fetchall()
        info = ''
        for el in users:
            info += f'Имя: {el[1]}, очки: {el[2]}\n'
        cur.close()
        conn.close()
        bot.send_message(call.message.chat.id, info)
        
    elif call.data == 'go_play':
        # Логика для начала игры
        bot.send_message(call.message.chat.id, "Вы начали игру! Бросайте кубик!")
        # Здесь можно добавить логику игры

    elif call.data == 'dont_play_cube':
        bot.send_message(call.message.chat.id, "Вы отказались играть.")
    
    # Добавляйте другие условия здесь для обработки других кнопок

@bot.message_handler(commands=['cube'])
def cube_game(message):
    markup = types.InlineKeyboardMarkup()
    YB = types.InlineKeyboardButton('Да', callback_data='go_play')
    NB = types.InlineKeyboardButton('Нет', callback_data='dont_play_cube')
    markup.row(YB, NB)
    bot.send_message(message.chat.id, 'Игра называется кубик, бот бросает кубик после чего' 'выпадает случайное число от 1 до 6, дальше ход переходит вам, хотите сыграть?', reply_markup=markup)

# Запускаем бота
bot.polling()
```

Суть изменений:
- У вас теперь один обработчик для всех кнопок, что позволяет избежать конфликта и обработки немногими декораторами.
- В функции `handle_query` проверяются все возможные значения `call.data`, и соответствующая логика выполняется в зависимости от нажатой кнопки. 

После этих изменений ваш бот должен корректно обрабатывать нажатия на кнопки.
Проблема, я полагаю, та же что и всегда - несколько обработчиков с func=lambda call: True .
Похожие вопросы