diff --git a/src/GmRelay.Bot/Infrastructure/Telegram/TelegramCommandsSetupService.cs b/src/GmRelay.Bot/Infrastructure/Telegram/TelegramCommandsSetupService.cs
new file mode 100644
index 0000000..a31159f
--- /dev/null
+++ b/src/GmRelay.Bot/Infrastructure/Telegram/TelegramCommandsSetupService.cs
@@ -0,0 +1,46 @@
+using Telegram.Bot;
+using Telegram.Bot.Types;
+
+namespace GmRelay.Bot.Infrastructure.Telegram;
+
+///
+/// Registers the bot's command list with Telegram so users see the
+/// command menu when they type "/" in a chat.
+///
+public sealed class TelegramCommandsSetupService(
+ ITelegramBotClient bot,
+ ILogger logger) : IHostedService
+{
+ public async Task StartAsync(CancellationToken cancellationToken)
+ {
+ var commands = new[]
+ {
+ new BotCommand { Command = "start", Description = "Начать работу с ботом" },
+ new BotCommand { Command = "newsession", Description = "Создать новую игровую сессию" },
+ new BotCommand { Command = "listsessions", Description = "Список предстоящих сессий" },
+ new BotCommand { Command = "exportcalendar", Description = "Экспортировать расписание в ICS" },
+ new BotCommand { Command = "help", Description = "Справка по командам" }
+ };
+
+ try
+ {
+ await bot.SetMyCommands(
+ commands,
+ scope: new BotCommandScopeAllPrivateChats(),
+ cancellationToken: cancellationToken);
+
+ await bot.SetMyCommands(
+ commands,
+ scope: new BotCommandScopeAllGroupChats(),
+ cancellationToken: cancellationToken);
+
+ logger.LogInformation("Telegram command menu registered for private chats and groups.");
+ }
+ catch (Exception ex)
+ {
+ logger.LogWarning(ex, "Failed to register Telegram command menu.");
+ }
+ }
+
+ public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
+}
diff --git a/src/GmRelay.Bot/Infrastructure/Telegram/UpdateRouter.cs b/src/GmRelay.Bot/Infrastructure/Telegram/UpdateRouter.cs
index 9b0df35..da800bb 100644
--- a/src/GmRelay.Bot/Infrastructure/Telegram/UpdateRouter.cs
+++ b/src/GmRelay.Bot/Infrastructure/Telegram/UpdateRouter.cs
@@ -366,6 +366,13 @@ public sealed class UpdateRouter(
text: """
GM-Relay — бот для управления игровыми сессиями.
+ /start — начать работу с ботом
+ /newsession — создать новую игровую сессию
+ /listsessions — список предстоящих сессий
+ /exportcalendar — экспортировать расписание в ICS
+ /help — эта справка
+
+ Пример создания сессии:
/newsession
Название: My Game
Время: 15.05.2026 19:30
@@ -377,10 +384,8 @@ public sealed class UpdateRouter(
Игр: 4
Интервал: 7
- /listsessions — список предстоящих сессий
Для owner/co-GM /listsessions показывает кнопки отмены, переноса, удаления и повышения из листа ожидания.
Игроки могут записаться кнопкой «На дату» и сняться кнопкой «Выйти».
- /help — эта справка
""",
cancellationToken: ct);
break;
diff --git a/src/GmRelay.Bot/Program.cs b/src/GmRelay.Bot/Program.cs
index 3a8b0e3..d347837 100644
--- a/src/GmRelay.Bot/Program.cs
+++ b/src/GmRelay.Bot/Program.cs
@@ -98,6 +98,7 @@ builder.Services.AddSingleton();
// ── Telegram infrastructure ──────────────────────────────────────────
builder.Services.AddSingleton();
builder.Services.AddSingleton(sp => sp.GetRequiredService());
+builder.Services.AddHostedService();
builder.Services.AddHostedService();
builder.Services.AddHostedService();