2016-04-07 5 views
8

Я пытаюсь получить доступ к полному оригинальному тексту из метода, помеченного как LuisIntent в пределах LuisDialog.Как получить исходный текст сообщения в Microsoft Bot Framework LuisIntent метод

документация показывает эти методы, как принимать два аргумента:

IDialogContext context, LuisResult result 

Ни один из которых публично выставляет оригинальный текст сообщения. Объект контекста содержит сообщение, но в частной собственности (context.data.message.text), который недоступен.

Есть ли способ получить доступ к этому в context или может быть передан в конструктор диалога?

+0

Тот же вопрос здесь. – fdezjose

ответ

5

Вы можете переопределить функцию MessageReceived (...) от LuisDialog держать полей сообщение, которое вам нужно в качестве переменных-члена и доступ к этим полям в ваших обработчиках целей. Ниже я модифицировал SimpleAlarmDialog, чтобы показать, как вы можете получить доступ к «message.Text» в одном из Намерение обработчиков:

[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); 
    } 
} 
+0

Несмотря на то, что версия 1.0 Framework версии Bot добавляет текст сообщения, она по-прежнему не включает в себя всю дополнительную информацию, ConversationId и т. Д., Включенную в объект сообщения контроллера. Это позволяет мне добавлять любые дополнительные поля, которые мне нужны. Благодаря! –

+1

Несмотря на то, что это работало для V1 платформы Bot, похоже, для V3 это не работает. Если вы попытаетесь переопределить метод async, он вернет ошибку внутреннего сервера, чтобы вызвать базовую команду .MessageReceived. –

1

Если вы входите в метод, вы можете быстро увидеть, что объект контекста имеет непубличное свойство через context.data.mesage.Text (обратите внимание на орфографию «mesage»). Поскольку свойство является непубличной, вы могли бы обмануть с помощью отражения, чтобы получить на него (см GetInstanceField в 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; 
8

С новой версией Bot Framework (1.0.2) LuisResult объект теперь имеет Запрос параметр, содержащий исходный запрос, отправленный в LUIS.

0

Вы могли бы сделать это так, используя свойство Query в LuisResult,

[LuisIntent(intentName: "someIntentName")] 
private async Task Eligibility(IDialogContext context, LuisResult result) 
{ 
    await context.PostAsync($"The original text is: {result.Query}"); 
    context.Wait(MessageReceivedAsync); 
}