2017-04-21 94 views
1

我有一個問題:我的機器人不遵循形式,它只是繼續威脅下一個答案的意圖。形式和意圖在Bot框架,wit.ai

http://g.recordit.co/GultDCEndR.gif

當我鍵入的第一條消息「порахуй」,它啓動我的形式Exams.BuildForm,但接下來我的回答使留下的形式,因爲其目的是不同的,因爲我得到了它。

我期望得到什麼:在我定義的意圖機器人開始形式,並不斷詢問問題,直到他們回答。

它在「порахуйконкурснийбал」案件上發佈表格。當消息的意圖與案例不匹配時留下。它預期的行爲?如果是這樣,我應該如何更改我的代碼以使表單提問,直到所有代碼都不會被回答?

我的代碼:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Net; 
using System.Net.Http; 
using System.Threading.Tasks; 
using System.Web.Http; 
using com.valgut.libs.bots.Wit; 
using Microsoft.Bot.Builder.Dialogs; 
using Microsoft.Bot.Builder.FormFlow; 
using Microsoft.Bot.Connector; 

namespace IoT_NULP_Bot.Controllers 
{ 
    [Serializable] 
    public class Exams 
    { 
     [Prompt("Для початку, ваш результат з Математики?")] 
     public float Math { get; set; } 

     [Prompt("Українська мова та Література?")] 
     public float Ukrainian { get; set; } 

     [Prompt("Вибіркова дисціпліна - Іноземна мова, Фізика або Історія України")] 
     public float LanguagePhysics { get; set; } 

     public static IForm<Exams> BuildForm() 
     { 
      return new FormBuilder<Exams>() 
       .Message("Давайте порахуємо ваш конкурсний бал при вступі на ІоТ :) Для цього дайте мені відповіді на наступні запитання") 
       .Field(nameof(Ukrainian)) 
       .Field(nameof(Math)) 
       .Field(nameof(LanguagePhysics)) 
       .Build(); 
     } 
    } 

    [BotAuthentication] 
    public class MessagesController : ApiController 
    { 
     private static IoT_BotDbEntities db = new IoT_BotDbEntities(); 

     /// <summary> 
     /// POST: api/Messages 
     /// Receive a message from a user and reply to it 
     /// </summary> 
     public async Task<HttpResponseMessage> Post([FromBody] Activity activity) 
     { 
      ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl)); 
      var wit = new WitClient("RKIJ5LVF4GKLEWJ5O5NPUPXVCQMKGLJW"); 
      switch (activity.Type) 
      { 
       case ActivityTypes.Message: 

        var msg = wit.Converse(activity.From.Id, activity.Text); 

        var intent = string.Empty; 
        double conf = 0; 
        try 
        { 
         var a = msg.entities["intent"]; 
         if (a != null) 
         { 
          foreach (var z in msg.entities["intent"]) 
          { 
           if (z.confidence > conf) 
           { 
            conf = z.confidence; 
            intent = z.value.ToString(); 
           } 
          } 
         } 
        } 
        catch (KeyNotFoundException) 
        { 
        } 
        Activity reply = activity.CreateReply(); 

        switch (intent) 
        { 
         case "порахуй конкурсний бал": 
          await Conversation.SendAsync(activity, MakeRoot); 
          break; 
         case "статистика вступу": 
          reply.Attachments = new List<Attachment>(); 
          Attachment attachment = new Attachment(); 
          attachment.ContentType = "image/png"; 
          attachment.ContentUrl = 
           @"http://image.prntscr.com/image/ee2502f6a68041e1813f1bcd125a8bb2.png"; 
          Attachment secondAttachment = new Attachment(); 
          secondAttachment.ContentType = "image/png"; 
          secondAttachment.ContentUrl = 
           @"http://image.prntscr.com/image/258aa8e844d74ab7b63447a9f551ecbd.png"; 
          reply.Attachments.Add(attachment); 
          reply.Attachments.Add(secondAttachment); 
          reply.Text = GetReplyFromDb(intent); 
          break; 
         case "фото": 
          var photo = GetRandomPhoto(); 
          reply.Attachments = new List<Attachment>(); 
          Attachment attachment1 = new Attachment(); 
          attachment1.ContentType = "image/png"; 
          attachment1.ContentUrl = photo.photoLink; 
          reply.Attachments.Add(attachment1); 
          reply.Text = photo.descrip; 
          break; 
         default: 
          reply.Text = GetReplyFromDb(intent); 
          break; 
        } 
        await connector.Conversations.ReplyToActivityAsync(reply); 
        break; 
       default: 
        break; 
      } 

      var response = Request.CreateResponse(HttpStatusCode.OK); 
      return response; 
     } 

     internal static IDialog<Exams> MakeRoot() 
     { 
      return Chain.From(() => FormDialog.FromForm(Exams.BuildForm)); 
     } 

     private static Photo GetRandomPhoto() 
     { 
      var arrToRandomFrom = db.Photos.ToArray(); 
      return arrToRandomFrom[new Random().Next(arrToRandomFrom.Length)]; 
     } 

     private static string GetReplyFromDb(string intent) 
     { 
      var arrToRandomFrom = db.Responses.Where(x => x.Intent.content == intent).ToArray(); 
      if (arrToRandomFrom.Length > 0) 
       return arrToRandomFrom[new Random().Next(arrToRandomFrom.Length)].content; 
      else 
      { 
       var noreply = db.Responses.Where(x => x.Intent.content == "noreply").ToArray(); 
       return noreply[new Random().Next(noreply.Length)].content; 
      } 
     } 
    } 
} 
+0

如果我正確理解你的問題,這不是正常的行爲。它應該回復「你的輸入不正確」等消息,並等待用戶再次嘗試。這是來自框架的內置行爲,所以我不明白這會如何破壞。你在使用框架的最後一個版本嗎? –

+0

是的,最後一個版本,幾天前從零開始創建了這個項目。 –

+0

您可以添加您用於開始表單的代碼嗎?也許這會告訴我更多。 –

回答

2

我認爲這個問題是由於你怎麼有代碼。一旦你檢測到啓動表單的意圖,你不應該處理任何其他意圖(意思是你不應該允許通過其他開關/情況語句)。表單開始後的後續消息應該是await Conversation.SendAsync(activity, MakeRoot),這樣才能正常工作。

我的建議是重新做你的邏輯。首先,你需要一個根對話框,你的大部分邏輯應該駐留在那裏;把它放在控制器上並不是一個很好的做法。一旦你這樣做了,你可以等待Conversation.SendAsync(activity,() => YourDialog)和對話框的MessageReceived,你可以調用wit.ai,處理意圖,啓動表單等。

我認爲做這些更改可能就足夠了。

+0

你是對的,這已經足夠了。謝謝。 –