using System.Net.Http.Headers; using System.Text; using System.Text.Json; using Azure; using Azure.AI.TextAnalytics; using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Http; using Microsoft.Extensions.Logging; public class DeHamerFeedbackFunction { private readonly ILogger _logger; public DeHamerFeedbackFunction(ILoggerFactory loggerFactory) { _logger = loggerFactory.CreateLogger(); } [Function("DeHamerFeedbackFunction")] public async Task Run( [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequestData req) { _logger.LogInformation("DeHamerFeedbackFunction triggered."); var requestBody = await new StreamReader(req.Body).ReadToEndAsync(); var data = JsonSerializer.Deserialize>(requestBody); string feedback = data?["feedback"] ?? string.Empty; // Get Text Analytics config var textEndpoint = Environment.GetEnvironmentVariable("TEXT_ANALYTICS_ENDPOINT"); var textKey = Environment.GetEnvironmentVariable("TEXT_ANALYTICS_KEY"); _logger.LogInformation("Using Text Analytics endpoint: {endpoint}", textEndpoint); var credentials = new AzureKeyCredential(textKey); var client = new TextAnalyticsClient(new Uri(textEndpoint), credentials); var documentSentiment = await client.AnalyzeSentimentAsync(feedback); var sentiment = documentSentiment.Value.Sentiment.ToString().ToLower(); _logger.LogInformation("Sentiment detected: {sentiment}", sentiment); // Compose prompt string prompt = sentiment switch { "positive" => $"Respond in a cheerful and thankful tone to the following positive customer feedback:\n\"{feedback}\"", "negative" => $"Respond in a harsh, sarcastic, and annoyed tone to the following negative customer feedback:\n\"{feedback}\"", _ => $"Respond neutrally and professionally to the following feedback:\n\"{feedback}\"" }; // OpenAI Setup var openaiEndpoint = Environment.GetEnvironmentVariable("OPENAI_ENDPOINT")?.TrimEnd('/'); var openaiKey = Environment.GetEnvironmentVariable("OPENAI_KEY"); var deployment = Environment.GetEnvironmentVariable("OPENAI_DEPLOYMENT"); _logger.LogInformation("Calling OpenAI at: {url}", $"{openaiEndpoint}/openai/deployments/{deployment}/chat/completions"); using var httpClient = new HttpClient(); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", openaiKey); var payload = JsonSerializer.Serialize(new { messages = new[] { new { role = "system", content = "You are a customer support agent who mirrors the customer's sentiment tone." }, new { role = "user", content = prompt } } }); _logger.LogInformation("Payload sent to OpenAI: {payload}", payload); var response = await httpClient.PostAsync( $"{openaiEndpoint}/openai/deployments/{deployment}/chat/completions?api-version=2024-02-15-preview", new StringContent(payload, Encoding.UTF8, "application/json")); if (!response.IsSuccessStatusCode) { var errorDetails = await response.Content.ReadAsStringAsync(); _logger.LogError("OpenAI API call failed: {status} - {details}", response.StatusCode, errorDetails); var errorResponse = req.CreateResponse(System.Net.HttpStatusCode.InternalServerError); await errorResponse.WriteAsJsonAsync(new { error = "Failed to get OpenAI response", status = response.StatusCode, details = errorDetails }); return errorResponse; } var json = JsonDocument.Parse(await response.Content.ReadAsStringAsync()); _logger.LogInformation("Raw OpenAI response: {json}", json); var message = json.RootElement.GetProperty("choices")[0].GetProperty("message").GetProperty("content").GetString(); var result = new { sentiment = sentiment, message = message }; var responseData = req.CreateResponse(System.Net.HttpStatusCode.OK); await responseData.WriteAsJsonAsync(result); return responseData; } }