当用户键入“退出",“退出"时,终止所有对话并退出MS Bot Framework中的对话.等等 [英] Terminate all dialogs and exit conversation in MS Bot Framework when the user types "exit", "quit" etc

查看:89
本文介绍了当用户键入“退出",“退出"时,终止所有对话并退出MS Bot Framework中的对话.等等的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道如何在MS Bot Framework中做一个非常简单的事情:允许用户中断任何对话,退出当前对话框并通过键入退出",退出"返回主菜单"或重新开始".

I can't figure out how to do the a very simple thing in MS Bot Framework: allow the user to break out of any conversation, leave the current dialogs and return to the main menu by typing "quit", "exit" or "start over".

这是我建立主要对话的方式:

Here's the way my main conversation is set up:

    public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
    {
        try
        {
            if (activity.Type == ActivityTypes.Message)
            {
                UserActivityLogger.LogUserBehaviour(activity);

                if (activity.Text.ToLower() == "start over")
                {
                    //Do something here, but I don't have the IDialogContext here!
                }
                BotUtils.SendTyping(activity); //send "typing" indicator upon each message received
                await Conversation.SendAsync(activity, () => new RootDialog());
            }
            else
            {
                HandleSystemMessage(activity);
            }
        }

我知道如何使用context.Done<DialogType>(this);终止对话框,但是在此方法中,我无权访问IDialogContext对象,因此无法调用.Done().

I know how to terminate a dialog with context.Done<DialogType>(this);, but in this method, I do not have access to the IDialogContext object, so I cannot call .Done().

除了用户在所有对话框的每个步骤中都添加检查内容以外,当用户键入特定消息时,是否还有其他方法可以终止整个对话框堆栈?

Is there any other way to terminate the whole dialog stack when the user types a certain message, other than adding a check for that in each step of all dialogs?

发布的赏金:

我需要一种终止所有IDialog的方法,而无需使用我在此处发布的骇人听闻的技巧(该技巧会删除我需要的所有用户数据,例如用户设置和首选项).

I need a way to terminate all IDialogs without using the outrageous hack that I've posted here (which deletes all user data, which I need, e.g. user settings and preferences).

基本上,当用户键入退出"或退出"时,我需要退出当前正在进行的任何IDialog并返回到新状态,就好像用户刚刚发起了对话一样.

Basically, when the user types "quit" or "exit", I need to exit whatever IDialog is currently in progress and return to the fresh state, as if the user has just initiated a conversation.

我需要能够从MessageController.cs,执行此操作,但仍然无法访问IDialogContext.我似乎只有的有用数据是Activity对象.如果有人指出其他方式可以做到这一点,我会很高兴.

I need to be able to do this from MessageController.cs, where I still do not have access to IDialogContext. The only useful data I seem to have there is the Activity object. I will be happy if someone points out to other ways to do that.

解决此问题的另一种方法是在机器人的其他位置而不是在Post方法中找到其他方法来检查"exit"和"quit"关键字.

Another way to approach this is find some other way to check for the "exit" and "quit" keywords at some other place of the bot, rather than in the Post method.

但这不应该是对IDialog的每个步骤都进行的检查,因为这是太多的代码,甚至不总是可能的(使用PromptDialog时,我无法访问用户键入).

But it shouldn't be a check that is done at every single step of the IDialog, because that's too much code and not even always possible (when using PromptDialog, I have no access to the text that the user typed).

我没有探索过的两种可能方法:

  • 开始新的对话,而不是终止所有当前的IDialog 与用户(新的ConversationId)
  • 获取IDialogStack对象,并对其进行处理以管理对话框堆栈.
  • Instead of terminating all current IDialogs, start a new conversation with the user (new ConversationId)
  • Obtain the IDialogStack object and do something with it to manage the dialog stack.

Microsoft文档对此对象保持沉默,因此我不知道如何获取它.我没有在机器人的任何地方使用允许.Switch()Chain对象,但是如果您认为可以对其进行重写以使用它,那么它也可以是解决此问题的方法之一.但是,我还没有找到如何在各种类型的对话框(FormFlow和普通的IDialog)之间进行分支的方法,这些对话框又调用了自己的子对话框等.

The Microsoft docs are silent on this object so I have no idea how to get it. I do not use the Chain object that allows .Switch() anywhere in the bot, but if you think it can be rewritten to use it, it can be one of the ways to solve this too. However, I haven't found how to do branching between various types of dialogs (FormFlow and the ordinary IDialog) which in turn call their own child dialogs etc.

推荐答案

问题分解

根据我对您问题的理解,您想要实现的是重置对话框堆栈而不会完全破坏机器人状态.

  1. 框架如何保存对话框堆栈如下:

BotDataStore> BotData> DialogStack

  1. BotFramework使用AutoFac作为DI容器
  2. DialogModule 是其用于对话框组件的Autofac模块
  1. BotFramework is using AutoFac as an DI container
  2. DialogModule is their Autofac module for dialog components


如何做

从上面知道事实,我的解决方法是


HOW TO DO

Knowing FACTS from above, my solution will be

  1. 注册依赖项,以便我们可以在控制器中使用:
  1. Register the dependencies so we can use in our controller:


// in Global.asax.cs
var builder = new ContainerBuilder();
builder.RegisterModule(new DialogModule());
builder.RegisterModule(new ReflectionSurrogateModule());
builder.RegisterModule(new DialogModule_MakeRoot());

var config = GlobalConfiguration.Configuration;
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
builder.RegisterWebApiFilterProvider(config);
var container = builder.Build();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);

  1. 获取 Autofac容器 (可随意在您喜欢的代码中放置任何地方)


private static ILifetimeScope Container
{
    get
    {
        var config = GlobalConfiguration.Configuration;
        var resolver = (AutofacWebApiDependencyResolver)config.DependencyResolver;
        return resolver.Container;
    }
}

  1. 范围
  2. 中加载 BotData
  3. 加载 DialogStack
  4. 重置 DialogStack
  5. 将新的 BotData 推回 BotDataStore
  1. Load the BotData in the scope
  2. Load the DialogStack
  3. Reset the DialogStack
  4. Push the new BotData back to BotDataStore


using (var scope = DialogModule.BeginLifetimeScope(Container, activity))
{
    var botData = scope.Resolve<IBotData>();
    await botData.LoadAsync(default(CancellationToken));
    var stack = scope.Resolve<IDialogStack>();
    stack.Reset();
    await botData.FlushAsync(default(CancellationToken));
}

希望有帮助.

感谢@ejadib指出,容器已在会话课程中公开.

Thanks to @ejadib to point out, Container is already being exposed in conversation class.

我们可以删除上述答案中的第2步,最终代码将如下所示

using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity))
{
    var botData = scope.Resolve<IBotData>();
    await botData.LoadAsync(default(CancellationToken));
    var stack = scope.Resolve<IDialogStack>();
    stack.Reset();
    await botData.FlushAsync(default(CancellationToken));
}

这篇关于当用户键入“退出",“退出"时,终止所有对话并退出MS Bot Framework中的对话.等等的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