Reputation: 1861
Introduction
Currently I'm trying to create a Bot Framework application using the Microsoft Bot Framework v4.
Structure of program
We currently have the following setup:
The root of the bot class is named: SubDialogBotBot
Within the SubDialogBot
we create a new Dialog named ParentDialog
. This Dialog is responsible for reacting to a specific Intent.
We then start a new Dialog from the ParentDialog
named ChildDialog
. This child dialog will be responsible for asking the user a question based on arguments passed by ParentDialog
.
After this question completed we want to return to the ParentDialog
and continue the flow.
In this example we want to re-use the ChildDialog
from all kinds of different intents as the code in here is exactly the same. The only thing that changes is the questions that have to be asked to the user.
Problem
When the ChildDialog
completes the 'flow' is never returned to the ParentDialog
.
We also tried to have the Dialog following after the ChildDialog
ID set to something specific and then call this using Context.BeginDialog(....) from the ChildDialog
. However because apparently the dialog was added to the ParentDialog
and not to the ChildDialog
it can't find this by the id.
Github repository reproducing the problem
https://github.com/devedse/SubDialogBotReproduction
Upvotes: 4
Views: 852
Reputation: 33379
First, this is an awesomely prepared question, thank you... especially for sharing the code.
Now, the good news is I don't think I see any problem with your dialogs. The problem is actually in your bot's OnTurnAsync
. You are only ever calling BeginDialogAsync
on your ParentDialog
. Every single activity is going to come in through your OnTurnAsync
and that means you're responsible for handling re-entrancy into the dialog stack. This means that, you need to check for an active dialog and, if there is one, you need to be calling ContinueDialogAsync
instead to resume from where the discussion left off. Here's your current OnTurnAsync
with the extra checks added:
public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
{
// Create a dialog context
var dc = await Dialogs.CreateContextAsync(turnContext);
// Handle Message activity type, which is the main activity type for shown within a conversational interface
// Message activities may contain text, speech, interactive cards, and binary or unknown attachments.
// see https://aka.ms/about-bot-activity-message to learn more about the message and other activity types
if (turnContext.Activity.Type == ActivityTypes.Message)
{
// If there's no active dialog, begin the parent dialog
if(dc.ActivDialog == null)
{
await dc.BeginDialogAsync(nameof(ParentDialog));
}
else
{
await dc.ContinueDialogAsync();
}
// Save the new turn count into the conversation state.
await _accessors.ConversationState.SaveChangesAsync(turnContext);
}
else
{
await turnContext.SendActivityAsync($"{turnContext.Activity.Type} event detected");
}
}
Upvotes: 2