c# - 如何在 C# [Bot Framework v4] 中从 QnaBot (qna maker api) 调用瀑布对话框?
问题描述
我已经使用 c# 在 Bot Framework v4 中创建了一个 qna maker bot,现在当 qna 知识库中没有找到答案时,我必须调用一个瀑布对话框向用户提出一些问题。
我该怎么做?
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
var httpClient = _httpClientFactory.CreateClient();
var qnaMaker = new QnAMaker(new QnAMakerEndpoint
{
KnowledgeBaseId = _configuration["QnAKnowledgebaseId"],
EndpointKey = _configuration["QnAAuthKey"],
Host = GetHostname()
},
null,
httpClient);
_logger.LogInformation("Calling QnA Maker");
// The actual call to the QnA Maker service.
var response = await qnaMaker.GetAnswersAsync(turnContext);
if (response != null && response.Length > 0)
{
string message = GetMessage(response[0].Answer);
Attachment attachment = GetHeroCard(response[0].Answer);
await turnContext.SendActivityAsync(MessageFactory.Text(message), cancellationToken);
if (attachment != null)
await turnContext.SendActivityAsync(MessageFactory.Attachment(attachment), cancellationToken);
}
else
{
//HERE I WANT TO CALL WATERFALL DIALOG
//await turnContext.SendActivityAsync(MessageFactory.Text("No QnA Maker answers were found."), cancellationToken);
}
}
解决方案
您可以使用多轮提示,它使用瀑布对话框、一些提示和组件对话框来创建简单的交互,向用户询问一系列问题。机器人通过 UserProfileDialog 与用户交互。当我们创建机器人的 DialogBot 类时,我们会将 UserProfileDialog 设置为其主对话框。然后,机器人使用 Run 辅助方法来访问对话框。
要使用提示,请从对话框中的步骤调用它,并使用 stepContext.Result 在以下步骤中检索提示结果。您应该始终从瀑布步骤返回非空 DialogTurnResult。
询问用户姓名的示例如下:
public class UserProfileDialog : ComponentDialog
{
private readonly IStatePropertyAccessor<UserProfile> _userProfileAccessor;
public UserProfileDialog(UserState userState)
: base(nameof(UserProfileDialog))
{
_userProfileAccessor = userState.CreateProperty<UserProfile>("UserProfile");
// This array defines how the Waterfall will execute.
var waterfallSteps = new WaterfallStep[]
{
NameStepAsync,
NameConfirmStepAsync,
SummaryStepAsync,
};
// Add named dialogs to the DialogSet. These names are saved in the dialog state.
AddDialog(new WaterfallDialog(nameof(WaterfallDialog), waterfallSteps));
AddDialog(new TextPrompt(nameof(TextPrompt)));
AddDialog(new ConfirmPrompt(nameof(ConfirmPrompt)));
// The initial child Dialog to run.
InitialDialogId = nameof(WaterfallDialog);
}
private static async Task<DialogTurnResult> NameStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
stepContext.Values["transport"] = ((FoundChoice)stepContext.Result).Value;
return await stepContext.PromptAsync(nameof(TextPrompt), new PromptOptions { Prompt = MessageFactory.Text("Please enter your name.") }, cancellationToken);
}
private async Task<DialogTurnResult> NameConfirmStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
stepContext.Values["name"] = (string)stepContext.Result;
// We can send messages to the user at any point in the WaterfallStep.
await stepContext.Context.SendActivityAsync(MessageFactory.Text($"Thanks {stepContext.Result}."), cancellationToken);
// WaterfallStep always finishes with the end of the Waterfall or with another dialog; here it is a Prompt Dialog.
return await stepContext.PromptAsync(nameof(ConfirmPrompt), new PromptOptions { Prompt = MessageFactory.Text("Would you like to give your age?") }, cancellationToken);
}
private async Task<DialogTurnResult> SummaryStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
if ((bool)stepContext.Result)
{
// Get the current profile object from user state.
var userProfile = await _userProfileAccessor.GetAsync(stepContext.Context, () => new UserProfile(), cancellationToken);
userProfile.Name = (string)stepContext.Values["name"];
}
else
{
await stepContext.Context.SendActivityAsync(MessageFactory.Text("Thanks. Your profile will not be kept."), cancellationToken);
}
// WaterfallStep always finishes with the end of the Waterfall or with another dialog, here it is the end.
return await stepContext.EndDialogAsync(cancellationToken: cancellationToken);
}
}
本文档将帮助您更好地理解多提示对话框。
希望这可以帮助。
推荐阅读
- python - 访问 FRED 时 panda DataReader 失败
- java - 设置 io.vertx.core.logging.Logger 级别并直接指向 System.out
- python - 如何在 python 中使用 googletrans API 翻译网页?
- java - 如何将属性存储到地图中
- parceljs - 包裹构建错误:“extendDefaultPlugins”
- blockchain - 注意:如果您发送值并且您发送的值应该小于您当前的余额,则调用的函数应该是应付的
- flutter - 比较来自 API 的日期并在 FLutter 的 ListView 中显示它们
- asp.net-core - 为什么使用 Azure 服务总线更新到 .NET 5 后 Rebus.Send 不起作用
- python - 加快将雪花数据加载到 Flask Web 应用程序的最佳实践?
- ios - iOS 中的 UndoManager 持久化