Создание бота для заказов на Aiogram 3 с FSM и SQLite
Автор: Javohir Abdullayev · · Telegram-боты

Введение: почему именно Aiogram 3 и FSM?
Telegram-боты сегодня стали самым удобным инструментом для связи с клиентами в сфере бизнеса и услуг. Автоматизированные боты для приема заказов особенно востребованы среди владельцев малого бизнеса и фрилансеров. В этой статье мы шаг за шагом создадим бота для приема заказов с помощью Python и современной библиотеки Aiogram 3.
В ходе проекта мы будем использовать технологию FSM (Finite State Machine — конечный автомат) для поэтапного сбора данных от пользователя и базу данных SQLite для сохранения полученной информации.
1. Подготовка рабочего окружения
Сначала создадим отдельное виртуальное окружение для нашего проекта и установим необходимые библиотеки. Выполните следующие команды в терминале:
python -m venv venv
source venv/bin/activate # Для Windows: venv\Scripts\activate
pip install aiogram aiosqliteФайловая структура нашего проекта будет выглядеть следующим образом:
main.py— основной файл запуска бота;database.py— модуль для асинхронной работы с SQLite;handlers.py— обработчики процесса заказа и команд;states.py— описание состояний FSM.
2. Настройка базы данных (database.py)
Для асинхронной записи заказов в базу данных мы используем библиотеку aiosqlite. Это увеличивает скорость работы бота и предотвращает задержки в очереди запросов.
import aiosqlite
DB_NAME = "orders.db"
async def init_db():
async with aiosqlite.connect(DB_NAME) as db:
await db.execute("""
CREATE TABLE IF NOT EXISTS orders (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER,
full_name TEXT,
phone_number TEXT,
product_name TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
""")
await db.commit()
async def add_order(user_id: int, full_name: str, phone: str, product: str):
async with aiosqlite.connect(DB_NAME) as db:
await db.execute(
"INSERT INTO orders (user_id, full_name, phone_number, product_name) VALUES (?, ?, ?, ?)",
(user_id, full_name, phone, product)
)
await db.commit()3. Определение состояний FSM (states.py)
В процессе оформления заказа пользователь проходит 3 шага: вводит имя, отправляет номер телефона и указывает наименование товара. Для этого создадим класс StatesGroup:
from aiogram.fsm.state import State, StatesGroup
class OrderState(StatesGroup):
full_name = State()
phone_number = State()
product_name = State()4. Обработка сообщений (handlers.py)
Теперь напишем логику работы бота. Когда пользователь вводит /start или /order, запускается FSM, и данные с каждого шага сохраняются в памяти:
from aiogram import Router, F
from aiogram.types import Message, ReplyKeyboardMarkup, KeyboardButton, ReplyKeyboardRemove
from aiogram.filters import CommandStart, Command
from aiogram.fsm.context import FSMContext
from states import OrderState
from database import add_order
router = Router()
@router.message(CommandStart())
async def start_cmd(message: Message):
await message.answer(
f"Здравствуйте, {message.from_user.first_name}!\n"
"Для оформления заказа отправьте команду /order."
)
@router.message(Command("order"))
async def order_start(message: Message, state: FSMContext):
await state.set_state(OrderState.full_name)
await message.answer("Пожалуйста, введите ваше полное имя:")
@router.message(OrderState.full_name)
async def process_name(message: Message, state: FSMContext):
await state.update_data(full_name=message.text)
await state.set_state(OrderState.phone_number)
phone_btn = ReplyKeyboardMarkup(
keyboard=[[KeyboardButton(text="Отправить номер", request_contact=True)]],
resize_keyboard=True,
one_time_keyboard=True
)
await message.answer("Отправьте ваш номер телефона или введите его вручную:", reply_markup=phone_btn)
@router.message(OrderState.phone_number)
async def process_phone(message: Message, state: FSMContext):
if message.contact:
phone = message.contact.phone_number
else:
phone = message.text
await state.update_data(phone_number=phone)
await state.set_state(OrderState.product_name)
await message.answer("Какой товар или услугу вы хотите заказать?", reply_markup=ReplyKeyboardRemove())
@router.message(OrderState.product_name)
async def process_product(message: Message, state: FSMContext):
product = message.text
user_data = await state.get_data()
full_name = user_data.get("full_name")
phone = user_data.get("phone_number")
# Сохранение в базу данных
await add_order(message.from_user.id, full_name, phone, product)
# Очистка состояния
await state.clear()
await message.answer(
"Спасибо! Ваш заказ успешно принят.\n\n"
f"Имя: {full_name}\n"
f"Телефон: {phone}\n"
f"Товар: {product}\n\n"
"В скором времени оператор свяжется с вами!"
)5. Запуск бота (main.py)
В основном файле объединим бота и диспетчер, инициализируем базу данных и запустим бота в режиме polling:
import asyncio
import logging
from aiogram import Bot, Dispatcher
from database import init_db
from handlers import router
BOT_TOKEN = "ВАШ_ТОКЕН_БОТА"
async def main():
logging.basicConfig(level=logging.INFO)
bot = Bot(token=BOT_TOKEN)
dp = Dispatcher()
# Инициализация базы данных
await init_db()
# Подключение роутеров
dp.include_router(router)
print("Бот успешно запущен!")
await dp.start_polling(bot)
if __name__ == "__main__":
try:
asyncio.run(main())
except (KeyboardInterrupt, SystemExit):
print("Бот остановлен.")Практические советы и расширение функционала
Для дальнейшего улучшения этого проекта вы можете добавить следующие возможности:
- Админ-панель: отправка уведомлений в Telegram-профиль администратора или специальную группу при поступлении нового заказа.
- Валидация: использование модуля
regular expressions (re)для проверки корректности введенного формата номера телефона. - Inline-кнопки: отображение списка товаров и предоставление пользователю возможности выбора с помощью кнопок вместо ручного ввода текста.
Заключение
Возможности FSM в Aiogram 3 позволяют организовать взаимодействие с пользователями структурированно и без ошибок. Вы можете включить этот готовый шаблон в свое портфолио или предложить его клиентам из малого бизнеса в качестве системы приема заказов.
Теги: #aiogram 3 #telegram bot #python darslari #sqlite #fsm