1

I have got a Telegram-bot in AIOgram. My aim in this bot is to run it and if user writes secret phrase - bot must send secret message.

My code in main.py file:

from aiogram.dispatcher.filters import Text
from aiogram.dispatcher import FSMContext

from database import Database
from states import *
from aiogram import Bot, Dispatcher, executor, types

bot = Bot(token="my_token")
dp = Dispatcher(bot)

@dp.message_handler(commands="start")
async def start(message: types.Message):
    keyboard1 = types.InlineKeyboardMarkup()
    links = ["one", "two", "three"]

    for row in links:
        button = types.InlineKeyboardButton(text=row[0])
        keyboard1.add(button)

    await message.answer("Chose the phrase", reply_markup=keyboard1)
    # options - is the next handler function
    dp.register_message_handler(options, state="*")

async def options(message: types.Message):
    if message.text == "Secret phrase":
        keyboard = types.ReplyKeyboardMarkup(one_time_keyboard=True)
        keyboard.add(types.KeyboardButton(text="Secret 1"),
                     types.KeyboardButton(text="Secret 2"),
                     types.KeyboardButton(text="Secret 3"),
                     types.KeyboardButton(text="Main menu"))
        await message.answer("Chose the phrase", reply_markup=keyboard)
        dp.register_message_handler(workingWithLinks, state="*")
    else:
        await message.answer("This command is error, for phrases update call command /update")

async def workingWithLinks(message: types.Message):
    if message.text == "Secret 1":
        await message.answer("This is secret number 1")
        await SecretOne.step_one.set()
    elif message.text == "Secret 2":
        await SecretTwo.step_one.set()
        await message.answer("This is secret 2")
    elif message.text == "Secret 3":
        await SecretThree.step_one.set()
        await message.answer("This is secret 3")
    else:
        await message.answer("This command is error, for phrases update call command /update")

def register_handlers_common(dp: Dispatcher):
    dp.register_message_handler(start, commands="start", state="*")
    dp.register_message_handler(start, commands="update", state="*")
    
if __name__ == "__main__":
    register_handlers_common(dp)
    executor.start_polling(dp, skip_updates=True)

My code in states.py file:

from aiogram.dispatcher.filters.state import State, StatesGroup

class SecretOne(StatesGroup):
    step_one = State()
    step_two = State()
    step_three = State()

class SecretTwo(StatesGroup):
    step_one = State()
    step_two = State()
    step_three = State()

class SecretThree(StatesGroup):
    step_one = State()
    step_two = State()
    step_three = State()

Scenario of my bot is next: I click command /start, and bot sends me message "Chose the phrase" with three inline-buttons - "one", "two" and "three". And if user don't click on one of this button and type "Secret phrase" - program link user to "options" handler-function. This is string, where linking is:

dp.register_message_handler(options, state="*")

"options" is handler-function. This link works. But, if in "options" I chose the phrase "Secret 1" - link on workingWithLinks handler-function doesn't work.

Linking on workingWithLinks handler-function:

dp.register_message_handler(workingWithLinks, state="*")

Also I tried to link on next handler-function with states as in this tutorial, but this also doesn't works.

How to link on workingWithLinks handler-function?

1 Answers1

0

Don't register message handlers in message handlers!

dp.register_message_handler(options, state="*")

This string will add handler to the stack on every message call.

Answer

If you wanna get something from user - use states. Look at the FSM example

Oleg
  • 523
  • 2
  • 10