using FastEndpoints;
using FrameworkBLL.EIPConversation;
using FrameworkDAL.DTO.EIPConversation;
using GB5Shared.DTO.Framework.Login;
using GB5Shared.DTO.Framework.ResponseStandard;
using GB5Shared.FastEndPoint;
using Microsoft.Extensions.Logging;
using System;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using static GB5Shared.GB5Constant.Constant;
namespace FrameworkSL.Endpoints.EIPConversation
{
///
/// Universal Webhook Endpoint
/// Supports: Telegram, Teams, WhatsApp, Slack, Postman, etc.
/// Always converts to standard MessageHubInboundDTO (3 fields)
///
public class EIPConcept
: BaseEndpoint>
{
private readonly ILogger _logger;
private readonly IEIPConceptBLL _bll;
public EIPConcept(
ILogger logger,
IEIPConceptBLL bll)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_bll = bll ?? throw new ArgumentNullException(nameof(bll));
}
public override void Configure()
{
Post("/api/messagehub/webhook");
AllowAnonymous();
}
#region Request Parameters
public record ReceiveParameters(
[property: FromHeader] string? Login,
[property: FromBody] object RawBody
);
#endregion
protected override async Task> ExecuteAsync(
ReceiveParameters req,
LoginDTO loginDTO,
CancellationToken ct)
{
try
{
loginDTO ??= new LoginDTO
{
UserId = 0,
UserName = "external",
ClientId = -1
};
// Serialize raw incoming JSON
var rawJson = JsonSerializer.Serialize(req.RawBody);
var inbound = NormalizeInboundPayload(rawJson);
_logger.LogInformation(
"Incoming message | Platform={Platform} | From={From} | Message={Message}",
inbound.Platform,
inbound.From,
inbound.Message);
// Send to BLL (always 3-field standard DTO)
string reply = await _bll.HandleIncomingMessageAsync(
sessionToken: inbound.From,
userMessage: inbound.Message,
loginContext: loginDTO, // ✅ use loginContext
platformName: inbound.Platform,
ct: ct
);
_logger.LogInformation(
"Outgoing reply | Platform={Platform} | To={From} | Message={Reply}",
inbound.Platform,
inbound.From,
reply);
return await GB5Shared.ResponseStandard.Response
.CreateSuccessResponse(reply, CacheKeyLevel.NOT_REQUIRED, loginDTO);
}
catch (Exception ex)
{
_logger.LogError(ex, "Webhook processing failed");
return await GB5Shared.ResponseStandard.Response
.CreateExceptionError(
ex,
CacheKeyLevel.NOT_REQUIRED,
loginDTO,
ex.Message,
500);
}
}
///
/// Normalizes all platform payloads into standard MessageHubInboundDTO
///
private MessageHubInboundDTO NormalizeInboundPayload(string rawJson)
{
var inbound = new MessageHubInboundDTO();
// 🔹 TELEGRAM
if (rawJson.Contains("\"update_id\""))
{
var telegram = JsonSerializer.Deserialize(rawJson);
inbound.Message = telegram?.Message?.Text ?? string.Empty;
inbound.From = telegram?.Message?.Chat?.Id.ToString() ?? "unknown";
inbound.Platform = "TELEGRAM";
}
// 🔹 STANDARD (Postman / Internal)
else if (rawJson.Contains("\"Message\"") &&
rawJson.Contains("\"Platform\""))
{
inbound = JsonSerializer.Deserialize(rawJson)
?? new MessageHubInboundDTO();
}
// 🔹 TEAMS (Basic example)
else if (rawJson.Contains("\"type\"") &&
rawJson.Contains("\"conversation\""))
{
var teams = JsonSerializer.Deserialize(rawJson);
inbound.Message = teams?.Text ?? string.Empty;
inbound.From = teams?.From?.Id ?? "unknown";
inbound.Platform = "TEAMS";
}
// 🔹 WHATSAPP (Meta Webhook Example)
else if (rawJson.Contains("\"entry\"") &&
rawJson.Contains("\"changes\""))
{
var whatsapp = JsonSerializer.Deserialize(rawJson);
inbound.Message = whatsapp?.GetMessageText() ?? string.Empty;
inbound.From = whatsapp?.GetSender() ?? "unknown";
inbound.Platform = "WHATSAPP";
}
else
{
inbound.Platform = "UNKNOWN";
inbound.Message = string.Empty;
inbound.From = "unknown";
}
return inbound;
}
}
#region Telegram Models
public class TelegramUpdate
{
public long Update_Id { get; set; }
public TelegramMessage? Message { get; set; }
}
public class TelegramMessage
{
public TelegramChat? Chat { get; set; }
public string? Text { get; set; }
}
public class TelegramChat
{
public long Id { get; set; }
}
#endregion
#region Teams Models (Simplified)
public class TeamsUpdate
{
public string? Text { get; set; }
public TeamsFrom? From { get; set; }
}
public class TeamsFrom
{
public string? Id { get; set; }
}
#endregion
#region WhatsApp Models (Simplified Placeholder)
public class WhatsAppUpdate
{
public string? GetMessageText() => string.Empty; // implement actual mapping
public string? GetSender() => string.Empty; // implement actual mapping
}
#endregion
}