2017-08-02 95 views
0

我正在爲FAQ創建bot。當機器人開始對話發送PromptDialog有2個選項:英語,法語。如何在Bot框架中從RootDialog轉發到LuisDialog

我想在用戶選擇英文按鈕時將對話框轉發到EnglishLuis,選擇法文時則將FrenchFile轉發給FrenchLuis。

這裏是我的代碼:

Rootdialog.cs

public class RootDialog : IDialog<object> 
{ 
    private const string EnglishMenu = "English"; 
    private const string FrenchMenu = "French"; 
    private const string QAMenu = "Q&A"; 

    private List<string> mainMenuList = new List<string>() { EnglishMenu, FrenchMenu, QAMenu }; 
    private string location; 

    public async Task StartAsync(IDialogContext context) 
    { 
     await context.PostAsync("Welcome to Root Dialog"); 
     context.Wait(MessageReceiveAsync); 
    } 

    private async Task MessageReceiveAsync(IDialogContext context, IAwaitable<IMessageActivity> result) 
    { 
     var reply = await result; 
     if (reply.Text.ToLower().Contains("help")) 
     { 
      await context.PostAsync("You can implement help menu here"); 
     } 
     else 
     { 
      await ShowMainmenu(context); 
     } 
    } 

    private async Task ShowMainmenu(IDialogContext context) 
    { 
     //Show menues 
     PromptDialog.Choice(context, this.CallDialog, this.mainMenuList, "What do you want to do?"); 
    } 

    private async Task CallDialog(IDialogContext context, IAwaitable<string> result) 
    { 
     //This method is resume after user choise menu 
     // this.luisResult = result; 
     // var message = await result; 
     var selectedMenu = await result; 
     var message = await result; 
     switch (selectedMenu) 
     { 
      case EnglishMenu: 
       //Call child dialog without data 
       // context.Call(new EnglishLuis(),ResumeAfterDialog); 
       // context.Call(new EnglishLuis(), ResumeAfterDialog); 

       await Conversation.SendAsync(context.MakeMessage(),() => new EnglishLuis()); 
       break; 
      case FrenchMenu: 
       //Call child dialog with data 
       context.Call(new HotelDialog(location), ResumeAfterDialog); 
       break; 
      case QAMenu: 
       context.Call(new LuisCallDialog(),ResumeAfterDialog); 
       break; 
     } 

    } 



    private async Task ResumeAfterDialog(IDialogContext context, IAwaitable<object> result) 
    { 
     //Resume this method after child Dialog is done. 
     var test = await result; 
     if (test != null) 
     { 
      location = test.ToString(); 
     } 
     else 
     { 
      location = null; 
     } 
     await this.ShowMainmenu(context); 
    } 
} 

}

EnglishLuis.cs:

public class EnglishLuis : LuisDialog<object> 
{ 
    private string location; 



    // string message = $"welcome to english dialog"; 

    public async Task None(IDialogContext context, LuisResult result) 
    { 
     string message = $"Sorry, I did not understand '{result.Query}'. Please try again"; 

     await context.PostAsync(message); 

     context.Wait(this.MessageReceived); 
     context.Done(true); 
    } 


    [LuisIntent("gretting")] 
    [LuisIntent("intentfr")] 
    public async Task Greeting(IDialogContext context, IAwaitable<IMessageActivity> activity, LuisResult result) 
    { 


     await context.PostAsync("Welcome :) "); 


     context.Wait(MessageReceived); 
     context.Done(true); 
    } 



    [LuisIntent("test")] 
    public async Task test(IDialogContext context, IAwaitable<IMessageActivity> activity, LuisResult result) 
    { 
     await context.PostAsync("Do you want to test our bot ? We suggest to type : hi or who are you, help etc.."); 
     // context.Done(true); 
     context.Wait(MessageReceived); 
     context.Done(true); 
    } 

我的問題是,當我選擇英語(甚至法國)我得到這個錯誤:這是一個錯誤發送這個消息到你的機器人:HTTP狀態碼InternalServerError

你能幫我一下如何啓動luis對話框嗎? P.S如果我從MessagesController.cs開始直接運行良好...但我的意圖是讓人們選擇兩種語言。

我嘗試使用以下命令調用luis:await context.Forward(new EnglishLuis(),ResumeAfterDialog,message,CancellationToken.None);但沒有結果。

新文件RootDialog.cs(更新):

using System; 
    using System.Collections.Generic; 
    using System.Threading.Tasks; 
    using Microsoft.Bot.Builder.Dialogs; 
    using Microsoft.Bot.Connector; 
    using System.Threading; 

