# 🎲 GM-Relay: TTRPG Session Scheduling Bot & Web Dashboard **GM-Relay** — это комплексное решение для Мастеров Подземелий (ГМов), состоящее из высокопроизводительного Telegram-бота и удобного веб-интерфейса. Предназначено для автоматизации записи игроков на сессии, управления расписанием и проведения игр. Проект разработан с упором на производительность, архитектуру Vertical Slice, Native AOT (для бота) и удобство развертывания с использованием .NET Aspire. **Текущая версия:** `v1.14.0`. --- ## ✨ Key Features ### 🤖 Telegram Bot - **📅 Создание расписаний (Batch Sessions)**: Создавайте сразу несколько игр одним сообщением изменения (на недельный месяц в перед). - **🖼 Обложки расписаний**: И batch-посту можно прикрепить фото к `/newsession` или указать строку `Картинка: https://...`; бот отправит обложку перед сообщением записи. - **⚡ Быстрые повторы расписания**: Для регулярной кампании можно указать одну дату, количество игр и интервал, а бот сам развернёт повторяющийся batch. - **✋ Интерактивная запись и выход**: Игроки записываются на конкретные даты и самостоятельно снимают запись нажатием одной кнопки. - **👥 Лимит мест и лист ожидания**: ГМ задаёт максимальный состав, бот не переполняет сессию, автоматически ведёт очередь ожидания и освобождённое место отдаёт первому ожидающему. - **📁 Поддержка Форумов (Telegram Topics)**: Если `/newsession` запущен в теме форума Telegram, расписание и групповые уведомления остаются в этой теме; при запуске из корня форума бот создает отдельную тему и сообщает о необходимости прав admin/Manage Topics, если их не хватает. - **❌ Управление сессиями**: Owner и назначенные co-GM могут создавать, отменять, удалять и переносить игры из Telegram через `/listsessions`; публичный пост записи показывает только кнопки игроков. - **🔄 Голосование за перенос**: Быстрый поиск свободного места с через свободное недель и кнопками новых времени и дедлайном. - **🔔 Уведомления**: Игрок получают за 24 часа, напоминание за 1 час, ссылку перед игрой, отмены и переносы; групповые уведомления при этом остаются. - **🕐 Режим уведомлений batch**: Для каждой пачки можно выбрать `В группе и в личку` или `Только в группе`. - **⬆️ Управление очередью**: Веб-интерфейс показывает заполненность, лист ожидания и позволяет ГМу поднять первого игрока из очереди. - **🔄 Автоматическая синхронизация**: Любые изменения в веб-интерфейсе мгновенно обновляют сообщения с расписанием в Telegram-чатах игроков. ### 🌐 Web Dashboard (Blazor Server) - **🔐 Авторизация через Telegram**: Telegram Login Widget с HMAC-SHA256 валидацией. - **📱 Telegram Mini App Dashboard**: Мобильная панель открывается из Telegram, проверяет `initData` на сервере, учитывает safe-area телефона и верхнюю панель Telegram. - **✏️ Редактирование**: Детальное изменение дат, названий и статусов сессий. - **🤝 Co-GM и делегирование**: Owner назначает помощников по Telegram ID; co-GM управляет расписанием, но **не может назначать других co-GM**. - **📋 Шаблоны кампаний**: Вкладка `Шаблоны` отдельно от страницы группы: сохранение типовых параметров и запуск нового batch из шаблона. - **📦 Bulk-операции для Batch Sessions**: - обновить общий `title`/`link` у всей пачки; - перенести пачку на фиксированный шаг в днях; - клонировать batch на следующую неделю или месяц. - **⬆️ Управление очередью**: Заполненность, лист ожидания и ручное повышение игрока из очереди. - **📜 История изменений сессий**: Страница `/session/{id}/history` показывает аудит-лог всех значимых изменений (время, ссылка, название, участники, статус) с указанием акторов и дат. - **📊 Статистика посещаемости**: Страница `/group/{id}/stats` показывает долю присутствия, количество пропусков и среднюю явку по каждому игроку группы. - **🔄 Автосинхронизация**: Изменения в вебе мгновенно перерисовывают Telegram-сообщения расписания. --- ## 🛠 Технологический стек | Компонент | Технология | |---|---| | Язык | C# 14 (.NET 10) | | Архитектура | Vertical Slice + общая библиотека `GmRelay.Shared` | | Бот | Telegram.Bot, **Native AOT** | | Веб | Blazor Server | | Оркестрация | .NET Aspire (`GmRelay.AppHost`) | | БД | PostgreSQL | | ORM | Dapper + **Dapper.AOT** (source generators) | | Миграции | DbUp | | Развёртывание | Docker Compose, Multi-arch (**AMD64/ARM64**) | > [!NOTE] > При использовании Dapper в режиме Native AOT все SQL-запросы используют строго типизированные DTO; динамические типы (`dynamic`) не поддерживаются. --- ## 🚀 Быстрый старт (Docker Compose) **Требования:** Docker и Docker Compose. ### 1. Настройка окружения ```bash cp .env.example .env ``` **Ключевые переменные `.env`:** ```env # Токен от @BotFather (используется ботом и как секретный ключ веб-авторизации) TELEGRAM_BOT_TOKEN=ваш_токен_здесь # Имя бота без @ (для Telegram Login Widget) TELEGRAM_BOT_USERNAME=ваше_имя_бота_здесь # HTTPS URL Mini App, например https://your-domain.example/miniapp TELEGRAM_MINI_APP_URL=https://your-domain.example/miniapp POSTGRES_PASSWORD=ваш_надежный_пароль GMRELAY_WEB_PORT=8080 ``` **Настройка в @BotFather:** - Команда `/setdomain` для работы виджета авторизации на вашем домене. - Для Mini App настройте домен Web Dashboard и menu button на URL из `TELEGRAM_MINI_APP_URL`. - Начиная с **v1.9.3** дополнительных действий для фикса входа не требуется: fallback выполняется внутри активного Telegram WebView по тому же HTTPS-адресу `/miniapp`. ### 2. Запуск ```bash docker compose up -d ``` **Автоматически выполняется:** - создание Docker-сети и volume PostgreSQL; - подъём PostgreSQL (`db:5432`); - запуск бота с плавной миграцией (DbUp); - запуск веб-приложения с подключением к БД и Telegram API. ### 3. Первоначальная настройка 1. Напишите боту `/start`. 2. Создайте группу через `/newgroup`. 3. Откройте Mini App или Web Dashboard для расширенного управления. --- ## 🗂 Структура репозитория ``` ├── src/ │ ├── GmRelay.AppHost/ # .NET Aspire orchestrator │ ├── GmRelay.Bot/ # Telegram-бот (Native AOT) │ ├── GmRelay.Migrator/ # DbUp-миграции │ ├── GmRelay.ServiceDefaults/ # Aspire service defaults │ ├── GmRelay.Shared/ # Общие доменные модели │ ├── GmRelay.Web/ # Blazor Server dashboard │ └── GmRelay.Worker/ # Background workers ├── tests/ │ └── GmRelay.Bot.Tests/ # xUnit + NSubstitute ├── compose.yaml # Docker Compose (AMD64 + ARM64) └── .env.example # Шаблон переменных окружения ``` --- ## 📜 Лицензия MIT License. См. [LICENSE](./LICENSE). --- *Построено с ❤️ для TTRPG-сообщества.*