简体   繁体   English

如何从机器人框架 v4 中的 ActivityHandler.OnMessageActivityAsync 启动瀑布对话框

[英]How to start a waterfall dialog from ActivityHandler.OnMessageActivityAsync in bot framework v4

I am trying to write a simple bot that will start my waterfall dialog when the user enter something.我正在尝试编写一个简单的机器人,当用户输入内容时,它将启动我的瀑布对话框。 The usecase is very simple but it just doesn't seem to work, what is wrong?用例非常简单,但它似乎不起作用,有什么问题?

The main bot is setup as such, I try to call my dialog in the OnMessageActivityAsync function:主机器人是这样设置的,我尝试在 OnMessageActivityAsync 函数中调用我的对话框:

namespace EmptyBot1.Dialogs
{
    public class MainChatbot : ActivityHandler
    {
        private readonly IOptions<Models.Configurations> _mySettings;
        protected readonly IRecognizer _recognizer;
        protected readonly BotState _conversationState;

        public MainChatbot(ConversationState conversationState, IOptions<Models.Configurations> mySettings, ChatbotRecognizer recognizer)
        {
            _mySettings = mySettings ?? throw new ArgumentNullException(nameof(mySettings));
            _recognizer = recognizer;
            _conversationState = conversationState;
        }

        protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
        {
            string LuisAppId = _mySettings.Value.LuisAppId;
            string LuisAPIKey = _mySettings.Value.LuisAPIKey;
            string LuisAPIHostName = _mySettings.Value.LuisAPIHostName;
            await turnContext.SendActivityAsync(MessageFactory.Text($"You Said: {turnContext.Activity.Text}"), cancellationToken);


            var luisResult = await _recognizer.RecognizeAsync<Models.ChatbotIntent>(turnContext, cancellationToken);
            Models.ChatbotIntent.Intent TopIntent = luisResult.TopIntent().intent;
            await turnContext.SendActivityAsync(MessageFactory.Text($"Your Intention Is: {TopIntent.ToString()}"), cancellationToken);

            switch (TopIntent)
            {
                case Models.ChatbotIntent.Intent.RunBot:
                    var RunBotOptions = new Models.RunBotOptions();
                    Dialog d = new MyCustomDialog();
                    // Trying to start my dialog here.
                    await d.RunAsync(turnContext, _conversationState.CreateProperty<DialogState>(nameof(DialogState)), cancellationToken);
                    break;
                default:
                    break;
            }
            return;
        }


    }
}

Then I setup my dialog like this, also simple enough:然后我像这样设置我的对话框,也很简单:

namespace EmptyBot1.Dialogs
{
    public class MyCustomDialog : InteruptsDialog
    {
        public MyCustomDialog()
            : base(nameof(MyCustomDialog))
        {
            AddDialog(new TextPrompt(nameof(TextPrompt)));
            AddDialog(new ConfirmPrompt(nameof(ConfirmPrompt)));
            AddDialog(new WaterfallDialog(nameof(WaterfallDialog), new WaterfallStep[]
            {
                AskName,
                AskUseDefault,
                FinalStep
            }));

            // The initial child Dialog to run.
            InitialDialogId = nameof(WaterfallDialog);
        }
     // ...
    }
}

Everything is injected in startup.cs一切都注入了startup.cs

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

        // Add functionality to inject IOptions<T>
        services.AddOptions();

        // Add our Config object so it can be injected
        services.Configure<Models.Configurations>(Configuration);

        // Create the Bot Framework Adapter with error handling enabled.
        services.AddSingleton<IBotFrameworkHttpAdapter, AdapterWithErrorHandler>();

        // Create the bot as a transient. In this case the ASP Controller is expecting an IBot.
        services.AddTransient<IBot, Dialogs.MainChatbot>();

        // Create the Conversation state. (Used by the Dialog system itself.)
        var storage = new MemoryStorage();
        var conversationState = new ConversationState(storage);
        services.AddSingleton(conversationState);



        // Register LUIS recognizer
        services.AddSingleton<ChatbotRecognizer>();

        services.AddSingleton<Dialogs.MyCustomDialog>();
    }

