Toutsu 9deccd3a9d
PR Checks / test-and-build (pull_request) Successful in 7m7s
docs: add MIT LICENSE file
Add LICENSE file with MIT License text to repository root.
README.md already references it; the file was missing.

Includes TDD-verified tests ensuring LICENSE exists and contains
MIT License text, and README references it correctly.

Bump version → 1.15.1

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 16:25:17 +03:00
2026-05-12 16:25:17 +03:00
2026-05-12 16:25:17 +03:00
2026-04-13 13:52:49 +03:00
2026-05-12 16:25:17 +03:00

🎲 GM-Relay: TTRPG Session Scheduling Bot & Web Dashboard

GM-Relay — это комплексное решение для Мастеров Подземелий (ГМов), состоящее из высокопроизводительного Telegram-бота и удобного веб-интерфейса. Предназначено для автоматизации записи игроков на сессии, управления расписанием и проведения игр.

Проект разработан с упором на производительность, архитектуру Vertical Slice, Native AOT (для бота) и удобство развертывания с использованием .NET Aspire.

Текущая версия: v1.15.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. Настройка окружения

cp .env.example .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. Запуск

docker compose up -d

Автоматически выполняется:

  • создание Docker-сети и volume PostgreSQL;
  • подъём PostgreSQL (db:5432);
  • запуск бота с плавной миграцией (DbUp);
  • запуск веб-приложения с подключением к БД и Telegram API.

3. Первоначальная настройка

  1. Напишите боту /start.
  2. Создайте группу через /newgroup.
  3. Откройте Mini App или Web Dashboard для расширенного управления.

💾 Backup и восстановление

Проект включает автоматический ежедневный backup PostgreSQL через сервис db-backup в Docker Compose.

Как это работает

  • Каждый день в 03:00 выполняется pg_dump базы gmrelay_db.
  • Дампы сжимаются (gzip) и сохраняются в volume pgbackups (/backups).
  • Формат имени: gmrelay_db_YYYYMMDD_HHMMSS.sql.gz.
  • Ротация: по умолчанию хранятся последние 7 дней (настраивается через BACKUP_RETENTION_DAYS).

Проверка бэкапов

docker compose exec db-backup ls -la /backups

Ручное создание дампа

docker compose exec db-backup sh -c "pg_dump -h db -U gmrelay -d gmrelay_db | gzip > /backups/gmrelay_db_manual.sql.gz"

Восстановление из бэкапа

# Использовать последний автоматический бэкап
./scripts/restore.sh

# Или указать конкретный файл
./scripts/restore.sh backups/gmrelay_db_20260512_030000.sql.gz

Warning

Восстановление перезаписывает текущую базу данных. Убедитесь, что вы понимаете последствия, прежде чем запускать restore.sh.

Переменные окружения (опциональные)

BACKUP_RETENTION_DAYS=7
BACKUP_VOLUME_NAME=game_pgbackups

🗂 Структура репозитория

├── 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.


Построено с ❤️ для TTRPG-сообщества.

S
Description
No description provided
Readme MIT 10 MiB
Languages
C# 80.8%
HTML 13.9%
CSS 3.6%
PLpgSQL 1%
Dockerfile 0.2%
Other 0.5%