Створимо простого бота, який:
• Відповідає на команду /start
• Відповідає на команду /help
• Ехо-повторює будь-яке повідомлення
Асинхронність у Python:
aiogram використовує async/await — це асинхронне програмування. Бот може одночасно обробляти багато користувачів, не блокуючи один одного.
Ключові концепції:
• Router — маршрутизатор для обробників
• @router.message() — декоратор для обробки повідомлень
• CommandStart() — фільтр для команди /start
• message.answer() — відповісти користувачу
@router.message(Command('calc'))
async def cmd_calc(message: Message):
try:
parts = message.text.split()
if len(parts) != 4:
await message.answer('Формат: /calc число операція число')
return
a, op, b = float(parts[1]), parts[2], float(parts[3])
if op == '+': result = a + b
elif op == '-': result = a - b
elif op == '*': result = a * b
elif op == '/':
if b == 0: raise ZeroDivisionError
result = a / b
else:
await message.answer('Невідома операція')
return
await message.answer(f'Результат: {result}')
except (ValueError, ZeroDivisionError) as e:
await message.answer(f'Помилка: {e}')
from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import State, StatesGroup
class Quiz(StatesGroup):
question = State()
questions = [
{'q': 'Що виведе print(2 + 2)?', 'opts': ['22', '4', 'Помилка'], 'ans': 1},
{'q': 'Який тип у 3.14?', 'opts': ['int', 'float', 'str'], 'ans': 1},
{'q': 'Що робить len()?', 'opts': ['Видаляє', 'Рахує довжину', 'Сортує'], 'ans': 1}
]
@router.message(Command('quiz'))
async def start_quiz(message: Message, state: FSMContext):
await state.set_data({'current': 0, 'score': 0})
q = questions[0]
opts = '\n'.join(f'{i+1}. {o}' for i, o in enumerate(q['opts']))
await message.answer(f'{q["q"]}\n{opts}')
await state.set_state(Quiz.question)
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery
@router.message(Command('menu'))
async def show_menu(message: Message):
kb = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text='Погода', callback_data='weather')],
[InlineKeyboardButton(text='Курс валют', callback_data='currency')],
[InlineKeyboardButton(text='Жарт', callback_data='joke')]
])
await message.answer('Оберіть:', reply_markup=kb)
@router.callback_query(lambda c: c.data in ('weather', 'currency', 'joke'))
async def handle_callback(callback: CallbackQuery):
responses = {
'weather': 'Сьогодні сонячно, +22°C',
'currency': '1 USD = 41.5 UAH',
'joke': 'Чому програмісти плутають Гелловін і Різдво? Бо Oct 31 = Dec 25'
}
await callback.message.answer(responses[callback.data])
await callback.answer()