But when I run it I get 500 error, what am I doing wrong?但是当我运行它时出现 500 错误,我做错了什么?

EDIT: To clarify, my goal is to be able to start a hardcoded waterfall dialog directly from ActivityHandler.OnMessageActivityAsync .编辑:澄清一下,我的目标是能够直接从ActivityHandler.OnMessageActivityAsync启动硬编码的瀑布对话框。

The general solution from online and from the example projects from Microsoft all say to pass the dialog as a type T to my bot.来自在线和来自 Microsoft 的示例项目的一般解决方案都说将对话框作为 T 类型传递给我的机器人。

However, I already know exactly which dialog to start so there is need to pass it as a type, I can just hardcode it directly inside the bot, how do I start it?但是,我已经确切地知道要启动哪个对话框,因此需要将其作为类型传递,我可以直接在机器人内部对其进行硬编码,我该如何启动它?

Turn out my code seem to work fine, not sure why it wasn't working yesterday.结果我的代码似乎运行良好,不知道为什么它昨天不起作用。 I'll leave it for future people checking up on answers.我会把它留给未来的人检查答案。 You can just use it exactly as it is in the question.您可以按照问题中的原样使用它。

From what I can see, you're not adding the bot itself when you add the bot in startup.据我所知,当您在启动时添加机器人时,您并没有添加机器人本身。 you have你有

// Create the bot as a transient. In this case the ASP Controller is expecting an IBot.
services.AddTransient<IBot, Dialogs.MainChatbot>();

try:尝试:

// Create the bot as a transient. In this case the ASP Controller is expecting an IBot.
services.AddTransient<IBot, MainChatbot<MyCustomDialog>>();

In order to do this, you're going to have to change your MainChatBot.为此,您将不得不更改 MainChatBot。 In your class delcaration, you have:在您的班级声明中,您有:

public class MainChatbot : ActivityHandler

change it to:将其更改为:

public class MainChatbot<T> : ActivityHandler
    where T : Dialog

You have your main 'bot' there, but you're not calling a dialog until it gets a LUIS intent.您在那里有主要的“机器人”,但在获得 LUIS 意图之前您不会调用对话框。 But you can't call a LUIS intent until a dialog is started.但在对话启动之前,您无法调用 LUIS 意图。 Initialize your bot with a dialog instead, so your bot knows where to 'start' essentially.改为使用对话框初始化您的机器人,以便您的机器人基本上知道从哪里“开始”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在bot框架v4中调用中间件OnMessageActivityAsync? - How to call the middleware OnMessageActivityAsync in bot framework v4? 如何在C#[Bot Framework v4]中从QnaBot(qna制造商api)调用瀑布对话框? - How to call waterfall dialog from QnaBot (qna maker api) in C# [Bot Framework v4]? 在瀑布对话框中使用 luis 验证提示(Bot 框架 V4) - Validate prompt with luis in waterfall dialog (Bot framework V4) 通过跳过bot框架v4中第一个对话的第一步,将第一个对话的瀑布步骤调用到另一个对话中 - Invoke the steps of waterfall of first dialog into other dialog by skipping the first step of a first dialog in bot framework v4 接受瀑布对话框上的附件并将它们本地存储在机器人框架 v4 中 - Accepting attachments on a waterfall dialog and storing them locally in bot framework v4 Botframework v4:如何简化这个瀑布式对话框? - Botframework v4: How to simplify this waterfall dialog? 具有复杂对话流的顺序瀑布模型Bot Framework C#v4 - Sequential Waterfall Models with Complex Dialog flows Bot Framework C# v4 瀑布对话框中的C#Bot V4文本提示 - C# bot V4 Text Prompt inside a waterfall dialog 如何验证自适应卡片机器人框架 v4(瀑布模型)c# 中的输入字段 - How to validate input fields in adaptive card bot framework v4 (waterfall model) c# 从bot框架v4中的当前步骤转到下一个瀑布步骤 - Go to next Waterfall step from current step in bot framework v4
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM