-->

Sending an IForm from a LUIS intent

2019-06-02 22:26发布

问题:

I currently have a chatbot running in visual studio using Microsoft's bot framework in the language c#. I integrated LUIS into the bot and I'm wondering how can I make it so that a FormFlow similar to this example appears on a specific intent.

So far this is the code for my Form:

internal static IDialog<InfoGroup> MakeRootDialog()
    {
        return Chain.From(() => FormDialog.FromForm(InfoGroup.BuildForm));
    }
public enum GroupOptions
{
    A, B, C, D, E, F, G, H
};
[Serializable]
public class InfoGroup
{
    public GroupOptions? groupId;

    public static IForm<InfoGroup> BuildForm()
    {
        return new FormBuilder<InfoGroup>()
                .Message("Please select an option")
                .Build();
    }
};

And I'm trying to send it form my LUIS intent method like so:

[LuisIntent("SpecificGroup")]
    public async Task SpecificGroupIntent(IDialogContext context, IAwaitable<IMessageActivity> activity, LuisResult result)
    {
        await context.PostAsync(FormDialog.FromForm(InfoGroup.BuildForm));
        context.Wait(MessageReceived);
        return;
    }

This is obviously not the correct way to call the form, how can I make it so that a form appears as a response called directly from my SpecificGroupIntent() method? Any help will be greatly appreciated. After the form is filled I want to use the option that the user selected to display text accordingly.

回答1:

You can invoke the formflow builder from a luis intent method like calling a dialog from a parent dialog using the context.Call() method. You will also need to specify a method that will be executed once the form is filled.

Eg: Calling the formbuilder by creating a FormDialog of InfoGroup(Your form) type and specifying method to be executed after it.

InfoGroup form = new InfoGroup();    
FormDialog<InfoGroup> InfoGroupform = new FormDialog<InfoGroup>(form, InfoGroup.BuildForm, FormOptions.PromptInStart);
context.Call(InfoGroupform, InfoGroupFormSubmitted);

InfoGroupFormSubmitted is the method that will be called once your form is filled. You need this because if you are using context.Call() method you need to specify a resumeAfter method for it. In this InfoGroupFormSubmitted method you can just give a confirmation if the form was correctly filled or if the user quit you can just catch the exception and show where the user quit.

public static async Task InfoGroupFormSubmitted(IDialogContext context, IAwaitable<InfoGroup> result)
{
        try
        {
             var query = await result;
             context.PostAsync("Your choice has been recorded.");
        } 
        catch (FormCanceledException<InfoGroup> e)
        {
              string reply;
              if (e.InnerException == null)
              {
                    reply = $"You quit on {e.Last}--maybe you can finish next time!";
              }
              else
              {
                    reply = $"Sorry, I've had a short circuit.  Please try again.";
              }
              context.Done(true);
              await context.PostAsync(reply);
        }
}