3

I'm trying to build a Dialog using the Microsoft Bot Framework which helps users consult purchase order status (currently, just a mock). I am using a LuisDialog which, when it detects the "ConsultPO" intent, it's supposed to ask for the user's 'customer id' and wait a follow up message from the user. However, it keeps going back to the start of the Luis Dialog and processing the intent instead of resuming from the waited method. This is the intent's code, which runs correctly:

        [LuisIntent("ConsultPO")]
    public async Task POIntent(IDialogContext context, LuisResult result)
    {
        string PO = "";
        foreach (var entity in result.Entities)
        {
            if (entity.Type == "purchaseOrder")
                PO = entity.Entity;
        }
        if (PO.Length != 0)
        {
            po_query = PO;
        }
        await context.PostAsync("Ok, can you confirm your customer id and I'll check for you?");
        context.Wait(confirmCustomer_getPO);
    }

This is the code I would expect to be executed after the user responds with a follow up message:

        public async Task confirmCustomer_getPO(IDialogContext context, IAwaitable<object> argument)
    {
        await context.PostAsync("DEBUG TEST");
        IMessageActivity activity = (IMessageActivity)await argument;

        customer_query = activity.Text;
        if (po_query.Length > 0)
        {
            PurchaseOrder po = POservice.findPO(po_query, customer_query);
            await buildSendResponse(po, context);
//more non relevant code

When I answer to the bot's inquiry after context.Wait(confirmCustomer_getPO) is executed, it just goes into LUIS then runs the code respective to "None" intent. The message "DEBUG TEST" is never sent.

Why is "confirmCustomer_getPO" never getting called?

EDIT:

I added a debug message in the StartAsync method. I'm not sure whether this is supposed to happen but it pops up every time I send a message to the bot, which makes me believe the Dialog is simply restarting every time I message the bot:

    public class EchoDialog : LuisDialog<object>
{
    public EchoDialog() : base(new LuisService(new LuisModelAttribute(
        ConfigurationManager.AppSettings["LuisAppId"], 
        ConfigurationManager.AppSettings["LuisAPIKey"], 
        domain: ConfigurationManager.AppSettings["LuisAPIHostName"])))
    {
    }

    public override Task StartAsync(IDialogContext context)
    {
        context.PostAsync("I'm in startAsync");
        return base.StartAsync(context);
    }

Local debugging shows no exceptions are occurring and that any breakpoint in the waited method is never reached, although the context.Wait call does happen.

YuriW
  • 869
  • 1
  • 11
  • 22
  • How are you loading the LUIS Dialog? – Eric Dahlvang Oct 05 '18 at 18:47
  • Eric, apologies for the delay and thanks for reading my question. It is my root dialog so it is called straight off the default/unchanged template code in Message Controller (`await Conversation.SendAsync(activity, () => new EchoDialog());`). I didn't even rename it from EchoDialog yet... – YuriW Oct 09 '18 at 14:42
  • What you're doing should work how you expect it to. Have you run the bot locally, and check the output window for errors? – Eric Dahlvang Oct 09 '18 at 23:46
  • I ran the bot locally - the only thing in the console is a warning about localhost not being trusted and "thread exited with code 0" - no exceptions or errors. I also added a debug message in the "StartAsync" method of my LuisDialog. Updating the question to include that... The debug message pops up every time I send a message to the bot. – YuriW Oct 10 '18 at 21:16
  • 1
    I am not able to reproduce this issue. Can you share a simple project somewhere that reproduces the problem, and I'll take a look. – Eric Dahlvang Oct 11 '18 at 16:21
  • I think I finally found the problem after creating a new project. It seems like there was a problem with my DataStore which was preventing state information from being saved - I found it after I created a new bot. I will debug more to identify the root cause and share to maybe help others... – YuriW Oct 11 '18 at 17:27
  • Oh, sure! You'll need to use either InMemoryDataStore or one of the Azure Extensions: https://github.com/Microsoft/BotBuilder-Azure – Eric Dahlvang Oct 11 '18 at 17:34

1 Answers1

1

I figured out the issue myself after fighting with it for a while. The issue was with the bot store. I was using an InMemoryDataStore which was not working - switching to TableBotDataStore fixed the problem. The issue with the DataStore meant that states weren't being saved so my "waits" and "forwards" were not being saved into the dialog stack - any new incoming message was sent to the RootDialog.

Broken - not working while this was in global.asax.cs:

Conversation.UpdateContainer(
    builder =>
    {
        builder.RegisterModule(new AzureModule(Assembly.GetExecutingAssembly()));
        var store = new InMemoryDataStore(); // volatile in-memory store

        builder.Register(c => store)
            .Keyed<IBotDataStore<BotData>>(AzureModule.Key_DataStore)
            .AsSelf()
            .SingleInstance();

    });
GlobalConfiguration.Configure(WebApiConfig.Register);

As soon as I updated store to:

var store = new TableBotDataStore(ConfigurationManager.AppSettings["AzureWebJobsStorage"]);

Having a valid "AzureWebJobsStorage" setting in web.config from my application settings in Azure, the problem was fixed without any other changes in the code.

YuriW
  • 869
  • 1
  • 11
  • 22