2017-06-19 59 views
3

在Skype或Facebook上,當用戶通過提示或表單流問題脫機(不知道其他問題)並稍後加入時,用戶將被強制爲他/她留下的最後一個對話框提供輸入;不管類型如何(選擇,文字等)。例如,如果用戶在「是」或「否」提示下退出,並且稍後加入,他將被強制回答「是」或「否」(提示。選項)當用戶離開對話並稍後加入時重新啓動對話

是否可以以某種方式重置會話,而不管用戶身在何處在對話堆棧中,當用戶重新聯機時? (可能是找出用戶已連接/在Facebook和Skype上聯機並重置的方式?)。 如果在用戶輸入「退出」之類的情況下發生這種重置會非常好,以便實際觸發重置。 (主動消息?)

如果上述解決方案是不可能的,我有以下解決方案,用戶可以輸入'quit',它會從頭開始。它適用於模擬器,但不適用於Skype和Facebook。我的代碼如下:

if (activity.Text.ToString() == "quit") 
      { 
       BotData oldActivityData = activity.GetStateClient().BotState.GetUserData(activity.ChannelId, activity.From.Id); 
       activity.GetStateClient().BotState.DeleteStateForUser(activity.ChannelId, activity.From.Id); 
       activity.GetStateClient().BotState.SetUserData(activity.ChannelId, activity.From.Id, oldActivityData); 
       await Conversation.SendAsync(activity,() => new RootDialog()); 
      } 
      else 
      { 
       // Typing indicator      
       var connector = new ConnectorClient(new Uri(activity.ServiceUrl)); 
       Activity isTypingReply = activity.CreateReply(); 
       isTypingReply.Type = ActivityTypes.Typing; 
       await connector.Conversations.ReplyToActivityAsync(isTypingReply); 

       // Sending the message to the dialog respective stack 
       await Conversation.SendAsync(activity,() => new RootDialog()); 
      } 

這個完美的工作在模擬器上。我可以在對話框中的任何地方輸入「退出」(提示,表單流等),並將我帶到第一個問題。 但是在Skype/Facebook上,當我輸入'quit'時,沒有任何反應。然後,我必須再次發送消息(可以是「退出」以外的任何內容),以便從頭開始實際開始對話。

那麼,對於非用戶發起的重置和用戶發起的重置會話都有什麼想法?

更新1:用代碼顯示我的MessageController和PromptDialogs

MessageController:

public async Task<HttpResponseMessage> Post([FromBody]Activity activity) 
    { 
     if (activity.Type == ActivityTypes.Message) 
     { 
      if (listOfResetMessages.Contains(activity.Text.ToString().ToLower().Trim(' '))) 
      { 
       BotData oldActivityData = activity.GetStateClient().BotState.GetUserData(activity.ChannelId, activity.From.Id); 
       activity.GetStateClient().BotState.DeleteStateForUser(activity.ChannelId, activity.From.Id); 
       activity.GetStateClient().BotState.SetUserData(activity.ChannelId, activity.From.Id, oldActivityData); 
       await connector.Conversations.ReplyToActivityAsync(newConvoMessage); 
       await Conversation.SendAsync(activity,() => new RootDialog()); 
      } 
      else 
      { 
       // Typing indicator      
       var connector = new ConnectorClient(new Uri(activity.ServiceUrl)); 
       Activity isTypingReply = activity.CreateReply(); 
       isTypingReply.Type = ActivityTypes.Typing; 
       await connector.Conversations.ReplyToActivityAsync(isTypingReply); 

       // Sending the message to the dialog respective stack 
       await Conversation.SendAsync(activity,() => new RootDialog()); 
      } 
     } 
     else 
     { 
      await this.HandleSystemMessage(activity); 
     } 

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

系統提示符(就像任何其他的提示,仍然發佈):

public async Task StartAsync(IDialogContext context) 
    { 
     PromptDialog.Choice(context, this.NextFunction, new List<string>() { Constants.YES, Constants.NO }, "This is my question"); 
    } 

    private async Task NextFunction(IDialogContext context, IAwaitable<string> result) 
    { 
     var optionSelected = await result; 

     switch (optionSelected) 
     { 
      case Constants.YES: 
       // Do whatever 
       break; 
      case Constants.NO: 
       // Do whatever 
       break; 
     } 
    } 

更新2: 爲了m讓客戶不知道這個問題,我用一條消息來挑起客戶輸入第二條消息來重置。

if (activity.Text.ToString().ToLower().Trim(' ') == "quit") 
      { 
       BotData oldActivityData = activity.GetStateClient().BotState.GetUserData(activity.ChannelId, activity.From.Id); 
       activity.GetStateClient().BotState.DeleteStateForUser(activity.ChannelId, activity.From.Id); 
       activity.GetStateClient().BotState.SetUserData(activity.ChannelId, activity.From.Id, oldActivityData); 
       var connector = new ConnectorClient(new Uri(activity.ServiceUrl)); 
       Activity newConvoMessage = activity.CreateReply(); 
       newConvoMessage.Text = "You have just quit. Say 'Hello' to start a new conversation!"; 
       await connector.Conversations.ReplyToActivityAsync(newConvoMessage); 
       await Conversation.SendAsync(activity,() => new RootDialog()); 
      } 

這並不能解決問題,因爲用戶需要重新聯機並首先輸入'quit'。 (意思是,用戶需要知道'退出'命令)。

+0

任何消息開始沒有默認的會話超時,因此您需要設置一個計時器並在X秒/分鐘後結束會話。 – nilsw

+0

類似於https://stackoverflow.com/questions/41825964/cancel-a-prompt-or-dialog-after-certain-time-bot-framework – JasonSowers

+0

@JasonSowers我看到了這個問題,並不完全理解回答。我在哪個時間點設置時間戳?對於我從用戶那裏獲得的每個輸入?我在哪裏比較時間戳?每個輸入函數的開始?理想情況下,我想檢查消息控制器中的這些細節,但是我可以在那時訪問UserData嗎?對不起,我是這個框架的新手,很難找到合適的例子來從中獲得靈感。 – RetardedJoker

回答

0

這個原因可以在模擬器中工作,但不是其他通道中的模擬器中可以離開通道的原因。在Skype/Facebook中,即使未登錄,對話仍然存在。例如,在Skype中保留對話的唯一方法是刪除bot並重新添加。

也許而不是要求用戶輸入一些東西來阻止你可以使用計時器。流將工作是這樣的:

  1. 消息接收
  2. 時間戳
  3. 啓動定時器
  4. 後x分鐘結束會話,如果沒有其他響應
  5. 用戶類型超過
+0

所以,我試了這段代碼。它在模擬器或Skype中不起作用。對話停止,當我發送下一條消息從頭開始重新啓動對話框時,它不會重置它。我的黑客讓我通過發送第二條消息來重置對話。我試圖找到理想的解決方案,我不需要發送第二條消息以重置。 我會在一段時間內按要求發佈代碼。 – RetardedJoker

+0

好的,我盡力重現它。我會檢查回來。 – JasonSowers

相關問題