From c1af8c61900ce8491828b00c8536de2e32b44b51 Mon Sep 17 00:00:00 2001 From: TamilRamGanesan-SF5080 Date: Wed, 15 Oct 2025 16:28:21 +0530 Subject: [PATCH 1/2] 986912: need to port the bot integration in chat UI --- blazor-toc.html | 12 + .../ai-integrations/gemini-integration.md | 6 +- .../ai-integrations/ollama-llm-integration.md | 282 ++++++++++++++++++ .../ai-integrations/openai-integration.md | 4 +- .../ai-assistview/images/llm-integration.png | Bin 0 -> 22403 bytes .../integration-with-bot-dialogflow.md | 213 +++++++++++++ .../integration-with-bot-framework.md | 281 +++++++++++++++++ blazor/chat-ui/images/dialogflow.png | Bin 0 -> 33992 bytes 8 files changed, 793 insertions(+), 5 deletions(-) create mode 100644 blazor/ai-assistview/ai-integrations/ollama-llm-integration.md create mode 100644 blazor/ai-assistview/images/llm-integration.png create mode 100644 blazor/chat-ui/bot-integrations/integration-with-bot-dialogflow.md create mode 100644 blazor/chat-ui/bot-integrations/integration-with-bot-framework.md create mode 100644 blazor/chat-ui/images/dialogflow.png diff --git a/blazor-toc.html b/blazor-toc.html index d5f1cfb51b..fc9b606de3 100644 --- a/blazor-toc.html +++ b/blazor-toc.html @@ -497,6 +497,8 @@
  • Toolbar items
  • @@ -1489,6 +1491,16 @@
  • Messages
  • +
  • Chat Bot Integrations + +
  • Time break
  • Timestamp
  • Typing indicator
  • diff --git a/blazor/ai-assistview/ai-integrations/gemini-integration.md b/blazor/ai-assistview/ai-integrations/gemini-integration.md index e144fa6af0..d66a3e8deb 100644 --- a/blazor/ai-assistview/ai-integrations/gemini-integration.md +++ b/blazor/ai-assistview/ai-integrations/gemini-integration.md @@ -29,7 +29,7 @@ Follow the Syncfusion AI AssistView [Getting Started](../getting-started) guide Install the required packages: -1. Install the `Gemini AI` nuget package in the application. +* Install the `Gemini AI` nuget package in the application. ```bash @@ -37,7 +37,7 @@ Nuget\Install-Package Mscc.GenerativeAI ``` -2. Install the `Markdig` nuget packages in the application. +* Install the `Markdig` nuget packages in the application. ```bash @@ -59,7 +59,7 @@ Nuget\Install-Package Markdig ## Gemini AI with AI AssistView -Modify the razor file to integrate the Gemini AI with the AI AssistView component. +Modify the Razor file to integrate the Gemini AI with the AI AssistView component. * update your Gemini API key securely in the configuration: diff --git a/blazor/ai-assistview/ai-integrations/ollama-llm-integration.md b/blazor/ai-assistview/ai-integrations/ollama-llm-integration.md new file mode 100644 index 0000000000..ff048615a5 --- /dev/null +++ b/blazor/ai-assistview/ai-integrations/ollama-llm-integration.md @@ -0,0 +1,282 @@ +--- +layout: post +title: LLM Model with Blazor AI AssistView Component | Syncfusion +description: Checkout and learn about Integration of LLM Model with Blazor AI AssistView component in Blazor WebAssembly Application. +platform: Blazor +control: AI AssistView +documentation: ug +--- + +# Integrate LLM via Ollama with Blazor AI AssistView Component + +The AI AssistView component integrates with [LLM via Ollama](https://ollama.com) to enable advanced conversational AI features in your Blazor application. The component acts as a user interface where user prompts are sent to the selected LLM model via API calls, providing natural language understanding and context-aware responses. + +## Prerequisites + +Before starting, ensure you have the following: + +* [Ollama](https://ollama.com) installed to run and manage LLM models locally. + +* **Syncfusion AI AssistView**: Package [Syncfusion Blazor package](https://www.nuget.org/packages/Syncfusion.Blazor.InteractiveChat) installed. + +* [Markdig](https://www.nuget.org/packages/Markdig) package: For parsing Markdown responses. + +## Set Up the AI AssistView Component + +Follow the Syncfusion AI AssistView [Getting Started](../getting-started) guide to configure and render the AI AssistView component in the application and that prerequisites are met. + +## Install Dependency + +To install the Markdig package by run `NuGet\Install-Package Markdig` in Package Manager Console. + +## Configuring Ollama + +Install Ollama for your operating system: + +{% tabs %} +{% highlight ts tabtitle="Windows" %} + +1. Visit [Windows](https://ollama.com/download) +2. Click `Download for Windows` to get the `.exe installer`. +3. Run `OllamaSetup.exe` and follow the wizard to install. + +{% endhighlight %} + +{% highlight ts tabtitle="macOS" %} + +1. Visit [macOS](https://ollama.com/download/mac) +2. Click `Download for macOS` to get `.dmg file` +3. Install it by following the wizard. + +{% endhighlight %} + +{% highlight ts tabtitle="Linux" %} + +1. Visit [Linux](https://ollama.com/download/linux) +2. Run the below command to install Ollama in your system + + curl -fsSL https://ollama.com/install.sh | sh + +{% endhighlight %} +{% endtabs %} + +## Download and run an Ollama model + +* Download and run a model using the following command. Replace `deepseek-r1` with your preferred model (e.g., `llama3`, `phi4`). See the [Ollama model](https://ollama.com/search) library for available models. + +```bash + +ollama run deepseek-r1 + +``` + +* After the model download completes, start the Ollama server to make the model accessible: + +```bash + +ollama serve + +``` + +## Configure AI AssistView with Ollama + +To integrate Ollama with the Syncfusion Blazor AI AssistView component in your Blazor application: + +* Configure the AI services in the `Program.cs` file to register the Ollama client and Syncfusion Blazor services. + +{% tabs %} +{% highlight cs tabtitle="Program.cs" %} + + +using Blazor_AssistView_Ollama.Components; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.AI; +using OllamaSharp; +using Syncfusion.Blazor; + +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. +builder.Services.AddRazorComponents() + .AddInteractiveServerComponents(); +builder.Services.AddSyncfusionBlazor(); + +builder.Services.AddHttpClient(); + +builder.Services.AddDistributedMemoryCache(); + +// Ollama configuration +builder.Services.AddChatClient(new OllamaApiClient(new Uri("http://localhost:11434/"), "llama3.2")) + .UseDistributedCache() + .UseLogging(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (!app.Environment.IsDevelopment()) +{ + app.UseExceptionHandler("/Error", createScopeForErrors: true); + // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. + app.UseHsts(); +} + +app.UseHttpsRedirection(); + + +app.UseAntiforgery(); + +app.MapStaticAssets(); +app.MapRazorComponents() + .AddInteractiveServerRenderMode(); + +app.Run(); + +{% endhighlight %} +{% endtabs %} + +* Modify the `Index.razor` file (or a dedicated component) to host the integration logic and handle prompt requests. + +{% tabs %} +{% highlight razor %} + +@rendermode InteractiveServer +@using Markdig +@using Microsoft.Extensions.AI +@using Syncfusion.Blazor.Navigations + +
    +
    + + + + + + + + + + + + + + +
    +
    + +@code { + private SfAIAssistView AIAssist = new(); + private bool responseStopped = false; + private bool isStreaming = false; + + // Suggestion list + private List suggestions = new() + { + "What are the best tools for organizing my tasks?", + "How can I maintain work-life balance effectively?" + }; + + [Inject] private IChatClient ChatClient { get; set; } = default!; + + private async Task PromptRequest(AssistViewPromptRequestedEventArgs args) + { + responseStopped = false; + isStreaming = true; // turn on Stop button + + try + { + var pipeline = new MarkdownPipelineBuilder() + .UseAdvancedExtensions() + .UsePipeTables() + .UseTaskLists() + .Build(); + + var messages = new List + { + new(ChatRole.System, "You are a helpful AI assistant. Respond with clear, concise explanations. Use Markdown when helpful."), + new(ChatRole.User, args.Prompt) + }; + + var buffer = new System.Text.StringBuilder(); + const int updateRateChars = 5; + int lastLenPushed = 0; + + await foreach (var update in ChatClient.GetStreamingResponseAsync(messages)) + { + if (responseStopped) break; + if (string.IsNullOrEmpty(update?.Text)) continue; + + buffer.Append(update.Text); + + if (buffer.Length - lastLenPushed >= updateRateChars) + { + string html = Markdown.ToHtml(buffer.ToString(), pipeline); + await AIAssist.UpdateResponseAsync(html); + await AIAssist.ScrollToBottomAsync(); + lastLenPushed = buffer.Length; + } + } + + if (!responseStopped) + { + string finalHtml = Markdown.ToHtml(buffer.ToString(), pipeline); + await AIAssist.UpdateResponseAsync(finalHtml); + await AIAssist.ScrollToBottomAsync(); + } + + args.PromptSuggestions = suggestions; + } + catch (Exception ex) + { + await AIAssist.UpdateResponseAsync($"Error generating response: {ex.Message}"); + await AIAssist.ScrollToBottomAsync(); + } + finally + { + responseStopped = false; + isStreaming = true; + StateHasChanged(); + } + } + + private void ToolbarItemClicked(AssistViewToolbarItemClickedEventArgs args) + { + // Handle Refresh + if (args.Item.IconCss == "e-icons e-refresh") + { + AIAssist.Prompts.Clear(); + + AIAssist.PromptSuggestions = suggestions; + } + } + + private void HandleStopResponse(ResponseStoppedEventArgs args) + { + responseStopped = true; + } +} + + + +{% endhighlight %} +{% endtabs %} + +![Blazor AI AssistView LLM Integration](../images/llm-integration.png) \ No newline at end of file diff --git a/blazor/ai-assistview/ai-integrations/openai-integration.md b/blazor/ai-assistview/ai-integrations/openai-integration.md index 661836d8a6..608dbfdb6d 100644 --- a/blazor/ai-assistview/ai-integrations/openai-integration.md +++ b/blazor/ai-assistview/ai-integrations/openai-integration.md @@ -29,7 +29,7 @@ Follow the Syncfusion AI AssistView [Getting Started](../getting-started) guide Install the required packages: -1. Install the `OpenAI` and `Azure` nuget packages in the application. +* Install the `OpenAI` and `Azure` nuget packages in the application. ```bash @@ -39,7 +39,7 @@ NuGet\Install-Package Azure.Core ``` -2. Install the `Markdig` nuget packages in the application. +* Install the `Markdig` nuget packages in the application. ```bash diff --git a/blazor/ai-assistview/images/llm-integration.png b/blazor/ai-assistview/images/llm-integration.png new file mode 100644 index 0000000000000000000000000000000000000000..c72e1f85c7f035960333f10bc7dac722b6283311 GIT binary patch literal 22403 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

    hE$i8H#fF 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 Credentials, create a service account with the Dialogflow API Client role, and download the JSON key file. + +> `Security Note`: Never commit the JSON key file to version component. Use environment variables or a secret manager (e.g., Google Cloud Secret Manager) for production. + +## Configure Backend API + +In a Blazor application, create a minimal API endpoint to handle Dialogflow requests. Add the following to `Program.cs`: + +{% tabs %} +{% highlight cs tabtitle="Program.cs" %} + +using Google.Cloud.Dialogflow.V2; +using Google.Apis.Auth.OAuth2; +using Syncfusion.Blazor; + +var builder = WebApplication.CreateBuilder(args); + +// Add services... +builder.Services.AddRazorPages(); +builder.Services.AddServerSideBlazor(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline... +app.MapRazorPages(); +app.MapBlazorHub(); +app.MapFallbackToPage("/_Host"); + +// Minimal API for Dialogflow requests +app.MapPost("/api/chat/message", async ([FromBody] MessageRequest request) => +{ + var credential = GoogleCredential.FromFile("service-acct.json"); + var sessionsClient = SessionsClient.Create(credential.ToChannelCredentials()); + var projectId = builder.Configuration["DialogflowProjectId"]; // Add to appsettings.json or extract from JSON + + var sessionId = request.SessionId ?? "default-session"; + var session = SessionName.FromProjectSession(projectId, sessionId); + var queryInput = new QueryInput + { + Text = new TextInput + { + Text = request.Text, + LanguageCode = "en-US" + } + }; + + try + { + var response = await sessionsClient.DetectIntentAsync(new DetectIntentRequest { Session = session.ToString(), QueryInput = queryInput }); + var reply = response.QueryResult.FulfillmentText; + return Results.Ok(new { reply }); + } + catch (Exception ex) + { + return Results.Problem("Error connecting to Dialogflow.", ex, statusCode: 500); + } +}); + +app.Run(); + +public class MessageRequest +{ + public string Text { get; set; } = string.Empty; + public string SessionId { get; set; } = string.Empty; +} + +{% endhighlight %} +{% endtabs %} + +Add the project ID to `appsettings.json` (extract from the JSON key file if needed): + +```bash + +{ + "DialogflowProjectId": "your-dialogflow-project-id" +} + +``` + +> Use a unique `sessionId` (e.g., Guid) for each user to maintain conversation context. + +## Configure Message Send + +Use the `MessageSend` event of the `SfChatUI` component to handle message exchanges. Each time a user sends a message, this event will be invoked with details of the sent message. + +### Forward Message to Backend + +In the `MessageSend` event handler, send a POST request to your backend API endpoint (`/api/chat/message`). The backend forwards the message to Dialogflow and returns the response. + +### Displaying Bot Response + +* Use the `AddMessageAsync` method (via a reference to the component) to programmatically add the bot's reply to the Chat UI. + +* Create or modify a Razor component (`e.g., Pages/Chat.razor`) to integrate the Syncfusion Chat UI with the Dialogflow backend: + +{% tabs %} +{% highlight razor %} + +@using Syncfusion.Blazor.InteractiveChat +@using System.Net.Http.Json + +

    + + +
    + + + +@code { + private SfChatUI ChatUI { get; set; } = default!; + private UserModel CurrentUserModel = new() { ID = "user1", User = "Albert" }; + private UserModel BotUserModel = new() { ID = "user2", User = "Bot", AvatarUrl = "https://ej2.syncfusion.com/demos/src/chat-ui/images/bot.png" }; + private string currentUserId = "user1"; + private readonly HttpClient httpClient = new(); + + private async Task OnMessageSend(MessageSendEventArgs args) + { + // The user message will be added automatically after this event + // Send to backend + var request = new { text = args.Message.Text, sessionId = currentUserId }; + try + { + var response = await httpClient.PostAsJsonAsync("/api/chat/message", request); + if (response.IsSuccessStatusCode) + { + var data = await response.Content.ReadFromJsonAsync(); + // Add bot's reply + await ChatUI.AddMessageAsync(new ChatMessage { Text = data.reply.ToString(), Author = BotUserModel }); + } + else + { + await ChatUI.AddMessageAsync(new ChatMessage { Text = "Sorry, I couldn't contact the server.", Author = BotUserModel }); + } + } + catch (Exception) + { + await ChatUI.AddMessageAsync(new ChatMessage { Text = "Sorry, I couldn't contact the server.", Author = BotUserModel }); + } + args.Cancel = true; // Prevent default send if needed, but user message is already added + } +} + +{% endhighlight %} +{% endtabs %} + +> Ensure Syncfusion scripts and styles are included in `_Host.cshtml` (Blazor Server) or `index.html` (Blazor WebAssembly) as per the getting started guide. + +## Run and Test + +### Start the Application + +* Run the project using `dotnet run` or Visual Studio. +* Open your app in the browser (e.g., `http://localhost:port`) to chat with your dialogflow-powered bot. + +![ChatUI with Dialogflow](../images/dialogflow.png) + +## Troubleshooting: + +* `Permission Denied`: Ensure the service account has the `Dialogflow API Client` role in the Google Cloud Console. +* `CORS Error`: If using separate origins, configure CORS in Web.config (e.g., add custom headers under ). +* `No Response`: Test intents in the Dialogflow Console simulator to ensure they are configured correctly. +* `Quota Exceeded`: Check Dialogflow API quotas in the Google Cloud Console. +* `Network Issues`: Confirm the application is running and the frontend is pointing to the correct API URL. +* `Invalid Credentials`: Verify the service account JSON or configuration settings are correctly set up. \ No newline at end of file diff --git a/blazor/chat-ui/bot-integrations/integration-with-bot-framework.md b/blazor/chat-ui/bot-integrations/integration-with-bot-framework.md new file mode 100644 index 0000000000..f563ad2b66 --- /dev/null +++ b/blazor/chat-ui/bot-integrations/integration-with-bot-framework.md @@ -0,0 +1,281 @@ +--- +layout: post +title: Integrate Microsoft Bot Framework with Blazor Chat UI Component | Syncfusion +description: Checkout and learn here all about Integrate Microsoft Bot Framework with Syncfusion Blazor Chat UI component in Blazor Server App and Blazor WebAssembly App. +platform: Blazor +control: Chat UI +documentation: ug +--- + +# Integrate Microsoft Bot Framework with Blazor Chat UI component + +The Chat UI component integrates with a [Microsoft Bot Framework](https://learn.microsoft.com/en-us/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0) bot hosted on Azure, enabling a custom chat interface for seamless user interaction. The process involves setting up a secure backend token server, configuring Direct Line in Azure, and integrating the Chat UI in the Blazor application. + +## Prerequisites + +Before starting, ensure you have the following: + +* [Microsoft Azure Account](https://portal.azure.com/#home): Required to create and host the bot. + +* **Syncfusion Chat UI**: Package [Syncfusion Blazor package](https://www.nuget.org/packages/Syncfusion.Blazor.InteractiveChat) installed. + +* **Deployed Azure Bot**: A bot should be created and published using the [Microsoft Bot Framework](https://learn.microsoft.com/en-us/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0), which is accessible via an Azure App Service. Refer to Microsoft's Bot Creation Guide. + +## Set Up the Chat UI component + +Follow the Syncfusion Chat UI [Getting Started](../getting-started) guide to configure and render the Chat UI component in the application and that prerequisites are met. + +## Install Dependencies + +* Install backend dependencies for bot communication using NuGet: + +``` bash + +dotnet add package Microsoft.Bot.Connector.DirectLine +dotnet add package Newtonsoft.Json + +``` + +Note: While the integration uses a JavaScript-based Direct Line client for client-side handling, the .NET packages support token generation on the server side. + +## Configure the Azure Bot + +1. In the [Azure Portal](https://portal.azure.com/auth/login/), navigate to your bot resource. + +2. Enable the direct line channel: + * Go to Channels > Direct Line > Default-Site. + * Copy one of the displayed secret keys. + +3. Verify the messaging endpoint in the configuration section (e.g., https://your-bot-service.azurewebsites.net/api/messages). + +> `Security Note`: Never expose the Direct Line secret key in frontend code. Use a backend token server to handle it securely. + +## Set Up Token Server + +In a Blazor Server application, create a minimal API endpoint or controller to handle direct line token generation. For simplicity, add a minimal API in `Program.cs` (or use a dedicated controller in a Pages or Areas folder). + +Add the following to `Program.cs`: + +{% tabs %} +{% highlight cs tabtitle="Program.cs" %} + +using Syncfusion.Blazor; + +var builder = WebApplication.CreateBuilder(args); + +// Add services... +builder.Services.AddRazorPages(); +builder.Services.AddServerSideBlazor(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline... +app.MapRazorPages(); +app.MapBlazorHub(); +app.MapFallbackToPage("/_Host"); + +// Minimal API for token generation +app.MapPost("/api/token/directline/token", async () => +{ + var directLineSecret = builder.Configuration["DirectLineSecret"]; + if (string.IsNullOrEmpty(directLineSecret)) + { + return Results.BadRequest("Direct Line secret is not configured."); + } + + using var httpClient = new HttpClient(); + try + { + var request = new HttpRequestMessage(HttpMethod.Post, "https://directline.botframework.com/v3/directline/tokens/generate"); + request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", directLineSecret); + var response = await httpClient.SendAsync(request); + response.EnsureSuccessStatusCode(); + var responseContent = await response.Content.ReadAsStringAsync(); + dynamic tokenResponse = Newtonsoft.Json.JsonConvert.DeserializeObject(responseContent); + return Results.Ok(new { token = tokenResponse.token }); + } + catch (HttpRequestException ex) + { + return Results.Problem("Failed to generate Direct Line token.", ex, statusCode: 500); + } +}); + +app.Run(); + +{% endhighlight %} +{% endtabs %} + +Add the Direct Line secret to `Web.config`: + +{% tabs %} +{% highlight js tabtitle=".env" %} + + + + +{% endhighlight %} +{% endtabs %} + +>`Security Note`: Store the Direct Line secret in a secure configuration, such as Azure Key Vault, for production environments. + +## Configure Chat UI + +Use the `MessageSend`event of the `SfChatUI` component to handle message exchanges. This event is triggered before a message is sent, allowing you to forward it to the bot via the Direct Line API. Use the `AddMessageAsync` method (via a reference to the component) to programmatically add the bot's reply to the Chat UI. + +Create or modify a Razor component (e.g., `Pages/Chat.razor`) to integrate the Syncfusion Chat UI with the Direct Line API: + +{% tabs %} +{% highlight razor %} + +@using Syncfusion.Blazor.InteractiveChat +@using Syncfusion.Blazor + +
    + + +
    + + + + + +@code { + private SfChatUI ChatUI { get; set; } + private UserModel CurrentUserModel = new() { ID = "user1", User = "You" }; + private UserModel BotUserModel = new() { ID = "bot", User = "Bot" }; + private string currentUserId = "user1"; + private bool isConnected = false; + + private async Task OnMessageSend(MessageSendEventArgs args) + { + // Initialize Direct Line connection on first message if not already connected + if (!isConnected) + { + try + { + // Fetch Direct Line token via HttpClient (Blazor Server can call backend directly) + using var httpClient = new HttpClient(); + var response = await httpClient.PostAsync("/api/token/directline/token", null); + var data = await response.Content.ReadFromJsonAsync(); + if (data?.error != null) + { + await ChatUI.AddMessageAsync(new ChatMessage { Text = "Failed to connect to bot.", Author = BotUserModel }); + return; + } + + // Use JSInterop to initialize Direct Line (client-side for real-time updates) + var directLine = await JS.InvokeAsync("eval", + $"new BotFramework.DirectLine.DirectLine({{ token: '{data.token}' }})"); + + isConnected = true; + + // Subscribe to bot messages via JS callback + await JS.InvokeVoidAsync("setupBotSubscription", directLine, DotNetObjectReference.Create(this), currentUserId); + } + catch (Exception ex) + { + await ChatUI.AddMessageAsync(new ChatMessage { Text = "Sorry, I couldn’t connect to the bot.", Author = BotUserModel }); + Console.WriteLine($"Connection error: {ex.Message}"); + return; + } + } + + // Send message to bot via JSInterop + await JS.InvokeVoidAsync("sendToBot", /* directLine ref or global */, args.Message.Text, currentUserId); + args.Cancel = true; // Prevent default send + } + + private Task OnCreated() + { + // Additional initialization if needed + return Task.CompletedTask; + } + + [JSInvokable] + public async Task ReceiveBotMessage(string messageText) + { + await ChatUI.AddMessageAsync(new ChatMessage { Text = messageText, Author = BotUserModel }); + } +} + +{% endhighlight %} +{% endtabs %} + +Add the following JavaScript to a global script file (e.g., `wwwroot/js/bot-integration.js`) and reference it in `_Host.cshtml` or `index.html`: + +{% tabs %} +{% highlight js tabtitle="_Host.cshtml" %} + +window.setupBotSubscription = (directLine, dotNetHelper, currentUserId) => { + directLine.activity$ + .filter(activity => activity.type === 'message' && activity.from.id !== currentUserId) + .subscribe(async (message) => { + await dotNetHelper.invokeMethodAsync('ReceiveBotMessage', message.text); + }); +}; + +window.sendToBot = async (directLine, text, currentUserId) => { + directLine.postActivity({ + from: { id: currentUserId, name: 'You' }, + type: 'message', + text: text + }).subscribe( + id => console.log('Sent message with ID: ', id), + error => { + console.error('Error sending message: ', error); + // Handle error via JS callback if needed + } + ); +}; + +{% endhighlight %} +{% endtabs %} + +> Ensure Syncfusion scripts and styles are included in _Host.cshtml (Blazor Server) or index.html (Blazor WebAssembly) as per the getting started guide. Also, include the Bot Framework Web Chat script for Direct Line functionality. Replace 'YourAssemblyName' with your actual assembly name in the JS invoke calls. + +## Configure CORS (if needed for Blazor WebAssembly) + +For Blazor WebAssembly (client-side), configure CORS in `Program.cs` to allow API requests to your backend: + +{% tabs %} +{% highlight cs tabtitle="Program.cs" %} + +builder.Services.AddCors(options => +{ + options.AddDefaultPolicy(policy => + { + policy.WithOrigins("https://localhost:5001") // Your Blazor WASM URL + .AllowAnyHeader() + .AllowAnyMethod(); + }); +}); + +// In app... +app.UseCors(); + +{% endhighlight %} +{% endtabs %} + +## Run and Test + +### Start the Application + +* Run the project in Visual Studio or use IIS Express. +* Open your app in the browser (e.g., `http://localhost:port`) to interact with your Microsoft Bot Framework chatbot. + +## Troubleshooting + +* `Token Server Error (500)`: Ensure the `DirectLineSecret` in `Web.config` is correct and the token endpoint is accessible. +* `CORS Error`: Verify the CORS configuration in `Web.config` allows requests from your frontend URL. +* `Bot is Not Responding`: + - Test the bot in the Azure Portal using the `Test in Web Chat` feature to ensure it’s running correctly. + - Check the bot’s `Messaging endpoint` in the Configuration section and ensure it is correct and accessible. +* `Connection Fails on Load`: Verify the token controller is running and accessible. Check the browser console for network errors. +* `Token Expiration`: Direct Line tokens are short-lived. The Direct Line client typically handles token refresh, but if issues persist, restart the Direct Line connection. \ No newline at end of file diff --git a/blazor/chat-ui/images/dialogflow.png b/blazor/chat-ui/images/dialogflow.png new file mode 100644 index 0000000000000000000000000000000000000000..8b96f608e9f47c5a16749fed251df4d9a8a8b621 GIT binary patch literal 33992 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 literal 0 HcmV?d00001 From f54ca36bcd36c3571762d2be61b43f5551e9405e Mon Sep 17 00:00:00 2001 From: TamilRamGanesan-SF5080 Date: Wed, 15 Oct 2025 17:02:24 +0530 Subject: [PATCH 2/2] 986912: resolved CI failure --- blazor-toc.html | 4 ++-- .../bot-integrations/integration-with-bot-dialogflow.md | 2 +- .../bot-integrations/integration-with-bot-framework.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/blazor-toc.html b/blazor-toc.html index fc9b606de3..05dac09e99 100644 --- a/blazor-toc.html +++ b/blazor-toc.html @@ -497,7 +497,7 @@ @@ -1497,7 +1497,7 @@ Google Dialogflow
  • - Microsoft Bot Framework + Microsoft Bot Framework
  • diff --git a/blazor/chat-ui/bot-integrations/integration-with-bot-dialogflow.md b/blazor/chat-ui/bot-integrations/integration-with-bot-dialogflow.md index 303b4f00c3..497e0d4106 100644 --- a/blazor/chat-ui/bot-integrations/integration-with-bot-dialogflow.md +++ b/blazor/chat-ui/bot-integrations/integration-with-bot-dialogflow.md @@ -1,6 +1,6 @@ --- layout: post -title: Integrate Microsoft Bot Framework with Blazor Chat UI Component | Syncfusion +title: Google Dialogflow with Blazor Chat UI Component | Syncfusion description: Checkout and learn here all about Integrate Microsoft Bot Framework with Syncfusion Blazor Chat UI component in Blazor Server App and Blazor WebAssembly App. platform: Blazor control: Chat UI diff --git a/blazor/chat-ui/bot-integrations/integration-with-bot-framework.md b/blazor/chat-ui/bot-integrations/integration-with-bot-framework.md index f563ad2b66..5e966901d7 100644 --- a/blazor/chat-ui/bot-integrations/integration-with-bot-framework.md +++ b/blazor/chat-ui/bot-integrations/integration-with-bot-framework.md @@ -1,6 +1,6 @@ --- layout: post -title: Integrate Microsoft Bot Framework with Blazor Chat UI Component | Syncfusion +title: Bot Framework with Blazor Chat UI Component | Syncfusion description: Checkout and learn here all about Integrate Microsoft Bot Framework with Syncfusion Blazor Chat UI component in Blazor Server App and Blazor WebAssembly App. platform: Blazor control: Chat UI