我目前计划在我的 C# 机器人中使用对话框。我已经设计了一个 完成对话框并将其实现到我当前的解决方案中,但是当我对其进行测试时,我只能触发它的第一部分。
我的机器人配置如下:
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
string[] PostCodeDialogStartTrigger = new string[] { "trigger1", "trigger2", "trigger3" };
if (PostCodeDialogStartTrigger.Contains(turnContext.Activity.Text) /* Maybe || ConversationState != null */)
{
await Dialog.RunAsync(turnContext, ConversationState.CreateProperty<DialogState>(nameof(DialogState)), cancellationToken);
}
else
{
// First, we use the dispatch model to determine which cognitive service (LUIS or QnA) to use.
var recognizerResult = await BotServices.Dispatch.RecognizeAsync(turnContext, cancellationToken);
// Top intent tell us which cognitive service to use.
var topIntent = recognizerResult.GetTopScoringIntent();
// Next, we call the dispatcher with the top intent.
await DispatchToTopIntentAsync(turnContext, topIntent.intent, recognizerResult, cancellationToken);
}
}
我在 PostCodeDialogStartTrigger
中有一组字符串。我希望对话框在用户消息与触发器之一匹配时启动。否则我的常规流程应该开始,其中包括用于一维对话的 LUIS 和 QnA Maker。问题是我不能留在对话框中,因为下一条消息显然不会再次触发对话框。
有没有办法检查 ConversationState 或 UserState,如果它已经取得进展,对话会继续吗?
答案 0 :(得分:1)
你想要的是中断:https://docs.microsoft.com/azure/bot-service/bot-builder-howto-handle-user-interrupt
核心机器人示例通过创建一个使任何对话“可中断”的基本 CancelAndHelpDialog
类,包括一种处理中断的稍微复杂的方法,但有一种更简单的方法。关键是默认每回合都调用ContinueDialogAsync
,只有在该回合发生中断时才调用它。您可以将每个回合视为三种情况:
逻辑可能是这样的:
string[] PostCodeDialogStartTrigger = new string[] { "trigger1", "trigger2", "trigger3" };
if (PostCodeDialogStartTrigger.Contains(turnContext.Activity.Text))
{
// Case 1: Handle interruptions by starting a dialog
await dialogContext.BeginDialogAsync(DIALOG_ID);
}
else
{
// Case 2: Try to continue the dialog in case there is one
var result = await dialogContext.ContinueDialogAsync();
if (result.Status == DialogTurnStatus.Empty)
{
// Case 3: If there aren't any dialogs on the stack
// First, we use the dispatch model to determine
// which cognitive service (LUIS or QnA) to use.
// . . .
}
}
您可能会注意到我在这里没有使用 RunAsync
。 RunAsync
与您的机器人的“主对话框”配合使用时效果最好,它意味着始终在堆栈中,如果您没有真正的主对话框,它就不会那么好用。 RunAsync
的最初目的是将几个方法调用合并为一个,因为机器人调用 ContinueDialogAsync
然后检查结果然后启动主对话框是一种常见的模式,如果对话框堆栈是空的。您想做类似的事情,但不是在对话堆栈为空的情况下开始主对话,而是只想调用 dispatch。
如果您好奇,这里有一些其他 Stack Overflow 帖子,您可以在其中阅读有关中断的信息:
我应该提到您正在尝试以一种过时的方式做事。您可能已经注意到 Dispatch 已被 Orchestrator 取代,因此您确实应该改用 Orchestrator。此外,Composer 还简化了诸如中断之类的操作,无论如何,建议每个人现在都使用 Composer。