Задать вопрос
@Gouzaiku

Не работает FSM в Aiogram 3.18.0, у меня ошибка где-то?

Пытаюсь сделать состояния уже в сумме 5 часов и разобраться в чём ошибка, помогите ,пожалуйста, укажите где ошибка.

использовал даже ИИ

Код
import asyncio
import logging
import sqlite3

from aiogram import Bot, Dispatcher, html, types, F
from aiogram.client.default import DefaultBotProperties
from aiogram.enums import ParseMode
from aiogram.fsm.state import State, StatesGroup
from aiogram.fsm.context import FSMContext
from aiogram.fsm.storage.memory import MemoryStorage
from aiogram.fsm.strategy import FSMStrategy
from aiogram.types import Message
from aiogram.utils.keyboard import ReplyKeyboardBuilder as RKB

TOKEN = 'ТОКЕН'  # Рекомендуется использовать переменные окружения

bot = Bot(token=TOKEN, default=DefaultBotProperties(parse_mode=ParseMode.HTML))
dp = Dispatcher(storage=MemoryStorage(), fsm_strategy=FSMStrategy.USER_IN_CHAT)

logging.basicConfig(level=logging.INFO)

class Form(StatesGroup):
    name = State()
    phonenumber = State()
    mail = State()
    address = State()

@dp.message(F.text)
async def command_start_handler(message: Message, state: FSMContext) -> None:
    if message.text == "/start":
        builder = RKB()
        regbutton = types.KeyboardButton(text="Создать запрос")
        builder.add(regbutton)
        await message.reply(f"Привет, {html.bold(message.from_user.full_name)}!")
        await message.reply("Для создания запроса нажмите кнопку ниже:", reply_markup=builder.as_markup())
    elif message.text == "Создать запрос":  # использовал elif
        await message.answer("Введите своё ФИО:")
        await state.set_state(Form.name)
        print(Form.name.state)

@dp.message(F.text, Form.name)
async def reg1(message: Message, state: FSMContext) -> None:
    print('Рег1')
    await state.update_data(name=message.text)
    await message.reply("Напишите свой номер телефона:")
    await state.set_state(Form.phonenumber)

@dp.message(F.text, Form.phonenumber)
async def reg2(message: Message, state: FSMContext) -> None:
    await state.update_data(phonenumber=message.text)
    await message.reply("Теперь введите свою почту ниже")
    await state.set_state(Form.mail)

@dp.message(F.text, Form.mail)
async def reg3(message: Message, state: FSMContext) -> None:
    await state.update_data(mail=message.text)
    await message.reply("Напишите адрес дома или квартиры")
    await state.set_state(Form.address)

@dp.message(F.text, Form.address)
async def reg4(message: Message, state: FSMContext) -> None:
    await state.update_data(address=message.text)

    data = await state.get_data()

    try:
        con = sqlite3.connect('userdata.db')
        cur = con.cursor()
        cur.execute("""
            CREATE TABLE IF NOT EXISTS user (
                name TEXT,
                phonenumber TEXT,
                mail TEXT,
                address TEXT
            )
        """)
        cur.execute("INSERT INTO user (name, phonenumber, mail, address) VALUES (?, ?, ?, ?)", 
                    (data['name'], data['phonenumber'], data['mail'], data['address']))
        con.commit()
    except sqlite3.Error as e:
        logging.error(f"Ошибка базы данных: {e}")
    finally:
        con.close()  # Закрываем соединение

    await message.reply("Ваш запрос успешно создан!")

async def main() -> None:
    logging.info("Бот запущен")
    await dp.start_polling(bot)

if __name__ == '__main__':
    asyncio.run(main())
  • Вопрос задан
  • 38 просмотров
Подписаться 1 Простой 3 комментария
Пригласить эксперта
Ответы на вопрос 1
@nevvery
@dp.message(F.text)
async def command_start_handler(message: Message, state: FSMContext) -> None:
    if message.text == "/start":
        builder = RKB()
        regbutton = types.KeyboardButton(text="Создать запрос")
        builder.add(regbutton)
        await message.reply(f"Привет, {html.bold(message.from_user.full_name)}!")
        await message.reply("Для создания запроса нажмите кнопку ниже:", reply_markup=builder.as_markup())
    elif message.text == "Создать запрос":  # использовал elif
        await message.answer("Введите своё ФИО:")
        await state.set_state(Form.name)
        print(Form.name.state)


У тебя первый хендлер перехватывает все сообщение, потому что он слишком "общий". Какое бы состояние ты не передал, он перехватывает все сообщение, который вводишь (поэтому до следующих хендлеров при проверки даже не доходит). Либо перенеси его под всего остальные хендлеры, чтобы он проверялся в последнею очередь, либо же раздели этот хендлер на два более специфичные

@dp.message(F.text == '/start')
async def command_start_handler(message: Message) -> None:
        builder = RKB()
        regbutton = types.KeyboardButton(text="Создать запрос")
        builder.add(regbutton)
        await message.reply(f"Привет, {html.bold(message.from_user.full_name)}!")
        await message.reply("Для создания запроса нажмите кнопку ниже:", reply_markup=builder.as_markup())


@dp.message(F.text == 'Создать запрос')
async def command_start_handler(message: Message, state: FSMContext) -> None:
    await message.answer("Введите своё ФИО:")
    await state.set_state(Form.name)
    print(Form.name.state)


Грубый пример, но думаю суть ясна.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы