Русская документация. For English version see README.en.md.
- Назначение
- Возможности
- Архитектура
- Требования
- Установка
- Переменные окружения
- Docker
- Тесты и линтинг
- Команды и меню
- Логи
- Вклад
- Дорожная карта
- Лицензия и контакты
Telegram‑бот для показа спектаклей/событий из Profticket и оперативной аналитики продаж. Поддерживает персональные фильтры пользователей (по артистам) и админ‑панель с метриками.
- Главное меню: выбор месяца, персональный фильтр «👤Выбрать актёра/актрису», переход в «📊 Аналитика».
- Персональные показы: расписание только с участием выбранного артиста.
- Аналитика:
- 🏆 Топ продаж (спектакли) — валовые/чистые продажи;
- ⚡️ Топ скорости (спектакли) — текущий темп продаж;
- ⏳ Прогноз Sold Out — ближайшие sold out;
- 🎭 Топ продаж (артисты);
- 📅 Календарь продаж — по датам;
- 🔄 Топ по возвратам и 📉 Топ по % возвратов.
- Длинные ответы разбиваются на части («чанки») — не упираются в лимиты Telegram.
- Админ‑панель (🛠 Админка):
- 📈 Статистика — сводка/топы, выбранный артист у пользователей;
- 👥 Пользователи — активность, роли, топы по запросам/троттлингу;
- 🎭 Предпочтения — топ выбранных артистов, примеры пользователей, список без выбора;
- 🗄 База (шоу) — метрики по shows/истории мест, свежесть данных.
Админка доступна ADMIN_ID и пользователям с User.admin=True.
main.py— запуск, middlewares, фоновое обновление данных.telegram/— хендлеры, клавиатуры, фильтры, middlewares, утилиты.services/profticket/— клиент и аналитика Profticket.alembic/— миграции БД;alembic.ini— конфиг Alembic.tests/— pytest‑тесты для аналитики и утилит.
- Python 3.14 (устанавливается через uv)
- uv
- PostgreSQL 17 (версия образа в Compose)
Для постоянного прямого выхода через российский сервер без SSH-туннеля
подготовлены HTTPS-прокси и инструкция подключения.
Бот подключается через docker-compose.mosbilet.yml; собственный сертификат
прокси задаётся через MOSBILET_PROXY_CA_FILE и не меняет доверие к сайту.
По умолчанию SCHEDULE_SOURCE=ermolova: расписание и составы берутся с
официального сайта театра, остатки билетов — из API «Мосбилета».
Для прежнего загрузчика можно явно установить SCHEDULE_SOURCE=profticket.
На сервере вне России для «Мосбилета» может потребоваться российский выход.
Настройте MOSBILET_PROXY_URL в .env, например:
SCHEDULE_SOURCE=ermolova
MOSBILET_PROXY_URL=socks5h://127.0.0.1:18080Для локальной проверки можно использовать SSH SOCKS-туннель к своему российскому серверу, доступному по настроенному SSH alias:
ssh -N -D 127.0.0.1:18080 -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 ru-serverТуннель должен работать всё время, пока используется этот адрес прокси.
Для Docker укажите адрес прокси, достижимый из контейнера: 127.0.0.1
внутри контейнера не является loopback хоста. Прокси должен быть закрыт от
посторонних клиентов. Поддерживаются HTTP CONNECT и SOCKS5; эта настройка
используется только для «Мосбилета», Telegram и сайт театра идут напрямую.
Проверка TLS-сертификатов включена. URL прокси с паролем не храните в Git.
Месяцы показываются при наличии расписания, в том числе до начала продаж. Неизвестный остаток ведёт на сайт и не записывается в историю как ноль. Ошибка API, неполный разбор или неподтверждённая пустая афиша сохраняют последний успешный месячный снимок. После трёх ошибок одного месяца администратор получает одно уведомление до следующего успешного обновления.
События нового источника имеют отдельные строковые ID с префиксом ermolova:;
ID спектаклей — отрицательные ID страниц театра. История Profticket остаётся
под прежними ID и не объединяется с новыми событиями. Для смены источника
используются существующие поля. Новая аналитика накапливается после
первых успешных снимков; ранее отсутствовавшую историю восстановить нельзя.
Состав на сайте может включать нескольких исполнителей одной роли, поэтому
персональный фильтр не подтверждает конкретный состав на выбранную дату.
- Установите Python и синхронизируйте окружение:
uv python install
uv sync --lockedВерсия Python закреплена в .python-version. Зависимости объявлены в
pyproject.toml, точные версии закреплены в uv.lock. Команда создаёт .venv
и устанавливает также инструменты разработки
из группы dev. Активация окружения для команд uv run не требуется.
- Скопируйте
.env.exampleв.envи заполните:
cp .env.example .env- Примените миграции перед запуском:
uv run --locked alembic upgrade headМиграция a137bd92c410 восстанавливает is_deleted=False для старых NULL,
добавляет обязательное значение/default и индекс истории
(show_id, timestamp, id). История мест сохраняется. Перед обновлением рабочей
БД сделайте резервную копию; создание индекса может временно задержать запись.
Прошлые месяцы архивируются автоматически. Исторические отчёты включают эти события. Снижения и увеличения доступной квоты агрегируются в PostgreSQL; темп использует последние сутки, прогноз — последние семь дней. Для старого выбранного месяца скорость считается по последним суткам наблюдений каждого события.
- Запустите бота:
uv run --locked main.pyСм. .env.example. Минимально нужны: BOT_TOKEN/TEST_BOT_TOKEN, ADMIN_ID,
DB_URL, COM_ID, DEFAULT_TIMEZONE. Для запуска в Docker установите
IN_DOCKER=true — тогда используется BOT_TOKEN.
Быстрый старт:
docker compose up -d --wait profticket_postgres
docker compose run --rm --no-deps profticket_bot_service alembic upgrade head
docker compose up -d profticket_bot_serviceПоднимет Postgres, применит схему и запустит бот. Проверьте переменные окружения.
Для проверки локальной сборки:
docker build -t profticket_to_tg:local .Образ использует Python 3.14 и зависимости из uv.lock без группы dev.
Compose запускает опубликованный образ; локальная сборка сама по себе его
не заменяет.
uv run --locked pytest -q
uv run --locked ruff format --check .
uv run --locked ruff check .Тесты быстрые, сетевые вызовы замоканы.
Для форматирования и автоматического исправления замечаний:
uv run --locked ruff format .
uv run --locked ruff check --fix .- Нативное меню (см.
telegram/keyboards/native_menu.py):/start,/help,/set_actor,/analytics,/subscriptions. - Тексты кнопок —
telegram/lexicon/lexicon_ru.py.
В личном чате откройте 🔔 Подписки или /subscriptions. Найдите спектакль
по части названия либо артиста по части имени, выберите результат и частоту:
30 минут, 1 час, 6 часов, 12 часов, сутки или неделя. Подписка на спектакль
следит за всеми его будущими сеансами, включая новые даты. Подписка на артиста
следит за спектаклями, где он указан в опубликованном составе. Этот состав
может включать нескольких исполнителей роли и не подтверждает участие
конкретного артиста на выбранную дату.
В карточке подписки можно изменить частоту, поставить её на паузу,
возобновить или удалить. Уведомления приходят только при изменениях;
первая подписка и возобновление начинают наблюдение с текущего состояния.
Выбранный интервал задаёт частоту отправки, а доступные данные обновляются
по UPDATE_INTERVAL. Пауза, частота и исходное состояние сохраняются в БД.
Большое уведомление содержит кнопку «Остальные изменения →». Страницы
сохраняют все изменения на момент отправки и доступны только получателю,
в том числе после перезапуска бота и следующих уведомлений.
Перед первым запуском новой версии примените миграции до d734c2a8f190:
uv run --locked alembic upgrade head.
В аналитике есть 📈 Тенденции: остаток билетов, наблюдённые снижения и увеличения за 24 часа, темп изменения и сравнение с предыдущими сутками. В источнике нет заказов: уменьшение остатка может означать продажу либо снятие квоты, увеличение — возврат либо добавление мест. Эти числа не являются подтверждёнными продажами и возвратами.
Прогноз исчерпания текущей квоты условный. Он использует свежую историю не короче суток, проверяет перерывы, скачки квоты и стабильность темпа, ограничивается датой сеанса и горизонтом 14 дней. Вместо квадратичной экстраполяции используется наблюдаемый темп по фактическому времени. Диапазон показывает сценарии темпа, а не вероятность или статистический доверительный интервал. Если данных недостаточно, отчёт объясняет причину.
Настраиваются в telegram/utils/startup.py (setup_logging), выводятся в
stdout через coloredlogs на уровне INFO.
Перед PR проверьте локально:
uv run --locked ruff format --check .uv run --locked ruff check .uv run --locked pytest -q- При изменении зависимостей обновляйте
pyproject.tomlиuv.lockвместе. - Соблюдайте Conventional Commits (например:
feat(telegram): ...). - Не включайте секреты в коммиты; используйте
.env.
- Пагинация в админ‑отчётах и аналитике.
- Экспорт CSV для предпочтений/топов.
- Поиск пользователя (id/username) и быстрая карточка.
- Управление ролями/баном из админ‑меню.
Лицензия — MIT (см. LICENSE). Вопросы: см. ADMIN_USERNAME в .env.