К содержимому
Hub
Бот бронирования столиков

Бот бронирования столиков

Боты2026Pythonaiogram 3SQLiteTelegramFSM

Телеграм-бот для ресторана: гость выбирает дату, время и столик, администратор подтверждает в чате. Двойное бронирование исключено на уровне базы.

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

Для гостя: пошаговая форма — дата, время, число человек, столик, контакты. Занятые и уже прошедшие слоты помечены и не выбираются. Показываются только те столики, куда помещается указанное число гостей. Свои брони видно списком, отмена в один клик. Телефон можно отправить кнопкой или ввести руками, номер проверяется.

Для администратора: уведомление о каждой новой брони с кнопками «Подтвердить» и «Отклонить», гость сразу получает результат. Отчёты за сегодня, завтра, произвольный день и за всё время.

Главное решение — защита от двойного бронирования. Проверять занятость запросом перед вставкой ненадёжно: между проверкой и записью успевает вклиниться второй гость. Поэтому запрет живёт в самой базе — частичный уникальный индекс по столику, дате и времени, из которого исключены отменённые брони. Две одновременные заявки на один слот физически не могут обе записаться.

Python 3.11, aiogram 3, SQLite. Асинхронный код, конечный автомат для многошаговой формы, зависимости прокидываются в обработчики через встроенный механизм aiogram.

Как это устроено

Фрагмент из настоящего кода проекта — чтобы было видно, что внутри.

Репозиторий
SQL
CREATE TABLE IF NOT EXISTS bookings (    id         INTEGER PRIMARY KEY AUTOINCREMENT,    user_id    INTEGER NOT NULL,    username   TEXT,    table_id   INTEGER NOT NULL REFERENCES tables(id),    book_date  TEXT    NOT NULL,    book_time  TEXT    NOT NULL,    guests     INTEGER NOT NULL,    status     TEXT    NOT NULL DEFAULT 'pending');-- Один столик нельзя занять дважды на один и тот же слот.-- Отменённые брони из проверки исключаются.---- Проверять занятость запросом перед вставкой ненадёжно: между-- проверкой и записью успевает вклиниться второй гость. Здесь-- запрет живёт в самой базе, и обойти его нельзя.CREATE UNIQUE INDEX IF NOT EXISTS idx_booking_slot    ON bookings (table_id, book_date, book_time)    WHERE status <> 'cancelled';CREATE INDEX IF NOT EXISTS idx_booking_user ON bookings (user_id);CREATE INDEX IF NOT EXISTS idx_booking_date ON bookings (book_date);
Связаться

Заявка на проект

Заполните форму — обсудим детали и сроки.

По проекту: Бот бронирования столиков
Следующий проект

TechnoMarket — магазин техники