0

I have chatbot created in C# using SDK .net Core 2.2 Virtual Assistant Template which has 1 main dialog and multiple dialog's(Component Dialog's). Each component dialog calls another component dialog. Let's say I have MainDialog, 2 component dialog's named ComponentDialog1,ComponentDialog2.

I am using DialogsTriggerState to know to which component dialog to trigger across entire bot.

Main Dialog Code: I am calling ComponentDialog1 in RouteAsync method of main dialog.

protected override async Task RouteAsync(DialogContext dc, CancellationToken cancellationToken = default(CancellationToken))
{
    var triggerState = await _triggerStateAccessor.GetAsync(dc.Context, () => new DialogsTriggerState());
    await dc.BeginDialogAsync(nameof(ComponentDialog1), triggerState);
    var turnResult = EndOfTurn;
    if (turnResult != EndOfTurn)
    {
        await CompleteAsync(dc);
    }
}

ComponentDialog1 Code: I have 3 waterfall steps , in which 2nd step will call to specific "ComponentDialog" depend on bot state. Assume I am triggering to "ComponentDialog2".

private async Task<DialogTurnResult> TriggerToSpecificComponentDialogAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
    var triggerState = await _DialogsTriggerStateAccessor.GetAsync(stepContext.Context, () => null);

    if (triggerState.TriggerDialogId.ToString().ToLower() == "componentdialog2")
    {
        return await stepContext.BeginDialogAsync(nameof(ComponentDialog2), triggerState);
    }
    else if (triggerState.TriggerDialogId.ToString().ToLower() == "componentdialog3")
    {
        return await stepContext.BeginDialogAsync(nameof(ComponentDialog3), triggerState);
    }
    else
    {
        return await stepContext.NextAsync();
    }
}

ComponentDialog2 Code: I have 2 waterfall steps that shows adaptive card and fetch values from card and end dialog(ComponentDialog2)

private async Task<DialogTurnResult> DisplayCardAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
    // Display the Adaptive Card
    var cardPath = Path.Combine(".", "AdaptiveCard.json");
    var cardJson = File.ReadAllText(cardPath);
    var cardAttachment = new Attachment()
    {
        ContentType = "application/vnd.microsoft.card.adaptive",
        Content = JsonConvert.DeserializeObject(cardJson),
    };
    var message = MessageFactory.Text("");
    message.Attachments = new List<Attachment>() { cardAttachment };
    await stepContext.Context.SendActivityAsync(message, cancellationToken);

    // Create the text prompt
    var opts = new PromptOptions
    {
        Prompt = new Activity
        {
            Type = ActivityTypes.Message,
            Text = "waiting for user input...", // You can comment this out if you don't want to display any text. Still works.
        }
    };

    // Display a Text Prompt and wait for input
    return await stepContext.PromptAsync(nameof(TextPrompt), opts);
}

private async Task<DialogTurnResult> HandleResponseAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
    await stepContext.Context.SendActivityAsync($"INPUT: {stepContext.Result}");
   //I am doing some logic and may continue to next steps also from here, but as I am stuck here i am ending dialog.
    return await stepContext.EndDialogAsync();
}

Problem: After clicking adaptive card submit in "ComponentDialog2" of 1st step, code(control) is not pointing to 2nd step "HandleResponseAsync" which it should be happen as I had provided Prompt and waiting for input.

Actual Output: I am neither getting any output nor errors in bot.

Expected Output:

1) Display to bot from ComponentDialog2: INPUT:Whatever I submitted

2) As i am ending dialog in ComponentDialog2, control(code) should return back to ComponentDialog1 and should go to 3rd waterfall step of ComponentDialog1.

Sample Adaptive Card

  {
   "type": "AdaptiveCard",
   "body": [
    {
        "type": "TextBlock",
        "size": "Medium",
        "weight": "Bolder",
        "text": "Let us know your feedback"
    }
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.0",
"actions": [
    {
        "type": "Action.Submit",
        "title": "Good",
        "data": "good"
    },

     {
        "type": "Action.Submit",
        "title": "Average",
        "data": "avaerage"
    }
    ,{
        "type": "Action.Submit",
        "title": "Bad",
        "data": "bad"
    }
]
}

Please help me how to achieve

Roberto Pegoraro
  • 1,313
  • 2
  • 16
  • 31
PavanKumar GVVS
  • 859
  • 14
  • 45

1 Answers1

0

After significant testing, I'm fairly certain that you're missing this call somewhere (it should somehow get called in OnMessageAsync():

var results = await dialogContext.ContinueDialogAsync(cancellationToken);

The way the Core Bot Sample does this is by adding it to DialogExtensions, which gets called in OnMessageAsync()


Update: I've also noticed that this can happen if await ConversationState.SaveChangesAsync(turnContext, true, cancellationToken); is in OnTurnAsync() but on in OnDialogAsync() (or if it isn't in either location); you also want to make sure that it's set to false and not true, generally.

mdrichardson
  • 7,141
  • 1
  • 7
  • 21