1

facebook我使用 MS Bot Framework 的机器人在通道和emulator通道上都陷入了无限循环向用户发送消息的问题。

我的机器人有一个 "root" ,有点像菜单,根据用户的选择IDialog调用其他几个s。IDialog子对话框以这种方式调用:

        ...
        else if (response.Text == MainOptions[2])
        {
            await context.Forward(new InfoCounterDialog(), ChildDialogComplete, 
                                  response, CancellationToken.None);
        }
        ...
  • responseIMessageActivity用户发送的;
  • ChildDialogComplete是一种重新构建主菜单并以这些行结束的方法:

.

await context.PostAsync(restartPrompt);
context.Wait(MainScreenSelectionReceived);

除了这个非常短的对话框之外,所有对话框都可以正常工作,这会导致无限循环 - 机器人会一次又一次地发送此消息,直到我停止 Web 应用程序。

namespace XXXX
{
[Serializable]
public class InfoCounterDialog : IDialog
{
    public async Task StartAsync(IDialogContext context)
    {
        var hourNow = DateTime.Now.Hour;
        var openNow = "";
        if (hourNow >= 7)
        {
            openNow = "It is open now and will close at midnight.";
        }
        else
        {
            openNow = "It is closed now and will open at 7:00";
        }
        var card = HeroCardUtils.CardWithImageAndMiscButtons(
            "Our information counter can help!",
            "It's located in Shop 081, Level 3 in Building 2. " + openNow,
            "http://www.[image URL here].jpg",
            new[] { "More Details" },
            new[] { ActionTypes.OpenUrl },
            new[] { "[webpage URL here]" }
            );
        await BotUtils.SendCardToChat(context, card);
        context.Done(this);
    }
}

}

如果你想知道什么SendCardToChat是:

    public async static Task SendCardToChat(IDialogContext context, HeroCard card)
    {
        var activity = context.MakeMessage();
        activity.Attachments = HeroCardUtils.CardToAttachments(card);
        await context.PostAsync(activity);
    }

回顾一下:

  • 我正在使用另一个对话框启动一个对话框context.Forward()
  • 该对话框应该向用户显示一条消息并立即终止,无需用户额外输入
  • 相反,它不断发送“我们的信息柜台可以提供帮助!” 消息无限。

我最好的猜测是子对话以某种方式将用户的初始消息返回给对话,这会一次又一次地触发相同的对话。但这不应该发生,孩子IDialog不应该向对话发送任何内容,除了HeroCard我创建的。

或者,也许我正在寻找错误的方向,而 Bot Framework 只是不支持IDialogs 做某事并立即终止而没有context.Wait()?

4

1 回答 1

1

我发现关于 context.Done(R value) 的文档并不多,但它在控制对话流程方面非常重要。

我猜那个 context.Done(this) 会再次调用你的 Dialog 吗?你有没有尝试过

context.Done(true);

我发现没有 context.Done() 方法(无参数)来告诉对话框您已完成,这令人沮丧。

除此之外,我发现在这个 Microsoft 示例中,他们使用

// within a HotelsDialog.cs
context.Done<object>(null);

这是可能的,因为他们从根对话框调用对话框

// within RootDialog.cs
context.Call(new HotelsDialog(), this.ResumeAfterOptionDialog);
于 2017-02-28T09:41:50.240 回答