#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously public async Task Telemetry_NullTelemetryClient() #pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously { // Arrange / Act // // Note: The TelemetryClient will most likely be DI'd in, and handling a null // TelemetryClient should be handled by placing the NullBotTelemetryClient(). var logger = new TelemetryLoggerMiddleware(null, logPersonalInformation: true); // Assert Assert.NotNull(logger); }
public async Task Telemetry_NullTelemetryClient() { // Arrange / Act // // Note: The TelemetryClient will most likely be DI'd in, and handling a null // TelemetryClient should be handled by placing the NullBotTelemetryClient(). // var logger = new TelemetryLoggerMiddleware(null, logPersonalInformation: true); // Assert Assert.IsNotNull(logger); }
public void ConfigureServices(IServiceCollection services) { // Load the connected services from .bot file. var botFilePath = Configuration.GetSection("botFilePath")?.Value; var botFileSecret = Configuration.GetSection("botFileSecret")?.Value; var botConfig = BotConfiguration.Load(botFilePath ?? @".\ToDoSkill.bot", botFileSecret); services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot config file could not be loaded.")); // Use Application Insights services.AddBotApplicationInsights(botConfig); // Initializes your bot service clients and adds a singleton that your Bot can access through dependency injection. var parameters = Configuration.GetSection("parameters")?.Get <string[]>(); var configuration = Configuration.GetSection("configuration")?.GetChildren()?.ToDictionary(x => x.Key, y => y.Value as object); var supportedProviders = Configuration.GetSection("supportedProviders")?.Get <string[]>(); var languageModels = Configuration.GetSection("languageModels").Get <Dictionary <string, Dictionary <string, string> > >(); ISkillConfiguration connectedServices = new SkillConfiguration(botConfig, languageModels, supportedProviders, parameters, configuration); services.AddSingleton <ISkillConfiguration>(sp => connectedServices); var defaultLocale = Configuration.GetSection("defaultLocale").Get <string>(); // 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; var cosmosOptions = new CosmosDbStorageOptions() { CosmosDBEndpoint = new Uri(cosmosDb.Endpoint), AuthKey = cosmosDb.Key, CollectionId = cosmosDb.Collection, DatabaseId = cosmosDb.Database, }; var dataStore = new CosmosDbStorage(cosmosOptions); var userState = new UserState(dataStore); var conversationState = new ConversationState(dataStore); services.AddSingleton(dataStore); services.AddSingleton(userState); services.AddSingleton(conversationState); services.AddSingleton(new BotStateSet(userState, conversationState)); var serviceProvider = configuration.ContainsKey("TaskServiceProvider") ? configuration["TaskServiceProvider"].ToString() : string.Empty; if (serviceProvider.Equals("Outlook", StringComparison.InvariantCultureIgnoreCase)) { services.AddTransient <ITaskService, OutlookService>(); } else { services.AddTransient <ITaskService, OneNoteService>(); } services.AddTransient <IMailService, MailService>(); // Add the bot with options services.AddBot <ToDoSkill>(options => { // Load the connected services from .bot file. var environment = _isProduction ? "production" : "development"; var service = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.Endpoint && s.Name == environment); if (!(service is EndpointService endpointService)) { throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'."); } options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword); // Telemetry Middleware (logs activity messages in Application Insights) var appInsightsService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.AppInsights) ?? throw new Exception("Please configure your AppInsights connection in your .bot file."); var instrumentationKey = (appInsightsService as AppInsightsService).InstrumentationKey; var sp = services.BuildServiceProvider(); var telemetryClient = sp.GetService <IBotTelemetryClient>(); var appInsightsLogger = new TelemetryLoggerMiddleware(telemetryClient, logUserName: true, logOriginalMessage: true); options.Middleware.Add(appInsightsLogger); // Catches any errors that occur during a conversation turn and logs them to AppInsights. options.OnTurnError = async(context, exception) => { CultureInfo.CurrentUICulture = new CultureInfo(context.Activity.Locale); await context.SendActivityAsync(context.Activity.CreateReply(ToDoSharedResponses.ToDoErrorMessage)); await context.SendActivityAsync(new Activity(type: ActivityTypes.Trace, text: $"To Do Skill Error: {exception.Message} | {exception.StackTrace}")); telemetryClient.TrackException(exception); }; // 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)); }); }
public void ConfigureServices(IServiceCollection services) { // Load the connected services from .bot file. var botFilePath = Configuration.GetSection("botFilePath")?.Value; var botFileSecret = Configuration.GetSection("botFileSecret")?.Value; var botConfig = BotConfiguration.Load(botFilePath, botFileSecret); services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot config file could not be loaded.")); // Get default locale from appsettings.json var defaultLocale = Configuration.GetSection("defaultLocale").Get <string>(); // Use Application Insights services.AddBotApplicationInsights(botConfig); // Initializes your bot service clients and adds a singleton that your Bot can access through dependency injection. var connectedServices = new BotServices(botConfig); services.AddSingleton(sp => connectedServices); // 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; var cosmosOptions = new CosmosDbStorageOptions() { CosmosDBEndpoint = new Uri(cosmosDb.Endpoint), AuthKey = cosmosDb.Key, CollectionId = cosmosDb.Collection, DatabaseId = cosmosDb.Database, }; var dataStore = new CosmosDbStorage(cosmosOptions); var userState = new UserState(dataStore); var conversationState = new ConversationState(dataStore); services.AddSingleton(dataStore); services.AddSingleton(userState); services.AddSingleton(conversationState); services.AddSingleton(new BotStateSet(userState, conversationState)); // Add the bot with options services.AddBot <Kevya>(options => { // Load the connected services from .bot file. var environment = _isProduction ? "production" : "development"; var service = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.Endpoint && s.Name == environment); if (!(service is EndpointService endpointService)) { throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'."); } options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword); // Telemetry Middleware (logs activity messages in Application Insights) var sp = services.BuildServiceProvider(); var telemetryClient = sp.GetService <IBotTelemetryClient>(); var appInsightsLogger = new TelemetryLoggerMiddleware(telemetryClient, logUserName: true, logOriginalMessage: true); options.Middleware.Add(appInsightsLogger); // Catches any errors that occur during a conversation turn and logs them to AppInsights. options.OnTurnError = async(context, exception) => { telemetryClient.TrackException(exception); await context.SendActivityAsync(MainStrings.ERROR); }; // 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) //options.Middleware.Add(new ShowTypingMiddleware()); // Locale Middleware (sets UI culture based on Activity.Locale) options.Middleware.Add(new SetLocaleMiddleware(defaultLocale ?? "en-us")); // Autosave State Middleware (saves bot state after each turn) options.Middleware.Add(new AutoSaveStateMiddleware(userState, conversationState)); }); }
public void ConfigureServices(IServiceCollection services) { // add background task queue services.AddSingleton<IBackgroundTaskQueue, BackgroundTaskQueue>(); services.AddHostedService<QueuedHostedService>(); // Load the connected services from .bot file. var botFilePath = Configuration.GetSection("botFilePath")?.Value; var botFileSecret = Configuration.GetSection("botFileSecret")?.Value; var botConfig = BotConfiguration.Load(botFilePath ?? @".\PointOfInterestSkill.bot", botFileSecret); services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot config file could not be loaded.")); // Use Application Insights services.AddBotApplicationInsights(botConfig); // Initializes your bot service clients and adds a singleton that your Bot can access through dependency injection. var parameters = Configuration.GetSection("parameters")?.Get<string[]>(); var configuration = Configuration.GetSection("configuration")?.GetChildren()?.ToDictionary(x => x.Key, y => y.Value as object); var languageModels = Configuration.GetSection("languageModels").Get<Dictionary<string, Dictionary<string, string>>>(); var connectedServices = new SkillConfiguration(botConfig, languageModels, null, parameters, configuration); services.AddSingleton<SkillConfigurationBase>(sp => connectedServices); var supportedLanguages = languageModels.Select(l => l.Key).ToArray(); var responses = new IResponseIdCollection[] { new CancelRouteResponses(), new FindPointOfInterestResponses(), new POIMainResponses(), new RouteResponses(), new POISharedResponses(), }; var responseManager = new ResponseManager(responses, supportedLanguages); // Register bot responses for all supported languages. services.AddSingleton(sp => responseManager); // 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; var cosmosOptions = new CosmosDbStorageOptions() { CosmosDBEndpoint = new Uri(cosmosDb.Endpoint), AuthKey = cosmosDb.Key, CollectionId = cosmosDb.Collection, DatabaseId = cosmosDb.Database, }; var dataStore = new CosmosDbStorage(cosmosOptions); var userState = new UserState(dataStore); var conversationState = new ConversationState(dataStore); var proactiveState = new ProactiveState(dataStore); services.AddSingleton(dataStore); services.AddSingleton(userState); services.AddSingleton(conversationState); services.AddSingleton(proactiveState); services.AddSingleton(new BotStateSet(userState, conversationState)); var environment = _isProduction ? "production" : "development"; var service = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.Endpoint && s.Name == environment); if (!(service is EndpointService endpointService)) { throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'."); } services.AddSingleton(endpointService); services.AddSingleton<IServiceManager, ServiceManager>(); // Add the bot with options services.AddBot<PointOfInterestSkill>(options => { options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword); // Telemetry Middleware (logs activity messages in Application Insights) var sp = services.BuildServiceProvider(); var telemetryClient = sp.GetService<IBotTelemetryClient>(); var appInsightsLogger = new TelemetryLoggerMiddleware(telemetryClient, logPersonalInformation: true); options.Middleware.Add(appInsightsLogger); // Catches any errors that occur during a conversation turn and logs them to AppInsights. options.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); }; // 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 EventDebuggerMiddleware()); options.Middleware.Add(new AutoSaveStateMiddleware(userState, conversationState)); }); }
public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_2_2); // add background task queue services.AddSingleton <IBackgroundTaskQueue, BackgroundTaskQueue>(); services.AddHostedService <QueuedHostedService>(); // Load the connected services from .bot file. var botFilePath = Configuration.GetSection("botFilePath")?.Value; var botFileSecret = Configuration.GetSection("botFileSecret")?.Value; var botConfig = BotConfiguration.Load(botFilePath ?? @".\automotiveskill.bot", botFileSecret); services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot config file could not be loaded.")); // Use Application Insights services.AddBotApplicationInsights(botConfig); // Initializes your bot service clients and adds a singleton that your Bot can access through dependency injection. var parameters = Configuration.GetSection("Parameters")?.Get <string[]>(); var configuration = Configuration.GetSection("Configuration")?.Get <Dictionary <string, object> >(); var supportedProviders = Configuration.GetSection("SupportedProviders")?.Get <string[]>(); var languageModels = Configuration.GetSection("languageModels").Get <Dictionary <string, Dictionary <string, string> > >(); var connectedServices = new SkillConfiguration(botConfig, languageModels, supportedProviders, parameters, configuration); services.AddSingleton <SkillConfigurationBase>(sp => connectedServices); var supportedLanguages = languageModels.Select(l => l.Key).ToArray(); var responseManager = new ResponseManager( supportedLanguages, new AutomotiveSkillMainResponses(), new AutomotiveSkillSharedResponses(), new VehicleSettingsResponses()); // Register bot responses for all supported languages. services.AddSingleton(sp => responseManager); // 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; var cosmosOptions = new CosmosDbStorageOptions() { CosmosDBEndpoint = new Uri(cosmosDb.Endpoint), AuthKey = cosmosDb.Key, CollectionId = cosmosDb.Collection, DatabaseId = cosmosDb.Database, }; var dataStore = new CosmosDbStorage(cosmosOptions); var userState = new UserState(dataStore); var conversationState = new ConversationState(dataStore); var proactiveState = new ProactiveState(dataStore); services.AddSingleton(dataStore); services.AddSingleton(userState); services.AddSingleton(conversationState); services.AddSingleton(proactiveState); services.AddSingleton(new BotStateSet(userState, conversationState)); var environment = _isProduction ? "production" : "development"; var service = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.Endpoint && s.Name == environment); if (!(service is EndpointService endpointService)) { throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'."); } services.AddSingleton(endpointService); // Initialize service client services.AddSingleton <IServiceManager, ServiceManager>(); // HttpContext required for path resolution services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>(); // Add the bot services.AddSingleton <IBot, AutomotiveSkill>(); // Add the http adapter to enable MVC style bot API services.AddTransient <IBotFrameworkHttpAdapter>((sp) => { var credentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword); // Telemetry Middleware (logs activity messages in Application Insights) var telemetryClient = sp.GetService <IBotTelemetryClient>(); var botFrameworkHttpAdapter = new BotFrameworkHttpAdapter(credentialProvider) { 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); } }; var appInsightsLogger = new TelemetryLoggerMiddleware(telemetryClient, logPersonalInformation: true); botFrameworkHttpAdapter.Use(appInsightsLogger); // 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); botFrameworkHttpAdapter.Use(transcriptMiddleware); // Typing Middleware (automatically shows typing when the bot is responding/working) var typingMiddleware = new ShowTypingMiddleware(); botFrameworkHttpAdapter.Use(typingMiddleware); botFrameworkHttpAdapter.Use(new AutoSaveStateMiddleware(userState, conversationState)); return(botFrameworkHttpAdapter); }); }
/// <summary> /// Initializes a new instance of the <see cref="TelemetryInitializerMiddleware"/> class. /// </summary> /// <param name="httpContextAccessor">The IHttpContextAccessor to allow access to the HttpContext.</param> /// <param name="telemetryLoggerMiddleware">The TelemetryLoggerMiddleware to allow for logging of activity events.</param> /// <param name="logActivityTelemetry">Indicates if the TelemetryLoggerMiddleware should be executed to log activity events.</param> public TelemetryInitializerMiddleware(IHttpContextAccessor httpContextAccessor, TelemetryLoggerMiddleware telemetryLoggerMiddleware, bool logActivityTelemetry = true) { _httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor)); _telemetryLoggerMiddleware = telemetryLoggerMiddleware; _logActivityTelemetry = logActivityTelemetry; }
/// <summary> /// This method gets called by the runtime. Use this method to add services to the container. /// </summary> /// <param name="services">Specifies the contract for a <see cref="IServiceCollection"/> of service descriptors.</param> /// <seealso cref="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.1"/> public void ConfigureServices(IServiceCollection services) { var secretKey = Configuration.GetSection("botFileSecret")?.Value; var botFilePath = Configuration.GetSection("botFilePath")?.Value; Constants.PersonalityChatKey = Configuration.GetSection("personalityChatKey")?.Value; // Loads .bot configuration file and adds a singleton that your Bot can access through dependency injection. var botConfig = BotConfiguration.Load(botFilePath ?? @".\BotConfiguration.bot", secretKey); // Add Application Insights services.AddBotApplicationInsights(botConfig); // Initialize Bot Connected Services clients. var connectedServices = InitBotServices(botConfig); services.AddSingleton(sp => connectedServices); services.AddSingleton(sp => botConfig); services.AddBot <SupportBotService>(options => { services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot configuration file could not be loaded. ({botConfig})")); // Retrieve current endpoint. var environment = _isProduction ? "production" : "development"; var service = botConfig.Services.Where(s => s.Type == "endpoint" && s.Name == environment).FirstOrDefault(); if (!(service is EndpointService endpointService)) { throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'."); } options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword); // Creates a telemetryClient for OnTurnError handler var spTelemetry = services.BuildServiceProvider(); var telemetryClient = spTelemetry.GetService <IBotTelemetryClient>(); // Add TelemetryLoggerMiddleware (logs activity messages into Application Insights) var appInsightsLogger = new TelemetryLoggerMiddleware(telemetryClient, logUserName: true, logOriginalMessage: true); options.Middleware.Add(appInsightsLogger); // Creates a logger for the application to use. ILogger logger = _loggerFactory.CreateLogger <SupportBotService>(); // Catches any errors that occur during a conversation turn and logs them. options.OnTurnError = async(context, exception) => { telemetryClient.TrackException(exception); await context.SendActivityAsync("I don't have an answer for that. Try typing MENU to go back to the main menu"); }; // The Memory Storage used here is for local bot debugging only. When the bot // is restarted, everything stored in memory will be gone. IStorage dataStore = new MemoryStorage(); // For production bots use the Azure Blob or // Azure CosmosDB storage providers. For the Azure // based storage providers, add the Microsoft.Bot.Builder.Azure // Nuget package to your solution. That package is found at: // https://www.nuget.org/packages/Microsoft.Bot.Builder.Azure/ // Uncomment the following lines to use Azure Blob Storage // //Storage configuration name or ID from the .bot file. // const string StorageConfigurationId = "<STORAGE-NAME-OR-ID-FROM-BOT-FILE>"; // var blobConfig = botConfig.FindServiceByNameOrId(StorageConfigurationId); // if (!(blobConfig is BlobStorageService blobStorageConfig)) // { // throw new InvalidOperationException($"The .bot file does not contain an blob storage with name '{StorageConfigurationId}'."); // } // // Default container name. // const string DefaultBotContainer = "<DEFAULT-CONTAINER>"; // var storageContainer = string.IsNullOrWhiteSpace(blobStorageConfig.Container) ? DefaultBotContainer : blobStorageConfig.Container; // IStorage dataStore = new Microsoft.Bot.Builder.Azure.AzureBlobStorage(blobStorageConfig.ConnectionString, storageContainer); // Create Conversation State object. // The Conversation State object is where we persist anything at the conversation-scope. var conversationState = new ConversationState(dataStore); options.State.Add(conversationState); }); // Acessors created here are passed into the IBot - derived class on every turn. services.AddSingleton <ShowQnAResultAccessor>(sp => { var options = sp.GetRequiredService <IOptions <BotFrameworkOptions> >().Value; if (options == null) { throw new InvalidOperationException("BotFrameworkOptions must be configured prior to setting up the state accessors"); } var conversationState = options.State.OfType <ConversationState>().FirstOrDefault(); if (conversationState == null) { throw new InvalidOperationException("ConversationState must be defined and added before adding conversation-scoped state accessors."); } // Create the custom QnAMaker accessor. var accessors = new ShowQnAResultAccessor(conversationState) { QnAResultState = conversationState.CreateProperty <ShowQnAResultState>(ShowQnAResultAccessor.QnAResultStateName), ConversationDialogState = conversationState.CreateProperty <DialogState>("DialogState"), }; return(accessors); }); }
public void ConfigureServices(IServiceCollection services) { // Load the connected services from .bot file. var botFilePath = Configuration.GetSection("botFilePath")?.Value; var botFileSecret = Configuration.GetSection("botFileSecret")?.Value; var botConfig = BotConfiguration.Load(botFilePath ?? @".\CalendarSkill.bot", botFileSecret); services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot config file could not be loaded.")); // Initializes your bot service clients and adds a singleton that your Bot can access through dependency injection. var parameters = Configuration.GetSection("Parameters")?.Get <string[]>(); var configuration = Configuration.GetSection("Configuration")?.GetChildren()?.ToDictionary(x => x.Key, y => y.Value as object); var supportedProviders = Configuration.GetSection("SupportedProviders")?.Get <string[]>(); var connectedServices = new SkillConfiguration(botConfig, supportedProviders, parameters, configuration); services.AddSingleton(sp => connectedServices); // 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; var cosmosOptions = new CosmosDbStorageOptions() { CosmosDBEndpoint = new Uri(cosmosDb.Endpoint), AuthKey = cosmosDb.Key, CollectionId = cosmosDb.Collection, DatabaseId = cosmosDb.Database, }; var dataStore = new CosmosDbStorage(cosmosOptions); var userState = new UserState(dataStore); var conversationState = new ConversationState(dataStore); services.AddSingleton(dataStore); services.AddSingleton(userState); services.AddSingleton(conversationState); services.AddSingleton(new BotStateSet(userState, conversationState)); // Initialize calendar service client services.AddSingleton <IServiceManager, ServiceManager>(); // Add the bot with options services.AddBot <CalendarSkill>(options => { // Load the connected services from .bot file. var environment = _isProduction ? "production" : "development"; var service = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.Endpoint && s.Name == environment); if (!(service is EndpointService endpointService)) { throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'."); } options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword); // Telemetry Middleware (logs activity messages in Application Insights) var appInsightsService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.AppInsights) ?? throw new Exception("Please configure your AppInsights connection in your .bot file."); var instrumentationKey = (appInsightsService as AppInsightsService).InstrumentationKey; var appInsightsLogger = new TelemetryLoggerMiddleware(instrumentationKey, logUserName: true, logOriginalMessage: true); options.Middleware.Add(appInsightsLogger); // Catches any errors that occur during a conversation turn and logs them to AppInsights. options.OnTurnError = async(context, exception) => { await context.SendActivityAsync(context.Activity.CreateReply(CalendarSharedResponses.CalendarErrorMessage)); await context.SendActivityAsync(new Activity(type: ActivityTypes.Trace, text: $"Calendar Skill Error: {exception.Message} | {exception.StackTrace}")); connectedServices.TelemetryClient.TrackException(exception); }; // 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 AutoSaveStateMiddleware(userState, conversationState)); }); }
/// <summary> /// Initializes a new instance of the <see cref="TelemetryInitializerMiddleware"/> class. /// </summary> /// <param name="telemetryLoggerMiddleware">The TelemetryLoggerMiddleware to allow for logging of activity events.</param> /// <param name="logActivityTelemetry">Indicates if the TelemetryLoggerMiddleware should be executed to log activity events.</param> public TelemetryInitializerMiddleware(TelemetryLoggerMiddleware telemetryLoggerMiddleware, bool logActivityTelemetry = true) { _telemetryLoggerMiddleware = telemetryLoggerMiddleware; _logActivityTelemetry = logActivityTelemetry; }