aiogram FSM и кнопка вернуть назад
Я хочу сделать бота который будет добавлять в базу данных информацию про бензин на заправках. У каждой заправки может быть свой список марок горючего.
Как мне сделать чтобы я заходил в заправку выбрал например на этой клавиатуре А92 оно бах записало в переменную, потом выбрал А95 записало в переменную... а потом я говорю ок из 3х вариантов горючего есть только два значит я сохраняю их бд.. и эти две переменные я отдаю в функцию сохранение в бд.
from db import db_connect as db
from settings import config
from aiogram import types, Dispatcher
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.dispatcher.filters import Text
from db import db_connect as db
class FSMAdmin(StatesGroup):
station = State()
fuel = State()
async def fsm_start(message: types.Message):
await FSMAdmin.station.set()
await message.answer("Оберіть заправку", reply_markup=config.STATION_FUEL_MENU, disable_notification=True)
async def cancel_handler(message: types.Message, state: FSMContext):
current_state = await state.get_state()
if current_state is None:
return
await state.finish()
await message.answer("Відміна команди виконана", reply_markup=types.ReplyKeyboardRemove())
async def back_state():
await FSMAdmin.previous()
async def set_station(message: types.Message, state: FSMContext):
async with state.proxy() as data:
data['station'] = message.text
stations = {
'⛽ Shell': config.FUELS_ALL_MENU,
'⛽ MAC': config.FUELS_BEZ_GAZ,
'⛽ Belarus': config.FUELS_GAZ_MENU,
}
await message.answer("Вкажіть наявність пального",
reply_markup=stations[message.text],
disable_notification=True)
await FSMAdmin.next()
async def save_fuel(message: types.Message, state: FSMContext):
current_state = await state.get_state()
if current_state is None:
return
await db.update_db(state)
await state.finish()
await message.answer("Дані успішно збережені", reply_markup=types.ReplyKeyboardRemove())
async def set_fuel(message: types.Message, state: FSMContext):
dict_fuel = {
"А-95": "fuel_95",
"А-92": "fuel_92",
"ДП": "fuel_dp",
"Газ": "fuel_gaz"
}
async with state.proxy() as data:
data.setdefault("choise_fuel", [])
if dict_fuel[message.text] not in data["choise_fuel"]:
data["choise_fuel"].append(dict_fuel[message.text])
def register_handlers_admin(dp: Dispatcher):
dp.register_message_handler(fsm_start, commands="пальне", state=None, chat_id=[978284975, 261891285, 145333452])
dp.register_message_handler(cancel_handler, state="*", commands="відміна")
dp.register_message_handler(cancel_handler, Text(equals="відміна", ignore_case=True), state="*")
dp.register_message_handler(back_state, Text(equals="?️ Назад", ignore_case=True), state="*")
dp.register_message_handler(save_fuel, state="*", commands="/Зберегти")
dp.register_message_handler(save_fuel, Text(equals="? Зберегти", ignore_case=True), state="*")
dp.register_message_handler(set_station, state=FSMAdmin.station)
dp.register_message_handler(set_fuel, Text(equals=["А-95", "А-92", "ДП", "Газ"]), state=FSMAdmin.fuel)
Ответы (1 шт):
Автор решения: oleksandrigo
→ Ссылка
Немного поменял ваш код, но в целом оно теперь будет в стейт записывать выбранный тип топлива.
PS. И да, я не люблю регистрацию хендлеров, ибо фиг поймешь что вообще происходит.
class FSMAdmin(StatesGroup):
station = State()
set_fuel = State()
# state=None писать бессмысленно, этот фильтр стоит по умолчанию
@dp.message_handler(commands=["пальне"], chat_id=[978284975, 261891285, 145333452])
async def fsm_start(message: types.Message):
await message.answer("Оберіть заправку",
reply_markup=config.STATION_FUEL_MENU,
disable_notification=True)
await FSMAdmin.station.set()
@dp.message_handler(state="*", commands="відміна")
@dp.message_handler(Text(equals="відміна", ignore_case=True), state="*")
async def cancel_handler(message: types.Message, state: FSMContext):
current_state = await state.get_state()
if current_state is None:
return
await state.finish()
await message.answer("Відміна команди виконана",
reply_markup=types.ReplyKeyboardRemove())
@dp.message_handler(state=FSMAdmin.station)
async def set_station(message: types.Message, state: FSMContext):
async with state.proxy() as data:
data['station'] = message.text
choise_dict = {
'⛽ Заправка1': config.FUELS_ALL_MENU,
'⛽ Заправка2': config.FUELS_BEZ_GAZ,
'⛽ Заправка3': config.FUELS_GAZ_MENU,
}
await message.answer("Вкажіть наявність пального",
reply_markup=choise_dict[message.text],
disable_notification=True)
await FSMAdmin.next()
@dp.message_handler(state="*", commands="/Зберегти")
@dp.message_handler(Text(equals="? Зберегти", ignore_case=True), state="*")
async def save_fuel(message: types.Message, state: FSMContext):
current_state = await state.get_state()
if current_state is None:
return
await db.update_db(state)
await state.finish()
await message.answer("Дані успішно збережені", reply_markup=types.ReplyKeyboardRemove())
@dp.message_handler(text=["А-95", "А-92", "ДП", "Газ"], state=FSMAdmin.set_fuel)
async def set_fuel(message: types.Message, state: FSMContext):
dict_fuel = {
"А-95": "fuel_95",
"А-92": "fuel_92",
"ДП": "fuel_dp",
"Газ": "fuel_gaz"
}
async with state.proxy() as data:
# делаем список по-умолчанию
data.setdefault("choise_fuel", [])
# если такого элемента нет то добалвляем
if dict_fuel[message.text] not in data["choise_fuel"]:
data["choise_fuel"].append(dict_fuel[message.text])
# дабавлен какой-то типо топлива в стейт