Botframework-sdk: [Question] How does BotBuilder understand when create new IDialog object?

Created on 1 Nov 2017  路  6Comments  路  Source: microsoft/botframework-sdk

Bot Info

  • SDK Platform: .NET
  • SDK Version: 3.11.0

Issue Description

Hi!

I created a bot from the VS template. As a result, I have MessageController that launches RootDialog:

public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
    if (activity.Type == ActivityTypes.Message)
    {
        await Conversation.SendAsync(activity, () => new RootDialog());
    }
    ...
}

MessagesController.Post is called every time the bot is sent some activity from the client. If the bot is sent a "message" activity, it is called:

await Conversation.SendAsync(activity, () => new RootDialog());

I had a need to pass a parameter into RootDialog(). I created the required constructor

public class RootDialog()
{
    int _param;
    public RootDialog(int param)
    {
        _param = param;
    }

and overwrote the call

await Conversation.SendAsync(activity, () => new RootDialog(param));

After a while, I noticed that in some cases in RootDialog objects this parameter is not filled.

After experimenting, I concluded that the RootDialog object is created only once for each specific channel and user. That is, if any particular user has already entered in the RootDialog before, then a new object will never be created for him. Even if reboot IIS.

The bot understands for whom to create a new RootDialog object, and for whom not to create and use the already created one.

Questions:

  1. How does the bot know to create a new dialog object for the user or not?
  2. Where is the information about the dialog objects already created stored?

All 6 comments

You could pass your param in one of the data bags in the context object UserData, ConversationData, or PrivateConversationData depending on what exactly you need to accomplish. What is your use case?

Now there is no problem, because I used the data of activity object, so I moved the code to RootDialog.MessageReceivedAsync in which this object is also available through context.Activity.

Now I'm curious:

  1. How does the bot know to create a new dialog object for the user or not?
  2. Where is the information about the dialog objects already created stored?

The dialog stack is serialized and sent to the bot connector along with the outgoing message. When the subsequent message is sent back, this serialized payload is sent back. If it's not a user's first message, then instead of creating a new root dialog, their conversation will be deserialized and resumed.

sphanley, thanks!

I correctly understand that it is not right to describe any business logic in the constructor or StartAsync method of dialog?

For example, I want one message handler to be called for a particular user, and for the other users another. It would seem that this could be done like this:

public class RootDialog : IDialog<object>
{
    public async Task StartAsync(IDialogContext context)
    {
        if(context.Activity.From.Id == "123456")
            context.Wait(this.SpecialMessageReceivedAsync);
        else
            context.Wait(this.MessageReceivedAsync);
    }

But if user 123456 has already entered into a dialogue with the bot (before we decided to define for him a special handler), it will never get into SpecialMessageReceivedAsync handler.

@Verdysh, it depends on your use case, but generally, that's likely true. You'd only want to put business logic in the constructor or StartAsync if it's logic which you genuinely only wanted run the first time the user enters the dialog.

In your example, it may be valid to do that sort of flow control in the StartAsync. But at the end of the code flow that a user goes through, you want to make sure you end by calling context.Wait(Something) if you want their next method to be handled by a different method within the dialog, as their next message is going to immediately hit the last thing you set via context.Wait().

@sphanley, thanks!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

daveta picture daveta  路  3Comments

RaoVenka picture RaoVenka  路  3Comments

kenyeung128 picture kenyeung128  路  3Comments

maba4891 picture maba4891  路  3Comments

stijnherreman picture stijnherreman  路  3Comments