Files
Toutsu a1ec688ec8
Deploy Telegram Bot / build-and-push (push) Successful in 3m44s
Deploy Telegram Bot / deploy (push) Successful in 11s
feat: add multi-option reschedule voting
2026-04-27 14:58:32 +03:00

14 KiB
Raw Permalink Blame History

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

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

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

Текущая версия: v1.7.0.


Ключевые возможности

🤖 Telegram Бот

  • 📅 Создание расписаний (Batch Sessions): Создавайте сразу несколько игр одним сообщением (на неделю или месяц вперед).
  • Интерактивная запись и выход: Игроки записываются на конкретные даты и самостоятельно снимают запись нажатием одной кнопки.
  • 👥 Лимит мест и лист ожидания: ГМ задаёт максимальный состав, бот не переполняет сессию, автоматически ведёт очередь ожидания и освобождённое место отдаёт первому ожидающему.
  • 📁 Поддержка Форумов (Telegram Topics): Бот автоматически создает тему во вложенных чатах Telegram под каждую новую пачку игр.
  • Управление сессиями: Owner и назначенные co-GM могут создавать, отменять, удалять и переносить игры прямо из Telegram.
  • 🔄 Голосование за перенос: При переносе сессии GM предлагает 2-3 новых времени и дедлайн, игроки голосуют кнопками, а бот показывает текущие результаты и применяет победивший вариант.
  • 🔔 Персональные уведомления: Игроки получают DM о RSVP за 24 часа, напоминание за 1 час, ссылку перед игрой, отмены и переносы; групповые уведомления при этом остаются.
  • 🗓 Экспорт в Календарь: Генерация файла .ics для добавления всех игр в Google, Apple или Яндекс Календарь одной командой.
  • 🚀 Native AOT: Скомпилирован в нативный бинарный файл. Мгновенный запуск и минимальное потребление памяти. Идеально для Raspberry Pi.

🌐 Web Dashboard (Blazor Server)

  • 🔐 Авторизация через Telegram: Безопасный вход с использованием Telegram Login Widget (HMAC-SHA256 валидация).
  • 📝 Удобное редактирование: Веб-интерфейс для детального редактирования сессий, изменения дат, названий и статусов.
  • 🤝 Co-GM и делегирование: Owner группы назначает помощников по Telegram ID, а co-GM получает доступ к управлению расписанием в Telegram и Web Dashboard.
  • 🧩 Bulk-операции для Batch Sessions: ГМ может обновить общий title/link, перенести всю пачку на фиксированный шаг и клонировать batch на следующую неделю или месяц.
  • 🔕 Режим уведомлений batch: Для каждой пачки можно выбрать В группе и в личку или Только в группе.
  • ⬆️ Управление очередью: Веб-интерфейс показывает заполненность, лист ожидания и позволяет ГМу поднять первого игрока из очереди.
  • 🔄 Автоматическая синхронизация: Любые изменения в веб-интерфейсе мгновенно обновляют сообщения с расписанием в Telegram-чатах игроков.
  • 🕒 Управление временем: UI адаптирован под московское время (UTC+3), в то время как база данных работает в UTC.

🛠 Технологический стек

  • Язык: C# 14 (.NET 10)
  • Архитектура: Vertical Slice Architecture, общая библиотека (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).

🚀 Быстрый старт (Docker Compose)

Проект использует Docker Compose для одновременного запуска базы данных, бота и веб-интерфейса.

1. Подготовка

Убедитесь, что у вас установлены Docker и Docker Compose.

2. Настройка окружения

Скопируйте файл-шаблон и заполните его значениями:

cp .env.example .env

Отредактируйте .env:

# Токен вашего бота от @BotFather (используется и для бота, и как секретный ключ для веб-авторизации)
TELEGRAM_BOT_TOKEN=ваш_токен_здесь

# Имя вашего бота в Telegram (без @), например: GmRelayBot.
# Найти его можно в информации о боте у @BotFather. 
# Используется для работы виджета авторизации (Telegram Login Widget).
TELEGRAM_BOT_USERNAME=ваше_имя_бота_здесь

# Пароль для базы данных PostgreSQL
POSTGRES_PASSWORD=ваш_надежный_пароль

# Локальный порт веб-интерфейса GM-Relay
GMRELAY_WEB_PORT=8080

(Опционально) Настройте домен Telegram бота в @BotFather командой /setdomain для работы виджета авторизации на вашем сайте.

3. Запуск

Выполните команду:

docker compose up -d

