Reputation: 4655
I'm trying to access the complete original text from within a method marked as a LuisIntent
within a LuisDialog
.
The documentation shows these methods as taking two arguments:
IDialogContext context, LuisResult result
Neither of which publicly exposes the original text of the message. The context object does contain the message but in a private property (context.data.message.text
) which is not accessible.
Is there a way to access this in the context
, or can it be passed into the dialog constructor?
Upvotes: 10
Views: 2738
Reputation: 5853
You could do it like this by using the Query property of the LuisResult,
[LuisIntent(intentName: "someIntentName")]
private async Task Eligibility(IDialogContext context, LuisResult result)
{
await context.PostAsync($"The original text is: {result.Query}");
context.Wait(MessageReceivedAsync);
}
Upvotes: 0
Reputation: 617
With the new version of Bot Framework (1.0.2) the LuisResult object now has a Query parameter that contains the original query sent to LUIS.
Upvotes: 9
Reputation: 304
You can override the MessageReceived(...) function of the LuisDialog keep the fields of the message that you need as member variables and access those fields in your intent handlers. Below I modified the SimpleAlarmDialog to show how you can access 'message.Text' in one of the intent handlers:
[LuisModel("c413b2ef-382c-45bd-8ff0-f76d60e2a821", "6d0966209c6e4f6b835ce34492f3e6d9")]
[Serializable]
public class SimpleAlarmDialog : LuisDialog<object>
{
private readonly Dictionary<string, Alarm> alarmByWhat = new Dictionary<string, Alarm>();
[Serializable]
public class PartialMessage
{
public string Text { set; get; }
}
private PartialMessage message;
protected override async Task MessageReceived(IDialogContext context, IAwaitable<Message> item)
{
var msg = await item;
this.message = new PartialMessage { Text = msg.Text };
await base.MessageReceived(context, item);
}
[LuisIntent("builtin.intent.alarm.delete_alarm")]
public async Task DeleteAlarm(IDialogContext context, LuisResult result)
{
await context.PostAsync($"echo: {message.Text}");
Alarm alarm;
if (TryFindAlarm(result, out alarm))
{
this.alarmByWhat.Remove(alarm.What);
await context.PostAsync($"alarm {alarm} deleted");
}
else
{
await context.PostAsync("did not find alarm");
}
context.Wait(MessageReceived);
}
}
Upvotes: 8
Reputation: 1367
If you break into the method, you can see in the quick watch that the context object has a non-public property through to context.data.mesage.Text (note the misspelling of "mesage"). Since the property is non-public, you could cheat by using reflection to get at it (see GetInstanceField in How to get the value of private field in C#?)
Microsoft.Bot.Builder.Dialogs.Internals.JObjectBotData data = GetInstanceField(typeof (Microsoft.Bot.Builder.Dialogs.Internals.DialogContext), context, "data") as Microsoft.Bot.Builder.Dialogs.Internals.JObjectBotData;
Microsoft.Bot.Connector.Message originalMessage = GetInstanceField(typeof(Microsoft.Bot.Builder.Dialogs.Internals.JObjectBotData), data, "mesage") as Microsoft.Bot.Connector.Message;
string originalMessageText = originalMessage.Text;
Upvotes: 1