Телеграм-бот для геймификации прогулок: пользователи фиксируют шаги через live-локацию, копят баланс, обменивают его на товары и управляют заказами. Поверх бота доступны FastAPI-админка (подавать ПВЗ и выгружать заказы) и отдельная Django-админка для контента. Код структурирован по слоям (handlers → services → repo → SQLAlchemy) и полностью управляется из .env.
- Отслеживание шагов и валидация скорости (геопозиция,
geopy, детектор ускорения) с дневными лимитами. - Баланс пользователя и семейный банк, совместные покупки, реферальная программа и промокоды.
- Каталог товаров, оформление заказов, выбор ПВЗ и интеграция с CDEK (тарифы, веса, габариты).
- Служебные сценарии: FAQ, история начислений, уведомления, админ-команды внутри бота.
- Планировщик рассылок (broadcast worker) и push по расписанию с медиа.
- API для массовой загрузки ПВЗ и выгрузки заказов (FastAPI, заголовок
API_Key).
- Telegram worker (aiogram 3) —
app/steps_bot/handlers/*содержит роутеры с finite-state-machine (app/steps_bot/states/*) и in-memory storage (app/steps_bot/storage/user_memory.py). - Сервисный слой — папка
services/инкапсулирует бизнес-правила: расчет шагов и скорости, проверки промокодов, интеграции с погодой (Open-Meteo), CDEK и т. д. - Данные и репозиторий —
db/models(SQLAlchemy 2.0, async) +db/repo.pyс атомарными операциями и хелперами для заказов, семей, ПВЗ. Миграции лежат в корнеmigrations/(Alembic). - Admin API —
app/steps_bot/api/admin.py(FastAPI + uvicorn). Используется для загрузки списка ПВЗ и выгрузки заказов за период c обязательным API-ключом. - Django admin — отдельный проект
app/admin/(Django 5.2) для контент-редакторов. Сервис поднимается из Docker Compose и использует те же таблицы. - Фоновые задачи —
services/broadcast_service.pyвызывается планировщиком внутриpolling.pyкаждые 60 секунд; поддерживаются медиафайлы иMEDIA_ROOT. - Webhooks vs polling —
app/steps_bot/main.pyразвёртывает FastAPI с роутом/webhook,polling.pyпереключает бота в long polling и выключает вебхук.
- Python 3.11+, Poetry
- aiogram 3.x, FSM, кастомные кейборды
- FastAPI + uvicorn для API и webhook
- Django 5.2 (опциональная админка)
- SQLAlchemy 2.0 (async) + Alembic
- PostgreSQL 15 (asyncpg)
- Docker / Docker Compose
- httpx, geopy, pydantic-settings, aiosmtplib
app/steps_bot/handlers/— сценарии бота (start,walk,family,catalog,balance,promo,referral,admin_tools, и др.).app/steps_bot/services/— бизнес-логика (расчет шагов, финиш прогулок, каталог, покупки, рассылки, валидации, погода).app/steps_bot/db/models/— сущности (user, family, catalog/product, ledger, promo, pvz, referral, walk и т. д.).app/steps_bot/api/— FastAPI-приложение для админских задач.app/steps_bot/webhooks/— обработчик Telegram webhook для FastAPI-приложения.app/admin/— Django-проект (ASGI/WSGI, settings, admin site, миграции).migrations/— Alembic-скрипты, синхронизирующие PostgreSQL.tests/— заготовка под pytest-сценарии.
cp .env.example .env # заполните токены и ключи
docker compose up -d --build # поднимет bot, Postgres, FastAPI и Django
docker compose exec steps_bot alembic upgrade head- Telegram бот (polling) запускается внутри контейнера
steps_bot. - FastAPI Admin API:
http://localhost:8000(заголовокAPI_Key: <ваш ключ>). - Django admin:
http://localhost:8001. - Postgres проброшен на
localhost:5423(логин/пароль как в.env).
poetry install
cp .env.example .env # дополните переменные
poetry run alembic upgrade head
poetry run python app/steps_bot/polling.py # long polling + планировщик рассылок
# или webhook-режим:
poetry run uvicorn app.steps_bot.main:app --host 0.0.0.0 --port 8080FastAPI Admin API поднимается командой:
poetry run uvicorn app.steps_bot.api.admin:app --host 0.0.0.0 --port 8000| Переменная | Назначение |
|---|---|
BOT_TOKEN |
токен Telegram-бота |
WEBHOOK_URL |
публичный URL webhook (для режима FastAPI) |
POSTGRES_HOST/PORT/USER/PASSWORD/DB |
доступ к PostgreSQL (совпадает у бота, API и Django) |
API_KEY |
ключ доступа к FastAPI Admin API (заголовки API_Key или API-Key) |
CDEK_ACCOUNT, CDEK_SECURE, CDEK_* |
настройки интеграции с CDEK (OAuth, тарифы, веса) |
DEFAULT_PACKAGE_* |
дефолтные размеры посылки (мм/г) |
MEDIA_ROOT |
каталог хранения медиафайлов для рассылок |
Все секреты должны храниться только в .env. Пример со значениями по умолчанию — .env.example.
- Alembic конфигурирован через
alembic.ini, скрипты вmigrations/versions. - Создание новой миграции:
poetry run alembic revision --autogenerate -m "...". - Django имеет собственные миграции (
app/admin/core/migrations) и использует ту же БД; при правках моделей в Django не забывайте синхронизировать слои.
POST /pvz— принимает массив ПВЗ[{ "id": "...", "full_address": "..." }], полностью заменяет содержимое таблицы.GET /order/{YYYY-MM-DD-YYYY-MM-DD}— выгрузка заказов с маппингом на MSK-время, возвращает ФИО, контакт, ПВЗ, код товара.- Любой запрос обязан отправлять заголовок
API_Key(илиAPI-Key) с значением из.env. Некорректные ключи логируются без вывода фактического значения.
- Тестовый каркас —
pytest. Запуск:poetry run pytest. - Логирование на уровне INFO включает все сервисы; docker-compose монтирует
./logs. - Для линтинга можно использовать
ruff/black(не входят в зависимости по умолчанию, но проект совместим).
- Расчёт шагов (
services/step_counter.py) используетgeopyи фильтрует скачки по дистанции и скорости, поэтому GPS-шума меньше. - Погодные данные (
services/weather_service.py) кэшируются в памяти пользователя и обновляются по необходимости. - Все FSM-состояния сгруппированы в
app/steps_bot/states/, что упрощает реюз и автотестирование сценариев. - Для рассылок допускаются файлы/URL/Telegram file_id; worker обновляет статус
BroadcastStatus.SENTпосле успешной отправки.
MIT