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)); }); }
/// <summary> /// Initializes a new instance of the <see cref="ConversationHistoryBot"/> class. /// </summary> /// <param name="transcriptStore">Injected via ASP.NET dependency injection.</param> public ConversationHistoryBot(AzureBlobTranscriptStore transcriptStore) { _transcriptStore = transcriptStore ?? throw new ArgumentNullException(nameof(transcriptStore)); }
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); }); }
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)); }); }
/// <summary> /// This method gets called by the runtime. Use this method to add services to the container. /// </summary> /// <param name="services">The <see cref="IServiceCollection"/> specifies the contract for a collection of service descriptors.</param> /// <seealso cref="IStatePropertyAccessor{T}"/> /// <seealso cref="https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/dependency-injection"/> /// <seealso cref="https://docs.microsoft.com/en-us/azure/bot-service/bot-service-manage-channels?view=azure-bot-service-4.0"/> public void ConfigureServices(IServiceCollection services) { AzureBlobTranscriptStore blobStore = null; services.AddBot <ConversationHistoryBot>(options => { var secretKey = Configuration.GetSection("botFileSecret")?.Value; var botFilePath = Configuration.GetSection("botFilePath")?.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); services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot configuration file could not be loaded. botFilePath: {botFilePath}")); // Retrieve current endpoint. var environment = _isProduction ? "production" : "development"; var service = botConfig.Services.FirstOrDefault(s => s.Type == "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); // Creates a logger for the application to use. ILogger logger = _loggerFactory.CreateLogger <ConversationHistoryBot>(); // Catches any errors that occur during a conversation turn and logs them. options.OnTurnError = async(context, exception) => { logger.LogError($"Exception caught : {exception}"); await context.SendActivityAsync("Sorry, it looks like something went wrong."); }; // 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(); 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; // 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. // IStorage dataStore = new 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); // Enable the conversation transcript middleware. blobStore = new AzureBlobTranscriptStore(blobStorageConfig.ConnectionString, storageContainer); var transcriptMiddleware = new TranscriptLoggerMiddleware(blobStore); options.Middleware.Add(transcriptMiddleware); }) .AddSingleton(_ => blobStore); }
public void TestInit() { StorageEmulatorHelper.StartStorageEmulator(); _transcriptStore = new AzureBlobTranscriptStore(ConnectionString, ContainerName); }
/// <param name="transcriptStore">Injected via ASP.NET dependency injection.</param> public EchoWithCounterBot(AzureBlobTranscriptStore transcriptStore) { _transcriptStore = transcriptStore ?? throw new ArgumentNullException(nameof(transcriptStore)); }
/// <summary> /// This method gets called by the runtime. Use this method to add services to the container. /// </summary> /// <param name="services">Service Collection.</param> public void ConfigureServices(IServiceCollection services) { // var botFilePath = Configuration.GetSection("BotFilePath")?.Value; // var botFileSecret = Configuration.GetSection("BotFileSecret")?.Value; //// Loads .bot configuration file and adds a singleton that your Bot can access through dependency injection. // var botConfig = BotConfiguration.LoadAsync(botFilePath).GetAwaiter().GetResult(); // services.AddSingleton(sp => botConfig); //// Initializes your bot service clients and adds a singleton that your Bot can access through dependency injection. // var connectedServices = InitBotServices(botConfig); var luisModels = this.Configuration.GetSection("services").Get <LanguageModel[]>(); var luis = luisModels[0]; var emailSkillServices = new EmailSkillServices(); { var luisApp = new LuisApplication(luis.Id, luis.SubscriptionKey, "https://westus.api.cognitive.microsoft.com"); var luisRecognizer = new LuisRecognizer(luisApp); emailSkillServices.LuisRecognizer = luisRecognizer; } services.AddSingleton(sp => emailSkillServices); services.AddSingleton(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."); } var accessors = new EmailSkillAccessors { ConversationDialogState = conversationState.CreateProperty <DialogState>("EmailSkillDialogState"), EmailSkillState = conversationState.CreateProperty <EmailSkillState>("EmailSkillState"), }; return(accessors); }); services.AddSingleton <IMailSkillServiceManager, MailSkillServiceManager>(); services.AddBot <EmailSkill>(options => { options.CredentialProvider = new ConfigurationCredentialProvider(this.Configuration); var transcriptStore = new AzureBlobTranscriptStore(this.Configuration.GetSection("AzureBlobConnectionString")?.Value, this.Configuration.GetSection("transcriptContainer")?.Value); options.Middleware.Add(new TranscriptLoggerMiddleware(transcriptStore)); IStorage memoryDataStore = new MemoryStorage(); options.State.Add(new ConversationState(memoryDataStore)); options.Middleware.Add(new AutoSaveStateMiddleware(options.State.ToArray())); }); }
public void ConfigureServices(IServiceCollection services) { // Enable distributed tracing. services.AddApplicationInsightsTelemetry(o => { o.RequestCollectionOptions.EnableW3CDistributedTracing = true; o.RequestCollectionOptions.InjectResponseHeaders = true; o.RequestCollectionOptions.TrackExceptions = true; }); services.AddSingleton <ITelemetryInitializer>(new OperationCorrelationTelemetryInitializer()); _logger = _loggerFactory.CreateLogger <Startup>(); _logger.LogInformation($"Configuring services for {nameof(EnterpriseBot)}. IsProduction: {_isProduction}."); // 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.")); // 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 <EnterpriseBot>(options => { _logger.LogInformation($"Adding bot {nameof(EnterpriseBot)}"); // 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("Sorry, it looks like something went wrong."); 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)); _logger.LogTrace($"Bot added successfully."); }); }
public void ConfigureServices(IServiceCollection services) { services.AddSingleton(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."); } var accessors = new CalendarSkillAccessors { ConversationDialogState = conversationState.CreateProperty <DialogState>("CalendarSkillDialogState"), CalendarSkillState = conversationState.CreateProperty <CalendarSkillState>("CalendarSkillState"), }; return(accessors); }); services.AddSingleton <IServiceManager, ServiceManager>(); services.AddSingleton <CalendarSkillServices>(sp => { var luisModels = this.Configuration.GetSection("services").Get <LanguageModel[]>(); var luis = luisModels[0]; var calendarSkillService = new CalendarSkillServices(); { var luisApp = new LuisApplication(luis.Id, luis.SubscriptionKey, "https://westus.api.cognitive.microsoft.com"); var luisRecognizer = new LuisRecognizer(luisApp); calendarSkillService.LuisRecognizer = luisRecognizer; var authConnectionName = this.Configuration.GetSection("authConnectionName")?.Value; calendarSkillService.AuthConnectionName = authConnectionName; } return(calendarSkillService); }); services.AddBot <CalendarSkill>(options => { options.CredentialProvider = new ConfigurationCredentialProvider(Configuration); // Catches any errors that occur during a conversation turn and logs them to AppInsights. options.OnTurnError = async(context, exception) => { await context.SendActivityAsync($"CalendarSkill: {exception.Message}"); await context.SendActivityAsync(exception.StackTrace); }; var transcriptStore = new AzureBlobTranscriptStore(this.Configuration.GetSection("AzureBlobConnectionString")?.Value, this.Configuration.GetSection("transcriptContainer")?.Value); options.Middleware.Add(new TranscriptLoggerMiddleware(transcriptStore)); IStorage dataStore = new MemoryStorage(); options.State.Add(new ConversationState(dataStore)); options.Middleware.Add(new AutoSaveStateMiddleware(options.State.ToArray())); }); }
/// <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> public void ConfigureServices(IServiceCollection services) { var secretKey = Configuration.GetSection("botFileSecret")?.Value; var botFilePath = Configuration.GetSection("botFilePath")?.Value; if (!File.Exists(botFilePath)) { throw new FileNotFoundException($"The .bot configuration file was not found. botFilePath: {botFilePath}"); } // Loads .bot configuration file and adds a singleton that your Bot can access through dependency injection. BotConfiguration botConfig = null; try { botConfig = BotConfiguration.Load(botFilePath, secretKey); } catch { var msg = @"Error reading bot file. Please ensure you have valid botFilePath and botFileSecret set for your environment. - You can find the botFilePath and botFileSecret in the Azure App Service application settings. - If you are running this bot locally, consider adding a appsettings.json file with botFilePath and botFileSecret. - See https://aka.ms/about-bot-file to learn more about .bot file its use and bot configuration. "; throw new InvalidOperationException(msg); } services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot configuration file could not be loaded. botFilePath: {botFilePath}")); // Add BotServices singleton. // Create the connected services from .bot file. services.AddSingleton(sp => new BotServices(botConfig)); // Create PimBotServiceProvider var featureService = new FeatureService(new FeatureRepository()); var keywordService = new KeywordService(new KeywordRepository()); var categoryService = new CategoryService(new CategoryRepository()); var itemService = new ItemService(new ItemRepository(), featureService, keywordService, categoryService, new PictureRepository()); var serviceProvider = new PimBotServiceProvider(itemService, keywordService, featureService, categoryService); services.AddSingleton <IPimbotServiceProvider>(serviceProvider); services.AddScoped <IKeywordService, KeywordService>(); // Retrieve current endpoint. var environment = _isProduction ? "production" : "development"; var service = botConfig.Services.FirstOrDefault(s => s.Type == "endpoint" && s.Name == environment); if (service == null && _isProduction) { // Attempt to load development environment service = botConfig.Services.Where(s => s.Type == "endpoint" && s.Name == "development").FirstOrDefault(); } if (!(service is EndpointService endpointService)) { throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'."); } // For testing and develop IStorage dataStore = new MemoryStorage(); // For publishing // IStorage dataStore = new CosmosDbStorage(new CosmosDbStorageOptions() // { // AuthKey = Constants.CosmosDBKey, // CollectionId = Constants.CosmosDBCollectionName, // CosmosDBEndpoint = new Uri(Constants.CosmosServiceEndpoint), // DatabaseId = Constants.CosmosDBDatabaseName, // }); // Create and add conversation state. var conversationState = new ConversationState(dataStore); services.AddSingleton(conversationState); services.AddScoped <IKeywordService, KeywordService>(); var userState = new UserState(dataStore); services.AddSingleton(userState); var blobStorage = new AzureBlobTranscriptStore( Constants.AzureBlogStorageConnectionString, Constants.BlobTranscriptStorageContainerName); services.AddBot <PimBot.PimBot>(options => { options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword); options.ChannelProvider = new ConfigurationChannelProvider(Configuration); ILogger logger = _loggerFactory.CreateLogger <PimBot.PimBot>(); // For logging every single conversations // options.Middleware.Add(new TranscriptLoggerMiddleware(blobStorage)); options.Middleware.Add(new ShowTypingMiddleware()); var middleware = options.Middleware; // Catches any errors that occur during a conversation turn and logs them to currently // configured ILogger. options.OnTurnError = async(context, exception) => { logger.LogError($"Exception caught : {exception}"); if (exception is System.Net.Http.HttpRequestException || exception is System.Net.Sockets.SocketException) { await context.SendActivityAsync(Messages.ServerIssue); } else { await context.SendActivityAsync(Messages.SomethingWrong); } }; }); }
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 ?? throw new Exception("Please configure your bot file path in appsettings.json."), botFileSecret); // Use Application Insights services.AddBotApplicationInsights(botConfig); // Initializes your bot service clients and adds a singleton that your Bot can access through dependency injection. var languageModels = Configuration.GetSection("languageModels").Get <Dictionary <string, Dictionary <string, string> > >(); var skills = Configuration.GetSection("skills").Get <List <SkillDefinition> >(); List <SkillEvent> skillEvents = null; var skillEventsConfig = Configuration.GetSection(SkillEventsConfigName); if (skillEventsConfig != null) { skillEvents = skillEventsConfig.Get <List <SkillEvent> >(); } var connectedServices = new BotServices(botConfig, languageModels, skills, skillEvents); services.AddSingleton(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); 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 <IBot, VirtualAssistant>(); // Add the http adapter to enable MVC style bot API services.AddSingleton <IBotFrameworkHttpAdapter>((sp) => { var credentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword); var telemetryClient = sp.GetService <IBotTelemetryClient>(); var botFrameworkHttpAdapter = new BotFrameworkHttpAdapter(credentialProvider) { OnTurnError = async(context, exception) => { CultureInfo.CurrentUICulture = new CultureInfo(context.Activity.Locale); var responseBuilder = new MainResponses(); await responseBuilder.ReplyWith(context, MainResponses.ResponseIds.Error); await context.SendActivityAsync(new Activity(type: ActivityTypes.Trace, text: $"Virtual Assistant Error: {exception.Message} | {exception.StackTrace}")); telemetryClient.TrackExceptionEx(exception, context.Activity); } }; // Telemetry Middleware (logs activity messages in Application Insights) 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) botFrameworkHttpAdapter.Use(new ShowTypingMiddleware()); botFrameworkHttpAdapter.Use(new SetLocaleMiddleware(defaultLocale ?? "en-us")); botFrameworkHttpAdapter.Use(new EventDebuggerMiddleware()); botFrameworkHttpAdapter.Use(new AutoSaveStateMiddleware(userState, conversationState)); botFrameworkHttpAdapter.Use(new ProactiveStateMiddleware(proactiveState)); return(botFrameworkHttpAdapter); }); }
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 ?? @".\CustomAssistant.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 skills = Configuration.GetSection("skills").Get <List <SkillDefinition> >(); var connectedServices = new BotServices(botConfig, skills); services.AddSingleton(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)); // Add the bot with options services.AddBot <VirtualAssistant>(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("Sorry, it looks like something went wrong. Please try again."); await context.SendActivityAsync(new Activity(type: ActivityTypes.Trace, text: $"Virtual Assistant 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) options.Middleware.Add(new ShowTypingMiddleware()); options.Middleware.Add(new SetLocaleMiddleware(defaultLocale ?? "en")); options.Middleware.Add(new EventDebuggerMiddleware()); options.Middleware.Add(new AutoSaveStateMiddleware(userState, conversationState)); //// Translator is an optional component for scenarios when an Assistant needs to work beyond native language support //var translatorKey = Configuration.GetValue<string>("translatorKey"); //if (!string.IsNullOrEmpty(translatorKey)) //{ // options.Middleware.Add(new TranslationMiddleware(new string[] { "en", "fr", "it", "de", "es" }, translatorKey, false)); //} //else //{ // throw new InvalidOperationException("Microsoft Text Translation API key is missing. Please add your translation key to the 'translatorKey' setting."); //} }); }
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 ?? @".\weatherskill.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 languageModels = Configuration.GetSection("languageModels").Get <Dictionary <string, Dictionary <string, string> > >(); var connectedServices = new SkillConfiguration(botConfig, languageModels, 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 service client services.AddSingleton <IServiceManager, ServiceManager>(); // Add the bot with options services.AddBot <weatherskill>(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) => { await context.SendActivityAsync(context.Activity.CreateReply(weatherskillSharedResponses.ErrorMessage)); await context.SendActivityAsync(new Activity(type: ActivityTypes.Trace, text: $"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> /// 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> public void ConfigureServices(IServiceCollection services) { var config = Configuration.Get <CarWashConfiguration>(); services.AddSingleton(config); var secretKey = Configuration.GetSection("botFileSecret")?.Value; var botFilePath = Configuration.GetSection("botFilePath")?.Value; // Loads .bot configuration file and adds a singleton that your Bot can access through dependency injection. BotConfiguration botConfig; try { botConfig = BotConfiguration.Load(botFilePath ?? @".\carwashubot.bot", secretKey); } catch (Exception) { var msg = @"Error reading bot file. Please ensure you have valid botFilePath and botFileSecret set for your environment. - You can find the botFilePath and botFileSecret in the Azure App Service application settings. - If you are running this bot locally, consider adding a appsettings.json file with botFilePath and botFileSecret. - See https://aka.ms/about-bot-file to learn more about .bot file its use and bot configuration. "; throw new InvalidOperationException(msg); } services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot config file could not be loaded. ({botConfig})")); // Add BotServices singleton. // Create the connected services from .bot file. services.AddSingleton(sp => new BotServices(botConfig)); // Retrieve current endpoint. var environment = _isProduction ? "production" : "development"; var service = botConfig.Services.FirstOrDefault(s => s.Type == "endpoint" && s.Name == environment); if (!(service is EndpointService endpointService)) { throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'."); } // Configure AppInsights services.AddApplicationInsightsTelemetry(Configuration); // Configure SnapshotCollector from application settings services.Configure <SnapshotCollectorConfiguration>(Configuration.GetSection(nameof(SnapshotCollectorConfiguration))); // Add SnapshotCollector telemetry processor. services.AddSingleton <ITelemetryProcessorFactory>(sp => new SnapshotCollectorTelemetryProcessorFactory(sp)); // Add proactive message services services.AddSingleton <DropoffReminderMessage, DropoffReminderMessage>(); services.AddSingleton <WashStartedMessage, WashStartedMessage>(); services.AddSingleton <WashCompletedMessage, WashCompletedMessage>(); services.AddSingleton <CarWashCommentLeftMessage, CarWashCommentLeftMessage>(); services.AddSingleton <VehicleArrivedMessage, VehicleArrivedMessage>(); // Memory Storage is for local bot debugging only. When the bot // is restarted, everything stored in memory will be gone. // IStorage dataStore = new MemoryStorage(); // Storage configuration name or ID from the .bot file. const string storageConfigurationId = "carwashstorage"; 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 = "botstate"; var storageContainer = string.IsNullOrWhiteSpace(blobStorageConfig.Container) ? defaultBotContainer : blobStorageConfig.Container; IStorage dataStore = new AzureBlobStorage(blobStorageConfig.ConnectionString, storageContainer); // Create and add conversation state. var conversationState = new ConversationState(dataStore); services.AddSingleton(conversationState); // Create and add user state. var userState = new UserState(dataStore); services.AddSingleton(userState); services.AddBot <CarWashBot>(options => { options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword); // Enable the show typing middleware. options.Middleware.Add(new ShowTypingMiddleware()); // Enable the conversation transcript middleware. var transcriptStore = new AzureBlobTranscriptStore(blobStorageConfig.ConnectionString, "transcripts"); options.Middleware.Add(new TranscriptLoggerWorkaroundMiddleware(transcriptStore)); // Add Teams authentication workaround middleware. options.Middleware.Add(new TeamsAuthWorkaroundMiddleware()); // Catches any errors that occur during a conversation turn and logs them to currently // configured ILogger. ILogger logger = _loggerFactory.CreateLogger <CarWashBot>(); options.OnTurnError = async(context, exception) => { var telemetryClient = new TelemetryClient(); telemetryClient.TrackException(exception); logger.LogError($"Exception caught : {exception}"); await context.SendActivityAsync("Sorry, it looks like something went wrong."); }; }); // Create and register state accessors. // Accessors created here are passed into the IBot-derived class on every turn. services.AddSingleton(sp => { if (conversationState == null) { throw new InvalidOperationException("ConversationState must be defined and added before adding conversation-scoped state accessors."); } if (userState == null) { throw new InvalidOperationException("UserState must be defined and added before adding user-scoped state accessors."); } // Create the custom state accessor. // State accessors enable other components to read and write individual properties of state. var accessors = new StateAccessors(conversationState, userState); return(accessors); }); }
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 ?? throw new Exception("Please configure your bot file path in appsettings.json."), botFileSecret); // Use Application Insights services.AddBotApplicationInsights(botConfig); // Initializes your bot service clients and adds a singleton that your Bot can access through dependency injection. var languageModels = Configuration.GetSection("languageModels").Get <Dictionary <string, Dictionary <string, string> > >(); var skills = Configuration.GetSection("skills").Get <List <SkillDefinition> >(); List <SkillEvent> skillEvents = null; var skillEventsConfig = Configuration.GetSection(SkillEventsConfigName); if (skillEventsConfig != null) { skillEvents = skillEventsConfig.Get <List <SkillEvent> >(); } var connectedServices = new BotServices(botConfig, languageModels, skills, skillEvents); services.AddSingleton(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); 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); // Add the bot with options services.AddBot <VirtualAssistant>(options => { // Load the connected services from .bot file. 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); var responseBuilder = new MainResponses(); await responseBuilder.ReplyWith(context, MainResponses.ResponseIds.Error); await context.SendActivityAsync(new Activity(type: ActivityTypes.Trace, text: $"Virtual Assistant 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) options.Middleware.Add(new ShowTypingMiddleware()); options.Middleware.Add(new SetLocaleMiddleware(defaultLocale ?? "en-us")); options.Middleware.Add(new EventDebuggerMiddleware()); options.Middleware.Add(new AutoSaveStateMiddleware(userState, conversationState)); options.Middleware.Add(new ProactiveStateMiddleware(proactiveState)); //// Translator is an optional component for scenarios when an Assistant needs to work beyond native language support // var translatorKey = Configuration.GetValue<string>("translatorKey"); // if (!string.IsNullOrEmpty(translatorKey)) // { // options.Middleware.Add(new TranslationMiddleware(new string[] { "en", "fr", "it", "de", "es" }, translatorKey, false)); // } // else // { // throw new InvalidOperationException("Microsoft Text Translation API key is missing. Please add your translation key to the 'translatorKey' setting."); // } }); }
/// <summary> /// This method gets called by the runtime. Use this method to add services to the container. /// </summary> /// <param name="services">The <see cref="IServiceCollection"/> specifies the contract for a collection of service descriptors.</param> /// <seealso cref="IStatePropertyAccessor{T}"/> /// <seealso cref="https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/dependency-injection"/> /// <seealso cref="https://docs.microsoft.com/en-us/azure/bot-service/bot-service-manage-channels?view=azure-bot-service-4.0"/> public void ConfigureServices(IServiceCollection services) { services.AddBot <EchoWithCounterBot>(options => { var blobStore = new AzureBlobTranscriptStore("DefaultEndpointsProtocol=https;AccountName=sq7ofgblobs;AccountKey=2k0LVUrttdcPB50R3DNIgZrB2ff1yapC6Iv0r/SeCKFW4D+bL2ezwy8zO0lCw/Adw2ysPSdsu13OZ07RtXufFw==;EndpointSuffix=core.windows.net", "bot-storage"); var transcriptMiddleware = new TranscriptLoggerMiddleware(blobStore); options.Middleware.Add(transcriptMiddleware); // Creates a logger for the application to use. ILogger logger = _loggerFactory.CreateLogger <EchoWithCounterBot>(); //var secretKey = Configuration.GetSection("botFileSecret")?.Value; //var botFilePath = Configuration.GetSection("botFilePath")?.Value; var secretKey = "s0/1svAFPxOxUcTfsyoILPUcWLfJlACnsGlkzAotEGw="; var botFilePath = "./customerassistant.bot"; if (!File.Exists(botFilePath)) { throw new FileNotFoundException($"The .bot configuration file was not found. botFilePath: {botFilePath}"); } // Loads .bot configuration file and adds a singleton that your Bot can access through dependency injection. BotConfiguration botConfig = null; try { botConfig = BotConfiguration.Load(botFilePath ?? @".\BotConfiguration.bot", secretKey); } catch { var msg = @"Error reading bot file. Please ensure you have valid botFilePath and botFileSecret set for your environment. - You can find the botFilePath and botFileSecret in the Azure App Service application settings. - If you are running this bot locally, consider adding a appsettings.json file with botFilePath and botFileSecret. - See https://aka.ms/about-bot-file to learn more about .bot file its use and bot configuration. "; logger.LogError(msg); throw new InvalidOperationException(msg); } services.AddSingleton(sp => botConfig); // Retrieve current endpoint. var environment = _isProduction ? "production" : "development"; var service = botConfig.Services.FirstOrDefault(s => s.Type == "endpoint" && s.Name == environment); if (service == null && _isProduction) { // Attempt to load development environment service = botConfig.Services.Where(s => s.Type == "endpoint" && s.Name == "development").FirstOrDefault(); logger.LogWarning("Attempting to load development endpoint in production 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); options.ChannelProvider = new ConfigurationChannelProvider(Configuration); // Catches any errors that occur during a conversation turn and logs them. options.OnTurnError = async(context, exception) => { logger.LogError($"Exception caught : {exception}"); Console.WriteLine($"Exception: {exception}"); await context.SendActivityAsync("Sorry, it looks like something went wrong."); }; // 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 = "botstate"; // 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); var userState = new UserState(dataStore); options.State.Add(conversationState); services.AddSingleton <StateBotAccessors>(sp => { // Create the custom state accessor. return(new StateBotAccessors(conversationState, userState) { ConversationDataAccessor = conversationState.CreateProperty <ConversationData>(StateBotAccessors.ConversationDataName), UserProfileAccessor = userState.CreateProperty <UserData>(StateBotAccessors.UserProfileName), }); }); }); // Create and register state accessors. // Accessors created here are passed into the IBot-derived class on every turn. services.AddSingleton <EchoBotAccessors>(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 state accessor. // State accessors enable other components to read and write individual properties of state. var accessors = new EchoBotAccessors(conversationState) { CounterState = conversationState.CreateProperty <CounterState>(EchoBotAccessors.CounterStateName), }; return(accessors); }); }