public Bot(BotConfiguration configuration, IChatClient client, ILogger logger = null) { if (configuration == null) throw new ArgumentNullException("configuration"); if (client == null) throw new ArgumentNullException("client"); _Configuration = configuration; _Client = client; _Logger = logger ?? new VoidLogger(); }
static int Main() { // TODO: Need to load credentials from a file with JSON format // TODO: Decide where/how to save that file var configuration = new BotConfiguration(); //Added ability to load from text file - Need to discuss the FromJson method configuration.Credentials = BotCredentials.LoadFromFile(@"C:\Users\Elewis\desktop\credentials.txt"); //configuration.Credentials.Username = "******"; //configuration.Credentials.Password = "******"; return new Bot(configuration, new StackOverflowChatClient(), new ConsoleLogger()).Run(); }
public async Task NullFile() { var config = await BotConfiguration.LoadAsync(null); }
public async Task DeserializeBotFile() { var config = await BotConfiguration.LoadAsync(TestBotFileName); Assert.AreEqual("test", config.Name); Assert.AreEqual("test description", config.Description); Assert.AreEqual(string.Empty, config.Padlock); Assert.AreEqual(12, config.Services.Count); dynamic properties = config.Properties; Assert.AreEqual(true, (bool)properties.extra, "extra property should round trip"); // verify types are right foreach (var service in config.Services) { switch (service.Type) { case ServiceTypes.AppInsights: Assert.AreEqual(typeof(AppInsightsService), service.GetType()); break; case ServiceTypes.Bot: Assert.AreEqual(typeof(BotService), service.GetType()); break; case ServiceTypes.BlobStorage: Assert.AreEqual(typeof(BlobStorageService), service.GetType()); break; case ServiceTypes.CosmosDB: Assert.AreEqual(typeof(CosmosDbService), service.GetType()); break; case ServiceTypes.Generic: Assert.AreEqual(typeof(GenericService), service.GetType()); break; case ServiceTypes.Dispatch: Assert.AreEqual(typeof(DispatchService), service.GetType()); break; case ServiceTypes.Endpoint: Assert.AreEqual(typeof(EndpointService), service.GetType()); break; case ServiceTypes.File: Assert.AreEqual(typeof(FileService), service.GetType()); break; case ServiceTypes.Luis: Assert.AreEqual(typeof(LuisService), service.GetType()); break; case ServiceTypes.QnA: Assert.AreEqual(typeof(QnAMakerService), service.GetType()); break; case "unknown": // this is cool, because we want to round-trip unknown service types for future proofing break; default: throw new Exception("Unknown service type!"); } } }
/// <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 <TriviaBotT5Bot>(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 ?? @".\TriviaBotT5.bot", secretKey); services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot config file could not be loaded. ({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}'."); } options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword); // Creates a logger for the application to use. ILogger logger = _loggerFactory.CreateLogger <TriviaBotT5Bot>(); // 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(); // 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); }); // Create and register state accessors. // Accessors created here are passed into the IBot-derived class on every turn. services.AddSingleton <TriviaBotT5Accessors>(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 TriviaBotT5Accessors(conversationState) { CounterState = conversationState.CreateProperty <QuestionState>(TriviaBotT5Accessors.CounterStateName), ConversationDialogState = conversationState.CreateProperty <DialogState>("DialogState") }; return(accessors); }); services.AddMvc(); // Required by Razor pages }
public BotService(BotConfiguration config) { _config = config; Client = new TelegramBotClient(_config.BotToken); }
public async Task LoadAndSaveEncrypted() { string secret = BotConfiguration.GenerateKey(); var config = await BotConfiguration.LoadAsync(@"..\..\test.bot"); Assert.AreEqual("", config.Padlock, "There should be no padlock"); // save with secret await config.SaveAsAsync("savesecret.bot", secret); Assert.IsTrue(config.Padlock?.Length > 0, "There should be a padlock"); // load with secret var config2 = await BotConfiguration.LoadAsync("savesecret.bot", secret); Assert.IsTrue(config2.Padlock?.Length > 0, "There should be a padlock"); Assert.AreEqual(config.Padlock, config2.Padlock, "Padlocks should be the same"); // make sure these were decrypted for (int i = 0; i < config.Services.Count; i++) { Assert.AreEqual(JsonConvert.SerializeObject(config.Services[i]), JsonConvert.SerializeObject(config2.Services[i])); switch (config.Services[i].Type) { case ServiceTypes.Bot: break; case ServiceTypes.AppInsights: { var appInsights = (AppInsightsService)config2.Services[i]; Assert.IsTrue(appInsights.InstrumentationKey.Contains("0000"), "failed to decrypt instrumentationKey"); Assert.AreEqual(appInsights.ApplicationId, "00000000-0000-0000-0000-000000000007", "failed to decrypt applicationId"); Assert.AreEqual(appInsights.ApiKeys["key1"], "testKey1", "failed to decrypt key1"); Assert.AreEqual(appInsights.ApiKeys["key2"], "testKey2", "failed to decrypt key2"); } break; case ServiceTypes.BlobStorage: { var blobStorage = (BlobStorageService)config2.Services[i]; Assert.AreEqual("UseDevelopmentStorage=true;", blobStorage.ConnectionString, "failed to decrypt connectionString"); Assert.AreEqual("testContainer", blobStorage.Container, "failed to decrypt Container"); } break; case ServiceTypes.CosmosDB: { var cosmosDb = (CosmosDbService)config2.Services[i]; Assert.AreEqual("https://localhost:8081/", cosmosDb.Endpoint, "failed to decrypt endpoint"); Assert.AreEqual("C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==", cosmosDb.Key, "failed to decrypt key"); Assert.AreEqual("testDatabase", cosmosDb.Database, "failed to decrypt database"); Assert.AreEqual("testCollection", cosmosDb.Collection, "failed to decrypt collection"); } break; case ServiceTypes.Dispatch: { var dispatch = (DispatchService)config2.Services[i]; Assert.IsTrue(dispatch.AuthoringKey.Contains("0000"), "failed to decrypt authoringkey"); Assert.IsTrue(dispatch.SubscriptionKey.Contains("0000"), "failed to decrypt subscriptionKey"); } break; case ServiceTypes.Endpoint: { var endpoint = (EndpointService)config2.Services[i]; Assert.AreEqual("testpassword", endpoint.AppPassword, "failed to decrypt appPassword"); } break; case ServiceTypes.File: break; case ServiceTypes.Luis: { var luis = (LuisService)config2.Services[i]; Assert.IsTrue(luis.AuthoringKey.Contains("0000"), "failed to decrypt authoringkey"); Assert.IsTrue(luis.SubscriptionKey.Contains("0000"), "failed to decrypt subscriptionKey"); } break; case ServiceTypes.QnA: { var qna = (QnAMakerService)config2.Services[i]; Assert.IsTrue(qna.KbId.Contains("0000"), "kbId should not be changed"); Assert.IsTrue(qna.EndpointKey.Contains("0000"), "failed to decrypt EndpointKey"); Assert.IsTrue(qna.SubscriptionKey.Contains("0000"), "failed to decrypt SubscriptionKey"); } break; case ServiceTypes.Generic: { var generic = (GenericService)config2.Services[i]; Assert.AreEqual(generic.Url, "https://bing.com", "url should not change"); Assert.AreEqual(generic.Configuration["key1"], "testKey1", "failed to decrypt key1"); Assert.AreEqual(generic.Configuration["key2"], "testKey2", "failed to decrypt key2"); } break; default: break; } } // encrypt in memory copy config2.Encrypt(secret); // make sure these are all true for (int i = 0; i < config.Services.Count; i++) { switch (config.Services[i].Type) { case ServiceTypes.AppInsights: { var appInsights = (AppInsightsService)config2.Services[i]; Assert.IsFalse(appInsights.InstrumentationKey.Contains("0000"), "failed to encrypt instrumentationKey"); Assert.AreEqual(appInsights.ApplicationId, "00000000-0000-0000-0000-000000000007", "should not encrypt applicationId"); Assert.AreNotEqual(appInsights.ApiKeys["key1"], "testKey1", "failed to encrypt key1"); Assert.AreNotEqual(appInsights.ApiKeys["key2"], "testKey2", "failed to encrypt key2"); } break; case ServiceTypes.BlobStorage: { var azureStorage = (BlobStorageService)config2.Services[i]; Assert.AreNotEqual("UseDevelopmentStorage=true;", azureStorage.ConnectionString, "failed to encrypt connectionString"); Assert.AreEqual("testContainer", azureStorage.Container, "should not change container"); } break; case ServiceTypes.CosmosDB: { var cosmosdb = (CosmosDbService)config2.Services[i]; Assert.AreEqual("https://localhost:8081/", cosmosdb.Endpoint, "should not change endpoint"); Assert.AreNotEqual("C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==", cosmosdb.Key, "failed to encrypt key"); Assert.AreEqual("testDatabase", cosmosdb.Database, "should not change database"); Assert.AreEqual("testCollection", cosmosdb.Collection, "should not change collection"); } break; case ServiceTypes.Bot: Assert.AreEqual(JsonConvert.SerializeObject(config.Services[i]), JsonConvert.SerializeObject(config2.Services[i])); break; case ServiceTypes.Dispatch: { Assert.AreNotEqual(JsonConvert.SerializeObject(config.Services[i]), JsonConvert.SerializeObject(config2.Services[i])); var dispatch = (DispatchService)config2.Services[i]; Assert.IsFalse(dispatch.AuthoringKey.Contains("0000"), "failed to encrypt authoringkey"); Assert.IsFalse(dispatch.SubscriptionKey.Contains("0000"), "failed to encrypt subscriptionKey"); } break; case ServiceTypes.Endpoint: { Assert.AreNotEqual(JsonConvert.SerializeObject(config.Services[i]), JsonConvert.SerializeObject(config2.Services[i])); var endpoint = (EndpointService)config2.Services[i]; Assert.IsTrue(endpoint.AppId.Contains("0000"), "appId should not be changed"); Assert.IsFalse(endpoint.AppPassword.Contains("testpassword"), "failed to encrypt appPassword"); } break; case ServiceTypes.File: Assert.AreEqual(JsonConvert.SerializeObject(config.Services[i]), JsonConvert.SerializeObject(config2.Services[i])); break; case ServiceTypes.Luis: { Assert.AreNotEqual(JsonConvert.SerializeObject(config.Services[i]), JsonConvert.SerializeObject(config2.Services[i])); var luis = (LuisService)config2.Services[i]; Assert.IsFalse(luis.AuthoringKey.Contains("0000"), "failed to encrypt authoringkey"); Assert.IsFalse(luis.SubscriptionKey.Contains("0000"), "failed to encrypt subscriptionKey"); } break; case ServiceTypes.QnA: { Assert.AreNotEqual(JsonConvert.SerializeObject(config.Services[i]), JsonConvert.SerializeObject(config2.Services[i])); var qna = (QnAMakerService)config2.Services[i]; Assert.IsTrue(qna.KbId.Contains("0000"), "kbId should not be changed"); Assert.IsFalse(qna.EndpointKey.Contains("0000"), "failed to encrypt EndpointKey"); Assert.IsFalse(qna.SubscriptionKey.Contains("0000"), "failed to encrypt SubscriptionKey"); } break; case ServiceTypes.Generic: { var generic = (GenericService)config2.Services[i]; Assert.AreEqual(generic.Url, "https://bing.com", "url should not change"); Assert.AreNotEqual(generic.Configuration["key1"], "testKey1", "failed to encrypt key1"); Assert.AreNotEqual(generic.Configuration["key2"], "testKey2", "failed to encrypt key2"); } break; default: // ignore unknown service type break; } } }
public ConfigurationService(DataService data) { _data = data; _config = data.Configuration; }
public BotService(IOptions <BotConfiguration> config) { _config = config.Value; Client = new TelegramBotClient(_config.BotToken); }
/// <summary> /// Initialize the bot's references to external services. /// /// For example, QnaMaker services are created here. /// These external services are configured /// using the <see cref="BotConfiguration"/> class (based on the contents of your ".bot" file). /// </summary> /// <param name="config"><see cref="BotConfiguration"/> object based on your ".bot" file.</param> /// <returns>A <see cref="BotServices"/> representing client objects to access external services the bot uses.</returns> /// <seealso cref="BotConfiguration"/> /// <seealso cref="QnAMaker"/> /// <seealso cref="TelemetryClient"/> private static BotServices InitBotServices(BotConfiguration config) { var qnaServices = new Dictionary <string, QnAMaker>(); var luisServices = new Dictionary <string, LuisRecognizer>(); foreach (var service in config.Services) { switch (service.Type) { case ServiceTypes.Luis: { // Create a Luis Recognizer that is initialized and suitable for passing // into the IBot-derived class (NlpDispatchBot). // In this case, we're creating a custom class (wrapping the original // Luis Recognizer client) that logs the results of Luis Recognizer results // into Application Insights for future anaysis. if (!(service is LuisService luis)) { throw new InvalidOperationException("The LUIS service is not configured correctly in your '.bot' file."); } if (string.IsNullOrWhiteSpace(luis.AppId)) { throw new InvalidOperationException("The LUIS Model Application Id ('appId') is required to run this sample. Please update your '.bot' file."); } if (string.IsNullOrWhiteSpace(luis.AuthoringKey)) { throw new InvalidOperationException("The Luis Authoring Key ('authoringKey') is required to run this sample. Please update your '.bot' file."); } if (string.IsNullOrWhiteSpace(luis.SubscriptionKey)) { throw new InvalidOperationException("The Subscription Key ('subscriptionKey') is required to run this sample. Please update your '.bot' file."); } if (string.IsNullOrWhiteSpace(luis.Region)) { throw new InvalidOperationException("The Region ('region') is required to run this sample. Please update your '.bot' file."); } var app = new LuisApplication(luis.AppId, luis.AuthoringKey, luis.Region); var recognizer = new LuisRecognizer(app); luisServices.Add(luis.Name, recognizer); break; } case ServiceTypes.Dispatch: // Create a Dispatch Recognizer that is initialized and suitable for passing // into the IBot-derived class (NlpDispatchBot). // In this case, we're creating a custom class (wrapping the original // Luis Recognizer client) that logs the results of Luis Recognizer results // into Application Insights for future anaysis. if (!(service is DispatchService dispatch)) { throw new InvalidOperationException("The Dispatch service is not configured correctly in your '.bot' file."); } if (string.IsNullOrWhiteSpace(dispatch.AppId)) { throw new InvalidOperationException("The LUIS Model Application Id ('appId') is required to run this sample. Please update your '.bot' file."); } if (string.IsNullOrWhiteSpace(dispatch.AuthoringKey)) { throw new InvalidOperationException("The LUIS Authoring Key ('authoringKey') is required to run this sample. Please update your '.bot' file."); } if (string.IsNullOrWhiteSpace(dispatch.SubscriptionKey)) { throw new InvalidOperationException("The Subscription Key ('subscriptionKey') is required to run this sample. Please update your '.bot' file."); } if (string.IsNullOrWhiteSpace(dispatch.Region)) { throw new InvalidOperationException("The Region ('region') is required to run this sample. Please update your '.bot' file."); } var dispatchApp = new LuisApplication(dispatch.AppId, dispatch.AuthoringKey, dispatch.Region); // Since the Dispatch tool generates a LUIS model, we use LuisRecognizer to resolve dispatching of the incoming utterance var dispatchARecognizer = new LuisRecognizer(dispatchApp); luisServices.Add(dispatch.Name, dispatchARecognizer); break; case ServiceTypes.QnA: { // Create a QnA Maker that is initialized and suitable for passing // into the IBot-derived class (NlpDispatchBot). // In this case, we're creating a custom class (wrapping the original // QnAMaker client) that logs the results of QnA Maker into Application // Insights for future anaysis. if (!(service is QnAMakerService qna)) { throw new InvalidOperationException("The QnA service is not configured correctly in your '.bot' file."); } if (string.IsNullOrWhiteSpace(qna.KbId)) { throw new InvalidOperationException("The QnA KnowledgeBaseId ('kbId') is required to run this sample. Please update your '.bot' file."); } if (string.IsNullOrWhiteSpace(qna.EndpointKey)) { throw new InvalidOperationException("The QnA EndpointKey ('endpointKey') is required to run this sample. Please update your '.bot' file."); } if (string.IsNullOrWhiteSpace(qna.Hostname)) { throw new InvalidOperationException("The QnA Host ('hostname') is required to run this sample. Please update your '.bot' file."); } var qnaEndpoint = new QnAMakerEndpoint() { KnowledgeBaseId = qna.KbId, EndpointKey = qna.EndpointKey, Host = qna.Hostname, }; var qnaMaker = new QnAMaker(qnaEndpoint); qnaServices.Add(qna.Name, qnaMaker); break; } } } return(new BotServices(qnaServices, luisServices)); }
public void ConfigureServices(IServiceCollection services) { BotConfiguration botConfig = null; 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}"); } try { botConfig = BotConfiguration.Load(botFilePath ?? @".\BotConfiguration.bot", secretKey); // Loads .bot configuration file and adds a singleton that your Bot can access through dependency injection. services.AddSingleton(_ => botConfig); } 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.AddBot <EurekaBot>(options => { // Creates a logger for the application to use. ILogger logger = _loggerFactory.CreateLogger <EurekaBot>(); // 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}"); await context.SendActivityAsync($"Oops - {exception.Message}"); }; options.Middleware.Add(new ConversationLogger(botConfig)); }); }
public PokemonRaidBotDbContext CreateDbContext(string[] args) { var config = BotConfiguration.Load(); return(new PokemonRaidBotDbContext(config, new StatMapper())); }
/// <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); }); }
public SkillConfiguration(BotConfiguration botConfiguration, string[] supportedProviders, string[] parameters, Dictionary <string, object> configuration) { if (supportedProviders != null && supportedProviders.Count() > 0) { IsAuthenticatedSkill = true; } foreach (var service in botConfiguration.Services) { switch (service.Type) { case ServiceTypes.AppInsights: { var appInsights = service as AppInsightsService; var telemetryConfig = new TelemetryConfiguration(appInsights.InstrumentationKey); TelemetryClient = new TelemetryClient(telemetryConfig); break; } case ServiceTypes.Luis: { var luis = service as LuisService; var luisApp = new LuisApplication(luis.AppId, luis.SubscriptionKey, luis.GetEndpoint()); LuisServices.Add(service.Id, new TelemetryLuisRecognizer(luisApp)); break; } case ServiceTypes.Generic: { if (service.Name == "Authentication") { var auth = service as GenericService; foreach (var provider in supportedProviders) { auth.Configuration.TryGetValue(provider, out var connectionName); if (connectionName != null) { AuthenticationConnections.Add(provider, connectionName); } } } break; } } } if (parameters != null) { // add the parameters the skill needs foreach (var parameter in parameters) { // Initialize each parameter to null. Needs to be set later by the bot. Properties.Add(parameter, null); } } if (configuration != null) { // add the additional keys the skill needs foreach (var set in configuration) { Properties.Add(set.Key, set.Value); } } }
public async Task Chat(BotConfiguration config, IServiceProvider services, CancellationToken cancellationToken) { _config = config; bool retry = true; int retryCount = 0; await _reminderContainer.LoadReminders(); reminderTimer = new System.Timers.Timer(7000); try { while (!cancellationToken.IsCancellationRequested && retry) { try { //join server and set nick using var irc = new TcpClient(config.Server, config.Port); using var stream = irc.GetStream(); using var reader = new StreamReader(stream); using var writer = new StreamWriter(stream); using CancellationTokenRegistration ctr = cancellationToken.Register(() => { retryCount = _maxRetries; retry = false; writer.Close(); reader.Close(); stream.Close(); irc.Close(); }); SetClientNick(writer, config.Username, config.Nick); reminderTimer.Elapsed += async(sender, args) => await CheckReminders(writer); reminderTimer.AutoReset = true; reminderTimer.Start(); string inputLine; while (!cancellationToken.IsCancellationRequested && (inputLine = reader.ReadLine()) != null) //someone sent a message { try { ChatReply reply = ParseReply(inputLine); if (reply == null) { continue; } else if (reply.User == "PING") // reply to server ping { SendPongReply(writer, reply); } else if (reply.Command == "001") //join a channel { JoinChannel(writer, config.Channel); } else if (reply.Command == "PRIVMSG" && !string.IsNullOrWhiteSpace(reply.Message)) { await _resolver.ResolveCommand(writer, reply, services, config.Nick); } } catch (Exception ex) { _logger.LogError(ex.Message); } } } catch (Exception e) { // shows the exception, sleeps for a little while and then tries to establish a new connection to the IRC server _logger.LogInformation(e.ToString()); reminderTimer.Stop(); await Task.Delay(5000, cancellationToken); retryCount++; if (retryCount > _maxRetries) { retry = false; } } } } catch (Exception e) { Console.WriteLine(e.Message); } finally { if (reminderTimer != null) { reminderTimer.Dispose(); } } }
public BotService(IOptions <BotConfiguration> config, ILogHelper logHelper, INgrokService ngrokService) { _logHelper = logHelper; _logHelper.Log("4H456K454KKFGFF", "Bot service is starting", LogLevel.Information); _ngrokService = ngrokService; _config = config.Value; switch (_config.ProxyMode) { case Enums.ProxyMode.NONE: _logHelper.Log("K65K65765JFDFGFD55", "Starting without a proxy", LogLevel.Information); Client = new TelegramBotClient(_config.BotToken); break; case Enums.ProxyMode.HTTP: int httpPort = (int)_config.HTTPProxy.HTTPPort; _logHelper.Log("5K65FJHGJGFDF89893", $"Starting HTTP proxy. host: {_config.HTTPProxy.HTTPHost} port {httpPort.ToString()}", LogLevel.Information); WebProxy httpProxy = new WebProxy(_config.HTTPProxy.HTTPHost, httpPort); Client = new TelegramBotClient( _config.BotToken, httpProxy); break; case Enums.ProxyMode.SOCKS5: int socksPort = (int)_config.SOCKS5Proxy.Socks5Port; if (string.IsNullOrEmpty(_config.SOCKS5Proxy.Socks5Username)) { _logHelper.Log("L5KLJ345HJHDDS98XC", "Starting with an open SOCKS5 proxy", LogLevel.Information); Client = new TelegramBotClient( _config.BotToken, new HttpToSocks5Proxy(_config.SOCKS5Proxy.Socks5Host, socksPort)); } else { _logHelper.Log("NM6456NMLKJ4554", "Starting with a protected SOCKS5 proxy", LogLevel.Information); Client = new TelegramBotClient( _config.BotToken, new HttpToSocks5Proxy(_config.SOCKS5Proxy.Socks5Host, socksPort, _config.SOCKS5Proxy.Socks5Username, _config.SOCKS5Proxy.Socks5Password)); } break; default: break; } _logHelper.Log("KBJH43543JH65765KWS", "TelegramBotClient created", LogLevel.Information); string externalUrl = ""; if (_config.ExternalURL != "") { externalUrl = _config.ExternalURL; Client.SetWebhookAsync(externalUrl + "/api/update/").Wait(); } else { externalUrl = _ngrokService.GetNgrokUrlAsync().Result; Client.SetWebhookAsync(externalUrl + "/api/update/").Wait(); } var info = Client.GetWebhookInfoAsync().Result; if (string.IsNullOrEmpty(info.LastErrorMessage)) { _logHelper.Log("KJ5LK456L4B4654F45", $"Webhook set. Webhook url: {externalUrl}/api/update/", LogLevel.Information); } else { _logHelper.Log("MNVNV435CN435N43KJ", $"Webhook not set. Webhook url: {externalUrl}/api/update/ \r\nError: {info.LastErrorMessage}", LogLevel.Error); } }
/// <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) { // Add botConfiguration singleton // See https://aka.ms/about-bot-file to learn more about .bot file its use and bot configuration. var secretKey = Configuration.GetSection("botFileSecret")?.Value; var botFilePath = Configuration.GetSection("botFilePath")?.Value; var botConfig = BotConfiguration.Load(botFilePath ?? @".\CafeBot.bot", secretKey); services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot configuration file could not be loaded. botFilePath: {botFilePath}")); // add BotServices singleton services.AddSingleton(sp => new BotServices(botConfig)); // 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/ // Un-comment 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); services.AddSingleton(dataStore); var userState = new UserState(dataStore); var conversationState = new ConversationState(dataStore); services.AddSingleton(userState); services.AddSingleton(conversationState); // The BotStateSet enables read() and write() in parallel on multiple BotState instances. services.AddSingleton(new BotStateSet(userState, conversationState)); // add the bot with options services.AddBot <CafeBot>(options => { // Load the connected services from .bot file. 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); // Catches any errors that occur during a conversation turn and logs them to currently // configured ILogger. ILogger logger = _loggerFactory.CreateLogger <CafeBot>(); options.OnTurnError = async(context, exception) => { logger.LogError($"Exception caught : {exception}"); await context.SendActivityAsync("Sorry, it looks like something went wrong."); }; // Automatically save state at the end of a turn. 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) { services.AddSingleton <IStorage, MemoryStorage>(); services.AddSingleton <ConversationState>(); services.AddSingleton <ComponentDialogsBotAccessors>(); services.AddScoped <GreetingDialog>(); services.AddBot <ComponentDialogsBot>(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 ?? @".\ComponentDialogBot.bot", secretKey); services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot config file could not be loaded. ({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}'."); } options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword); // Creates a logger for the application to use. ILogger logger = _loggerFactory.CreateLogger <ComponentDialogsBot>(); // Catches any errors that occur during a conversation turn and logs them. options.OnTurnError = async(context, exception) => { logger.LogError(exception, "----- ComponentBotDialog ERROR"); await context.SendActivityAsync("Sorry, it looks like something went wrong."); }; // 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 = _appServices.GetService <ConversationState>(); options.State.Add(conversationState); options.Middleware.Add(new AutoSaveStateMiddleware(conversationState)); }); services.AddSingleton <RegistrationRepo>(); services.AddScoped <IBotUserServices, BotUserServices>(); }
public async Task NullFolder() { var config = await BotConfiguration.LoadFromFolderAsync(null); }
// This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { //Instantiate the bot configuration for use in the bot //Traffic coming through to your app is protected by the app ID and app secret //credentials applied to your Bot Registration on Azure. //If you are running locally, these can be blank. var secretKey = Configuration.GetSection("botFileSecret")?.Value; var botFilePath = Configuration.GetSection("botFilePath")?.Value; var botConfig = BotConfiguration.Load(botFilePath ?? @".\BotConfiguration.bot", secretKey); if (botConfig == null) { throw new InvalidOperationException($"The .bot config file could not be loaded from [{botFilePath}]"); } //Step 1) Add the bot configuration as something we can retrieve through DI services.AddSingleton(botConfig); //Step 2) Configure QnA // - Retrieve the service from botConfig that is of type QnA; // - (Optional) Throw an exception if the service is null or if any required fields are empty var qnaService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.QnA) as QnAMakerService; if (qnaService == null) { throw new InvalidOperationException($"The QnA Service is not configured correctly in {botFilePath}"); } //Create a new instance of QnAMaker and add it to the services container as a singleton var qnaMaker = new QnAMaker(qnaService); services.AddSingleton(qnaMaker); //The extension to add a bot to our services container //can be found in Microsoft.Bot.Builder.Integration.AspNet.Core //Whichever type is passed will be the bot that is created services.AddBot <QnAMakerBot>(options => { //The bot configuration can map different endpoints for different environments var serviceName = Environment.EnvironmentName.ToLowerInvariant(); var service = botConfig.FindServiceByNameOrId(serviceName) as EndpointService; if (service == null) { throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{serviceName}'."); } options.CredentialProvider = new SimpleCredentialProvider(service.AppId, service.AppPassword); //Memory storage is only used for this example. //In a production application, you should always rely on //a more persistant storage mechanism, such as CosmosDB IStorage dataStore = new MemoryStorage(); //Whichever datastore we're working with, we will need to use it //to actually store the conversation state. var conversationState = new ConversationState(dataStore); options.State.Add(conversationState); //Step 3) Add a callback for "OnTurnError" that logs any bot or middleware errors to the console // - (Optional) Send a message to the user indicating there was a problem ILogger logger = _loggerFactory.CreateLogger <QnAMakerBot>(); options.OnTurnError = async(context, e) => { //Ideally you do not want to get here - you want to handle business logic errors more gracefully. //But if we're here, we can do any housekeeping such as logging and letting the know something went wrong. logger.LogError(e, "Unhandled exception on bot turn - incoming input was {0}", context.Activity.Text); //Since we have the context, we can send (helpful) messagse to the user await context.SendActivityAsync($"Something went wrong. Please forgive me. Exception: {e.Message}"); }; }); }
public UpdateController(IUpdateService updateService, BotConfiguration config) { _updateService = updateService; _config = config; }
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)); 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 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) => { 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}")); 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-us")); 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."); // } }); }
/// <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; // 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. "; 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.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}'."); } // Memory Storage 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/ // Un-comment 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 and add conversation state. var conversationState = new ConversationState(dataStore); services.AddSingleton(conversationState); var userState = new UserState(dataStore); services.AddSingleton(userState); services.AddBot <BasicBot>(options => { options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword); // Catches any errors that occur during a conversation turn and logs them to currently // configured ILogger. ILogger logger = _loggerFactory.CreateLogger <BasicBot>(); options.OnTurnError = async(context, exception) => { logger.LogError($"Exception caught : {exception}"); await context.SendActivityAsync("Sorry, it looks like something went wrong."); }; }); }
public void ConfigureServices(IServiceCollection services) { var environment = _isProduction ? "production" : "development"; // Load the connected services from .bot file. var botFilePath = Configuration.GetSection("botFilePath")?.Value; //var botFileSecret = Configuration.GetSection("botFileSecret")?.Value; var botFileSecret = "dTonuuzS+krI6S69RITRAII7T/hAqtLYM1BLN7/eqAI="; 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); var jobState = new JobState(dataStore); services.AddSingleton(sp => jobState); services.AddSingleton(dataStore); services.AddSingleton(userState); services.AddSingleton(conversationState); services.AddSingleton(new BotStateSet(userState, conversationState)); // Add the bot with options services.AddBot <Bot>(options => { 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, 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) => { 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)); }); services.AddSingleton(sp => { 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}'."); } return((EndpointService)service); }); }
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> > >(); SkillConfigurationBase connectedServices = new SkillConfiguration(botConfig, languageModels, supportedProviders, parameters, configuration); services.AddSingleton <SkillConfigurationBase>(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)); services.AddTransient <IServiceManager, ServiceManager>(); // 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 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.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 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.")); // 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 <SubCommander>(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(MainStrings.ERROR); 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)); }); }
public async Task LoadNotExistentFile() { var config = await BotConfiguration.LoadAsync(@"..\..\..\filedoesntexist.bot"); }
/// <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) { // 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 Job State object. // The Job State object is where we persist anything at the job-scope. // Note: It's independent of any user or conversation. var jobState = new JobState(dataStore); // Make it available to our bot services.AddSingleton(sp => jobState); // Register the proactive bot. services.AddBot <ProactiveBot>(options => { 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. 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 <ProactiveBot>(); // 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."); }; }); services.AddSingleton(sp => { var config = BotConfiguration.Load(@".\BotConfiguration.bot"); var endpointService = (EndpointService)config.Services.First(s => s.Type == "endpoint") ?? throw new InvalidOperationException(".bot file 'endpoint' must be configured prior to running."); return(endpointService); }); }
public async Task LoadNotExistentFolder() { var config = await BotConfiguration.LoadFromFolderAsync(@"\prettysurethisdoesnotexist"); }
/// <summary> /// Initializes a new instance of the <see cref="BotServices"/> class. /// </summary> /// <param name="botConfiguration">The <see cref="BotConfiguration"/> instance for the bot.</param> /// <param name="skills">List of <see cref="SkillDefinition"/> for loading skill configurations.</param> /// <param name="languageModels">The locale specifc language model configs for each supported language.</param> public BotServices(BotConfiguration botConfiguration, Dictionary <string, Dictionary <string, string> > languageModels, List <SkillDefinition> skills) { // Create service clients for each service in the .bot file. foreach (var service in botConfiguration.Services) { switch (service.Type) { case ServiceTypes.AppInsights: { var appInsights = (AppInsightsService)service; if (appInsights == null) { throw new InvalidOperationException("The Application Insights is not configured correctly in your '.bot' file."); } if (string.IsNullOrWhiteSpace(appInsights.InstrumentationKey)) { throw new InvalidOperationException("The Application Insights Instrumentation Key ('instrumentationKey') is required to run this sample. Please update your '.bot' file."); } var telemetryConfig = new TelemetryConfiguration(appInsights.InstrumentationKey); TelemetryClient = new TelemetryClient(telemetryConfig) { InstrumentationKey = appInsights.InstrumentationKey, }; break; } case ServiceTypes.CosmosDB: { var cosmos = service as CosmosDbService; CosmosDbOptions = new CosmosDbStorageOptions { AuthKey = cosmos.Key, CollectionId = cosmos.Collection, DatabaseId = cosmos.Database, CosmosDBEndpoint = new Uri(cosmos.Endpoint), }; break; } case ServiceTypes.Generic: { if (service.Name == "Authentication") { var authentication = service as GenericService; AuthenticationConnections = authentication.Configuration; } break; } } } // Create locale configuration object for each language config in appsettings.json foreach (var language in languageModels) { if (language.Value.TryGetValue("botFilePath", out var botFilePath) && File.Exists(botFilePath)) { var botFileSecret = language.Value["botFileSecret"]; var config = BotConfiguration.Load(botFilePath, !string.IsNullOrEmpty(botFileSecret) ? botFileSecret : null); var localeConfig = new LocaleConfiguration { Locale = language.Key }; foreach (var service in config.Services) { switch (service.Type) { case ServiceTypes.Dispatch: { var dispatch = service as DispatchService; if (dispatch == null) { throw new InvalidOperationException("The Dispatch service is not configured correctly in your '.bot' file."); } if (string.IsNullOrWhiteSpace(dispatch.AppId)) { throw new InvalidOperationException("The Dispatch Luis Model Application Id ('appId') is required to run this sample. Please update your '.bot' file."); } if (string.IsNullOrWhiteSpace(dispatch.SubscriptionKey)) { throw new InvalidOperationException("The Subscription Key ('subscriptionKey') is required to run this sample. Please update your '.bot' file."); } var dispatchApp = new LuisApplication(dispatch.AppId, dispatch.SubscriptionKey, dispatch.GetEndpoint()); localeConfig.DispatchRecognizer = new TelemetryLuisRecognizer(dispatchApp); break; } case ServiceTypes.Luis: { var luis = service as LuisService; if (luis == null) { throw new InvalidOperationException("The Luis service is not configured correctly in your '.bot' file."); } if (string.IsNullOrWhiteSpace(luis.AppId)) { throw new InvalidOperationException("The Luis Model Application Id ('appId') is required to run this sample. Please update your '.bot' file."); } if (string.IsNullOrWhiteSpace(luis.AuthoringKey)) { throw new InvalidOperationException("The Luis Authoring Key ('authoringKey') is required to run this sample. Please update your '.bot' file."); } if (string.IsNullOrWhiteSpace(luis.SubscriptionKey)) { throw new InvalidOperationException("The Subscription Key ('subscriptionKey') is required to run this sample. Please update your '.bot' file."); } if (string.IsNullOrWhiteSpace(luis.Region)) { throw new InvalidOperationException("The Region ('region') is required to run this sample. Please update your '.bot' file."); } var luisApp = new LuisApplication(luis.AppId, luis.SubscriptionKey, luis.GetEndpoint()); var recognizer = new TelemetryLuisRecognizer(luisApp); localeConfig.LuisServices.Add(service.Id, recognizer); break; } case ServiceTypes.QnA: { var qna = service as QnAMakerService; var qnaEndpoint = new QnAMakerEndpoint() { KnowledgeBaseId = qna.KbId, EndpointKey = qna.EndpointKey, Host = qna.Hostname, }; var qnaMaker = new TelemetryQnAMaker(qnaEndpoint); localeConfig.QnAServices.Add(qna.Id, qnaMaker); break; } } } LocaleConfigurations.Add(language.Key, localeConfig); } } // Create a skill configurations for each skill in appsettings.json foreach (var skill in skills) { var skillConfig = new SkillConfiguration() { CosmosDbOptions = CosmosDbOptions }; foreach (var localeConfig in LocaleConfigurations) { skillConfig.LocaleConfigurations.Add(localeConfig.Key, new LocaleConfiguration { LuisServices = localeConfig.Value.LuisServices.Where(l => skill.LuisServiceIds.Contains(l.Key) == true).ToDictionary(l => l.Key, l => l.Value) }); } if (skill.SupportedProviders != null) { foreach (var provider in skill.SupportedProviders) { var matches = AuthenticationConnections.Where(x => x.Value == provider); foreach (var match in matches) { skillConfig.AuthenticationConnections.Add(match.Key, match.Value); } } } foreach (var set in skill.Configuration) { skillConfig.Properties.Add(set.Key, set.Value); } SkillDefinitions.Add(skill); SkillConfigurations.Add(skill.Id, skillConfig); } }
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 ?? @".\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> > >(); 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 AddToDoResponses(), new DeleteToDoResponses(), new ToDoMainResponses(), new MarkToDoResponses(), new ToDoSharedResponses(), new ShowToDoResponses()); // Register bot responses for all supported languages. services.AddSingleton(sp => responseManager); 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.AddTransient <IServiceManager, ServiceManager>(); // Add the bot services.AddSingleton <IBot, ToDoSkill>(); // 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) => { CultureInfo.CurrentUICulture = new CultureInfo(context.Activity.Locale); await context.SendActivityAsync(responseManager.GetResponse(ToDoSharedResponses.ToDoErrorMessage)); await context.SendActivityAsync(new Activity(type: ActivityTypes.Trace, text: $"To Do Skill Error: {exception.Message} | {exception.StackTrace}")); telemetryClient.TrackExceptionEx(exception, context.Activity); } }; 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 SetLocaleMiddleware(defaultLocale ?? "en-us")); botFrameworkHttpAdapter.Use(new AutoSaveStateMiddleware(userState, conversationState)); return(botFrameworkHttpAdapter); }); }
public static async Task <bool> JoinGameWithRetry(int gameCount, Client client, BotConfiguration botConfiguration, AccountCharacter cowAccount) { return(await GeneralHelpers.TryWithTimeout(async (retryCount) => { bool joinGame = false; try { joinGame = client.JoinGame($"{botConfiguration.GameNamePrefix}{gameCount}", botConfiguration.GamePassword); } catch { } if (!joinGame) { var retryDuration = Math.Pow(1 + retryCount, 1.2) * TimeSpan.FromSeconds(3); Log.Information($"Joining game failed for {client.LoggedInUserName()} retrying in {retryDuration.TotalSeconds} seconds"); await RealmConnectHelpers.ConnectToRealmWithRetry(client, botConfiguration, cowAccount, 10); await Task.Delay(retryDuration); } return joinGame; }, TimeSpan.FromSeconds(20))); }