From a97c71caafd22b8ebe2181f7199abf0f07565bba Mon Sep 17 00:00:00 2001 From: hzhang Date: Sun, 4 May 2025 19:11:12 +0100 Subject: [PATCH] add: hci --- Components/Pages/Chat.razor | 7 ++++--- Dockerfile | 2 -- Filters/WebhookAuthFilter.cs | 7 ++++--- Program.cs | 26 +++++++++++++++++++++----- Services/IChatSessionService.cs | 2 +- Services/InMemoryChatSessionService.cs | 4 ++-- 6 files changed, 32 insertions(+), 16 deletions(-) diff --git a/Components/Pages/Chat.razor b/Components/Pages/Chat.razor index 7dc7dd5..5c48253 100644 --- a/Components/Pages/Chat.razor +++ b/Components/Pages/Chat.razor @@ -15,6 +15,7 @@ + @if (!string.IsNullOrEmpty(activeSessionId)) { Active Session: @activeSessionId @@ -62,7 +63,7 @@ else if (sessionLoadAttempted) private string newMessage { get; set; } = string.Empty; private bool isLoading = false; private bool sessionLoadAttempted = false; - + private string externalWebhookUrl { get; set; } = string.Empty; private string? _previousSessionId = null; @@ -170,7 +171,7 @@ else if (sessionLoadAttempted) private async Task SendMessage() { - if (currentSession == null || string.IsNullOrWhiteSpace(newMessage) || currentSession.IsWaitingForResponse) + if (currentSession == null || string.IsNullOrWhiteSpace(newMessage) || currentSession.IsWaitingForResponse || String.IsNullOrWhiteSpace(externalWebhookUrl)) return; var userMessage = new ChatMessage { IsUser = true, Content = newMessage }; @@ -182,7 +183,7 @@ else if (sessionLoadAttempted) StateHasChanged(); - await ChatSessionService.SendMessageToExternalWebhook(activeSessionId, messageToSend); + await ChatSessionService.SendMessageToExternalWebhook(externalWebhookUrl, activeSessionId, messageToSend); } diff --git a/Dockerfile b/Dockerfile index 0f6e7f8..4a606dc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,6 @@ FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS base USER $APP_UID WORKDIR /app -EXPOSE 8080 -EXPOSE 8081 FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build ARG BUILD_CONFIGURATION=Release diff --git a/Filters/WebhookAuthFilter.cs b/Filters/WebhookAuthFilter.cs index 01c51b9..bba32b4 100644 --- a/Filters/WebhookAuthFilter.cs +++ b/Filters/WebhookAuthFilter.cs @@ -13,12 +13,13 @@ public class WebhookAuthFilter : IEndpointFilter } public async ValueTask InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next) { - var expectedToken = Environment.GetEnvironmentVariable("WebhookAuth__RequiredApiToken"); - var allowedOrigin = Environment.GetEnvironmentVariable("WebhookAuth__AllowedOrigin"); + var expectedToken = Environment.GetEnvironmentVariable("HCI_WEBHOOK_AUTH_TOKEN"); + var allowedOrigin = Environment.GetEnvironmentVariable("HCI_WEBHOOK_AUTH_ALLOW_ORIGIN"); if (string.IsNullOrEmpty(expectedToken) || string.IsNullOrEmpty(allowedOrigin)) { - _logger.LogCritical("Required environment variables 'WebhookAuth__RequiredApiToken' or 'WebhookAuth__AllowedOrigin' are not set."); + _logger.LogCritical("Required environment variables 'HCI_WEBHOOK_AUTH_TOKEN' or 'HCI_WEBHOOK_AUTH_TOKEN' are not set."); + _logger.LogInformation($"token: {expectedToken}, allowedOrigin: {allowedOrigin}"); return Results.StatusCode((int)HttpStatusCode.InternalServerError); } diff --git a/Program.cs b/Program.cs index 0b354e5..9ce63d9 100644 --- a/Program.cs +++ b/Program.cs @@ -2,6 +2,7 @@ using Alchegos.HCI.Components; using Alchegos.HCI.Filters; using Alchegos.HCI.Models; using Alchegos.HCI.Services; +using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Mvc; var builder = WebApplication.CreateBuilder(args); @@ -11,7 +12,14 @@ builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); builder.Services.AddHttpClient(); builder.Services.AddSingleton(); - +builder.Services.AddSingleton(); +builder.Services.AddCors(options => +{ + options.AddPolicy(name: "n8n", policy => + { + policy.WithOrigins("http://n8n:5678"); + }); +}); var app = builder.Build(); // Configure the HTTP request pipeline. @@ -37,25 +45,33 @@ app.MapPost("/api/chatwebhook", async ( if (string.IsNullOrEmpty(payload.SessionId)) { logger.LogWarning("Received webhook payload without sessionId."); - return Results.BadRequest("sessionId is required."); + var errors = new Dictionary { + { nameof(payload.SessionId), ["sessionId is required."] } + }; + return Results.ValidationProblem(errors, + title: "One or more validation errors occurred.", + statusCode: StatusCodes.Status400BadRequest); } if (payload.Action == "close_session") { logger.LogInformation("Webhook request received to close session: {SessionId}", payload.SessionId); await chatSessionService.TriggerSessionClosed(payload.SessionId); - return Results.Ok($"Session close requested for {payload.SessionId}"); + return Results.Ok(new { message = $"Session close requested for {payload.SessionId}" }); } else if (!string.IsNullOrEmpty(payload.Output)) { logger.LogInformation("Webhook request received with output for session: {SessionId}", payload.SessionId); await chatSessionService.TriggerMessageReceived(payload.SessionId, payload.Output); - return Results.Ok($"Output received for {payload.SessionId}"); + return Results.Ok(new { message = $"Output received for {payload.SessionId}" }); } else { logger.LogWarning("Received webhook payload for session {SessionId} with neither 'output' nor 'action':'close_session'.", payload.SessionId); - return Results.BadRequest("Payload must contain either 'output' or 'action':'close_session'."); + return Results.Problem( + title: "Invalid payload content.", + detail: "Payload must contain either a non-empty 'output' field or an 'action' field set to 'close_session'.", + statusCode: StatusCodes.Status400BadRequest); } }) .WithTags("Chat Webhook") diff --git a/Services/IChatSessionService.cs b/Services/IChatSessionService.cs index fefee79..883c077 100644 --- a/Services/IChatSessionService.cs +++ b/Services/IChatSessionService.cs @@ -8,7 +8,7 @@ public interface IChatSessionService void AddMessage(string sessionId, ChatMessage message); void SetWaitingStatus(string sessionId, bool isWaiting); void RemoveSession(string sessionId); - Task SendMessageToExternalWebhook(string sessionId, string chatInput); + Task SendMessageToExternalWebhook(string webhookUrl, string sessionId, string chatInput); void RegisterSessionCallbacks(string sessionId, Func? messageCallback, Func? closeCallback); void UnregisterSessionCallbacks(string sessionId); Task TriggerMessageReceived(string sessionId, string output); diff --git a/Services/InMemoryChatSessionService.cs b/Services/InMemoryChatSessionService.cs index 94f3ed7..285032d 100644 --- a/Services/InMemoryChatSessionService.cs +++ b/Services/InMemoryChatSessionService.cs @@ -79,9 +79,9 @@ public class InMemoryChatSessionService : IChatSessionService } } - public async Task SendMessageToExternalWebhook(string sessionId, string chatInput) + public async Task SendMessageToExternalWebhook(string webhookUrl, string sessionId, string chatInput) { - var webhookUrl = _configuration["ChatSettings:ExternalWebhookUrl"]; + //var webhookUrl = Environment.GetEnvironmentVariable("HCI_WEBHOOK_URL"); if (string.IsNullOrEmpty(webhookUrl)) { _logger.LogError("ExternalWebhookUrl is not configured in ChatSettings.");