在LuisIntent方法中处理自适应卡按钮

时间:2017-08-11 14:27:10

标签: c# botframework chatbot luis adaptive-cards

我正在使用MS Bot Framework和LUIS开发一个机器人,在我的对话流程中有很多带按钮的自适应卡。我需要一种方法来处理这个流程的按钮(准确的Action.Submit按钮)。

我第一次尝试:

public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
   if (activity.Type == ActivityTypes.Message)
   {
       if (activity.Text != null & activity.Value == null)
       {
          await Conversation.SendAsync(activity, () => new RootLuisDialog());
       }
       else if (activity.Text == null & activity.Value != null)
       {
         await Conversation.SendAsync(activity, () => new ButtonHandler());
       }
   }
   else
   {
       this.HandleSystemMessage(activity);
   }

   var response = Request.CreateResponse(HttpStatusCode.OK);
   return response;
}

因为单击自适应卡上的按钮时activity.Value包含Action.Submit按钮的属性。

我们的想法是能够分离按钮控制器和RootLuisDialog()的意图控制器。但它不起作用,我不知道为什么:使用此代码,始终RootLuisDialog()退出。换句话说,对话框保留在RootLuisDialog()

第二个想法是如此使用None Luis Intent:

    [LuisIntent("")]
    [LuisIntent("None")]
    public async Task None(IDialogContext context, LuisResult result)
    {
        var act = context.Activity as IMessageActivity;
        string message = String.Empty;
        if (act.Text != null & act.Value == null)
        {
            message = $"Sorry, I did not understand '{act.Text}'. Type 'help' if you need assistance.";
        }
        else if (act.Text == null & act.Value != null)
        {
            Button btn = JsonConvert.DeserializeObject<Button>(act.Value.ToString());
            message = $"You clicked on {btn.Type}";
        }
        await context.PostAsync(message);

        context.Wait(this.MessageReceived);
    }

虽然这有效,但在None意图下按下按钮代码似乎不合适。

我也试过context.Wait(buttonHandler) buttonHandler是一个异步函数来处理按钮按下但是我收到了这条错误消息:

   "exceptionMessage": "Object reference not set to an instance of an object.",
   "exceptionType": "System.NullReferenceException",

我确信我想要实现的目标已经有了一个很好的答案,但这是我的第一个C#项目/任务,我需要帮助才能对此进行排序。 非常感谢提前!!!

1 个答案:

答案 0 :(得分:2)

我认为如果你想将按钮的处理与LUIS意图分开,那么更好的设计可能是有一个RootDialog可以做三件事:

  1. 检查传入的活动
  2. 如果activity.Value为空,则将活动FWD转换为LuisDialog(使用context.Forward。假设您要检查1)的所有消息,则必须“结束”LUIS对话框使用context.Done执行逻辑后(而不是执行context.Wait(...)
  3. 如果activity.Value不为空,则可以在RootDialog中处理该消息,并以context.Wait(...)结束;