我开始开发一个简单的Bot,从文档中的Echo bot发展而来。我很快就遇到了问题。
我在RootDialog上有这三种方法:
public async Task StartAsync(IDialogContext context)
{
await context.PostAsync("Olá! Eu sou um bot!");
await context.PostAsync("Qual é o teu nome?");
context.Wait(NameReceivedAsync);
}
private async Task NameReceivedAsync(IDialogContext context, IAwaitable<object> result)
{
var activity = await result as Activity;
userName = activity.Text;
await context.PostAsync($"Olá {userName}. Podes dizer alguma coisa e eu vou repetir.");
context.Wait(MessageReceivedAsync);
}
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
{
var activity = await result as Activity;
// calculate something for us to return
int length = (activity.Text ?? string.Empty).Length;
// return our reply to the user
await context.PostAsync($"Tu disseste { activity.Text}, que tem {length} caracteres");
context.Wait(MessageReceivedAsync);
}
我的MessageController Post方法是这样的:
public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
await Conversation.SendAsync(activity, () => new Dialogs.RootDialog());
return new HttpResponseMessage(System.Net.HttpStatusCode.Accepted);
}
想法是让机器人立即发送两条消息,等待来自用户的userName输入,发送另一条消息,然后转到 MessageReceivedAsync ,在那里他将启动他的echo循环。问题是机器人没有等待输入,只是在 MessageReceivedAsync 的末尾停止,在那里他将启动回声。
我似乎无法理解为什么会发生这种情况,因为从我看到的 context.Wait(...)应该让Bot等待输入,这是没有发生的。我正在使用Chrome上的Bot Framework Channel Emulator进行测试,如果这有任何区别的话。
答案 0 :(得分:1)
context.Wait(方法)有点令人困惑,因为它实际上设置了一个“继续委托来指定收到新消息时应该调用的方法”来自:https://docs.microsoft.com/en-us/bot-framework/dotnet/bot-builder-dotnet-dialogs#implementation-details但是,context.Wait (方法)in .StartAsync将执行&#34;方法&#34;因为对话框是第一次运行所以立即。
如果您将代码更改为以下内容,它应该按预期工作:
[Serializable]
public class RootDialogTest : IDialog<object>
{
public async Task StartAsync(IDialogContext context)
{
context.Wait(NameReceivedAsync);
}
private async Task NameReceivedAsync(IDialogContext context, IAwaitable<object> result)
{
var activity = await result as Activity;
if (!context.UserData.ContainsKey("askedname"))
{
await context.PostAsync("Olá! Eu sou um bot!");
await context.PostAsync("Qual é o teu nome?");
context.UserData.SetValue("askedname", true);
context.Wait(NameReceivedAsync);
}
else
{
var userName = activity.Text;
await context.PostAsync($"Olá {userName}. Podes dizer alguma coisa e eu vou repetir.");
context.Wait(MessageReceivedAsync);
}
}
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
{
var activity = await result as Activity;
// calculate something for us to return
int length = (activity.Text ?? string.Empty).Length;
// return our reply to the user
await context.PostAsync($"Tu disseste { activity.Text}, que tem {length} caracteres");
context.Wait(MessageReceivedAsync);
}
}
编辑:另一个选项,对当前对话框的更改较少:
[Serializable]
public class RootDialogTest : IDialog<object>
{
public async Task StartAsync(IDialogContext context)
{
await context.PostAsync("Olá! Eu sou um bot!");
await context.PostAsync("Qual é o teu nome?");
context.Wait(SetupMethodWait);
}
private async Task SetupMethodWait(IDialogContext context, IAwaitable<object> result)
{
context.Wait(NameReceivedAsync);
}
private async Task NameReceivedAsync(IDialogContext context, IAwaitable<object> result)
{
var activity = await result as Activity;
var userName = activity.Text;
await context.PostAsync($"Olá {userName}. Podes dizer alguma coisa e eu vou repetir.");
context.Wait(MessageReceivedAsync);
}
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
{
var activity = await result as Activity;
// calculate something for us to return
int length = (activity.Text ?? string.Empty).Length;
// return our reply to the user
await context.PostAsync($"Tu disseste { activity.Text}, que tem {length} caracteres");
context.Wait(MessageReceivedAsync);
}
}
答案 1 :(得分:0)
从我使用Bot框架开发时可以看出,Conversation.SendAsync()
就像context.Forward()
一样将消息转发到RootDialog()
。
我建议使用AskNameDialog()
使用context.Call()
将用户引导到单独的对话框,并在那里处理您的代码。
看看BotBuilder提供的样本 https://github.com/Microsoft/BotBuilder-Samples他们应该帮助你理解。