feat(#13): add calendar subscription link to Telegram export

This commit is contained in:
2026-05-07 10:22:35 +03:00
parent c1fdba510b
commit 8c1e7991cd
@@ -1,9 +1,11 @@
using System.Text;
using Dapper;
using GmRelay.Shared.Domain;
using Microsoft.Extensions.Configuration;
using Npgsql;
using Telegram.Bot;
using Telegram.Bot.Types;
using Telegram.Bot.Types.ReplyMarkups;
namespace GmRelay.Bot.Features.Sessions.ExportCalendar;
@@ -11,7 +13,8 @@ internal sealed record CalendarSessionDto(Guid Id, string Title, DateTime Schedu
public sealed class ExportCalendarHandler(
NpgsqlDataSource dataSource,
ITelegramBotClient botClient)
ITelegramBotClient botClient,
IConfiguration configuration)
{
public async Task HandleAsync(Message message, CancellationToken cancellationToken)
{
@@ -64,11 +67,45 @@ public sealed class ExportCalendarHandler(
var inputFile = InputFile.FromStream(stream, "schedule.ics");
// Create calendar subscription
string? subscriptionUrl = null;
var baseUrl = configuration["Web:BaseUrl"];
var senderId = message.From?.Id;
if (!string.IsNullOrWhiteSpace(baseUrl) && senderId.HasValue)
{
try
{
var token = Guid.NewGuid().ToString("N");
var groupId = await connection.QueryFirstOrDefaultAsync<Guid?>(
@"SELECT id FROM game_groups WHERE telegram_chat_id = @ChatId",
new { ChatId = message.Chat.Id });
await connection.ExecuteAsync(
@"INSERT INTO calendar_subscriptions (id, token, user_telegram_id, group_id, filter_type, created_at, expires_at)
VALUES (gen_random_uuid(), @token, @userTelegramId, @groupId, @filterType, now(), NULL)",
new { token, userTelegramId = senderId.Value, groupId, filterType = (int)CalendarSubscriptionFilter.SpecificGroup });
subscriptionUrl = $"{baseUrl.TrimEnd('/')}/calendar/{token}.ics";
}
catch
{
// Non-critical: if subscription creation fails, still send the file
}
}
var replyMarkup = subscriptionUrl is not null
? new InlineKeyboardMarkup(new[]
{
new[] { InlineKeyboardButton.WithUrl("🔗 Подписаться на календарь", subscriptionUrl) }
})
: null;
await botClient.SendDocument(
chatId: message.Chat.Id,
document: inputFile,
caption: "📅 <b>Ваш календарь игр!</b>\nОткройте файл на устройстве, чтобы добавить события в свой календарь.",
parseMode: Telegram.Bot.Types.Enums.ParseMode.Html,
replyMarkup: replyMarkup,
messageThreadId: message.MessageThreadId,
cancellationToken: cancellationToken);
}