问题
my goal is to implement both dialogs and LUIS into a Microsoft Bot Framework application using their C# SDK. I tried to follow this thread https://github.com/Microsoft/BotBuilder/issues/127 and their related posts (referenced at the end) but couldn't get my code working in practice. This is my RootDialog class. Note that I created a method which handles the "GetProduct" intent, when it gets this intent, it should forward the LuisResult to ProductsDialog using context.Forward() method, but instead what I see is just that it goes straight to the ResumeAfter method, ProductsDialogCompleted. Now, here is probably where I fail but I couldn't find an example showing multiple LUIS dialogs.
public class RootDialog : LuisDialog<object>
{
[LuisIntent("GetProduct")]
private async Task GetProduct(IDialogContext context, LuisResult result)
{
await context.PostAsync("Calling ProductsDialog...");
await context.Forward(Chain.From(() => new ProductsDialog()), ProductsDialogCompleted, context.Activity, CancellationToken.None);
}
private async Task ProductsDialogCompleted(IDialogContext context, IAwaitable<object> result)
{
var res = await result;
context.PostAsync("ProductsDialogCompleted" + result);
context.Wait(this.MessageReceived);
}
}
public class ProductsDialog : LuisDialog<object>
{
public async Task StartAsync(IDialogContext context)
{
await context.PostAsync("Entered ProductsDialog");
context.Wait(this.MessageReceived);
}
[LuisIntent("None")]
private async Task None(IDialogContext context, LuisResult result)
{
context.Done(true);
}
}
The expected behavior is the following
- The user triggers the GetProduct intent
- The bot creates a new dialog and goes to the StartAsync method, where it waits for another user input
- The user triggers the None intent
- The dialog closes, returns true and triggers the ProductsDialogCompleted.
It seems like I'm not correctly binding the dialogs. How can I solve this?
EDIT: Added MessageController, version is 3.8.1
[BotAuthentication]
public class MessagesController : ApiController
{
/// <summary>
/// POST: api/Messages
/// Receive a message from a user and reply to it
/// </summary>
public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
if (activity.Type == ActivityTypes.Message)
{
await Conversation.SendAsync(activity, () => new RootDialog());
}
else
{
HandleSystemMessage(activity);
}
var response = Request.CreateResponse(HttpStatusCode.OK);
return response;
}
private Activity HandleSystemMessage(Activity message)
{
if (message.Type == ActivityTypes.DeleteUserData)
{
// Implement user deletion here
// If we handle user deletion, return a real message
}
else if (message.Type == ActivityTypes.ConversationUpdate)
{
// Handle conversation state changes, like members being added and removed
// Use Activity.MembersAdded and Activity.MembersRemoved and Activity.Action for info
// Not available in all channels
}
else if (message.Type == ActivityTypes.ContactRelationUpdate)
{
// Handle add/remove from contact lists
// Activity.From + Activity.Action represent what happened
}
else if (message.Type == ActivityTypes.Typing)
{
// Handle knowing tha the user is typing
}
else if (message.Type == ActivityTypes.Ping)
{
}
return null;
}
}
回答1:
Try removing the Chain.From(()
from the context.Forward
call. Not sure why you are adding it, but it shouldn't be there at all.
Try with:
await context.Forward(new ProductsDialog(), ProductsDialogCompleted, context.Activity, CancellationToken.None);
And btw, if the message you forward hits the None
intent the ProductsDialogCompleted
method will be hit because you are doing context.Done
, which basically ends the ProductsDialog
.
Also, have in mind the StartAsync
method is present in the LuisDialog<T>
base class, so you need to add the override
keyword.
来源:https://stackoverflow.com/questions/44593904/luis-bot-framework-multiple-dialog-move-intent-handling-to-another-dialog