From 030b73005b1016c3dc80c3faa74d164e50c45ec4 Mon Sep 17 00:00:00 2001 From: Ted Date: Sun, 31 Mar 2019 09:32:55 -0700 Subject: [PATCH] update startup for skills to add middlewares for skilladapter (#1040) * update startup for skills to add middlewares for skilladapter * update aspnetcore version * remove aspnetcore version * remove default coordinates setting --- .../SkillController.cs | 2 +- .../csharp/assistant/VirtualAssistant.csproj | 2 +- .../newsskill/Controllers/BotController.cs | 6 +- .../skills/newsskill/NewsSkill.csproj | 2 +- .../experimental/skills/newsskill/Startup.cs | 83 ++++++++++++------ .../Controllers/BotController.cs | 6 +- .../RestaurantBooking.csproj | 2 +- .../skills/restaurantbooking/Startup.cs | 83 ++++++++++++------ .../automotiveskill/AutomotiveSkill.csproj | 2 +- .../Controllers/BotController.cs | 6 +- .../automotiveskill/Startup.cs | 83 ++++++++++++------ .../AutomotiveSkillTest.csproj | 2 +- .../calendarskill/CalendarSkill.csproj | 2 +- .../Controllers/BotController.cs | 13 +-- .../calendarskill/calendarskill/Startup.cs | 85 ++++++++++++------- .../CalendarSkillTest.csproj | 2 +- .../emailskill/Controllers/BotController.cs | 6 +- .../emailskill/emailskill/EmailSkill.csproj | 2 +- .../skills/emailskill/emailskill/Startup.cs | 84 ++++++++++++------ .../emailskilltest/EmailSkillTest.csproj | 2 +- .../Controllers/BotController.cs | 6 +- .../PointOfInterestSkill.csproj | 2 +- .../pointofinterestskill/Startup.cs | 84 ++++++++++++------ .../PointOfInterestSkillTests.csproj | 2 +- .../todoskill/Controllers/BotController.cs | 6 +- .../skills/todoskill/todoskill/Startup.cs | 84 ++++++++++++------ .../todoskill/todoskill/ToDoSkill.csproj | 2 +- .../todoskilltest/ToDoSkillTest.csproj | 2 +- .../Experimental.Skills.Tests.csproj | 2 +- .../VirtualAssistant.Tests.csproj | 2 +- .../VirtualAssistantTemplate/BotServices.cs | 9 +- .../Dialogs/Main/MainDialog.cs | 8 ++ 32 files changed, 446 insertions(+), 238 deletions(-) diff --git a/lib/csharp/microsoft.bot.builder.skills/Microsoft.Bot.Builder.Skills/SkillController.cs b/lib/csharp/microsoft.bot.builder.skills/Microsoft.Bot.Builder.Skills/SkillController.cs index ab1c1b4b48..069751b91a 100644 --- a/lib/csharp/microsoft.bot.builder.skills/Microsoft.Bot.Builder.Skills/SkillController.cs +++ b/lib/csharp/microsoft.bot.builder.skills/Microsoft.Bot.Builder.Skills/SkillController.cs @@ -42,7 +42,7 @@ public async Task BotMessage() /// This API is the endpoint the bot exposes as skill /// /// - [Route("api/skills")] + [Route("api/skill/messages")] [HttpPost] public async Task SkillMessage() { diff --git a/solutions/Virtual-Assistant/src/csharp/assistant/VirtualAssistant.csproj b/solutions/Virtual-Assistant/src/csharp/assistant/VirtualAssistant.csproj index 5edc0a191b..a0b7744b3b 100644 --- a/solutions/Virtual-Assistant/src/csharp/assistant/VirtualAssistant.csproj +++ b/solutions/Virtual-Assistant/src/csharp/assistant/VirtualAssistant.csproj @@ -22,7 +22,7 @@ - + diff --git a/solutions/Virtual-Assistant/src/csharp/experimental/skills/newsskill/Controllers/BotController.cs b/solutions/Virtual-Assistant/src/csharp/experimental/skills/newsskill/Controllers/BotController.cs index 7a574f08e9..1183be9795 100644 --- a/solutions/Virtual-Assistant/src/csharp/experimental/skills/newsskill/Controllers/BotController.cs +++ b/solutions/Virtual-Assistant/src/csharp/experimental/skills/newsskill/Controllers/BotController.cs @@ -1,6 +1,6 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Bot.Builder; -using Microsoft.Bot.Builder.Integration; +using Microsoft.Bot.Builder.Integration.AspNet.Core; using Microsoft.Bot.Builder.Skills; namespace NewsSkill.Controllers @@ -8,8 +8,8 @@ namespace NewsSkill.Controllers [ApiController] public class BotController : SkillController { - public BotController(IAdapterIntegration adapter, ISkillAdapter skillAdapter, IBot bot) - : base(adapter, skillAdapter, bot) + public BotController(IBotFrameworkHttpAdapter botFrameworkHttpAdapter, SkillAdapter skillAdapter, IBot bot) + : base(botFrameworkHttpAdapter, skillAdapter, bot) { } } diff --git a/solutions/Virtual-Assistant/src/csharp/experimental/skills/newsskill/NewsSkill.csproj b/solutions/Virtual-Assistant/src/csharp/experimental/skills/newsskill/NewsSkill.csproj index a661d9e498..7cac9f45ea 100644 --- a/solutions/Virtual-Assistant/src/csharp/experimental/skills/newsskill/NewsSkill.csproj +++ b/solutions/Virtual-Assistant/src/csharp/experimental/skills/newsskill/NewsSkill.csproj @@ -7,7 +7,7 @@ - + diff --git a/solutions/Virtual-Assistant/src/csharp/experimental/skills/newsskill/Startup.cs b/solutions/Virtual-Assistant/src/csharp/experimental/skills/newsskill/Startup.cs index f8729bb5dd..18e64d0596 100644 --- a/solutions/Virtual-Assistant/src/csharp/experimental/skills/newsskill/Startup.cs +++ b/solutions/Virtual-Assistant/src/csharp/experimental/skills/newsskill/Startup.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Bot.Builder; @@ -11,6 +12,7 @@ using Microsoft.Bot.Builder.Integration.ApplicationInsights.Core; using Microsoft.Bot.Builder.Integration.AspNet.Core; using Microsoft.Bot.Builder.Skills; +using Microsoft.Bot.Builder.Solutions.Middleware; using Microsoft.Bot.Builder.Solutions.Proactive; using Microsoft.Bot.Builder.Solutions.Skills; using Microsoft.Bot.Builder.Solutions.TaskExtensions; @@ -50,8 +52,6 @@ public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_2_2); - services.AddSingleton(); - // add background task queue services.AddSingleton(); services.AddHostedService(); @@ -104,37 +104,68 @@ public void ConfigureServices(IServiceCollection services) services.AddSingleton(endpointService); - // Add the bot with options - services.AddBot(options => - { - options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword); + var defaultLocale = Configuration.GetSection("defaultLocale").Get(); + + // Add the bot + services.AddTransient(); + + var credentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword); - // Telemetry Middleware (logs activity messages in Application Insights) - var sp = services.BuildServiceProvider(); - var telemetryClient = sp.GetService(); - var appInsightsLogger = new TelemetryLoggerMiddleware(telemetryClient, logPersonalInformation: true); - options.Middleware.Add(appInsightsLogger); + // Create the middlewares + var telemetryClient = services.BuildServiceProvider().GetService(); + var appInsightsLogger = new TelemetryLoggerMiddleware(telemetryClient, logPersonalInformation: true); + + var storageService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.BlobStorage) ?? throw new Exception("Please configure your Azure Storage service in your .bot file."); + var blobStorage = storageService as BlobStorageService; + var transcriptStore = new AzureBlobTranscriptStore(blobStorage.ConnectionString, blobStorage.Container); + var transcriptMiddleware = new TranscriptLoggerMiddleware(transcriptStore); + + var typingMiddleware = new ShowTypingMiddleware(); + var setLocaleMiddleware = new SetLocaleMiddleware(defaultLocale ?? "en-us"); + var eventDebuggerMiddleware = new EventDebuggerMiddleware(); + var autoSaveStateMiddleware = new AutoSaveStateMiddleware(userState, conversationState); + + Func onTurnError = async (context, exception) => + { + await context.SendActivityAsync(MainStrings.ERROR); + await context.SendActivityAsync(new Activity(type: ActivityTypes.Trace, text: $"News Skill Error: {exception.Message} | {exception.StackTrace}")); + telemetryClient.TrackExceptionEx(exception, context.Activity); + }; - // Catches any errors that occur during a conversation turn and logs them to AppInsights. - options.OnTurnError = async (context, exception) => + // Add the http adapter with middlewares + services.AddTransient(sp => + { + var botFrameworkHttpAdapter = new BotFrameworkHttpAdapter(credentialProvider) { - await context.SendActivityAsync(MainStrings.ERROR); - await context.SendActivityAsync(new Activity(type: ActivityTypes.Trace, text: $"News Skill Error: {exception.Message} | {exception.StackTrace}")); - telemetryClient.TrackExceptionEx(exception, context.Activity); + OnTurnError = onTurnError }; - // Transcript Middleware (saves conversation history in a standard format) - var storageService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.BlobStorage) ?? throw new Exception("Please configure your Azure Storage service in your .bot file."); - var blobStorage = storageService as BlobStorageService; - var transcriptStore = new AzureBlobTranscriptStore(blobStorage.ConnectionString, blobStorage.Container); - var transcriptMiddleware = new TranscriptLoggerMiddleware(transcriptStore); - options.Middleware.Add(transcriptMiddleware); + botFrameworkHttpAdapter.Use(appInsightsLogger); + botFrameworkHttpAdapter.Use(transcriptMiddleware); + botFrameworkHttpAdapter.Use(typingMiddleware); + botFrameworkHttpAdapter.Use(setLocaleMiddleware); + botFrameworkHttpAdapter.Use(eventDebuggerMiddleware); + botFrameworkHttpAdapter.Use(autoSaveStateMiddleware); + + return botFrameworkHttpAdapter; + }); + + // Add the SkillAdapter with middlewares + services.AddTransient(sp => + { + var skillAdapter = new SkillAdapter(credentialProvider) + { + OnTurnError = onTurnError + }; - // Typing Middleware (automatically shows typing when the bot is responding/working) - var typingMiddleware = new ShowTypingMiddleware(); - options.Middleware.Add(typingMiddleware); + skillAdapter.Use(appInsightsLogger); + skillAdapter.Use(transcriptMiddleware); + skillAdapter.Use(typingMiddleware); + skillAdapter.Use(setLocaleMiddleware); + skillAdapter.Use(eventDebuggerMiddleware); + skillAdapter.Use(autoSaveStateMiddleware); - options.Middleware.Add(new AutoSaveStateMiddleware(userState, conversationState)); + return skillAdapter; }); } diff --git a/solutions/Virtual-Assistant/src/csharp/experimental/skills/restaurantbooking/Controllers/BotController.cs b/solutions/Virtual-Assistant/src/csharp/experimental/skills/restaurantbooking/Controllers/BotController.cs index 3524a20bba..c1de1bf48f 100644 --- a/solutions/Virtual-Assistant/src/csharp/experimental/skills/restaurantbooking/Controllers/BotController.cs +++ b/solutions/Virtual-Assistant/src/csharp/experimental/skills/restaurantbooking/Controllers/BotController.cs @@ -1,6 +1,6 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Bot.Builder; -using Microsoft.Bot.Builder.Integration; +using Microsoft.Bot.Builder.Integration.AspNet.Core; using Microsoft.Bot.Builder.Skills; namespace RestaurantBooking.Controllers @@ -8,8 +8,8 @@ namespace RestaurantBooking.Controllers [ApiController] public class BotController : SkillController { - public BotController(IAdapterIntegration adapter, ISkillAdapter skillAdapter, IBot bot) - : base(adapter, skillAdapter, bot) + public BotController(IBotFrameworkHttpAdapter botFrameworkHttpAdapter, SkillAdapter skillAdapter, IBot bot) + : base(botFrameworkHttpAdapter, skillAdapter, bot) { } } diff --git a/solutions/Virtual-Assistant/src/csharp/experimental/skills/restaurantbooking/RestaurantBooking.csproj b/solutions/Virtual-Assistant/src/csharp/experimental/skills/restaurantbooking/RestaurantBooking.csproj index ef399ad80c..fa273a7951 100644 --- a/solutions/Virtual-Assistant/src/csharp/experimental/skills/restaurantbooking/RestaurantBooking.csproj +++ b/solutions/Virtual-Assistant/src/csharp/experimental/skills/restaurantbooking/RestaurantBooking.csproj @@ -38,7 +38,7 @@ - + diff --git a/solutions/Virtual-Assistant/src/csharp/experimental/skills/restaurantbooking/Startup.cs b/solutions/Virtual-Assistant/src/csharp/experimental/skills/restaurantbooking/Startup.cs index 71ca6d0eb3..35445f7044 100644 --- a/solutions/Virtual-Assistant/src/csharp/experimental/skills/restaurantbooking/Startup.cs +++ b/solutions/Virtual-Assistant/src/csharp/experimental/skills/restaurantbooking/Startup.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; @@ -12,6 +13,7 @@ using Microsoft.Bot.Builder.Integration.ApplicationInsights.Core; using Microsoft.Bot.Builder.Integration.AspNet.Core; using Microsoft.Bot.Builder.Skills; +using Microsoft.Bot.Builder.Solutions.Middleware; using Microsoft.Bot.Builder.Solutions.Proactive; using Microsoft.Bot.Builder.Solutions.Responses; using Microsoft.Bot.Builder.Solutions.Skills; @@ -53,8 +55,6 @@ public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_2_2); - services.AddSingleton(); - // add background task queue services.AddSingleton(); services.AddHostedService(); @@ -86,6 +86,8 @@ public void ConfigureServices(IServiceCollection services) // Register bot responses for all supported languages. services.AddSingleton(sp => responseManager); + var defaultLocale = Configuration.GetSection("defaultLocale").Get(); + // Initialize Bot State var cosmosDbService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.CosmosDB) ?? throw new Exception("Please configure your CosmosDb service in your .bot file."); var cosmosDb = cosmosDbService as CosmosDbService; @@ -122,37 +124,66 @@ public void ConfigureServices(IServiceCollection services) // HttpContext required for path resolution services.AddSingleton(); - // Add the bot with options - services.AddBot(options => - { - options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword); + // Add the bot + services.AddTransient(); + + var credentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword); - // Telemetry Middleware (logs activity messages in Application Insights) - var sp = services.BuildServiceProvider(); - var telemetryClient = sp.GetService(); - var appInsightsLogger = new TelemetryLoggerMiddleware(telemetryClient, logPersonalInformation: true); - options.Middleware.Add(appInsightsLogger); + // Create the middlewares + var telemetryClient = services.BuildServiceProvider().GetService(); + var appInsightsLogger = new TelemetryLoggerMiddleware(telemetryClient, logPersonalInformation: true); + + var storageService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.BlobStorage) ?? throw new Exception("Please configure your Azure Storage service in your .bot file."); + var blobStorage = storageService as BlobStorageService; + var transcriptStore = new AzureBlobTranscriptStore(blobStorage.ConnectionString, blobStorage.Container); + var transcriptMiddleware = new TranscriptLoggerMiddleware(transcriptStore); + + var typingMiddleware = new ShowTypingMiddleware(); + var setLocaleMiddleware = new SetLocaleMiddleware(defaultLocale ?? "en-us"); + var eventDebuggerMiddleware = new EventDebuggerMiddleware(); + var autoSaveStateMiddleware = new AutoSaveStateMiddleware(userState, conversationState); + + Func onTurnError = async (context, exception) => + { + await context.SendActivityAsync(context.Activity.CreateReply(RestaurantBookingSharedResponses.ErrorMessage)); + await context.SendActivityAsync(new Activity(type: ActivityTypes.Trace, text: $"Skill Error: {exception.Message} | {exception.StackTrace}")); + telemetryClient.TrackExceptionEx(exception, context.Activity); + }; - // Catches any errors that occur during a conversation turn and logs them to AppInsights. - options.OnTurnError = async (context, exception) => + // Add the http adapter with middlewares + services.AddTransient(sp => + { + var botFrameworkHttpAdapter = new BotFrameworkHttpAdapter(credentialProvider) { - await context.SendActivityAsync(context.Activity.CreateReply(RestaurantBookingSharedResponses.ErrorMessage)); - await context.SendActivityAsync(new Activity(type: ActivityTypes.Trace, text: $"Skill Error: {exception.Message} | {exception.StackTrace}")); - telemetryClient.TrackExceptionEx(exception, context.Activity); + OnTurnError = onTurnError }; - // Transcript Middleware (saves conversation history in a standard format) - var storageService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.BlobStorage) ?? throw new Exception("Please configure your Azure Storage service in your .bot file."); - var blobStorage = storageService as BlobStorageService; - var transcriptStore = new AzureBlobTranscriptStore(blobStorage.ConnectionString, blobStorage.Container); - var transcriptMiddleware = new TranscriptLoggerMiddleware(transcriptStore); - options.Middleware.Add(transcriptMiddleware); + botFrameworkHttpAdapter.Use(appInsightsLogger); + botFrameworkHttpAdapter.Use(transcriptMiddleware); + botFrameworkHttpAdapter.Use(typingMiddleware); + botFrameworkHttpAdapter.Use(setLocaleMiddleware); + botFrameworkHttpAdapter.Use(eventDebuggerMiddleware); + botFrameworkHttpAdapter.Use(autoSaveStateMiddleware); + + return botFrameworkHttpAdapter; + }); + + // Add the SkillAdapter with middlewares + services.AddTransient(sp => + { + var skillAdapter = new SkillAdapter(credentialProvider) + { + OnTurnError = onTurnError + }; - // Typing Middleware (automatically shows typing when the bot is responding/working) - var typingMiddleware = new ShowTypingMiddleware(); - options.Middleware.Add(typingMiddleware); + skillAdapter.Use(appInsightsLogger); + skillAdapter.Use(transcriptMiddleware); + skillAdapter.Use(typingMiddleware); + skillAdapter.Use(setLocaleMiddleware); + skillAdapter.Use(eventDebuggerMiddleware); + skillAdapter.Use(autoSaveStateMiddleware); - options.Middleware.Add(new AutoSaveStateMiddleware(userState, conversationState)); + return skillAdapter; }); } diff --git a/solutions/Virtual-Assistant/src/csharp/skills/automotiveskill/automotiveskill/AutomotiveSkill.csproj b/solutions/Virtual-Assistant/src/csharp/skills/automotiveskill/automotiveskill/AutomotiveSkill.csproj index 3cf7d8eac7..907d8e5158 100644 --- a/solutions/Virtual-Assistant/src/csharp/skills/automotiveskill/automotiveskill/AutomotiveSkill.csproj +++ b/solutions/Virtual-Assistant/src/csharp/skills/automotiveskill/automotiveskill/AutomotiveSkill.csproj @@ -8,7 +8,7 @@ - + diff --git a/solutions/Virtual-Assistant/src/csharp/skills/automotiveskill/automotiveskill/Controllers/BotController.cs b/solutions/Virtual-Assistant/src/csharp/skills/automotiveskill/automotiveskill/Controllers/BotController.cs index 1f4c0a6219..8603160d63 100644 --- a/solutions/Virtual-Assistant/src/csharp/skills/automotiveskill/automotiveskill/Controllers/BotController.cs +++ b/solutions/Virtual-Assistant/src/csharp/skills/automotiveskill/automotiveskill/Controllers/BotController.cs @@ -1,6 +1,6 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Bot.Builder; -using Microsoft.Bot.Builder.Integration; +using Microsoft.Bot.Builder.Integration.AspNet.Core; using Microsoft.Bot.Builder.Skills; namespace AutomotiveSkill.Controllers @@ -8,8 +8,8 @@ namespace AutomotiveSkill.Controllers [ApiController] public class BotController : SkillController { - public BotController(IAdapterIntegration adapter, ISkillAdapter skillAdapter, IBot bot) - : base(adapter, skillAdapter, bot) + public BotController(IBotFrameworkHttpAdapter botFrameworkHttpAdapter, SkillAdapter skillAdapter, IBot bot) + : base(botFrameworkHttpAdapter, skillAdapter, bot) { } } diff --git a/solutions/Virtual-Assistant/src/csharp/skills/automotiveskill/automotiveskill/Startup.cs b/solutions/Virtual-Assistant/src/csharp/skills/automotiveskill/automotiveskill/Startup.cs index 3b4cd21ef4..e9ef44ce3f 100644 --- a/solutions/Virtual-Assistant/src/csharp/skills/automotiveskill/automotiveskill/Startup.cs +++ b/solutions/Virtual-Assistant/src/csharp/skills/automotiveskill/automotiveskill/Startup.cs @@ -6,6 +6,7 @@ namespace AutomotiveSkill using System; using System.Collections.Generic; using System.Linq; + using System.Threading.Tasks; using global::AutomotiveSkill.Dialogs.Main.Resources; using global::AutomotiveSkill.Dialogs.Shared.Resources; using global::AutomotiveSkill.Dialogs.VehicleSettings.Resources; @@ -18,6 +19,7 @@ namespace AutomotiveSkill using Microsoft.Bot.Builder.Integration.ApplicationInsights.Core; using Microsoft.Bot.Builder.Integration.AspNet.Core; using Microsoft.Bot.Builder.Skills; + using Microsoft.Bot.Builder.Solutions.Middleware; using Microsoft.Bot.Builder.Solutions.Proactive; using Microsoft.Bot.Builder.Solutions.Responses; using Microsoft.Bot.Builder.Solutions.Skills; @@ -55,8 +57,6 @@ public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_2_2); - services.AddSingleton(); - // add background task queue services.AddSingleton(); services.AddHostedService(); @@ -88,6 +88,8 @@ public void ConfigureServices(IServiceCollection services) // Register bot responses for all supported languages. services.AddSingleton(sp => responseManager); + var defaultLocale = Configuration.GetSection("defaultLocale").Get(); + // Initialize Bot State var cosmosDbService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.CosmosDB) ?? throw new Exception("Please configure your CosmosDb service in your .bot file."); var cosmosDb = cosmosDbService as CosmosDbService; @@ -124,37 +126,66 @@ public void ConfigureServices(IServiceCollection services) // HttpContext required for path resolution services.AddSingleton(); - // Add the bot with options - services.AddBot(options => - { - options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword); + // Add the bot + services.AddTransient(); + + var credentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword); - // Telemetry Middleware (logs activity messages in Application Insights) - var sp = services.BuildServiceProvider(); - var telemetryClient = sp.GetService(); - var appInsightsLogger = new TelemetryLoggerMiddleware(telemetryClient, logPersonalInformation: true); - options.Middleware.Add(appInsightsLogger); + // Create the middlewares + var telemetryClient = services.BuildServiceProvider().GetService(); + var appInsightsLogger = new TelemetryLoggerMiddleware(telemetryClient, logPersonalInformation: true); + + var storageService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.BlobStorage) ?? throw new Exception("Please configure your Azure Storage service in your .bot file."); + var blobStorage = storageService as BlobStorageService; + var transcriptStore = new AzureBlobTranscriptStore(blobStorage.ConnectionString, blobStorage.Container); + var transcriptMiddleware = new TranscriptLoggerMiddleware(transcriptStore); + + var typingMiddleware = new ShowTypingMiddleware(); + var setLocaleMiddleware = new SetLocaleMiddleware(defaultLocale ?? "en-us"); + var eventDebuggerMiddleware = new EventDebuggerMiddleware(); + var autoSaveStateMiddleware = new AutoSaveStateMiddleware(userState, conversationState); + + Func onTurnError = async (context, exception) => + { + await context.SendActivityAsync(responseManager.GetResponse(AutomotiveSkillSharedResponses.ErrorMessage)); + await context.SendActivityAsync(new Activity(type: ActivityTypes.Trace, text: $"Skill Error: {exception.Message} | {exception.StackTrace}")); + telemetryClient.TrackExceptionEx(exception, context.Activity); + }; - // Catches any errors that occur during a conversation turn and logs them to AppInsights. - options.OnTurnError = async (context, exception) => + // Add the http adapter with middlewares + services.AddTransient((sp) => + { + var botFrameworkHttpAdapter = new BotFrameworkHttpAdapter(credentialProvider) { - await context.SendActivityAsync(responseManager.GetResponse(AutomotiveSkillSharedResponses.ErrorMessage)); - await context.SendActivityAsync(new Activity(type: ActivityTypes.Trace, text: $"Skill Error: {exception.Message} | {exception.StackTrace}")); - telemetryClient.TrackExceptionEx(exception, context.Activity); + OnTurnError = onTurnError }; - // Transcript Middleware (saves conversation history in a standard format) - var storageService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.BlobStorage) ?? throw new Exception("Please configure your Azure Storage service in your .bot file."); - var blobStorage = storageService as BlobStorageService; - var transcriptStore = new AzureBlobTranscriptStore(blobStorage.ConnectionString, blobStorage.Container); - var transcriptMiddleware = new TranscriptLoggerMiddleware(transcriptStore); - options.Middleware.Add(transcriptMiddleware); + botFrameworkHttpAdapter.Use(appInsightsLogger); + botFrameworkHttpAdapter.Use(transcriptMiddleware); + botFrameworkHttpAdapter.Use(typingMiddleware); + botFrameworkHttpAdapter.Use(setLocaleMiddleware); + botFrameworkHttpAdapter.Use(eventDebuggerMiddleware); + botFrameworkHttpAdapter.Use(autoSaveStateMiddleware); + + return botFrameworkHttpAdapter; + }); + + // Add the SkillAdapter with middlewares + services.AddTransient(sp => + { + var skillAdapter = new SkillAdapter(credentialProvider) + { + OnTurnError = onTurnError + }; - // Typing Middleware (automatically shows typing when the bot is responding/working) - var typingMiddleware = new ShowTypingMiddleware(); - options.Middleware.Add(typingMiddleware); + skillAdapter.Use(appInsightsLogger); + skillAdapter.Use(transcriptMiddleware); + skillAdapter.Use(typingMiddleware); + skillAdapter.Use(setLocaleMiddleware); + skillAdapter.Use(eventDebuggerMiddleware); + skillAdapter.Use(autoSaveStateMiddleware); - options.Middleware.Add(new AutoSaveStateMiddleware(userState, conversationState)); + return skillAdapter; }); } diff --git a/solutions/Virtual-Assistant/src/csharp/skills/automotiveskill/automotiveskilltest/AutomotiveSkillTest.csproj b/solutions/Virtual-Assistant/src/csharp/skills/automotiveskill/automotiveskilltest/AutomotiveSkillTest.csproj index e9d872d6d0..bd971cd05c 100644 --- a/solutions/Virtual-Assistant/src/csharp/skills/automotiveskill/automotiveskilltest/AutomotiveSkillTest.csproj +++ b/solutions/Virtual-Assistant/src/csharp/skills/automotiveskill/automotiveskilltest/AutomotiveSkillTest.csproj @@ -13,7 +13,7 @@ - + diff --git a/solutions/Virtual-Assistant/src/csharp/skills/calendarskill/calendarskill/CalendarSkill.csproj b/solutions/Virtual-Assistant/src/csharp/skills/calendarskill/calendarskill/CalendarSkill.csproj index 5b713894e0..4b6d793c6d 100644 --- a/solutions/Virtual-Assistant/src/csharp/skills/calendarskill/calendarskill/CalendarSkill.csproj +++ b/solutions/Virtual-Assistant/src/csharp/skills/calendarskill/calendarskill/CalendarSkill.csproj @@ -13,7 +13,7 @@ - + diff --git a/solutions/Virtual-Assistant/src/csharp/skills/calendarskill/calendarskill/Controllers/BotController.cs b/solutions/Virtual-Assistant/src/csharp/skills/calendarskill/calendarskill/Controllers/BotController.cs index 22d0ffcce9..4701510e8e 100644 --- a/solutions/Virtual-Assistant/src/csharp/skills/calendarskill/calendarskill/Controllers/BotController.cs +++ b/solutions/Virtual-Assistant/src/csharp/skills/calendarskill/calendarskill/Controllers/BotController.cs @@ -1,6 +1,6 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Bot.Builder; -using Microsoft.Bot.Builder.Integration; +using Microsoft.Bot.Builder.Integration.AspNet.Core; using Microsoft.Bot.Builder.Skills; namespace CalendarSkill.Controllers @@ -8,16 +8,9 @@ namespace CalendarSkill.Controllers [ApiController] public class BotController : SkillController { - private readonly IAdapterIntegration _adapter; - private readonly ISkillAdapter _skillAdapter; - private readonly IBot _bot; - - public BotController(IAdapterIntegration adapter, ISkillAdapter skillAdapter, IBot bot) - : base(adapter, skillAdapter, bot) + public BotController(IBotFrameworkHttpAdapter botFrameworkHttpAdapter, SkillAdapter skillAdapter, IBot bot) + : base(botFrameworkHttpAdapter, skillAdapter, bot) { - _adapter = adapter; - _skillAdapter = skillAdapter; - _bot = bot; } } } \ No newline at end of file diff --git a/solutions/Virtual-Assistant/src/csharp/skills/calendarskill/calendarskill/Startup.cs b/solutions/Virtual-Assistant/src/csharp/skills/calendarskill/calendarskill/Startup.cs index 1963a84acc..42a42fa649 100644 --- a/solutions/Virtual-Assistant/src/csharp/skills/calendarskill/calendarskill/Startup.cs +++ b/solutions/Virtual-Assistant/src/csharp/skills/calendarskill/calendarskill/Startup.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Threading.Tasks; using CalendarSkill.Dialogs.ChangeEventStatus.Resources; using CalendarSkill.Dialogs.CreateEvent.Resources; using CalendarSkill.Dialogs.FindContact.Resources; @@ -57,8 +58,6 @@ public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_2_2); - services.AddSingleton(); - // add background task queue services.AddSingleton(); services.AddHostedService(); @@ -96,6 +95,8 @@ public void ConfigureServices(IServiceCollection services) // Register bot responses for all supported languages. services.AddSingleton(sp => responseManager); + var defaultLocale = Configuration.GetSection("defaultLocale").Get(); + // Initialize Bot State var cosmosDbService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.CosmosDB) ?? throw new Exception("Please configure your CosmosDb service in your .bot file."); var cosmosDb = cosmosDbService as CosmosDbService; @@ -129,41 +130,67 @@ public void ConfigureServices(IServiceCollection services) // Initialize calendar service client services.AddSingleton(); - // Add the bot with options - services.AddBot(options => - { - options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword); + // Add the bot + services.AddTransient(); + + var credentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword); - // Telemetry Middleware (logs activity messages in Application Insights) - var sp = services.BuildServiceProvider(); - var telemetryClient = sp.GetService(); - var appInsightsLogger = new TelemetryLoggerMiddleware(telemetryClient, logPersonalInformation: true); - options.Middleware.Add(appInsightsLogger); + // Create the middlewares + var telemetryClient = services.BuildServiceProvider().GetService(); + var appInsightsLogger = new TelemetryLoggerMiddleware(telemetryClient, logPersonalInformation: true); - // Catches any errors that occur during a conversation turn and logs them to AppInsights. - options.OnTurnError = async (context, exception) => + var storageService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.BlobStorage) ?? throw new Exception("Please configure your Azure Storage service in your .bot file."); + var blobStorage = storageService as BlobStorageService; + var transcriptStore = new AzureBlobTranscriptStore(blobStorage.ConnectionString, blobStorage.Container); + var transcriptMiddleware = new TranscriptLoggerMiddleware(transcriptStore); + + var typingMiddleware = new ShowTypingMiddleware(); + var setLocaleMiddleware = new SetLocaleMiddleware(defaultLocale ?? "en-us"); + var eventDebuggerMiddleware = new EventDebuggerMiddleware(); + var autoSaveStateMiddleware = new AutoSaveStateMiddleware(userState, conversationState); + + Func onTurnError = async (context, exception) => + { + CultureInfo.CurrentUICulture = new CultureInfo(context.Activity.Locale); + await context.SendActivityAsync(responseManager.GetResponse(CalendarSharedResponses.CalendarErrorMessage)); + await context.SendActivityAsync(new Activity(type: ActivityTypes.Trace, text: $"Calendar Skill Error: {exception.Message} | {exception.StackTrace}")); + telemetryClient.TrackExceptionEx(exception, context.Activity); + }; + + // Add the http adapter with middlewares + services.AddTransient(sp => + { + var botFrameworkHttpAdapter = new BotFrameworkHttpAdapter(credentialProvider) { - CultureInfo.CurrentUICulture = new CultureInfo(context.Activity.Locale); - await context.SendActivityAsync(responseManager.GetResponse(CalendarSharedResponses.CalendarErrorMessage)); - await context.SendActivityAsync(new Activity(type: ActivityTypes.Trace, text: $"Calendar Skill Error: {exception.Message} | {exception.StackTrace}")); - telemetryClient.TrackExceptionEx(exception, context.Activity); + OnTurnError = onTurnError }; - // Transcript Middleware (saves conversation history in a standard format) - var storageService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.BlobStorage) ?? throw new Exception("Please configure your Azure Storage service in your .bot file."); - var blobStorage = storageService as BlobStorageService; - var transcriptStore = new AzureBlobTranscriptStore(blobStorage.ConnectionString, blobStorage.Container); - var transcriptMiddleware = new TranscriptLoggerMiddleware(transcriptStore); - options.Middleware.Add(transcriptMiddleware); + botFrameworkHttpAdapter.Use(appInsightsLogger); + botFrameworkHttpAdapter.Use(transcriptMiddleware); + botFrameworkHttpAdapter.Use(typingMiddleware); + botFrameworkHttpAdapter.Use(setLocaleMiddleware); + botFrameworkHttpAdapter.Use(eventDebuggerMiddleware); + botFrameworkHttpAdapter.Use(autoSaveStateMiddleware); + + return botFrameworkHttpAdapter; + }); - // Typing Middleware (automatically shows typing when the bot is responding/working) - var typingMiddleware = new ShowTypingMiddleware(); - options.Middleware.Add(typingMiddleware); + // Add the SkillAdapter with middlewares + services.AddTransient(sp => + { + var skillAdapter = new SkillAdapter(credentialProvider) + { + OnTurnError = onTurnError + }; - options.Middleware.Add(new AutoSaveStateMiddleware(userState, conversationState)); + skillAdapter.Use(appInsightsLogger); + skillAdapter.Use(transcriptMiddleware); + skillAdapter.Use(typingMiddleware); + skillAdapter.Use(setLocaleMiddleware); + skillAdapter.Use(eventDebuggerMiddleware); + skillAdapter.Use(autoSaveStateMiddleware); - var defaultLocale = Configuration.GetSection("defaultLocale").Get(); - options.Middleware.Add(new SetLocaleMiddleware(defaultLocale ?? "en")); + return skillAdapter; }); } diff --git a/solutions/Virtual-Assistant/src/csharp/skills/calendarskill/calendarskilltest/CalendarSkillTest.csproj b/solutions/Virtual-Assistant/src/csharp/skills/calendarskill/calendarskilltest/CalendarSkillTest.csproj index 4b007e5153..04cbd214be 100644 --- a/solutions/Virtual-Assistant/src/csharp/skills/calendarskill/calendarskilltest/CalendarSkillTest.csproj +++ b/solutions/Virtual-Assistant/src/csharp/skills/calendarskill/calendarskilltest/CalendarSkillTest.csproj @@ -15,7 +15,7 @@ - + diff --git a/solutions/Virtual-Assistant/src/csharp/skills/emailskill/emailskill/Controllers/BotController.cs b/solutions/Virtual-Assistant/src/csharp/skills/emailskill/emailskill/Controllers/BotController.cs index 57e94cfc89..1be2d2c40c 100644 --- a/solutions/Virtual-Assistant/src/csharp/skills/emailskill/emailskill/Controllers/BotController.cs +++ b/solutions/Virtual-Assistant/src/csharp/skills/emailskill/emailskill/Controllers/BotController.cs @@ -1,6 +1,6 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Bot.Builder; -using Microsoft.Bot.Builder.Integration; +using Microsoft.Bot.Builder.Integration.AspNet.Core; using Microsoft.Bot.Builder.Skills; namespace EmailSkill.Controllers @@ -8,8 +8,8 @@ namespace EmailSkill.Controllers [ApiController] public class BotController : SkillController { - public BotController(IAdapterIntegration adapter, ISkillAdapter skillAdapter, IBot bot) - : base(adapter, skillAdapter, bot) + public BotController(IBotFrameworkHttpAdapter botFrameworkHttpAdapter, SkillAdapter skillAdapter, IBot bot) + : base(botFrameworkHttpAdapter, skillAdapter, bot) { } } diff --git a/solutions/Virtual-Assistant/src/csharp/skills/emailskill/emailskill/EmailSkill.csproj b/solutions/Virtual-Assistant/src/csharp/skills/emailskill/emailskill/EmailSkill.csproj index 856d807ebc..bd61395c68 100644 --- a/solutions/Virtual-Assistant/src/csharp/skills/emailskill/emailskill/EmailSkill.csproj +++ b/solutions/Virtual-Assistant/src/csharp/skills/emailskill/emailskill/EmailSkill.csproj @@ -11,7 +11,7 @@ - + diff --git a/solutions/Virtual-Assistant/src/csharp/skills/emailskill/emailskill/Startup.cs b/solutions/Virtual-Assistant/src/csharp/skills/emailskill/emailskill/Startup.cs index 2561bd9ba4..caec0a751c 100644 --- a/solutions/Virtual-Assistant/src/csharp/skills/emailskill/emailskill/Startup.cs +++ b/solutions/Virtual-Assistant/src/csharp/skills/emailskill/emailskill/Startup.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Threading.Tasks; using EmailSkill.Dialogs.DeleteEmail.Resources; using EmailSkill.Dialogs.FindContact.Resources; using EmailSkill.Dialogs.ForwardEmail.Resources; @@ -56,8 +57,6 @@ public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_2_2); - services.AddSingleton(); - // add background task queue services.AddSingleton(); services.AddHostedService(); @@ -129,38 +128,67 @@ public void ConfigureServices(IServiceCollection services) // Initialize Email client services.AddSingleton(); - // Add the bot with options - services.AddBot(options => + // Add the bot + services.AddTransient(); + + var credentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword); + + // Create the middlewares + var telemetryClient = services.BuildServiceProvider().GetService(); + var appInsightsLogger = new TelemetryLoggerMiddleware(telemetryClient, logPersonalInformation: true); + + var storageService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.BlobStorage) ?? throw new Exception("Please configure your Azure Storage service in your .bot file."); + var blobStorage = storageService as BlobStorageService; + var transcriptStore = new AzureBlobTranscriptStore(blobStorage.ConnectionString, blobStorage.Container); + var transcriptMiddleware = new TranscriptLoggerMiddleware(transcriptStore); + + var typingMiddleware = new ShowTypingMiddleware(); + var setLocaleMiddleware = new SetLocaleMiddleware(defaultLocale ?? "en-us"); + var eventDebuggerMiddleware = new EventDebuggerMiddleware(); + var autoSaveStateMiddleware = new AutoSaveStateMiddleware(userState, conversationState); + + Func onTurnError = async (context, exception) => { - options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword); + CultureInfo.CurrentUICulture = new CultureInfo(context.Activity.Locale); + await context.SendActivityAsync(responseManager.GetResponse(EmailSharedResponses.EmailErrorMessage)); + await context.SendActivityAsync(new Activity(type: ActivityTypes.Trace, text: $"Email Skill Error: {exception.Message} | {exception.StackTrace}")); + telemetryClient.TrackExceptionEx(exception, context.Activity); + }; - // Telemetry Middleware (logs activity messages in Application Insights) - var sp = services.BuildServiceProvider(); - var telemetryClient = sp.GetService(); - var appInsightsLogger = new TelemetryLoggerMiddleware(telemetryClient, logPersonalInformation: true); - options.Middleware.Add(appInsightsLogger); + // Add the http adapter with middlewares + services.AddTransient(sp => + { + var botFrameworkHttpAdapter = new BotFrameworkHttpAdapter(credentialProvider) + { + OnTurnError = onTurnError + }; - // Catches any errors that occur during a conversation turn and logs them to AppInsights. - options.OnTurnError = async (context, exception) => + botFrameworkHttpAdapter.Use(appInsightsLogger); + botFrameworkHttpAdapter.Use(transcriptMiddleware); + botFrameworkHttpAdapter.Use(typingMiddleware); + botFrameworkHttpAdapter.Use(setLocaleMiddleware); + botFrameworkHttpAdapter.Use(eventDebuggerMiddleware); + botFrameworkHttpAdapter.Use(autoSaveStateMiddleware); + + return botFrameworkHttpAdapter; + }); + + // Add the SkillAdapter with middlewares + services.AddTransient(sp => + { + var skillAdapter = new SkillAdapter(credentialProvider) { - CultureInfo.CurrentUICulture = new CultureInfo(context.Activity.Locale); - await context.SendActivityAsync(responseManager.GetResponse(EmailSharedResponses.EmailErrorMessage)); - await context.SendActivityAsync(new Activity(type: ActivityTypes.Trace, text: $"Email Skill Error: {exception.Message} | {exception.StackTrace}")); - telemetryClient.TrackExceptionEx(exception, context.Activity); + OnTurnError = onTurnError }; - // Transcript Middleware (saves conversation history in a standard format) - var storageService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.BlobStorage) ?? throw new Exception("Please configure your Azure Storage service in your .bot file."); - var blobStorage = storageService as BlobStorageService; - var transcriptStore = new AzureBlobTranscriptStore(blobStorage.ConnectionString, blobStorage.Container); - var transcriptMiddleware = new TranscriptLoggerMiddleware(transcriptStore); - options.Middleware.Add(transcriptMiddleware); - - // Typing Middleware (automatically shows typing when the bot is responding/working) - var typingMiddleware = new ShowTypingMiddleware(); - options.Middleware.Add(typingMiddleware); - options.Middleware.Add(new SetLocaleMiddleware(defaultLocale ?? "en-us")); - options.Middleware.Add(new AutoSaveStateMiddleware(userState, conversationState)); + skillAdapter.Use(appInsightsLogger); + skillAdapter.Use(transcriptMiddleware); + skillAdapter.Use(typingMiddleware); + skillAdapter.Use(setLocaleMiddleware); + skillAdapter.Use(eventDebuggerMiddleware); + skillAdapter.Use(autoSaveStateMiddleware); + + return skillAdapter; }); } diff --git a/solutions/Virtual-Assistant/src/csharp/skills/emailskill/emailskilltest/EmailSkillTest.csproj b/solutions/Virtual-Assistant/src/csharp/skills/emailskill/emailskilltest/EmailSkillTest.csproj index 47001613ee..60497054f8 100644 --- a/solutions/Virtual-Assistant/src/csharp/skills/emailskill/emailskilltest/EmailSkillTest.csproj +++ b/solutions/Virtual-Assistant/src/csharp/skills/emailskill/emailskilltest/EmailSkillTest.csproj @@ -15,7 +15,7 @@ - + diff --git a/solutions/Virtual-Assistant/src/csharp/skills/pointofinterestskill/pointofinterestskill/Controllers/BotController.cs b/solutions/Virtual-Assistant/src/csharp/skills/pointofinterestskill/pointofinterestskill/Controllers/BotController.cs index 8f88c9f862..572860295a 100644 --- a/solutions/Virtual-Assistant/src/csharp/skills/pointofinterestskill/pointofinterestskill/Controllers/BotController.cs +++ b/solutions/Virtual-Assistant/src/csharp/skills/pointofinterestskill/pointofinterestskill/Controllers/BotController.cs @@ -1,6 +1,6 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Bot.Builder; -using Microsoft.Bot.Builder.Integration; +using Microsoft.Bot.Builder.Integration.AspNet.Core; using Microsoft.Bot.Builder.Skills; namespace PointOfInterestSkill.Controllers @@ -8,8 +8,8 @@ namespace PointOfInterestSkill.Controllers [ApiController] public class BotController : SkillController { - public BotController(IAdapterIntegration adapter, ISkillAdapter skillAdapter, IBot bot) - : base(adapter, skillAdapter, bot) + public BotController(IBotFrameworkHttpAdapter botFrameworkHttpAdapter, SkillAdapter skillAdapter, IBot bot) + : base(botFrameworkHttpAdapter, skillAdapter, bot) { } } diff --git a/solutions/Virtual-Assistant/src/csharp/skills/pointofinterestskill/pointofinterestskill/PointOfInterestSkill.csproj b/solutions/Virtual-Assistant/src/csharp/skills/pointofinterestskill/pointofinterestskill/PointOfInterestSkill.csproj index a3f1653758..f03a38189e 100644 --- a/solutions/Virtual-Assistant/src/csharp/skills/pointofinterestskill/pointofinterestskill/PointOfInterestSkill.csproj +++ b/solutions/Virtual-Assistant/src/csharp/skills/pointofinterestskill/pointofinterestskill/PointOfInterestSkill.csproj @@ -8,7 +8,7 @@ - + diff --git a/solutions/Virtual-Assistant/src/csharp/skills/pointofinterestskill/pointofinterestskill/Startup.cs b/solutions/Virtual-Assistant/src/csharp/skills/pointofinterestskill/pointofinterestskill/Startup.cs index ef4c7eba7c..366d066618 100644 --- a/solutions/Virtual-Assistant/src/csharp/skills/pointofinterestskill/pointofinterestskill/Startup.cs +++ b/solutions/Virtual-Assistant/src/csharp/skills/pointofinterestskill/pointofinterestskill/Startup.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; @@ -54,8 +55,6 @@ public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_2_2); - services.AddSingleton(); - // add background task queue services.AddSingleton(); services.AddHostedService(); @@ -88,6 +87,8 @@ public void ConfigureServices(IServiceCollection services) // Register bot responses for all supported languages. services.AddSingleton(sp => responseManager); + var defaultLocale = Configuration.GetSection("defaultLocale").Get(); + // Initialize Bot State var cosmosDbService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.CosmosDB) ?? throw new Exception("Please configure your CosmosDb service in your .bot file."); var cosmosDb = cosmosDbService as CosmosDbService; @@ -123,39 +124,66 @@ public void ConfigureServices(IServiceCollection services) // HttpContext required for path resolution services.AddSingleton(); - // Add the bot with options - services.AddBot(options => - { - options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword); + // Add the bot + services.AddTransient(); + + var credentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword); - // Telemetry Middleware (logs activity messages in Application Insights) - var sp = services.BuildServiceProvider(); - var telemetryClient = sp.GetService(); - var appInsightsLogger = new TelemetryLoggerMiddleware(telemetryClient, logPersonalInformation: true); - options.Middleware.Add(appInsightsLogger); + // Create the middlewares + var telemetryClient = services.BuildServiceProvider().GetService(); + var appInsightsLogger = new TelemetryLoggerMiddleware(telemetryClient, logPersonalInformation: true); + + var storageService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.BlobStorage) ?? throw new Exception("Please configure your Azure Storage service in your .bot file."); + var blobStorage = storageService as BlobStorageService; + var transcriptStore = new AzureBlobTranscriptStore(blobStorage.ConnectionString, blobStorage.Container); + var transcriptMiddleware = new TranscriptLoggerMiddleware(transcriptStore); + + var typingMiddleware = new ShowTypingMiddleware(); + var setLocaleMiddleware = new SetLocaleMiddleware(defaultLocale ?? "en-us"); + var eventDebuggerMiddleware = new EventDebuggerMiddleware(); + var autoSaveStateMiddleware = new AutoSaveStateMiddleware(userState, conversationState); + + Func onTurnError = async (context, exception) => + { + CultureInfo.CurrentUICulture = new CultureInfo(context.Activity.Locale); + await context.SendActivityAsync(responseManager.GetResponse(POISharedResponses.PointOfInterestErrorMessage)); + await context.SendActivityAsync(new Activity(type: ActivityTypes.Trace, text: $"PointOfInterestSkill Error: {exception.Message} | {exception.StackTrace}")); + telemetryClient.TrackExceptionEx(exception, context.Activity); + }; - // Catches any errors that occur during a conversation turn and logs them to AppInsights. - options.OnTurnError = async (context, exception) => + // Add the http adapter with middlewares + services.AddTransient(sp => + { + var botFrameworkHttpAdapter = new BotFrameworkHttpAdapter(credentialProvider) { - CultureInfo.CurrentUICulture = new CultureInfo(context.Activity.Locale); - await context.SendActivityAsync(responseManager.GetResponse(POISharedResponses.PointOfInterestErrorMessage)); - await context.SendActivityAsync(new Activity(type: ActivityTypes.Trace, text: $"PointOfInterestSkill Error: {exception.Message} | {exception.StackTrace}")); - telemetryClient.TrackExceptionEx(exception, context.Activity); + OnTurnError = onTurnError }; - // Transcript Middleware (saves conversation history in a standard format) - var storageService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.BlobStorage) ?? throw new Exception("Please configure your Azure Storage service in your .bot file."); - var blobStorage = storageService as BlobStorageService; - var transcriptStore = new AzureBlobTranscriptStore(blobStorage.ConnectionString, blobStorage.Container); - var transcriptMiddleware = new TranscriptLoggerMiddleware(transcriptStore); - options.Middleware.Add(transcriptMiddleware); + botFrameworkHttpAdapter.Use(appInsightsLogger); + botFrameworkHttpAdapter.Use(transcriptMiddleware); + botFrameworkHttpAdapter.Use(typingMiddleware); + botFrameworkHttpAdapter.Use(setLocaleMiddleware); + botFrameworkHttpAdapter.Use(eventDebuggerMiddleware); + botFrameworkHttpAdapter.Use(autoSaveStateMiddleware); + + return botFrameworkHttpAdapter; + }); + + // Add the SkillAdapter with middlewares + services.AddTransient(sp => + { + var skillAdapter = new SkillAdapter(credentialProvider) + { + OnTurnError = onTurnError + }; - // Typing Middleware (automatically shows typing when the bot is responding/working) - var typingMiddleware = new ShowTypingMiddleware(); - options.Middleware.Add(typingMiddleware); + skillAdapter.Use(appInsightsLogger); + skillAdapter.Use(transcriptMiddleware); + skillAdapter.Use(typingMiddleware); + skillAdapter.Use(eventDebuggerMiddleware); + skillAdapter.Use(autoSaveStateMiddleware); - options.Middleware.Add(new EventDebuggerMiddleware()); - options.Middleware.Add(new AutoSaveStateMiddleware(userState, conversationState)); + return skillAdapter; }); } diff --git a/solutions/Virtual-Assistant/src/csharp/skills/pointofinterestskill/pointofinterestskilltests/PointOfInterestSkillTests.csproj b/solutions/Virtual-Assistant/src/csharp/skills/pointofinterestskill/pointofinterestskilltests/PointOfInterestSkillTests.csproj index 37ead9232e..023f26a651 100644 --- a/solutions/Virtual-Assistant/src/csharp/skills/pointofinterestskill/pointofinterestskilltests/PointOfInterestSkillTests.csproj +++ b/solutions/Virtual-Assistant/src/csharp/skills/pointofinterestskill/pointofinterestskilltests/PointOfInterestSkillTests.csproj @@ -6,7 +6,7 @@ - + diff --git a/solutions/Virtual-Assistant/src/csharp/skills/todoskill/todoskill/Controllers/BotController.cs b/solutions/Virtual-Assistant/src/csharp/skills/todoskill/todoskill/Controllers/BotController.cs index 2a131216da..7956ad6d81 100644 --- a/solutions/Virtual-Assistant/src/csharp/skills/todoskill/todoskill/Controllers/BotController.cs +++ b/solutions/Virtual-Assistant/src/csharp/skills/todoskill/todoskill/Controllers/BotController.cs @@ -1,6 +1,6 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Bot.Builder; -using Microsoft.Bot.Builder.Integration; +using Microsoft.Bot.Builder.Integration.AspNet.Core; using Microsoft.Bot.Builder.Skills; namespace ToDoSkill.Controllers @@ -8,8 +8,8 @@ namespace ToDoSkill.Controllers [ApiController] public class BotController : SkillController { - public BotController(IAdapterIntegration adapter, ISkillAdapter skillAdapter, IBot bot) - : base(adapter, skillAdapter, bot) + public BotController(IBotFrameworkHttpAdapter botFrameworkHttpAdapter, SkillAdapter skillAdapter, IBot bot) + : base(botFrameworkHttpAdapter, skillAdapter, bot) { } } diff --git a/solutions/Virtual-Assistant/src/csharp/skills/todoskill/todoskill/Startup.cs b/solutions/Virtual-Assistant/src/csharp/skills/todoskill/todoskill/Startup.cs index 1175dbaefb..55a3ff9127 100644 --- a/solutions/Virtual-Assistant/src/csharp/skills/todoskill/todoskill/Startup.cs +++ b/solutions/Virtual-Assistant/src/csharp/skills/todoskill/todoskill/Startup.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Bot.Builder; @@ -54,8 +55,6 @@ public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_2_2); - services.AddSingleton(); - // add background task queue services.AddSingleton(); services.AddHostedService(); @@ -124,38 +123,67 @@ public void ConfigureServices(IServiceCollection services) services.AddTransient(); - // Add the bot with options - services.AddBot(options => + // Add the bot + services.AddTransient(); + + var credentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword); + + // Create the middlewares + var telemetryClient = services.BuildServiceProvider().GetService(); + var appInsightsLogger = new TelemetryLoggerMiddleware(telemetryClient, logPersonalInformation: true); + + var storageService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.BlobStorage) ?? throw new Exception("Please configure your Azure Storage service in your .bot file."); + var blobStorage = storageService as BlobStorageService; + var transcriptStore = new AzureBlobTranscriptStore(blobStorage.ConnectionString, blobStorage.Container); + var transcriptMiddleware = new TranscriptLoggerMiddleware(transcriptStore); + + var typingMiddleware = new ShowTypingMiddleware(); + var setLocaleMiddleware = new SetLocaleMiddleware(defaultLocale ?? "en-us"); + var eventDebuggerMiddleware = new EventDebuggerMiddleware(); + var autoSaveStateMiddleware = new AutoSaveStateMiddleware(userState, conversationState); + + Func onTurnError = async (context, exception) => { - options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword); + CultureInfo.CurrentUICulture = new CultureInfo(context.Activity.Locale); + await context.SendActivityAsync(responseManager.GetResponse(ToDoSharedResponses.ToDoErrorMessage)); + await context.SendActivityAsync(new Activity(type: ActivityTypes.Trace, text: $"To Do Skill Error: {exception.Message} | {exception.StackTrace}")); + telemetryClient.TrackExceptionEx(exception, context.Activity); + }; - // Telemetry Middleware (logs activity messages in Application Insights) - var sp = services.BuildServiceProvider(); - var telemetryClient = sp.GetService(); - var appInsightsLogger = new TelemetryLoggerMiddleware(telemetryClient, logPersonalInformation: true); - options.Middleware.Add(appInsightsLogger); + // Add the http adapter with middlewares + services.AddTransient(sp => + { + var botFrameworkHttpAdapter = new BotFrameworkHttpAdapter(credentialProvider) + { + OnTurnError = onTurnError + }; - // Catches any errors that occur during a conversation turn and logs them to AppInsights. - options.OnTurnError = async (context, exception) => + botFrameworkHttpAdapter.Use(appInsightsLogger); + botFrameworkHttpAdapter.Use(transcriptMiddleware); + botFrameworkHttpAdapter.Use(typingMiddleware); + botFrameworkHttpAdapter.Use(setLocaleMiddleware); + botFrameworkHttpAdapter.Use(eventDebuggerMiddleware); + botFrameworkHttpAdapter.Use(autoSaveStateMiddleware); + + return botFrameworkHttpAdapter; + }); + + // Add the SkillAdapter with middlewares + services.AddTransient(sp => + { + var skillAdapter = new SkillAdapter(credentialProvider) { - CultureInfo.CurrentUICulture = new CultureInfo(context.Activity.Locale); - await context.SendActivityAsync(responseManager.GetResponse(ToDoSharedResponses.ToDoErrorMessage)); - await context.SendActivityAsync(new Activity(type: ActivityTypes.Trace, text: $"To Do Skill Error: {exception.Message} | {exception.StackTrace}")); - telemetryClient.TrackExceptionEx(exception, context.Activity); + OnTurnError = onTurnError }; - // Transcript Middleware (saves conversation history in a standard format) - var storageService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.BlobStorage) ?? throw new Exception("Please configure your Azure Storage service in your .bot file."); - var blobStorage = storageService as BlobStorageService; - var transcriptStore = new AzureBlobTranscriptStore(blobStorage.ConnectionString, blobStorage.Container); - var transcriptMiddleware = new TranscriptLoggerMiddleware(transcriptStore); - options.Middleware.Add(transcriptMiddleware); - - // Typing Middleware (automatically shows typing when the bot is responding/working) - var typingMiddleware = new ShowTypingMiddleware(); - options.Middleware.Add(typingMiddleware); - options.Middleware.Add(new SetLocaleMiddleware(defaultLocale ?? "en-us")); - options.Middleware.Add(new AutoSaveStateMiddleware(userState, conversationState)); + skillAdapter.Use(appInsightsLogger); + skillAdapter.Use(transcriptMiddleware); + skillAdapter.Use(typingMiddleware); + skillAdapter.Use(setLocaleMiddleware); + skillAdapter.Use(eventDebuggerMiddleware); + skillAdapter.Use(autoSaveStateMiddleware); + + return skillAdapter; }); } diff --git a/solutions/Virtual-Assistant/src/csharp/skills/todoskill/todoskill/ToDoSkill.csproj b/solutions/Virtual-Assistant/src/csharp/skills/todoskill/todoskill/ToDoSkill.csproj index d48af6026d..bf23066113 100644 --- a/solutions/Virtual-Assistant/src/csharp/skills/todoskill/todoskill/ToDoSkill.csproj +++ b/solutions/Virtual-Assistant/src/csharp/skills/todoskill/todoskill/ToDoSkill.csproj @@ -8,7 +8,7 @@ - + diff --git a/solutions/Virtual-Assistant/src/csharp/skills/todoskill/todoskilltest/ToDoSkillTest.csproj b/solutions/Virtual-Assistant/src/csharp/skills/todoskill/todoskilltest/ToDoSkillTest.csproj index 3187083866..d8bd0ee8ab 100644 --- a/solutions/Virtual-Assistant/src/csharp/skills/todoskill/todoskilltest/ToDoSkillTest.csproj +++ b/solutions/Virtual-Assistant/src/csharp/skills/todoskill/todoskilltest/ToDoSkillTest.csproj @@ -14,7 +14,7 @@ - + diff --git a/solutions/Virtual-Assistant/src/csharp/tests/experimental.skills.tests/Experimental.Skills.Tests.csproj b/solutions/Virtual-Assistant/src/csharp/tests/experimental.skills.tests/Experimental.Skills.Tests.csproj index 49a7ad6b50..7c4766434b 100644 --- a/solutions/Virtual-Assistant/src/csharp/tests/experimental.skills.tests/Experimental.Skills.Tests.csproj +++ b/solutions/Virtual-Assistant/src/csharp/tests/experimental.skills.tests/Experimental.Skills.Tests.csproj @@ -7,7 +7,7 @@ - + diff --git a/solutions/Virtual-Assistant/src/csharp/tests/virtualassistant.tests/VirtualAssistant.Tests.csproj b/solutions/Virtual-Assistant/src/csharp/tests/virtualassistant.tests/VirtualAssistant.Tests.csproj index 941ee079e2..5e99d1f982 100644 --- a/solutions/Virtual-Assistant/src/csharp/tests/virtualassistant.tests/VirtualAssistant.Tests.csproj +++ b/solutions/Virtual-Assistant/src/csharp/tests/virtualassistant.tests/VirtualAssistant.Tests.csproj @@ -7,7 +7,7 @@ - + diff --git a/templates/Virtual-Assistant-Template/VirtualAssistantTemplate/VirtualAssistantTemplate/BotServices.cs b/templates/Virtual-Assistant-Template/VirtualAssistantTemplate/VirtualAssistantTemplate/BotServices.cs index 523fa6bc27..091cb9dac3 100644 --- a/templates/Virtual-Assistant-Template/VirtualAssistantTemplate/VirtualAssistantTemplate/BotServices.cs +++ b/templates/Virtual-Assistant-Template/VirtualAssistantTemplate/VirtualAssistantTemplate/BotServices.cs @@ -28,10 +28,13 @@ public BotServices(BotSettings settings) var dispatchApp = new LuisApplication(config.DispatchModel.AppId, config.DispatchModel.SubscriptionKey, config.DispatchModel.GetEndpoint()); set.DispatchService = new TelemetryLuisRecognizer(dispatchApp); - foreach (var model in config.LanguageModels) + if (config.LanguageModels != null) { - var luisApp = new LuisApplication(model.AppId, model.SubscriptionKey, model.GetEndpoint()); - set.LuisServices.Add(model.Id, new TelemetryLuisRecognizer(luisApp)); + foreach (var model in config.LanguageModels) + { + var luisApp = new LuisApplication(model.AppId, model.SubscriptionKey, model.GetEndpoint()); + set.LuisServices.Add(model.Id, new TelemetryLuisRecognizer(luisApp)); + } } foreach (var kb in config.Knowledgebases) diff --git a/templates/Virtual-Assistant-Template/VirtualAssistantTemplate/VirtualAssistantTemplate/Dialogs/Main/MainDialog.cs b/templates/Virtual-Assistant-Template/VirtualAssistantTemplate/VirtualAssistantTemplate/Dialogs/Main/MainDialog.cs index 7faff42979..e3710b89cc 100644 --- a/templates/Virtual-Assistant-Template/VirtualAssistantTemplate/VirtualAssistantTemplate/Dialogs/Main/MainDialog.cs +++ b/templates/Virtual-Assistant-Template/VirtualAssistantTemplate/VirtualAssistantTemplate/Dialogs/Main/MainDialog.cs @@ -60,6 +60,14 @@ public MainDialog(BotServices services, ConversationState conversationState, Use { var skill = _services.SkillDefinitions.Where(s => s.DispatchIntent == intent.ToString()).First(); await dc.BeginDialogAsync(skill.Name); + + // Pass the activity we have + var result = await dc.ContinueDialogAsync(); + + if (result.Status == DialogTurnStatus.Complete) + { + await CompleteAsync(dc); + } } else if (intent == Dispatch.Intent.l_general) {