mirror of
https://github.com/aiogram/aiogram.git
synced 2025-12-11 18:01:04 +00:00
111 lines
3.2 KiB
Python
111 lines
3.2 KiB
Python
import asyncio
|
|
import logging
|
|
import sys
|
|
from os import getenv
|
|
|
|
from aiogram import Bot, Dispatcher, F
|
|
from aiogram.dispatcher.filters import Command
|
|
from aiogram.dispatcher.fsm.context import FSMContext
|
|
from aiogram.dispatcher.fsm.state import State, StatesGroup
|
|
from aiogram.types import KeyboardButton, Message, ReplyKeyboardMarkup, ReplyKeyboardRemove
|
|
from aiogram.utils.keyboard import KeyboardBuilder
|
|
from aiogram.utils.markdown import hbold
|
|
|
|
GENDERS = ["Male", "Female", "Helicopter", "Other"]
|
|
|
|
dp = Dispatcher()
|
|
|
|
|
|
# States
|
|
class Form(StatesGroup):
|
|
name = State() # Will be represented in storage as 'Form:name'
|
|
age = State() # Will be represented in storage as 'Form:age'
|
|
gender = State() # Will be represented in storage as 'Form:gender'
|
|
|
|
|
|
@dp.message(Command(commands=["start"]))
|
|
async def cmd_start(message: Message, state: FSMContext):
|
|
"""
|
|
Conversation's entry point
|
|
"""
|
|
# Set state
|
|
await state.set_state(Form.name)
|
|
await message.answer("Hi there! What's your name?")
|
|
|
|
|
|
@dp.message(Command(commands=["cancel"]))
|
|
@dp.message(F.text.lower() == "cancel")
|
|
async def cancel_handler(message: Message, state: FSMContext):
|
|
"""
|
|
Allow user to cancel any action
|
|
"""
|
|
current_state = await state.get_state()
|
|
if current_state is None:
|
|
return
|
|
|
|
logging.info("Cancelling state %r", current_state)
|
|
# Cancel state and inform user about it
|
|
await state.clear()
|
|
# And remove keyboard (just in case)
|
|
await message.answer("Cancelled.", reply_markup=ReplyKeyboardRemove())
|
|
|
|
|
|
@dp.message(Form.name)
|
|
async def process_name(message: Message, state: FSMContext):
|
|
"""
|
|
Process user name
|
|
"""
|
|
await state.update_data(name=message.text)
|
|
await state.set_state(Form.age)
|
|
await message.answer("How old are you?")
|
|
|
|
|
|
# Check age. Age gotta be digit
|
|
@dp.message(Form.age, ~F.text.isdigit())
|
|
async def process_age_invalid(message: Message):
|
|
"""
|
|
If age is invalid
|
|
"""
|
|
return await message.answer("Age gotta be a number.\nHow old are you? (digits only)")
|
|
|
|
|
|
@dp.message(Form.age)
|
|
async def process_age(message: Message, state: FSMContext):
|
|
# Update state and data
|
|
await state.set_state(Form.gender)
|
|
await state.update_data(age=int(message.text))
|
|
|
|
# Configure ReplyKeyboardMarkup
|
|
constructor = KeyboardBuilder(KeyboardButton)
|
|
constructor.add(*(KeyboardButton(text=text) for text in GENDERS)).adjust(2)
|
|
markup = ReplyKeyboardMarkup(
|
|
resize_keyboard=True, selective=True, keyboard=constructor.export()
|
|
)
|
|
await message.reply("What is your gender?", reply_markup=markup)
|
|
|
|
|
|
@dp.message(Form.gender)
|
|
async def process_gender(message: Message, state: FSMContext):
|
|
data = await state.update_data(gender=message.text)
|
|
await state.clear()
|
|
|
|
# And send message
|
|
await message.answer(
|
|
(
|
|
f'Hi, nice to meet you, {hbold(data["name"])}\n'
|
|
f'Age: {hbold(data["age"])}\n'
|
|
f'Gender: {hbold(data["gender"])}\n'
|
|
),
|
|
reply_markup=ReplyKeyboardRemove(),
|
|
)
|
|
|
|
|
|
async def main():
|
|
bot = Bot(token=getenv("TELEGRAM_TOKEN"), parse_mode="HTML")
|
|
|
|
await dp.start_polling(bot)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
logging.basicConfig(level=logging.INFO, stream=sys.stdout)
|
|
asyncio.run(main())
|