    namespace TeamsBot.Dialogs 
    { 
[Serializable] 
public class RootDialog : IDialog<object> 
{ 
    private const string EnglishMenu = "English"; 
    private const string FrenchMenu = "French"; 
    private const string QAMenu = "Q&A"; 

    private List<string> mainMenuList = new List<string>() { EnglishMenu, 
     FrenchMenu, QAMenu }; 
    private string location; 

    private string originalMessage; 

    public async Task StartAsync(IDialogContext context) 
    { 
     await context.PostAsync("Welcome to Root Dialog"); 
     context.Wait(MessageReceiveAsync); 
    } 

    private async Task MessageReceiveAsync(IDialogContext context, 
    IAwaitable<IMessageActivity> result) 
    { 
     var reply = await result; 

     this.originalMessage = reply.Text; 




     if (reply.Text.ToLower().Contains("help")) 
     { 
      await context.PostAsync("You can implement help menu here"); 
     } 
     else 
     { 
      await ShowMainmenu(context); 
     } 
    } 

    private async Task ShowMainmenu(IDialogContext context) 
    { 
     //Show menues 
     PromptDialog.Choice(context, this.CallDialog, this.mainMenuList, 
    "What do you want to do?"); 
    } 

    private async Task CallDialog(IDialogContext context, IAwaitable<string> 
    result) 
    { 

     var selectedMenu = await result; 
     switch (selectedMenu) 
     { 
      case EnglishMenu: 
       //Call child dialog without data 
       var newMessage = context.MakeMessage(); 
       newMessage.Text = reply.Text; 
       await context.Forward(new EnglishLuis(), ResumeAfterDialog, newMessage, CancellationToken.None); 
       break; 
      case FrenchMenu: 
       //Call child dialog with data 
       // context.Call(new HotelDialog(location), ResumeAfterDialog); 

       var frenchLuis = new FrenchLuis(); 
       var messageToForward = await result; 
      // await context.Forward(new FrenchLuis(), ResumeAfterDialog, messageToForward, CancellationToken.None); 
       break; 
      case QAMenu: 
       context.Call(new LuisCallDialog(),ResumeAfterDialog); 
       break; 
     } 

    } 



    private async Task ResumeAfterDialog(IDialogContext context, IAwaitable<object> result) 
    { 
     //Resume this method after child Dialog is done. 
     var test = await result; 
     if (test != null) 
     { 
      location = test.ToString(); 
     } 
     else 
     { 
      location = null; 
     } 
     await this.ShowMainmenu(context); 
    } 
} 

}

回答

2

首先,做

context.Wait(this.MessageReceived); 
context.Done(true); 

這是錯的。你需要選擇:或者你等待的EnglishDialog一個新的消息或會終止EnglishDialog(與Done

然後,你要發送的context.Forward一個字符串,你需要轉發IMessageActivity。我懷疑你想發送原始消息,因此在繼續提示之前,你需要將它保存在全局變量中。嘗試與:

var newMessage = context.MakeMessage(); 
newMessage.Text = this.originalMessageText //the variable that contains the text of the original message that you will have to save at MessageReceiveAsync 
await context.Forward(new EnglishLuis(), ResumeAfterDialog, newMessage, CancellationToken.None); 


MessageReceivedAsync in RootDialog should looks like: 

private async Task MessageReceiveAsync(IDialogContext context, IAwaitable<IMessageActivity> result) 
    { 
     var reply = await result; 
     if (reply.Text.ToLower().Contains("help")) 
     { 
      await context.PostAsync("You can implement help menu here"); 
     } 
     else 
     { 
      this.originalMessage = reply.Text; 
      await ShowMainmenu(context); 
     } 
    } 
+0

我不知道該把什麼放在:this.originalMessageText – user38

+0

傳入的消息文本。看看你的代碼,我的根對話框應該是reply.Text。 –

+0

我不知道發生了什麼,但沒有結果。我嘗試把:newMessage.Text = selectedMenu.ToString();或newMessage.Text =等待結果;或newMessage.Text = reply.Text :(我真的需要使它工作 – user38