Ejemplo n.º 1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EchoWithCounterBot"/> class.
        /// </summary>
        /// <param name="accessors">A class containing <see cref="IStatePropertyAccessor{T}"/> used to manage state.</param>
        /// <param name="loggerFactory">A <see cref="ILoggerFactory"/> that is hooked to the Azure App Service provider.</param>
        /// <seealso cref="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-2.1#windows-eventlog-provider"/>
        public EchoWithCounterBot(EchoBotAccessors accessors, ILoggerFactory loggerFactory)
        {
            if (loggerFactory == null)
            {
                throw new ArgumentNullException(nameof(loggerFactory));
            }

            _logger = loggerFactory.CreateLogger <EchoWithCounterBot>();
            _logger.LogTrace("EchoBot turn start.");


            var dialogState = accessors.DialogState;

            //// compose dialogs
            _dialogSet = new DialogSet(dialogState);
            _dialogSet.Add(PrincipalDialog.Instance);


            //Prompts
            _dialogSet.Add(new ChoicePrompt("choicePrompt"));
            _dialogSet.Add(new TextPrompt("textPrompt"));
            _dialogSet.Add(new NumberPrompt <int>("numberPrompt"));

            EchoBotAccessors = accessors ?? throw new ArgumentNullException(nameof(accessors));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EchoWithCounterBot"/> class.
        /// </summary>
        /// <param name="accessors">A class containing <see cref="IStatePropertyAccessor{T}"/> used to manage state.</param>
        /// <param name="loggerFactory">A <see cref="ILoggerFactory"/> that is hooked to the Azure App Service provider.</param>
        /// <seealso cref="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-2.1#windows-eventlog-provider"/>
        public EchoWithCounterBot(EchoBotAccessors accessors, ILoggerFactory loggerFactory)
        {
            if (loggerFactory == null)
            {
                throw new System.ArgumentNullException(nameof(loggerFactory));
            }

            var _logger = loggerFactory.CreateLogger <EchoWithCounterBot>();

            _logger.LogTrace("EchoBot turn start.");

            if (searchClient == null)
            {
                var searchname  = Startup.Configuration.GetSection("searchName")?.Value;
                var searchkey   = Startup.Configuration.GetSection("searchKey")?.Value;
                var searchindex = Startup.Configuration.GetSection("searchIndex")?.Value;

                // establish search service connection
                searchClient = new SearchIndexClient(searchname, searchindex, new SearchCredentials(searchkey));

                // read known cryptonyms (code names) from JSON file
                cryptonyms = JsonConvert.DeserializeObject <Dictionary <string, string> >(File.ReadAllText("cia-cryptonyms.json"));

                // get search URL for your main JFK Files site instance
                searchUrl = Startup.Configuration.GetSection("searchUrl")?.Value;

                // create set that remembers who the bot has greeted (add default-user to avoid double greeting on web app)
                greeted = new HashSet <string>();
                greeted.Add("default-user");
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="EchoWithCounterBot"/> class.
 /// </summary>
 /// <param name="accessors">A class containing <see cref="IStatePropertyAccessor{T}"/> used to manage state.</param>
 /// <param name="loggerFactory">A <see cref="ILoggerFactory"/> that is hooked to the Azure App Service provider.</param>
 /// <seealso cref="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-2.1#windows-eventlog-provider"/>
 public EchoWithCounterBot(EchoBotAccessors accessors, ILoggerFactory loggerFactory)
 {
     if (loggerFactory == null)
     {
         throw new System.ArgumentNullException(nameof(loggerFactory));
     }
 }
Ejemplo n.º 4
0
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddBot <EchoWithCounterBot>(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 ?? @".\AUDA.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.Where(s => s.Type == "endpoint" && s.Name == environment).FirstOrDefault();
                if (!(service is EndpointService endpointService))
                {
                    throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'.");
                }

                options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword);

                ILogger logger = _loggerFactory.CreateLogger <EchoWithCounterBot>();

                options.OnTurnError = async(context, exception) =>
                {
                    logger.LogError($"Exception caught : {exception}");
                    await context.SendActivityAsync("Sorry, it looks like something went wrong.");
                };

                IStorage dataStore = new MemoryStorage();

                var conversationState = new ConversationState(dataStore);

                options.State.Add(conversationState);
            });

            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.");
                }

                var accessors = new EchoBotAccessors(conversationState)
                {
                    ConversationDialogState = conversationState.CreateProperty <DialogState>("DialogState"),
                };

                return(accessors);
            });
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EchoWithCounterBot"/> class.
        /// </summary>
        /// <param name="accessors">A class containing <see cref="IStatePropertyAccessor{T}"/> used to manage state.</param>
        /// <param name="loggerFactory">A <see cref="ILoggerFactory"/> that is hooked to the Azure App Service provider.</param>
        /// <seealso cref="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-2.1#windows-eventlog-provider"/>
        public EchoWithCounterBot(EchoBotAccessors accessors, ILoggerFactory loggerFactory)
        {
            if (loggerFactory == null)
            {
                throw new System.ArgumentNullException(nameof(loggerFactory));
            }

            _logger = loggerFactory.CreateLogger <EchoWithCounterBot>();
            _logger.LogTrace("EchoBot turn start.");
            _accessors = accessors ?? throw new System.ArgumentNullException(nameof(accessors));
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EchoWithCounterBot"/> class.
        /// </summary>
        /// <param name="accessors">A class containing <see cref="IStatePropertyAccessor{T}"/> used to manage state.</param>
        /// <param name="loggerFactory">A <see cref="ILoggerFactory"/> that is hooked to the Azure App Service provider.</param>
        /// <seealso cref="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-2.1#windows-eventlog-provider"/>
        public EchoWithCounterBot(EchoBotAccessors accessors, ILoggerFactory loggerFactory)
        {
            turnid = System.Guid.NewGuid();

            if (loggerFactory == null)
            {
                throw new System.ArgumentNullException(nameof(loggerFactory));
            }

            logger = loggerFactory.CreateLogger <EchoWithCounterBot>();
            logger.LogTrace($"HOOVERBOT {turnid} turn start.");
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="EchoWithCounterBot"/> class.
        /// </summary>
        /// <param name="accessors">A class containing <see cref="IStatePropertyAccessor{T}"/> used to manage state.</param>
        /// <param name="loggerFactory">A <see cref="ILoggerFactory"/> that is hooked to the Azure App Service provider.</param>
        /// <seealso cref="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-2.1#windows-eventlog-provider"/>
        public EchoWithCounterBot(EchoBotAccessors accessors, ILoggerFactory loggerFactory)
        {
            turnid = System.Guid.NewGuid();

            if (loggerFactory == null)
            {
                throw new System.ArgumentNullException(nameof(loggerFactory));
            }

            logger = loggerFactory.CreateLogger <EchoWithCounterBot>();
            logger.LogTrace($"HOOVERBOT {turnid} turn start.");

            // avoid multiple initialization of static fields
            // it doesn't hurt anything in this case, but it's bad practice
            lock (InitLock)
            {
                if (greeted == null)
                {
                    var config = Startup.Configuration;

                    var searchname  = config.GetSection("searchName")?.Value;
                    var searchkey   = config.GetSection("searchKey")?.Value;
                    var searchindex = config.GetSection("searchIndex")?.Value;

                    // establish search service connection
                    searchClient = new SearchIndexClient(searchname, searchindex, new SearchCredentials(searchkey));

                    // read known cryptonyms (code names) from JSON file
                    cryptonyms = JsonConvert.DeserializeObject <Dictionary <string, string> >(File.ReadAllText("cia-cryptonyms.json"));

                    // get search URL for your main JFK Files site instance
                    searchUrl = config.GetSection("searchUrl")?.Value;

                    // create Text Analytics client
                    var textAnalyticsKey      = config.GetSection("textAnalyticsKey")?.Value;
                    var textAnalyticsEndpoint = config.GetSection("textAnalyticsEndpoint")?.Value;
                    textAnalyticsClient = new TextAnalyticsClient(new ApiKeyServiceClientCredentials(textAnalyticsKey))
                    {
                        Endpoint = textAnalyticsEndpoint,
                    };

                    // create set that remembers who the bot has greeted (add default-user to avoid double-greeting)
                    greeted = new HashSet <string>()
                    {
                        "default-user"
                    };
                }
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EchoWithCounterBot"/> class.
        /// </summary>
        /// <param name="conversationState">The managed conversation state.</param>
        /// <param name="loggerFactory">A <see cref="ILoggerFactory"/> that is hooked to the Azure App Service provider.</param>
        /// <seealso cref="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-2.1#windows-eventlog-provider"/>
        public EchoWithCounterBot(ConversationState conversationState, ILoggerFactory loggerFactory)
        {
            if (conversationState == null)
            {
                throw new System.ArgumentNullException(nameof(conversationState));
            }

            if (loggerFactory == null)
            {
                throw new System.ArgumentNullException(nameof(loggerFactory));
            }

            _accessors = new EchoBotAccessors(conversationState)
            {
                CounterState = conversationState.CreateProperty <CounterState>(EchoBotAccessors.CounterStateName),
            };

            _logger = loggerFactory.CreateLogger <EchoWithCounterBot>();
            _logger.LogTrace("EchoBot turn start.");
        }
Ejemplo n.º 9
0
        public EchoWithCounterBot(EchoBotAccessors accessors, ILoggerFactory loggerFactory)
        {
            _accessors = accessors ?? throw new ArgumentNullException(nameof(accessors));
            _dialogs   = new DialogSet(accessors.ConversationDialogState);

            var name_email_slots = new List <SlotDetails>
            {
                new SlotDetails("completename", "text", "Please, enter your complete name."),
                new SlotDetails("mail", "text", "Please, enter with mail you use in Americas University."),
            };

            var description_suggestion_slots = new List <SlotDetails>
            {
                new SlotDetails("problemdescription", "text", "We do know you're not happy with one of the courses you've made with us. Could you explain us why? Please, be detalistic."),
                new SlotDetails("suggestiontosolve", "text", "Get it. What do you think we should do to get that aspect(s) better?"),
            };

            var confirmation_list = new List <SlotDetails>
            {
                new SlotDetails("confirmationdata", "text", "May I send that info to our quality center?"),
            };

            // Dialogs can be nested and the slot filling dialog makes use of that. In this example some of the child
            // dialogs are slot filling dialogs themselves.
            var slots = new List <SlotDetails>
            {
                new SlotDetails("namemail", "namemail"),
                new SlotDetails("descriptionsuggestion", "descriptionsuggestion"),
            };

            // Add the various dialogs that will be used to the DialogSet.
            _dialogs.Add(new SlotFillingDialog("descriptionsuggestion", description_suggestion_slots));
            _dialogs.Add(new SlotFillingDialog("namemail", name_email_slots));
            _dialogs.Add(new TextPrompt("text"));
            _dialogs.Add(new SlotFillingDialog("confirmationdata", confirmation_list));
            _dialogs.Add(new ConfirmPrompt("conf"));
            _dialogs.Add(new SlotFillingDialog("slot-dialog", slots));

            // Defines a simple two step Waterfall to test the slot dialog.
            _dialogs.Add(new WaterfallDialog("root", new WaterfallStep[] { StartDialogAsync, ProcessResultsAsync }));
        }
Ejemplo n.º 10
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 =>
            {
                // 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;

                // 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);

                // 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 <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);
            });
        }
Ejemplo n.º 11
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 =>
            {
                // 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 microsoftAppId       = Configuration.GetSection("MicrosoftAppId")?.Value;
                var microsoftAppPassword = Configuration.GetSection("MicrosoftAppPassword")?.Value;

                options.CredentialProvider = new SimpleCredentialProvider(microsoftAppId, microsoftAppPassword);
                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("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);

                options.State.Add(conversationState);
            });

            // 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);
            });
        }