Инфраструктура автоматически:

  • Создаст локальную Docker-сеть и volume PostgreSQL, если их ещё нет.
  • Поднимет PostgreSQL, доступный для контейнеров как db:5432.
  • Запустит бота (применив миграции БД).
  • Запустит веб-интерфейс на http://localhost:8080 или другом порту из GMRELAY_WEB_PORT.

⚙️ Настройка бота в Telegram

Чтобы бот работал корректно:

  1. Добавьте бота в группу (или Супергруппу/Форум).
  2. Назначьте бота Администратором.
  3. Необходимые права:
    • Выбор тем (Managed Topics) — обязательно для Форумов.
    • Отправка сообщений.
    • Закрепление сообщений — рекомендуется.

Tip

Owner группы определяется по первому человеку, который создал сессию в этой группе. Owner может назначать co-GM в Web Dashboard; owner и co-GM могут управлять сессиями через кнопки бота и веб-интерфейс.


📝 Инструкция для Мастера

Создание расписания игр

Используйте команду /newsession с описанием в следующем формате:

/newsession
Название: Легенды Берега Мечей (D&D 5e)
Время: 15.05.2024 19:30
Время: 22.05.2024 19:00
Мест: 4
Ссылка: https://discord.gg/invite-link

Строка Мест: необязательна. Если она указана, игроки сверх лимита попадут в лист ожидания, а ГМ сможет повысить первого ожидающего через кнопку в Telegram или Web Dashboard.

Игрок может самостоятельно снять запись кнопкой 🚪 Выйти в сообщении расписания. Если он был в основном составе и в листе ожидания есть игроки, бот автоматически переводит первого ожидающего в основной состав и обновляет сообщение пачки.

Делегирование управления

На странице группы Web Dashboard показывает owner и список co-GM. Owner может добавить помощника по Telegram ID, имени и username, а также снять роль co-GM. Назначенный co-GM видит группу в панели управления и может редактировать сессии, управлять batch-операциями, очередью, переносами и удалением игр, но не может назначать других co-GM.

Перенос сессии голосованием

Owner или co-GM нажимает кнопку ⏰ Перенести у нужной сессии и отправляет в чат 2-3 варианта нового времени вместе с дедлайном:

25.04.2026 19:30
26.04.2026 18:00
Дедлайн: 25.04.2026 12:00

Дедлайн должен быть в будущем и раньше первого предложенного времени. Участники выбирают один вариант кнопкой в Telegram, могут изменить голос до дедлайна и видят текущие результаты в сообщении голосования. По дедлайну бот выбирает вариант с наибольшим числом голосов, переносит сессию, сбрасывает RSVP и обновляет batch-сообщение. Если голосов нет или есть ничья, перенос отклоняется, а время сессии остаётся прежним.

Bulk-операции в Web Dashboard

На странице группы Web Dashboard показывает отдельный блок для каждой пачки игр. Owner и co-GM могут:

  • обновить общий title и link сразу у всех сессий batch;
  • выбрать режим уведомлений: дублировать важные сообщения игрокам в личку или оставить только групповые уведомления;
  • перенести пачку, задав новую первую дату и фиксированный шаг между играми в днях;
  • клонировать batch на следующую неделю или следующий календарный месяц.

После редактирования или переноса исходное Telegram-сообщение расписания перерисовывается. При клонировании создаётся новая пачка с новым Telegram-сообщением и пустым составом игроков.

Если включён режим В группе и в личку, бот дополнительно отправляет игрокам персональные сообщения о RSVP за 24 часа, напоминание за 1 час, ссылку перед стартом, отмену и перенос. Если Telegram не позволяет написать игроку в ЛС, бот логирует ошибку и продолжает отправку остальным участникам.

Другие команды

  • /listsessions — Показать список всех актуальных игр в этой группе.
  • ⏰ Перенести в сообщении расписания — Запустить голосование по 2-3 вариантам нового времени.
  • /deletesession — Удалить сессию.
  • /exportcalendar — Получить .ics файл с играми.
  • /help — Справка по формату.

🏗 Разработка и запуск локально (.NET Aspire)

Для локальной разработки проще всего использовать .NET Aspire:

  1. Установите .NET 10 SDK и workload Aspire.
  2. Откройте решение GM-Relay.slnx.
  3. Установите переменные окружения (или user secrets) для GmRelay.AppHost.
  4. Запустите проект GmRelay.AppHost. Aspire Dashboard запустится автоматически, предоставляя удобный мониторинг БД, бота и веб-интерфейса.

Note

При использовании Dapper в режиме Native AOT, все SQL-запросы используют строго типизированные DTO. Динамические типы (dynamic) не поддерживаются.


📜 Лицензия

Проект распространяется под лицензией MIT. Использование в некоммерческих целях приветствуется.