在 LuisIntent 方法中处理自适应卡片按钮
Handle Adaptive Card button inside LuisIntent method
我正在使用 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# project/task,我需要帮助来解决这个问题。
提前致谢!!!
我认为,如果您想将按钮的处理与 LUIS
意图分开,更好的设计可能是让 RootDialog 做 3 件事:
- 检查传入activity
- 如果
activity.Value
为空,则将 activity FWD 到 LuisDialog(使用 context.Forward
。假设您要检查 1 的所有消息),那么您将不得不"end" 使用 context.Done
(而不是 context.Wait(...)
)执行逻辑后的 LUIS 对话框
- 如果
activity.Value
不为空,那么您可以在 RootDialog 中处理消息并以 context.Wait(...)
; 结束
我正在使用 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# project/task,我需要帮助来解决这个问题。 提前致谢!!!
我认为,如果您想将按钮的处理与 LUIS
意图分开,更好的设计可能是让 RootDialog 做 3 件事:
- 检查传入activity
- 如果
activity.Value
为空,则将 activity FWD 到 LuisDialog(使用context.Forward
。假设您要检查 1 的所有消息),那么您将不得不"end" 使用context.Done
(而不是context.Wait(...)
)执行逻辑后的 LUIS 对话框 - 如果
activity.Value
不为空,那么您可以在 RootDialog 中处理消息并以context.Wait(...)
; 结束