问题
I am developing a chatbot using Microsoft and C#. My bot basically gets the intent from LUIS and based on that either replies with a static String or forwards to a new Dialog of multiple questions. Inside the new dialog the messages sent by the user are directly handled from within the code without passing through LUIS.
My Code:
MainLUISDialog.cs:
[LuisIntent("Greetings")]
public async Task Greetings(IDialogContext context, IAwaitable<IMessageActivity> argument, LuisResult result)
{
await context.PostAsync(@"Hello user!");
context.Wait(MessageReceived);
}
[LuisIntent("NearbyRestaurants")]
public async Task NearbyRestaurants(IDialogContext context, IAwaitable<IMessageActivity> argument, LuisResult result)
{
var msg = await argument;
await context.Forward(new LocationDialog(), ResumeAfterLocationReceived, msg, CancellationToken.None);
}
LocationDialog.cs:
public async Task StartAsync(IDialogContext context)
{
context.Wait(MessageReceivedAsync);
}
public virtual async Task MessageReceivedAsync(IDialogCOntext context, IAwaitable<IMessageActivity> argument)
{
var msg = await argument;
var reply = context.MakeMessage();
reply.Type = ActivityTypes.Message;
reply.Text = "would you like to share your location?";
reply.TextFormat = TextFormatTypes.Plain;
reply.SuggestedActions = new SuggetedActions()
{
Actions = new List<CardAction>()
{
new CardAction(){ Title="Yes", Type=ActionTypes.ImBack, Value="yes"},
new CardAction(){ Title="No", Type=ActionTypes.ImBack, Value="no"}
}
};
await context.PostAsync(reply);
context.Wait(ReplyReceivedAsync);
}
public virtual async Task ReplyReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> argument)
{
var msg = await argument;
if(msg.Text.Equals("yes"))
{
//forward to function for handling location
}
else if (msg.Text.Equals("no"))
{
context.Done("no location")
}
else
{
context.Done(msg.Text)
}
}
MainLUISDialog.cs (ResumeAfterLocationReceived):
public async Task ResumeAfterLocationReceived(IDialogContext context, IAwaitable<String> result)
{
if(result.Equals("no"))
{
await context.PostAsync(@"Sorry can't search");
context.Wait(MessageReceived);
}
else
{
//in this case i need to forward the message directly to LUIS to get the user's intent
}
}
when the user is asked if he wants to share his location and the user answers by a message different that yes/no i need to forward that message directly back to LUIS to get the user's intent. How do I do that? I know that if I use context.Wait(MessageReceived) this will make the code forget the message sent by the user and the user will have to type it again.
回答1:
You may want to consider changing your logic here. Having your buttons ImBack values be something like "yes, use my location" or "no, do not use my location" or some variation of that. Then you can send the whole string to Luis just like in your greeting or nearby restaurants intent (or not as you are currently doing) as a location intent. This way you would not have to be concerned with handling other intents. Also, you will not tie up the words "yes" and "no"
回答2:
i solved it same way Ezequel Jadib answered in the below post with a few added lines: How to forward result of Prompt.Choice() to current dialog?
in my MainLUISDialog.cs (ResumeAfterLocationReceived):
public async Task ResumeAfterLocationReceived(IDialogContext context, IAwaitable<String> result)
{
if(result.Equals("no"))
{
await context.PostAsync(@"Sorry can't search");
context.Wait(MessageReceived);
}
else
{
//added code here:
var userSearchString = result.Text;
Activity myActivity = new Activity();
myActivity.Text = userSearchString ;
await MessageReceived(context, Awaitable.FromItem(myActivity));
}
}
the secret was to get the text that the user entered, create a new activity, add the text to the activity and then pass it to the LUIS dialog's messageReceived task.
来源:https://stackoverflow.com/questions/45700537/calling-back-luis-from-a-dialog