How to call custom dialogs in MessageController for custom events

时间:2018-12-19 11:22:44

标签: c# botframework

Problem statement:
I want to call dialogs from MessageController when custom events are sent to the bot.

Setup:
I have a bot build using Microsoft Bot Framework [v3.15.3]
I have a set of custom events that are sent to the bot from external systems to notify the bot adn ask it to perform actions.
[ Example, MarkUserAsOfflineInBackEndStore ShowExternalActionCompletedMessageToUser]

My users connect to the bot using a web portal that has a webchat connect. This also sends custom events to the bot to notify the bot about user actions
[Example UserClickedOnLogoutFromSite , userNavigatedToDifferentPage]

For these events also the bot has to take some actions.

Problem Statement:
From my message controller I have to redirect to different dialog based on different events that come in. My current setup is below:

 using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity))
 {
     if (activity.Type == ActivityTypes.Event)
     {
         var eventDialog = GetEventDialog(scope, activity);
         if (eventDialog != null)
         {
              await Conversation.SendAsync(activity, () => eventDialog).ConfigureAwait(false);
         }
     }
     else
     {
          await Conversation.SendAsync(activity, () => scope.Resolve<RootDialog>()).ConfigureAwait(false);
     }
}

I want the user ot be able to talk to the bot without error irrespective of the events that are happening. This means that If the bot is waiting for user input using context.Wait(...) the events should not cause unexpected behavior.

I explored calling dialogs using context.Call but could not find a recommended way to get the context reference in messagecontroller.

Looking for suggestion on how to setup the code here. In my basic scenario,when i send messages one at a time and one event at a time with no waits, it seems to be working correctly. But with complex dialog i get "Sorry my bot code is having an error".

1 个答案:

答案 0 :(得分:1)

您的问题似乎基于对MakeRoot中的Conversation.SendAsync委托的常见误解。委托不能用于控制将活动发送到哪个对话框。之所以必须传递一个委托而不是仅仅一个对话框,是因为在大多数情况下,不应构造新的对话框。 Conversation.SendAsync背后的想法是将活动发送到堆栈顶部的任何对话框。来自documentation

  

MakeRoot工厂方法仅用于新对话,因为现有对话具有对话框堆栈并在IMessageActivity数据中序列化了状态。

虽然我不知道您要执行的操作的详细信息,但我想您应该能够以不需要使用对话框的方式来响应大多数事件。如果确定要将这些事件发送到对话框,则需要记住,只有一个对话框堆栈,并且堆栈顶部只有一个对话框,这意味着您需要确保所有对话框能够优雅地处理所有可能的事件。请查看文档以更好地理解对话框和对话框流程:https://docs.microsoft.com/en-us/azure/bot-service/dotnet/bot-builder-dotnet-manage-conversation-flow?view=azure-bot-service-3.0