using FastEndpoints; using FrameworkBLL.MessageHubWebhook; using FrameworkDAL.DTO.MessageHub; using GB5Shared.DTO.Framework.Login; using GB5Shared.DTO.Framework.ResponseStandard; using GB5Shared.FastEndPoint; using Microsoft.Extensions.Logging; using System.Text.Json; using static GB5Shared.GB5Constant.Constant; namespace FrameworkSL.Endpoints.MessageHubGenerator { public class RequestMessageHubGenerator : BaseEndpoint> { private readonly IMessageHubWebhookBLL _messageHubWebhookBLL; private readonly ILogger _logger; public RequestMessageHubGenerator( IMessageHubWebhookBLL messageHubWebhookBLL, ILogger logger) { _messageHubWebhookBLL = messageHubWebhookBLL; _logger = logger; } public override void Configure() { Post("/MessageHubGenerator/RequestMessageHubGenerator"); AllowAnonymous(); } public record MessageHubWebhookParameters( [property: FromHeader] string? Login, [property: FromBody] MessageHubWebhookDTO? MessageHubWebhookDTO ); protected override async Task> ExecuteAsync( MessageHubWebhookParameters req, LoginDTO loginDTO, CancellationToken ct) { try { // ✅ RAW PAYLOAD LOGGING (important for debugging providers) var rawBody = await HttpContext.Request.ReadFromJsonAsync(cancellationToken: ct); _logger.LogInformation("RAW WEBHOOK PAYLOAD: {Payload}", JsonSerializer.Serialize(rawBody)); if (req?.MessageHubWebhookDTO == null) { _logger.LogWarning("Webhook received with null DTO."); return await GB5Shared.ResponseStandard.Response.CreateExceptionError( new ArgumentNullException(nameof(req.MessageHubWebhookDTO)), CacheKeyLevel.NOT_REQUIRED, loginDTO, "Invalid webhook payload", 400 ); } var messages = req.MessageHubWebhookDTO.Messages ?? new(); _logger.LogInformation( "Webhook received | LoginHeader={Login} | MessageCount={Count}", req.Login, messages.Count ); // ✅ DYNAMIC MESSAGE INSPECTION (NO HARDCODING) foreach (var msg in messages) { var extractedContent = ExtractMessageContent(msg); _logger.LogInformation( "Message Received | From={From} | Type={Type} | Content={Content}", msg.From, msg.Type, extractedContent ); } // ✅ DELEGATE FULL PROCESSING TO BLL // Capture base URL so DirectAction can build API callback URLs without config. var frameworkBaseUrl = $"{HttpContext.Request.Scheme}://{HttpContext.Request.Host}"; var result = await _messageHubWebhookBLL.MessageHubWebhook( req.MessageHubWebhookDTO, loginDTO!, frameworkBaseUrl, ct); _logger.LogInformation( "Webhook processed successfully | ResultType={ResultType}", result?.GetType().Name ?? "null" ); return await GB5Shared.ResponseStandard.Response.CreateSuccessResponse( result, CacheKeyLevel.NOT_REQUIRED, loginDTO ); } catch (Exception ex) { _logger.LogError(ex, "Error processing webhook | LoginHeader={Login}", req?.Login ); return await GB5Shared.ResponseStandard.Response.CreateExceptionError( ex, CacheKeyLevel.NOT_REQUIRED, loginDTO, ex.Message, 500 ); } } /// /// ✅ Extracts message content dynamically (text/button/interactive/fallback) /// private static string ExtractMessageContent(MessageWebhookDTO msg) { if (msg == null) return string.Empty; return msg.Type switch { "text" => msg.Text?.Body ?? string.Empty, "button" => msg.Button?.Text ?? msg.Button?.Payload ?? string.Empty, "interactive" => msg.Interactive?.ButtonReply?.Title ?? msg.Interactive?.ListReply?.Title ?? string.Empty, _ => $"UnsupportedType:{msg.Type}" }; } } }