Example #1
0
        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();
        }
Example #2
0
        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);
 }
Example #7
0
        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;
                }
            }
        }
Example #8
0
 public ConfigurationService(DataService data)
 {
     _data   = data;
     _config = data.Configuration;
 }
Example #9
0
 public BotService(IOptions <BotConfiguration> config)
 {
     _config = config.Value;
     Client  = new TelegramBotClient(_config.BotToken);
 }
Example #10
0
        /// <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));
        }
Example #11
0
        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()));
        }
Example #13
0
        /// <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);
            });
        }
Example #14
0
        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);
                }
            }
        }
Example #15
0
        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();
                }
            }
        }
Example #16
0
        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);
            }
        }
Example #17
0
        /// <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>();
        }
Example #19
0
 public async Task NullFolder()
 {
     var config = await BotConfiguration.LoadFromFolderAsync(null);
 }
Example #20
0
        // 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}");
                };
            });
        }
Example #21
0
 public UpdateController(IUpdateService updateService, BotConfiguration config)
 {
     _updateService = updateService;
     _config        = config;
 }
Example #22
0
        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.");
                // }
            });
        }
Example #23
0
        /// <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.");
                };
            });
        }
Example #24
0
        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);
            });
        }
Example #25
0
        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));
            });
        }
Example #26
0
        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");
 }
Example #28
0
        /// <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");
 }
Example #30
0
        /// <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);
            }
        }
Example #31
0
        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);
            });
        }
Example #32
0
        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)));
        }