anonymous1110
anonymous1110

Reputation: 885

Calling CarouselCardsDialog on Luis

Hi guys im trying to call a carouseldialog on my luis intent.

Luis Code:

[LuisIntent("Help")]
 public async Task Help(IDialogContext context, LuisResult result)
    { 
       context.Call(new CarouselCardsDialog(), DialogsCompleted);
    }

 private async Task DialogsCompleted(IDialogContext context, IAwaitable<object> result)
    {
        await context.PostAsync("Please choose from one of the topics above or Type in a new message.");
        context.Wait(MessageReceived);
    }

What happens is I have to type the message HELP 2x because on the first one, it appears as if nothing has happened, and it will only come out on the second attempt. Is there a way to call it like an attachment instead? I also notice that after loading the carousel any other message you enter after that will only return the carousel, I want it to retain the Luis dialog and simply call the carousel as an attachment.

enter image description here

Upvotes: 0

Views: 65

Answers (1)

Nicolas R
Nicolas R

Reputation: 14619

There are 2 problems in your implementation as you noticed:

  • start of your CarouselCards dialog which is currently "not automatic"
  • end of this dialog as it's continuously displaynig the cards

Problem 1 - Start of Carousel Dialog

For the 1st problem it comes from the way you are sending the user to the dialog:

[LuisIntent("Help")]
public async Task Help(IDialogContext context, LuisResult result)
{ 
   context.Call(new CarouselCardsDialog(), DialogsCompleted);
}

Here you are doing a Call so the child dialog will be started and... that's all. In fact, it's only waiting for your next input due to the implementation of the StartAsync in your child dialog:

public async Task StartAsync(IDialogContext context)
{
    context.Wait(this.MessageReceivedAsync);
}

There are 2 solutions, both are working (and are doing more or less the same things), choose one (but not both, or you will loop!):

  • Solution #1 - Change the StartAsync content of your child dialog

It will look like this:

public async Task StartAsync(IDialogContext context)
{
    // Force the call to MessageReceivedAsync instead of waiting
    await MessageReceivedAsync(context, new AwaitableFromItem<IMessageActivity>(context.Activity.AsMessageActivity()));
}
  • Solution #2 - Change the way you send to your child: Forward a message instead of Call

Here you forward the last message (context.Activity) to the dialog.

[LuisIntent("Help")]
public async Task Help(IDialogContext context, LuisResult result)
{ 
    //context.Call(new CarouselCardsDialog(), DialogsCompleted);
    await context.Forward(new CarouselCardsDialog(), DialogsCompleted, context.Activity.AsMessageActivity(), CancellationToken.None);
}

Problem 2 - End of the dialog to stop displaying cards

As you mentioned the use of the sample here, you may not have ended the Dialog as you can see in the last line here:

public virtual async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
{
    var reply = context.MakeMessage();

    reply.AttachmentLayout = AttachmentLayoutTypes.Carousel;
    reply.Attachments = GetCardsAttachments();

    await context.PostAsync(reply);

    context.Wait(this.MessageReceivedAsync);
}

So change context.Wait(this.MessageReceivedAsync); to context.Done<object>(null); and you will end the dialog after displaying the cards.

Upvotes: 1

Related Questions