srez

Срез: лендинг, Telegram Mini App и бот для цветочной мастерской

Учебный кейс для портфолио. Мастерская «Срез» вымышленная: адрес, телефон и цены придуманы.

Первый экран лендинга

Проект показывает связку, которую сейчас часто заказывает малый бизнес: сайт, который приводит клиентов, и магазин прямо внутри Telegram, где заказ оформляется за пару минут, а статус приходит в чат.

Задача

Небольшой цветочной мастерской нужно было:

  1. Принимать заказы без звонков и переписки в мессенджерах вручную.
  2. Не брать больше доставок, чем могут развезти курьеры: на каждый двухчасовой интервал их ограниченное число.
  3. Сообщать клиенту, что происходит с заказом, не отвлекая флориста на ответы.
  4. Показать в интернете, что букеты собираются из свежей поставки, и вести людей в Telegram.

Решение

Три части, которые работают вместе:

Часть Что делает
Лендинг (landing/) Рассказывает о мастерской, показывает букеты недели и живую демо-витрину, ведёт в бота
Mini App (miniapp/) Витрина внутри Telegram: каталог, корзина, выбор дня и интервала, оформление, мои заказы
Бот и API (bot/) Принимает заказы, проверяет их, отправляет флористу карточку с кнопками статусов и сообщает клиенту о каждом шаге

Лендинг

Лендинг на компьютере

Telegram Mini App

Витрина в светлой теме Витрина в тёмной теме

Бот и API

Защита и надёжность

Стек: Python 3.11+, aiogram 3, aiohttp, aiosqlite, pytest; HTML, CSS и JavaScript без фреймворков и сборки.

Проверка

cd bot
pip install -r requirements.txt
pytest

Как запустить

Посмотреть без бота

Лендинг и витрина работают как обычные статические страницы. Из корня проекта:

python -m http.server 8000

Откройте http://localhost:8000/landing/. Витрину в демо-режиме можно открыть и отдельно: http://localhost:8000/miniapp/.

Запустить бота

  1. Создайте бота у @BotFather и получите токен.
  2. Mini App открывается только по https. Для разработки подойдёт бесплатный туннель:
    cloudflared tunnel --url http://localhost:8080
    

    Он выдаст адрес вида https://…trycloudflare.com.

  3. В папке bot/ скопируйте .env.example в .env и заполните:
    • BOT_TOKEN — токен от BotFather;
    • ADMIN_IDS — свой Telegram id (его покажет @userinfobot);
    • WEBAPP_URL — адрес туннеля с /app/ в конце.
  4. Запустите:
    cd bot
    python -m venv .venv
    source .venv/bin/activate   # на Windows: .venv\Scripts\activate
    pip install -r requirements.txt
    python -m app.main
    
  5. Напишите боту /start со своего аккаунта: появится кнопка «Выбрать букет», а у флориста — команды /today и /tomorrow.

Бот и витрина работают в одном процессе: сервер отдаёт витрину по адресу /app/ и API по /api/.

Связать лендинг с ботом

В landing/script.js впишите BOT_USERNAME (имя бота без @) и при желании MANAGER_USERNAME для вопросов о подписке. Пока они пустые, кнопки «Заказать» ведут к демо-витрине на странице. Каждая кнопка передаёт боту свою метку (?start=site_hero, site_footer), чтобы было видно, откуда пришёл клиент.

Поменять букеты и цены

Всё в одном файле: miniapp/catalog.json. Там же интервалы доставки, число курьеров, стоимость доставки и порог бесплатной доставки. Сервер проверяет каталог при запуске и сообщит, если в нём ошибка.

art.js лежит в двух папках, miniapp/ и landing/, чтобы каждую можно было выложить отдельно. Если меняете рисунки, скопируйте файл в обе: тест напомнит, если копии разойдутся.

Структура

srez/
├── landing/          лендинг: index.html, styles.css, script.js, art.js
├── miniapp/          витрина: index.html, app.css, app.js, art.js, catalog.json
├── bot/
│   ├── app/
│   │   ├── main.py       запуск бота и веб-сервера
│   │   ├── api.py        API для витрины
│   │   ├── handlers.py   диалог бота и кнопки флориста
│   │   ├── logic.py      проверка заказа, цены, интервалы, статусы
│   │   ├── initdata.py   проверка подписи Telegram
│   │   ├── db.py         заказы в SQLite
│   │   ├── notify.py     сообщения флористу и клиенту
│   │   ├── texts.py      тексты бота
│   │   ├── keyboards.py  кнопки
│   │   ├── catalog.py    чтение каталога
│   │   └── config.py     настройки из .env
│   └── tests/        81 тест
└── docs/             картинки для README и Behance

Что можно добавить дальше

Важно про данные клиентов

Бот хранит имена, телефоны и адреса. В реальном проекте нужно согласие на обработку персональных данных и политика конфиденциальности, а база не должна быть доступна снаружи. Файл .env и базу *.db нельзя выкладывать в публичный репозиторий, они уже в .gitignore.