@VasiliyGubenkov

Как отправить переменную вместе с нажатием кнопки, в декоратор callback, не прибегая к созданию глобальной переменной?

Делаю бота, который задает пользователю детские загадки, и проверяет ответы. После того, как бот задал загадку, у меня появляется кнопка, 'Узнать ответ и закрыть загадку'. Соответственно после нажатия этой кнопки, мы из декоратора callback получаем ответ на загадку, и выходим в общий режим обработки команд.
В моем боте рандомная загадка запрашивается из базы sql, разбивается на две переменных- на загадку, и на ответ. Это происходит в декораторе @bot.message_handler(). Ну и весь остальной процесс сравнения тоже происходит в этом декораторе.
Чтобы "узнать правильный ответ" я отправляю переменную "ответ" в обработчик кнопок @bot.callback_query_handler через создание глобальной переменной.
Но вот в чем проблема: если два пользователя одновременно играют с ботом в загадки, то когда один нажмет на кнопку "узнать правильный ответ" то получит ответ другого пользователя, потому что в глобальной переменой в тот момент будет другое значение.
Как мне отправить переменную в декоратор callback, в привязке к этому конкретному пользователю?
Для простоты понимания я упрощу свой код, удалю оттуда всё, что связано с запросом в базу данных. Допустим пользователь просто отгадывает рандомное число.

otvet_na_zagadku = ''
@bot.message_handler()
def riddle(message):
    global otvet_na_zagadku
    randomny_nomer = random.choice(range(1, 11))
    markup = types.InlineKeyboardMarkup()
    markup.add(types.InlineKeyboardButton('Узнать правильный ответ и закрыть загадку', callback_data= 'sdalsia'))
    if 'загад' in message.text.lower():
        otvet_na_zagadku = ramdomny_nomer
        bot.send_message(message.chat.id, 'Угадай число", reply_markup=markup)
        bot.register_next_step_handler(message, answer)
    else:
        bot.reply_to(message, "Я задаю загадки, попроси меня... ")
def answer(message):
    markup = types.InlineKeyboardMarkup()
    markup.add(types.InlineKeyboardButton('Узнать правильный ответ и закрыть загадку', callback_data='sdalsia'))
    if message.text.lower() == otvet_na_zagadku:
        bot.send_message(message.chat.id, 'Правильный ответ! Попроси меня загадать следующую загадку!')
    else:
        bot.send_message(message.chat.id, 'Неправильный ответ', reply_markup = markup)
        bot.register_next_step_handler(message, answer)

@bot.callback_query_handler(func=lambda callback: True)
def loos(callback):
    if callback.data == 'sdalsia':
        bot.send_message(callback.message.chat.id, '<strong>Правильный ответ: </strong>' + otvet_na_zagadku, parse_mode='html')
        bot.clear_step_handler_by_chat_id(callback.message.chat.id)
  • Вопрос задан
  • 41 просмотр
Решения вопроса 1
@VasiliyGubenkov Автор вопроса
Я помог себе сам. Тыкался тыкался, и опытным путем выяснил, что через "callback_data= переменная" можно сразу передавать переменную с ответом, без каких-либо дополнительных "танцов с бубном".
Если когда-нибудь, у кого- нибудь, возникнет подобный вопрос. Пишите- помогу.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@twistfire92
Python backend developer
сходу можно 2 варианта рассмотреть.
1. Самое простое, но не самое правильное - глобальную переменную сделать не строкой, а словарем, куда будет записываться соответствие
id пользователя (ключ) и его ответ на загадку (значение). Соответственно можно просто через метод update вставлять ответ для каждого пользователя.

2. зашивать в callback_data номер текущей загадки и потом просто по этому номеру вытаскивать ответ.

второй способ предпочтительнее, т.к. в первом случае после рестарта бота весь процесс у пользователей слетит. Да и не очень хорошо глобальными переменными пользоваться
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы