feat(bot): register Telegram command menu on startup

Set /start, /newsession, /listsessions, /exportcalendar and /help
via setMyCommands for both private chats and group chats so users
see the command list when typing '/'.

Also update /help text to list all commands first and then show the
example.
This commit is contained in:
2026-06-15 11:41:33 +03:00
parent 40b13db320
commit 57f43408df
3 changed files with 54 additions and 2 deletions
@@ -0,0 +1,46 @@
using Telegram.Bot;
using Telegram.Bot.Types;
namespace GmRelay.Bot.Infrastructure.Telegram;
/// <summary>
/// Registers the bot's command list with Telegram so users see the
/// command menu when they type "/" in a chat.
/// </summary>
public sealed class TelegramCommandsSetupService(
ITelegramBotClient bot,
ILogger<TelegramCommandsSetupService> 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;
}
@@ -366,6 +366,13 @@ public sealed class UpdateRouter(
text: """ text: """
GM-Relay бот для управления игровыми сессиями. GM-Relay бот для управления игровыми сессиями.
/start начать работу с ботом
/newsession создать новую игровую сессию
/listsessions список предстоящих сессий
/exportcalendar экспортировать расписание в ICS
/help эта справка
Пример создания сессии:
/newsession /newsession
Название: My Game Название: My Game
Время: 15.05.2026 19:30 Время: 15.05.2026 19:30
@@ -377,10 +384,8 @@ public sealed class UpdateRouter(
Игр: 4 Игр: 4
Интервал: 7 Интервал: 7
/listsessions список предстоящих сессий
Для owner/co-GM /listsessions показывает кнопки отмены, переноса, удаления и повышения из листа ожидания. Для owner/co-GM /listsessions показывает кнопки отмены, переноса, удаления и повышения из листа ожидания.
Игроки могут записаться кнопкой «На дату» и сняться кнопкой «Выйти». Игроки могут записаться кнопкой «На дату» и сняться кнопкой «Выйти».
/help эта справка
""", """,
cancellationToken: ct); cancellationToken: ct);
break; break;
+1
View File
@@ -98,6 +98,7 @@ builder.Services.AddSingleton<DirectSessionNotificationSender>();
// ── Telegram infrastructure ────────────────────────────────────────── // ── Telegram infrastructure ──────────────────────────────────────────
builder.Services.AddSingleton<UpdateRouter>(); builder.Services.AddSingleton<UpdateRouter>();
builder.Services.AddSingleton<ITelegramUpdateHandler>(sp => sp.GetRequiredService<UpdateRouter>()); builder.Services.AddSingleton<ITelegramUpdateHandler>(sp => sp.GetRequiredService<UpdateRouter>());
builder.Services.AddHostedService<TelegramCommandsSetupService>();
builder.Services.AddHostedService<TelegramMiniAppMenuButtonService>(); builder.Services.AddHostedService<TelegramMiniAppMenuButtonService>();
builder.Services.AddHostedService<TelegramBotService>(); builder.Services.AddHostedService<TelegramBotService>();