//Confirm Change Charttype private async Task <DialogTurnResult> FinalStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { ConsoleWriter.WriteLineInfo("ResultTypeString: " + stepContext.Result.GetType().ToString()); ConsoleWriter.WriteLineInfo("Result: " + stepContext.Result.ToString()); var changeChartTypeDetails = (ChangeChartTypeDetails)stepContext.Options; //We are comming from a ChoicePromt/Ambiguity Dialog ==> Convert result to FoundCHoice if (stepContext.Result.GetType().ToString().Equals("Microsoft.Bot.Builder.Dialogs.Choices.FoundChoice")) { //Extract the picked result from the step-context var pickedChoice = (FoundChoice)stepContext.Result; var choiceText = pickedChoice.Value; //Set the result to the ChangeCharttypeDetails-Object changeChartTypeDetails.ToChartType = choiceText; changeChartTypeDetails.AmbiguousChartTypes = new string[] { choiceText }; } //Now the Object is set right and we can print, what we want to change our charttype to ConsoleWriter.WriteLineInfo("Change Charttype to: " + changeChartTypeDetails.AmbiguousChartTypes[0]); //Send Request to API await BOT_Api.SendChangeChartTypeAsync(stepContext, changeChartTypeDetails.AmbiguousChartTypes[0]); return(await stepContext.EndDialogAsync(changeChartTypeDetails, cancellationToken)); }
private async Task <DialogTurnResult> FinalStepAsync( WaterfallStepContext stepContext, CancellationToken cancellationToken) { // Retrieve their selection list, the choice they made, and whether they chose to finish. var list = stepContext.Values[CountriesSelected] as List <string>; var choice = (FoundChoice)stepContext.Result; var done = choice.Value == DoneOption; if (!done) { // If they chose a company, add it to the list. list.Add(choice.Value); } if (done) { // If they're done, exit and return their list. ConsoleWriter.WriteLineInfo("Filter for: " + string.Join(", ", list)); FilterForWordDetails filterForWordDetails = new FilterForWordDetails(); filterForWordDetails.columnName = list.ToArray(); ConsoleWriter.WriteLineInfo("ColumnName: " + filterForWordDetails.columnName[0]); await BOT_Api.SendFilterForWord(stepContext, usedColumn, list.ToArray()); return(await stepContext.EndDialogAsync(list, cancellationToken)); } else { // Otherwise, repeat this dialog, passing in the list from this iteration. return(await stepContext.ReplaceDialogAsync(nameof(FilterForWordDialog), list, cancellationToken)); } }
//Summarize results (e.g. by extracting information from the ambiguity dialog) private async Task <DialogTurnResult> FinalStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { var nl4dvQueryDetails = (Nl4dvQueryDetails)stepContext.Options; //We are comming from a ChoicePromt ==> Convert result to FoundCHoice (in this case we come from an ambiguity dialog. Otherwise there would have been no ChoicePromt) if (stepContext.Result.GetType().ToString().Equals("Microsoft.Bot.Builder.Dialogs.Choices.FoundChoice")) { //Extract the picked result from the step-context var pickedChoice = (FoundChoice)stepContext.Result; var choiceText = pickedChoice.Value; ConsoleWriter.WriteLineInfo("Replacing Chart by " + choiceText); if (choiceText.Equals("I am not sure")) { nl4dvQueryDetails.queryText = nl4dvQueryDetails.queryText.Replace("chart", ""); } else { nl4dvQueryDetails.queryText = nl4dvQueryDetails.queryText.Replace("chart", choiceText); if (!nl4dvQueryDetails.queryText.Contains(choiceText)) { nl4dvQueryDetails.queryText = nl4dvQueryDetails.queryText + " in a " + choiceText; } } } //Now the Object is set right and we can print, what we want to change our charttype to await BOT_Api.SendNL4DV(stepContext, nl4dvQueryDetails.queryText); return(await stepContext.EndDialogAsync(nl4dvQueryDetails, cancellationToken)); }
//Confirm task private async Task <DialogTurnResult> FinalStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { var changeAggregateDetails = (ChangeAggregateDetails)stepContext.Options; //Now the Object is set right and we can print, what we want to change our charttype to ConsoleWriter.WriteLineInfo("Change aggregate of " + changeAggregateDetails.visualizationPart + " to: " + changeAggregateDetails.toAggregate); await BOT_Api.SendChangeAggregate(stepContext, changeAggregateDetails.visualizationPart, changeAggregateDetails.toAggregate); return(await stepContext.EndDialogAsync(changeAggregateDetails, cancellationToken)); }
//Summarize results (e.g. by extracting information from the ambiguity dialog) private async Task <DialogTurnResult> FinalStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { var filterForNumberDetails = (FilterForNumberDetails)stepContext.Options; //We are comming from a ChoicePromt ==> Convert result to FoundCHoice (in this case we come from an ambiguity dialog. Otherwise there would have been no ChoicePromt) if (stepContext.Result.GetType().ToString().Equals("Microsoft.Bot.Builder.Dialogs.Choices.FoundChoice")) { //Extract the picked result from the step-context var pickedChoice = (FoundChoice)stepContext.Result; var choiceText = pickedChoice.Value; //Set the result to the ChangeCharttypeDetails-Object filterForNumberDetails.columnName = new string[] { choiceText }; } //Now the Object is set right and we can print, what we want to change our charttype to ConsoleWriter.WriteLineInfo("Filtering " + filterForNumberDetails.columnName[0] + " " + filterForNumberDetails.comparisonOperator + " " + filterForNumberDetails.filterNumber); await BOT_Api.SendFilterForNumber(stepContext, filterForNumberDetails.columnName[0], filterForNumberDetails.comparisonOperator, filterForNumberDetails.filterNumber); return(await stepContext.EndDialogAsync(filterForNumberDetails, cancellationToken)); }
//Confirm task private async Task <DialogTurnResult> FinalStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { var changeVisualizationPartDetails = (ChangeVisualizationPartDetails)stepContext.Options; //We are comming from a ChoicePromt ==> Convert result to FoundCHoice if (stepContext.Result.GetType().ToString().Equals("Microsoft.Bot.Builder.Dialogs.Choices.FoundChoice")) { //Extract the picked result from the step-context var pickedChoice = (FoundChoice)stepContext.Result; var choiceText = pickedChoice.Value; //Set the result to the ChangeCharttypeDetails-Object changeVisualizationPartDetails.toValue = new string[] { choiceText }; } //Now the Object is set right and we can print, what we want to change our charttype to ConsoleWriter.WriteLineInfo("Change " + changeVisualizationPartDetails.visualizationPart + " to (first Value): " + changeVisualizationPartDetails.toValue[0]); await BOT_Api.SendChangeVisualizationPart(stepContext, changeVisualizationPartDetails.visualizationPart, changeVisualizationPartDetails.toValue[0]); return(await stepContext.EndDialogAsync(changeVisualizationPartDetails, cancellationToken)); }
//This function is called every time the user enters an input. The intent is determined in the switch case block. From there we call the needed Dialogs private async Task <DialogTurnResult> ActStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { var luisResult = await _luisRecognizer.RecognizeAsync <VisualizationInteraction>(stepContext.Context, cancellationToken); switch (luisResult.TopIntent().intent) { //The user wants to change the charttype case VisualizationInteraction.Intent.ChangeChartType: string[] chartTypeResults = luisResult.ToChartTypeEntity; var changeChartTypeDetails = new ChangeChartTypeDetails() { AmbiguousChartTypes = chartTypeResults, ToChartType = chartTypeResults?[0], }; //Check if changechartTypeDetails is null (in the Dialog) and ask for information if it is null return(await stepContext.BeginDialogAsync(nameof(ChangeChartTypeDialog), changeChartTypeDetails, cancellationToken)); // user wants to filter for country, product or segment (nominal Rows) case VisualizationInteraction.Intent.Filter: (string[] columnnameLuis, string[] filterAttributeLuis, string[] countryLuis, string[] segmentLuis, string[] productLuis) = luisResult.FilterForWordEntities; string usedColumn; if (countryLuis != null) { usedColumn = "Country"; } else if (segmentLuis != null) { usedColumn = "Segment"; } else if (productLuis != null) { usedColumn = "Product"; } else { usedColumn = "Country"; } ConsoleWriter.WriteLineInfo("Column: " + usedColumn); var filterForWordDetails = new FilterForWordDetails { columnName = columnnameLuis, filterAttribute = filterAttributeLuis, country = countryLuis, segment = segmentLuis, product = productLuis, usedColumn = usedColumn }; return(await stepContext.BeginDialogAsync(nameof(FilterForWordDialog), filterForWordDetails, cancellationToken)); //user wants to filter for number (cardinal rows) case VisualizationInteraction.Intent.FilterForNumber: (string[] columnNameLuis, string comparisonOperatorLuis, string filterNumberLuis) = luisResult.FilterForNumberEntities; var filterForNumberDetails = new FilterForNumberDetails { columnName = columnNameLuis, comparisonOperator = comparisonOperatorLuis, filterNumber = filterNumberLuis }; return(await stepContext.BeginDialogAsync(nameof(FilterForNumberDialog), filterForNumberDetails, cancellationToken)); //user input is a complete query to be visualized -> send query to nl4dv case VisualizationInteraction.Intent.Nl4dv: //Gets the whole message from the User to the bot out of the luis result string nl4dvQuery = luisResult.Text; (string queryText, string[] chartType, string[] axis1, string[] axis2) = luisResult.Nl4dvEntities; var nl4dvQueryDetails = new Nl4dvQueryDetails { queryText = queryText, chartType = chartType, axis1 = axis1, axis2 = axis2 }; ConsoleWriter.WriteLineInfo("nl4dvQuery: " + nl4dvQuery); return(await stepContext.BeginDialogAsync(nameof(Nl4dvDialog), nl4dvQueryDetails, cancellationToken)); //Here we would have to call the NL4DV function in the event handler (in the Python project) //BOT_Api.SendNL4DV(nl4dvQuery); break; // user wants to change e.g. legend or y-axis case VisualizationInteraction.Intent.ChangeVisualizationPart: (string visualizationPartLuis, string[] toValueLuis) = luisResult.ChangeVisualizationPartEntities; var changeVisualizationPartDetails = new ChangeVisualizationPartDetails { visualizationPart = visualizationPartLuis, toValue = toValueLuis }; return(await stepContext.BeginDialogAsync(nameof(ChangeVisualizationPartDialog), changeVisualizationPartDetails, cancellationToken)); // user wants to change the aggregate of an axis case VisualizationInteraction.Intent.ChangeAggregate: (string toVisPartLuis, string toAggregateLuis) = luisResult.ChangeAggregateEntities; var changeAggregateDetails = new ChangeAggregateDetails { visualizationPart = toVisPartLuis, toAggregate = toAggregateLuis }; return(await stepContext.BeginDialogAsync(nameof(ChangeAggregateDialog), changeAggregateDetails, cancellationToken)); case VisualizationInteraction.Intent.ClearFilter: await BOT_Api.SendClearFilter(stepContext); break; case VisualizationInteraction.Intent.Help: var helpMessageText = "Here is a quick guide for you: say \"show me sales by country\" to create a new visualization || \"change yaxis to profit\" to change the label of y-axis to profit || \"change aggregate of yaxis to sum\" changes the data aggregation of yaxis to sum (you can say sum, count, average) || \"change charttype to piechart\" changes the visualization to a piechart || \"filter for sales >= 200\" filters the dataset for all rows containing sales >= 200 || \"clear filter\" to clear all added filters"; var helpMessage = MessageFactory.Text(helpMessageText, helpMessageText, InputHints.IgnoringInput); await stepContext.Context.SendActivityAsync(helpMessage, cancellationToken); break; //intent not recognized default: // Catch all for unhandled intents var didntUnderstandMessageText = $"Sorry, I didn't get that. Please try asking in a different way (intent was {luisResult.TopIntent().intent})"; var didntUnderstandMessage = MessageFactory.Text(didntUnderstandMessageText, didntUnderstandMessageText, InputHints.IgnoringInput); await stepContext.Context.SendActivityAsync(didntUnderstandMessage, cancellationToken); break; } return(await stepContext.NextAsync(null, cancellationToken)); }
//Check if input is empty or additionally it is asked to filter for countries, then add country option list private async Task <DialogTurnResult> SelectionStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { // Continue using the same selection list, if any, from the previous iteration of this dialog. var list = stepContext.Options as List <string> ?? new List <string>(); bool filterForCountry = false; if (stepContext.Options.GetType().ToString().Equals("Microsoft.BotBuilderSamples.FilterForWordDetails")) { FilterForWordDetails filterForWordDetails = (FilterForWordDetails)stepContext.Options; usedColumn = filterForWordDetails.usedColumn; // Check if filter for Word Dialog input is empty if (filterForWordDetails.columnName == null) { string messageNull = "I could not recognize what column you want to apply that filter to. Please say something like \"Filter for Germany and Canada\""; var cancelMessage = MessageFactory.Text(messageNull, CancelMsgText, InputHints.IgnoringInput); await stepContext.Context.SendActivityAsync(cancelMessage, cancellationToken); return(await stepContext.CancelAllDialogsAsync(cancellationToken)); } //Filter for country for (int i = 0; i < filterForWordDetails.columnName.Length; i++) { string s = UppercaseFirst(filterForWordDetails.columnName[i]); list.Add(s); //becomes true when you enter "filter for country" if (string.Equals(s, "Country") || string.Equals(s, "Countries")) { filterForCountry = true; } } if ((filterForWordDetails.country == null) && (filterForWordDetails.segment == null) && (filterForWordDetails.product == null) && !filterForCountry) { string messageNull = "I could not recognize what column you want to apply that filter to. Please say something like \"Filter for Germany and Canada\""; var cancelMessage = MessageFactory.Text(messageNull, CancelMsgText, InputHints.IgnoringInput); await stepContext.Context.SendActivityAsync(cancelMessage, cancellationToken); return(await stepContext.CancelAllDialogsAsync(cancellationToken)); } //Breaks if we did not recognize any countries if (!filterForCountry) { filterForWordDetails.columnName = list.ToArray(); ConsoleWriter.WriteLineInfo("Filter for: " + string.Join(", ", list)); ConsoleWriter.WriteLineInfo("ColumnName: " + filterForWordDetails.columnName[0]); await BOT_Api.SendFilterForWord(stepContext, usedColumn, list.ToArray()); return(await stepContext.EndDialogAsync(filterForWordDetails.columnName)); } } //if user entered "FILTER FOR COUNTRY" OR "COUNTRIES": stepContext.Values[CountriesSelected] = list; //Create a prompt message string message; if (list[0] == "Country") { message = $"Please choose a country to filter to finish."; list.Remove("Country"); } else if (list[0] == "Countries") { message = $"Please choose a country to filter to finish."; list.Remove("Countries"); } else { message = $"You have selected **{String.Join(", ", list)}**. You can filter for an additional country, " + $"or choose `{DoneOption}` to finish."; } // Create the list of options to choose from. var options = _countryOptions.ToList(); if (list.Count > 0) { options.Add(DoneOption); options = options.Except(list).ToList(); } var promptOptions = new PromptOptions { Prompt = MessageFactory.Text(message), RetryPrompt = MessageFactory.Text("Please choose an option from the list."), Choices = ChoiceFactory.ToChoices(options), }; // Prompt the user for a choice. return(await stepContext.PromptAsync(nameof(ChoicePrompt), promptOptions, cancellationToken)); }