基于MS Bot Framework中的响应分支对话框/表单

时间:2017-03-21 18:31:57

标签: c# botframework

我们正在尝试使用MS Bot框架,并且还没有完成如何实现这种情况:

我们有一个LUIS对话框(类型<object>),它正常工作并且训练有素。要使用常见的三明治示例,LUIS意图所寻找的基础是用户询问订单的状态。如果问题中提供了订单号(&#34;订单1234的状态是什么?&#34;),则LUIS对话框会执行查找并直接报告状态(当前正在运行)。

但是,如果用户只是在未提供订单号的情况下触发了意图(&#34;我想查询订单的状态。&#34;),我想要启动另一个对话框/表单,询问用户是否要按地址或订单号查找订单,然后根据他们的回答方式进行相应的数据库查找。

我只是不确定如何配置表单/对话框(或者甚至在这种情况下哪个是最好的)来根据他们选择地址或数字查找来执行不同的查找。

到目前为止的目的是:

private readonly BuildFormDelegate<OrderStatusDialog> OrderStatusDelegate;

[LuisIntent(nameof(LuisIntents.OrderStatus))]
public async Task OrderStatus(IDialogContext context, LuisResult result)
{
    // Order number(s) were provided
    if (result.Entities.Any(Entity => Entity.Type == nameof(LuisEntityTypes.OrderNumber)))
    {
        // Loop in case they asked about multiple orders
        foreach (var entity in result.Entities.Where(Entity => Entity.Type == nameof(LuisEntityTypes.OrderNumber)))
        {
            var orderNum = entity.Entity;

            // Call webservice to check status
            var request = new RestRequest(Properties.Settings.Default.GetOrderByNum, Method.GET);
            request.AddUrlSegment("num", orderNum);
            var response = await RestHelper.SendRestRequestAsync(request);

            var parsedResponse = JObject.Parse(response);

            if ((bool)parsedResponse["errored"])
            {
                await context.PostAsync((string)parsedResponse["errMsg"]);
                continue;
            }

            // Grab status from returned JSON
            var status = parsedResponse["orderStatus"].ToString();

            await context.PostAsync($"The status of order {orderNum} is {status}");
        }

        context.Wait(MessageReceived);
    }
    // Order number was not provided
    else
    {
        var orderStatusForm = new FormDialog<OrderStatusDialog>(new OrderStatusDialog(), OrderStatusDelegate,
            FormOptions.PromptInStart);
        context.Call<OrderStatusDialog>(orderStatusForm, CallBack);
    }
}

private async Task CallBack(IDialogContext context, IAwaitable<object> result)
{
    context.Wait(MessageReceived);
}

形式:

public enum OrderStatusLookupOptions
{
    Address,
    OrderNumber
}

[Serializable]
public class OrderStatusDialog
{
    public OrderStatusLookupOptions? LookupOption;

    public static IForm<OrderStatusDialog> BuildForm()
    {
        return new FormBuilder<OrderStatusDialog>()
            .Message("In order to look up the status of a order, we will first need either the order number or your delivery address.")
            .Build();
    }
}

1 个答案:

答案 0 :(得分:2)

FormFlow路由是一个有效的选项。表单流程中缺少的是在选择查找选项后询问地址/订单号。

在这种情况下,您可以执行的操作是在OrderStatusDialog课程中再添加两个字段:OrderNumberDeliveryAddress

然后,您需要使用所选的OrderStatusLookupOptions来激活/停用下一个字段。

从我的头脑中,代码将是:

[Serializable]
public class OrderStatusDialog
{
    public OrderStatusLookupOptions? LookupOption;

    public int OrderNumber;

    public string DeliveryAddress

    public static IForm<OrderStatusDialog> BuildForm()
    {
        return new FormBuilder<OrderStatusDialog>()
            .Message("In order to look up the status of a order, we will first need either the order number or your delivery address.")
            .Field(nameof(OrderStatusDialog.LookupOption))
            .Field(new FieldReflector<OrderStatusDialog>(nameof(OrderStatusDialog.OrderNumber))
                .SetActive(state => state.LookupOption == OrderStatusLookupOptions.OrderNumber))
            .Field(new FieldReflector<OrderStatusDialog>(nameof(OrderStatusDialog.DeliveryAddress))
                .SetActive(state => state.LookupOption == OrderStatusLookupOptions.Address))
            .Build();
    }
}

然后在您的Callback方法上,您将收到填写的表单,您可以进行数据库查找。

或者,您可以使用PromptDialogs并引导用户体验相同的体验。查看MultiDialogs示例,了解不同的替代方案。

我在此here上添加了一个工作示例。