using GymLogAI.Application.Handlers; using GymLogAI.Core.Enums; using Microsoft.Extensions.Logging; using Telegram.Bot; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; namespace GymLogAI.TelegramBot; public sealed class UpdateHandler( ImportTelegramMessageHandler importTelegramMessageHandler, RecommendWorkoutHandler recommendWorkoutHandler, ILogger logger) { public async Task HandleUpdateAsync(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken) { if (update.Type != UpdateType.Message || update.Message?.Text is null) { return; } var message = update.Message; var text = message.Text.Trim(); if (text.Equals("/start", StringComparison.OrdinalIgnoreCase)) { await botClient.SendMessage( message.Chat.Id, "GymLogAI bot is ready. Send workout text or use /today for a recommendation.", cancellationToken: cancellationToken); return; } if (text.Equals("/today", StringComparison.OrdinalIgnoreCase)) { var userId = CreateUserId(message.From?.Id ?? message.Chat.Id); var recommendation = await recommendWorkoutHandler.HandleAsync( new RecommendWorkoutCommand(userId, GoalType.Maintain, "Requested from Telegram command /today"), cancellationToken); await botClient.SendMessage( message.Chat.Id, $"{recommendation.Title}\n{recommendation.Summary}\nExercises: {string.Join(", ", recommendation.Exercises)}", cancellationToken: cancellationToken); return; } var importedMessageId = await importTelegramMessageHandler.HandleAsync( new ImportTelegramMessageCommand( CreateUserId(message.From?.Id ?? message.Chat.Id), message.From?.Id ?? message.Chat.Id, message.Chat.Id, message.MessageId, text, message.Date.ToUniversalTime(), message.From?.Username, message.From?.FirstName, message.From?.LastName), cancellationToken); logger.LogInformation("Imported telegram message {MessageId} from chat {ChatId}", importedMessageId, message.Chat.Id); await botClient.SendMessage( message.Chat.Id, "Message imported. It will be parsed by the worker shortly.", cancellationToken: cancellationToken); } public Task HandleErrorAsync(ITelegramBotClient botClient, Exception exception, CancellationToken cancellationToken) { logger.LogError(exception, "Telegram bot polling error"); return Task.CompletedTask; } private static Guid CreateUserId(long telegramUserId) { Span buffer = stackalloc byte[16]; BitConverter.TryWriteBytes(buffer[..8], telegramUserId); BitConverter.TryWriteBytes(buffer[8..], telegramUserId); return new Guid(buffer); } }