2017-08-15 1 views
2

Ich entwickle einen Chatbot mit Microsoft und C#. Mein Bot erhält im Grunde die Absicht von LUIS und basiert entweder auf einem statischen String oder leitet ihn zu einem neuen Dialog mit mehreren Fragen weiter. Innerhalb des neuen Dialogs werden die vom Benutzer gesendeten Nachrichten direkt aus dem Code heraus bearbeitet, ohne LUIS zu durchlaufen.LUIS von einem Dialog zurückrufen

Mein 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 
    } 
} 

, wenn der Benutzer ist gefragt, ob er seinen Standort teilen möchte und der Benutzer antwortet mit einer anderen Nachricht als Ja/Nein, ich muss diese Nachricht direkt an LUIS weiterleiten, um die Absicht des Benutzers zu erhalten. Wie mache ich das? Ich weiß, dass, wenn ich context.Wait (MessageReceived) verwende, dies den Code die Nachricht vergessen lässt, die vom Benutzer gesendet wird, und der Benutzer muss sie erneut eingeben.

+0

zur Klarstellung, möchten Sie das Wort "ja" an LUIS senden? – JasonSowers

+0

@JasonSowers nein, im Fall von ja/nein muss ich nicht zurück zu LUIS, für den Fall, dass der Benutzer etwas anderes als Ja/Nein wie "Wie geht es dir" beantwortet, muss ich diese Nachricht an LUIS zurücksenden . Danke :) – RayDEViOS

+0

Danke, ich habe es falsch gelesen :) – JasonSowers

Antwort

0

Vielleicht möchten Sie hier Ihre Logik ändern. Wenn Sie die ImBack-Werte für Ihre Schaltflächen verwenden, lautet dies beispielsweise "Ja, verwende meinen Standort" oder "Nein, verwende meinen Standort nicht" oder eine Variation davon. Dann können Sie die ganze Zeichenfolge an Luis senden, genau wie in Ihrer Begrüßung oder in der Nähe von Restaurants, in der Absicht (oder nicht wie Sie es gerade tun) als Standortabsicht. Auf diese Weise müssten Sie sich nicht um andere Absichten kümmern. Außerdem werden Sie die Worte nicht binden „ja“ und „nein“

+0

Dies ist nicht mein genauer Fall, in meinem Fall habe ich mehrere Dialoge und jeder kann bis zu 30 Fragen enthalten, ich kann es mir nicht leisten, zu LUIS Hauptdialog immer zu gehen, ich muss es tun, wenn der Benutzer einen Text eingibt, der nicht ist eine der Möglichkeiten. Wie auch immer ich meine Antwort in Ezequiel's Kommentar fand, ich werde es unten posten. DANKE :) – RayDEViOS

0

i löste es genauso Ezequel Jadib im folgenden Beitrag mit ein paar netten Zeilen beantwortet: How to forward result of Prompt.Choice() to current dialog?

in meinem 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)); 
    } 
} 

das Geheimnis war, den Text zu erhalten, die der Benutzer eingegeben, eine neue Aktivität erstellen, um den Text auf die Aktivität hinzufügen und sie dann an den MessageReceived Aufgabe des LUIS Dialogs übergeben.

+0

hinzugefügt weitere Details über Aktivität in meiner Antwort [hier] (https://stackoverflow.com/a/46057926/5532726) – phani

Verwandte Themen