1

i've faced with some problem in aiogram. And i have no idea what wrong with that code and what might be the reason of that problem.

My bot is asking for some question. Before asking it need to be sure, that user is now ready for that. After that he send the question and receives answer via inline button and schedules next question. Step looks like:

Step 1: user sends /start

Step 2: bot asking user is he ready to receive a message

Step 3: user press 'ready'

Step 4: bot send a message with inline keyboard

Step 5: user press inline button

Step 6: bot scheduling next step 2 and sending a message with the time

What the problem: When 1 user going through this steps everything is ok and works perfect. But when 2 or more users doing that the same time, first loop goes ok but during the second loop (after scheduling) bot reacts on 'ready' button in step 3 only for the user, who was last in step 6. For other users bot do not react on 'ready' button in step 3. Even though all users are in 'get_ready' state.

i was trying to resolve in for a days, setting logging and checking what happening in each step. But didn't find any problems.

aiogram 2.25.1 python 3.10.10

bot = Bot(token = os.environ.get('TOKEN'))
storage = MemoryStorage()

dp = Dispatcher(bot, storage = storage)

callback_answers = CallbackData("answer", "index")
callback_ready = CallbackData('ready')

msg_scheduler = AsyncIOScheduler()
msg_scheduler.start()

class Quiz(StatesGroup):
    get_ready = State()
    get_answer = State()

async def quiz(username, chat_id):

    # setting inline keyboard
    ready_keyboard = types.InlineKeyboardMarkup()
    ready_keyboard.add(types.InlineKeyboardButton(text = 'Ready!', callback_data = 'ready'))

    # sending message with 'ready' button
    await bot.send_message(chat_id = chat_id, text = 'Ready?', reply_markup = ready_keyboard)

    # put some data to the storage
    state = dp.current_state(chat = chat_id)
    await state.update_data(username = username)
    await state.update_data(chat_id = chat_id)

@dp.callback_query_handler(text = 'ready', state = Quiz.get_ready)
async def ask_question(call: types.CallbackQuery, state: FSMContext):

    # setting inline keyboard with answer
    keyboard = types.InlineKeyboardMarkup()
    keyboard.add(types.InlineKeyboardButton(text = 'some answer', callback_data = callback_answers.new(index = 'some_index')))

    # sending message with question
    await call.message.answer(text = 'Some message', reply_markup = keyboard)

    # pending for user reply
    await Quiz.get_answer.set()

@dp.callback_query_handler(callback_answers.filter(), state = Quiz.get_answer)
async def check_answer(call: types.CallbackQuery, callback_data: dict, state: FSMContext):

    data = await state.get_data()
    
    # scheduling next msg
    await schedule_next_msg(data['username'], data['chat_id'])

    await state.finish()


async def schedule_next_msg(username, chat_id):

    job = msg_scheduler.add_job(quiz, 'date', [username, chat_id], run_date = datetime.datetime.now() + datetime.timedelta(seconds = 5), name = 'Quiz for ' + username)

    await bot.send_message(chat_id = chat_id, text = f"next msg planned on {job.next_run_time}")

@dp.message_handler(commands=["start"])
async def cmd_start(message: types.Message, state: FSMContext):

    await quiz(message.from_user.username, message.from_user.id)

if __name__ == "__main__":
    executor.start_polling(dp, skip_updates=True)
Dmitry
  • 11
  • 2

0 Answers0