Krumelur
Krumelur

Reputation: 33048

How to forward result of Prompt.Choice() to current dialog?

I'm using PromptDialog.Choice() to present different options to my users. The number of attempts is set to 0, so if they type in anything that is not a valid option, there won't be any retries.

In this case I would like to pass the entered text to the current dialog who has presented to prompt and let it handle the message.

What is the correct way of doing this? I tried creating a new activity in the resume-handler of the prompt dialog and directly call the MessageReceivedAsync() method but that a) does not work as expected and b) seems to be a hack.

An example would be a prompt that asks "I'm not sure what you want to do. Show help or keep trying?" with two options "Help" and "Keep trying". However, if the user now enters "what is one plus one?", I'd like the current dialog to handle this.

I could also ask differently: how can I replace the current dialog on top of the stack with another one? This would allow me to just call the same dialog.

Upvotes: 2

Views: 921

Answers (2)

phani
phani

Reputation: 161

Adding some more context to Ezequiel Jadib answer. I ran into a requirement similar to question mentioned in link below. Also, used one of the answer provided to the same question.

Calling back Luis from a forward dialog

Though the above question is marked as duplicate to current, I feel the Luis context is missing from this question.

If the Activity is created without Channel, From and Recipient information, you may end up with some exception while creating a reply. So, below code will help you create the right activity and set the correct message before handing it over to Luis

Luis Intent Method

    [LuisIntent("PerformSearch")]
    public async Task Search(IDialogContext context, IAwaitable<IMessageActivity> activity, LuisResult result)
    {
        var msg = await activity;
        msg.Value = result;
        await context.Forward(new SearchDialog(), ResumeAfterSearchPerformed, msg, CancellationToken.None);

    }

Resume After method for Forwarded Dialog

    private async Task ResumeAfterSearchPerformed(IDialogContext context, IAwaitable<object> result)
    {

        var msg = await result;            
        var userSearchString = msg.ToString();
        if (userSearchString.Equals("searchCompleted", StringComparison.InvariantCultureIgnoreCase))
        {                
            context.Wait(MessageReceived);
        }
        else
        {
            // At this point send the message back to LUIS MessageReceived 
            // method to re-identify the intent and trigger the method
            Activity myActivity = (Activity)context.Activity;
            myActivity.Text = userSearchString;
            await MessageReceived(context, Awaitable.FromItem(myActivity));
        }
    }

By doing above, you can easily create a reply from properly hydrated Activity

 Activity reply = ((Activity)message).CreateReply();
 reply.AttachmentLayout = AttachmentLayoutTypes.Carousel;

Upvotes: 1

Ezequiel Jadib
Ezequiel Jadib

Reputation: 14787

I think that calling MessageReceivedAsync will be the way to go here. The key is to pass an IAwaitable from the activity you are creating.

The code should be like:

await MessageReceivedAsync(context, Awaitable.FromItem(yourActivity));

Upvotes: 2

Related Questions