python-3.xpython-telegram-botaiogram

You need to accept the user’s message in aiogram after the bot’s message has been sent


My bot sends a message like “enter the quantity to exchange:” and I need to accept the message that the user sent after this message.

I tried through "message.text" but I was getting the previous message from the user, i.e. "Exchange"

@router.message(F.text == "💱 Exchange")
async def exchange(msg: Message, state: FSMContext):
    State.id = msg.from_user.id
    State.first_name = msg.from_user.first_name
    State.last_name = msg.from_user.last_name
    State.is_premium = msg.from_user.is_premium
    State.is_bot = msg.from_user.is_bot
    await msg.answer('Enter the amount what u need to exchange💱:')
    need_message = msg.text
    print(need_message)
    await state.set_state(UserState.exchange_amount)
    
@router.message(UserState.exchange_amount)
async def exchange_amount_handler(msg: Message, state: FSMContext):
    amount = msg.text
    print(f"You enter {amount} clicks?")
    await state.clear()

github repository: https://github.com/neforskiy/pythonBotClicker


Solution

  • You need to work around Finite State Machine(FSM), built in aiogram

    first things first: configuring storage

    from aiogram.fsm.storage.memory import MemoryStorage
    
    
    storage = MemoryStorage() # memory storage as an example.
    
    dp = Dispatcher(storage=storage)
    

    then you need to make states group

    from aiogram.fsm.state import State, StatesGroup
    
    class UserState(StatesGroup):
        exchange_amount = State()
    

    then you need to modify your existing handler

    from aiogram.fsm.context import FSMContext
    
    @router.message(F.text == "💱 Exchange") # no need to filter state here
    async def exchange(msg: Message, state: FSMContext): # adding state var
        State.id = msg.from_user.id  # idk what is this State you are using
        State.first_name = msg.from_user.first_name  # so I will keep your code untouched
        State.last_name = msg.from_user.last_name
        State.is_premium = msg.from_user.is_premium
        State.is_bot = msg.from_user.is_bot
        await msg.answer('Enter the amount of clicks what u want to exchange to $NOT: 💱')
        need_message = msg.text
        print(need_message)
        await state.set_state(UserState.exchange_amount) # setting state to filter incoming message
    

    then you need a handler to handle different state and new message

    @router.message(UserState.exchange_amount)
    async def exchange_amount_handler(msg: Message, state: FSMContext):
        amount = msg.text
        ... # do whatever you need
        await state.clear() # clear state to enable main menu options or set another to continue routing
    

    more info on states: https://docs.aiogram.dev/en/latest/dispatcher/finite_state_machine/index.html