using BLAIzor.Models; using BLAIzor.Services; using Google.Cloud.Speech.V1; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Mvc; using Microsoft.JSInterop; using Radzen; using System.Text; using System.Text.Json; namespace BLAIzor.Components.Pages { public class MainPageBase : ComponentBase { public string SelectedBrandName = "default"; [Inject] protected ScopedContentService _scopedContentService { get; set; } [Inject] protected ContentEditorService _contentEditorService { get; set; } [Inject] protected IConfiguration configuration { get; set; } [Inject] protected HttpClient Http { get; set; } [Inject] protected IJSRuntime jsRuntime { get; set; } [Inject] protected ISimpleLogger _logger { get; set; } [Inject] protected AIService ChatGptService { get; set; } [Inject] protected NotificationService NotificationService { get; set; } [Inject] protected CacheService CacheService { get; set; } public static readonly Dictionary _instances = new(); public string SessionId; public static MainPageBase myHome; public int SiteId; public SiteInfo SiteInfo; public StringBuilder HtmlContent = new StringBuilder(""); public string TextContent = ""; public string StatusContent = ""; public string UserInput = string.Empty; public string TemplateCollectionName = "html_snippets"; public string ContentCollectionName = ""; public bool VoiceEnabled; public bool TTSEnabled; public bool STTEnabled; public bool _initVoicePending = false; public bool welcomeStage = true; public bool AiVoicePermitted = true; public string FirstColumnClass = ""; public bool isEmailFormVisible = false; public ContactFormModel ContactFormModel = new(); // private string? SuccessMessage; // private string? ErrorMessage; public string? DocumentEmailAddress = ""; public string Menu; public List MenuItems = new(); public string dynamicallyLoadedCss = string.Empty; public MenuItem currentMenuItem = new(); public bool IsContentSaved = false; public WebsiteContentModel SiteModel = new(); public void DoSharedWork() { // Logic here } public async void HandleBrandNameChanged() { SelectedBrandName = _scopedContentService.SelectedBrandName; //await InvokeAsync(() => // { // StateHasChanged(); // }); try { StateHasChanged(); //await Task.Run(() => //{ // StateHasChanged(); //}).ConfigureAwait(false); } catch (Exception ex) { Console.WriteLine(ex); } } public async Task GetMenuList(int siteId) { List menuItems = (await _contentEditorService.GetMenuItemsBySiteIdAsync(siteId)).Where(m => m.ShowInMainMenu == true).OrderBy(m => m.SortOrder).ToList(); string menuList = ""; foreach (MenuItem item in menuItems) { menuList += item.Name + ","; } return menuList; } public async Task> GetMenuItems(int siteId) { List menuItems = (await _contentEditorService.GetMenuItemsBySiteIdWithChildrenAsync(siteId)).Where(m => m.ShowInMainMenu == true).OrderBy(m => m.SortOrder).ToList(); return menuItems; } private string GetApiKey() => configuration?.GetSection("ElevenLabsAPI")?.GetValue("ApiKey") ?? string.Empty; public async Task ConvertTextToSpeech(string textContent) { // string plainText = WebUtility.HtmlDecode(HtmlContent.ToString()); if (string.IsNullOrWhiteSpace(textContent) || VoiceEnabled == false || TTSEnabled == false || welcomeStage || !AiVoicePermitted) return; Console.WriteLine("------------------------------OMGOMGOMG TTS call!!!!-------------"); var requestContent = new { text = textContent, // model_id = "eleven_multilingual_v2", model_id = "eleven_flash_v2_5", voice_settings = new { stability = 0.5, similarity_boost = 0.75, speed = 1.1 } }; var requestJson = JsonSerializer.Serialize(requestContent); string voiceId; if (SiteInfo.VoiceId != null) { voiceId = SiteInfo.VoiceId; } else { voiceId = "rE22Kc7UGoQj4zdHNYvd"; } // string voiceId = "yyPLNYHg3CvjlSdSOdLh"; var httpRequest = new HttpRequestMessage(HttpMethod.Post, $"https://api.elevenlabs.io/v1/text-to-speech/{voiceId}/stream") { Content = new StringContent(requestJson, Encoding.UTF8, "application/json") }; httpRequest.Headers.Add("xi-api-key", GetApiKey()); var response = await Http.SendAsync(httpRequest); if (response.IsSuccessStatusCode) { var audioBytes = await response.Content.ReadAsByteArrayAsync(); var base64Audio = Convert.ToBase64String(audioBytes); var audioDataUrl = $"data:audio/mpeg;base64,{base64Audio}"; await jsRuntime.InvokeVoidAsync("playAudio", audioDataUrl); } else { // Handle error response var errorContent = await response.Content.ReadAsStringAsync(); Console.Error.WriteLine($"Error: {errorContent}"); } } [JSInvokable("CallCSharpMethod2")] public static async Task CallCSharpMethod2(string input, string sessionId, bool forceUnModified = false) { // if (myHome != null) // { // await myHome.HandleJsCall(input, ); // } if (_instances.TryGetValue(sessionId, out var instance)) { await instance.HandleJsCall(input, sessionId, forceUnModified); } Console.Write("Button clicked:" + input); } public async Task HandleJsCall(string input, string sessionId, bool forceUnmodified) { HtmlContent.Clear(); await InvokeAsync(StateHasChanged); UserInput = input; await DisplayMenuContent(input, forceUnmodified); UserInput = string.Empty; await InvokeAsync(StateHasChanged); } public async Task HandleVoiceCommand(string input, string sessionId) { // HtmlContent = string.Empty; UserInput = input; await InvokeAsync(StateHasChanged); await SendUserQuery(); //UserInput = string.Empty; } public async Task SendUserQuery() { welcomeStage = false; if (!string.IsNullOrEmpty(UserInput)) { HtmlContent.Clear(); var menu = await GetMenuList(SiteId); await ChatGptService.ProcessUserIntent(SessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, TemplateCollectionName, menu); UserInput = string.Empty; } } public async Task DisplayMenuContent(string input, bool forceUnmodified) { welcomeStage = false; if (!string.IsNullOrEmpty(UserInput)) { HtmlContent.Clear(); var menu = await GetMenuList(SiteId); var menuList = await GetMenuItems(SiteId); var menuItem = CompareMenuItemNames(input, menuList); if (menuItem == null) { await ChatGptService.ProcessContentRequest(SessionId, input, SiteId, (int)SiteInfo.TemplateId!, ContentCollectionName, menu, forceUnmodified); } else { currentMenuItem = menuItem; if (!string.IsNullOrEmpty(menuItem.StoredHtml)) { HtmlContent.Clear(); HtmlContent.Append(menuItem.StoredHtml); if (currentMenuItem.ContentItemId != null) { var content = await _contentEditorService.GetContentItemByIdAsync((int)currentMenuItem.ContentItemId); if (content != null) { string removedNumbers = TextHelper.ReplaceNumbersAndSpecialCharacters(content.Content, _scopedContentService.SelectedLanguage); Console.WriteLine(removedNumbers); UpdateTextContentForVoice(SessionId, removedNumbers); } } IsContentSaved = true; } else { await ChatGptService.ProcessContentRequest(SessionId, menuItem, SiteId, (int)SiteInfo.TemplateId!, ContentCollectionName, menu, forceUnmodified); } } UserInput = string.Empty; } } protected async void UpdateTextContentForVoice(string receivedSessionId, string content) { Console.WriteLine("UPDATETEXTCONTENT called"); if (receivedSessionId == SessionId) // Only accept messages meant for this tab { TextContent = content; await ConvertTextToSpeech(content); //_scopedContentService.CurrentDOM = await jsRuntime.InvokeAsync("getDivContent", "currentContent"); } } public async Task DisplayEmailForm(string emailAddress) { FirstColumnClass = "col-12 col-md-6"; DocumentEmailAddress = emailAddress; isEmailFormVisible = true; StateHasChanged(); var result = await jsRuntime.InvokeAsync("getDivContent", "currentContent"); _scopedContentService.CurrentDOM = JsonSerializer.Serialize(result); // Console.Write($"{_scopedContentService.CurrentDOM}"); } [JSInvokable("ProcessAudio2")] public static async Task ProcessAudio2(string base64Audio, string SessionId) { Console.Write("audio incoming"); if (myHome != null) { if (myHome.STTEnabled == false) return; Console.WriteLine("STT ENABLED -------------------------------------------------------------------------------"); var languageCode = "hu-HU"; if (myHome._scopedContentService.SelectedLanguage == "Hungarian") { languageCode = "hu-HU"; } else if (myHome._scopedContentService.SelectedLanguage == "English") { languageCode = "en-US"; } else if (myHome._scopedContentService.SelectedLanguage == "German") { languageCode = "de-DE"; } var credentialsPath = myHome.configuration.GetSection("GoogleAPI").GetValue("CredentialsPath"); Console.Write(credentialsPath); var builder = new SpeechClientBuilder { CredentialsPath = credentialsPath }; var speech = builder.Build(); byte[] audioBytes = Convert.FromBase64String(base64Audio); myHome.HtmlContent.Clear(); var response = await speech.RecognizeAsync(new RecognitionConfig { Encoding = RecognitionConfig.Types.AudioEncoding.Mp3, SampleRateHertz = 48000, // Match the actual sample rate LanguageCode = languageCode }, RecognitionAudio.FromBytes(audioBytes)); Console.Write("BILLED: " + response.TotalBilledTime); foreach (var result in response.Results) { //Console.Write("RESULT: " + result.Alternatives.Count); foreach (var alternative in result.Alternatives) { //Console.WriteLine($"Transcription: {alternative.Transcript}"); await myHome.HandleVoiceCommand(alternative.Transcript, SessionId); } } } } [JSInvokable("OpenEmailForm2")] public static async void OpenEmailForm2(string emailAddress) { if (myHome != null) { await myHome.DisplayEmailForm(emailAddress); } Console.Write("openEmail with: " + emailAddress); } public async Task SendMessage() { Console.WriteLine("Button clicked!"); var menu = await GetMenuList(SiteId); HtmlContent.Clear(); await ChatGptService.ProcessUserIntent(SessionId, UserInput, SiteId, (int)SiteInfo.TemplateId!, ContentCollectionName, menu); UserInput = string.Empty; } public MenuItem CompareMenuItemNames(string input, List menuList) { var parent = menuList.FirstOrDefault(ml => ml.Name == input); if (parent != null) { return parent; } foreach (var item in menuList) { var child = item.Children.FirstOrDefault(ch => ch.Name == input); if (child != null) { return child; } } return null; // or throw, or return a default } public void ShowNotification(NotificationMessage message) { NotificationService.Notify(message); } public async ValueTask DisposeAsync() { //await CssTemplateService.DeleteSessionCssFile(SessionId); _scopedContentService.OnBrandNameChanged -= HandleBrandNameChanged; //AIService.OnContentReceived -= UpdateContent; //AIService.OnContentReceiveFinished -= UpdateFinished; //AIService.OnStatusChangeReceived -= UpdateStatus; ChatGptService.OnTextContentAvailable -= UpdateTextContentForVoice; } } }