2017-05-14 81 views
0

所以要解釋我的問題,我必須給你的上下文。微軟DirectLine API到機器人不起作用

我得到了一個殭屍部署的微軟bot框架的Bot。現在它可以在機器人通信的後端發生這些「事件」。當一個事件發生時,我想通知我的機器人,然後讓它發送一條消息給它的所有對話中發生的事情。所以基本上:

Backend>Microserivce>Bot>users 

要做到這一點,我必須存儲在我的後端,我在數據庫中做的所有談話。當事件發生時,後端會將所有對話(基本上是他們的ID)以及它應該顯示的事件發送到機器人。

所以在本質上,我的後端需要發佈消息到我的機器人。

爲了做到這一點,我在這裏找到了微軟的directline api,這是一個更爲抽象的方式來與bot交談。問題是我不知道該怎麼做。我遵循微軟自己的教程,但它似乎並不適合我:

這是我的後端用來通知機器人的端點。 「內容」包含會話和事件作爲json格式字符串。

[HttpPost] 
    [Route("conversationsEvents")] 
    public HttpResponseMessage PostConversationsEvents([FromBody]string content) 
    { 
     NotifyBot.Notify(content); 
     return Request.CreateResponse(HttpStatusCode.NoContent); 
    } 

NotifyBot.Notify(內容)看起來是這樣的:

 private static async Task StartBotConversation(string contents) 
    { 
     string directLineSecret = "secret"; 
     string fromUser = "microserviceNotifyEndpoint"; 
     Activity activity = new Activity 
     { 
      From = new ChannelAccount(fromUser), 
      Text = contents, 
      Type = ActivityTypes.Event 
     }; 
     DirectLineClient client = new DirectLineClient(directLineSecret); 
     var conversation = await client.Conversations.StartConversationAsync(); 
     await client.Conversations.PostActivityAsync(conversation.ConversationId, activity); 
    } 

Basicly執行GET的停留在var conversation = await client.Conversations.StartConversationAsync();,它只是等待,直到永遠。 我試圖將其更改爲var conversation = await client.Conversations.StartConversationAsync().ConfigureAwait(continueOnCapturedContext: false);'執行繼續,但活動似乎沒有發佈。

回答

0

您不需要使用DirectLine,它被設計用於創建替代的bot UI。

要實現什麼你願意,你可以嘗試以下方法:

首先,您需要將用戶地址存儲要發送消息的人。我可以通過將用戶最後一條消息的ResumptionCookie存儲在後端數據庫中來完成。

var state = new ResumptionCookie(message).GZipSerialize(); 

當您的PostConversationsEvents被調用時,您可以在每個用戶的最新點繼續對話。

 var resumptionCookie = ResumptionCookie.GZipDeserialize(state); 
     var message = resumptionCookie.GetMessage(); 
     message.Text = content; 
     await Conversation.ResumeAsync(resumptionCookie, message); 

這不是唯一的解決方案。正如我所說的,在這種情況下,您剛剛恢復了與用戶的對話。另一種解決方案是保存用戶地址(用戶相同的ResumptionCookie類),但開始對話時,你需要:

 var resumptionCookie = ResumptionCookie.GZipDeserialize(state); 
     var message = cookie.GetMessage(); 

     ConnectorClient client = new ConnectorClient(new Uri(message.ServiceUrl)); 

     var conversation = await 
     client.Conversations.CreateDirectConversationAsync(message.Recipient, message.From); 
     message.Conversation.Id = conversation.Id; 
     var newMessage = message.CreateReply(); 
     newMessage.Text = content; 
     await client.Conversations.SendToConversationAsync(newMessage); 

查看BotFramework文檔的更多信息。

+0

我認爲使用directline api是一種很好的做法。我也試過在我可以調用的bot中定義一個「正常」端點,但它給了我相同的結果。我會看看你的例子。 – lallaliff

0

我不知道爲什麼調用.StartConversationAsync()會凍結你的情況。也許你還沒有啓用dev.botframework.com/botsDirect Line頻道?儘管如此,正如Sergey指出的那樣,Direct Line是一個頻道,並不是通過其他渠道與您的機器人通信的手段。

查閱連接器客戶端:bot-builder-dotnet-connector

這裏是用它來主動地從一個機器人將消息發送到一個用戶的靜態例如:MicrosoftDX/botFramework-proactiveMessages - sample: ConversationStarter.cs

相關代碼從樣品:

public static async Task Resume(string conversationId,string channelId) 
    { 
     var userAccount = new ChannelAccount(toId,toName); 
     var botAccount = new ChannelAccount(fromId, fromName); 
     var connector = new ConnectorClient(new Uri(serviceUrl)); 

     IMessageActivity message = Activity.CreateMessageActivity(); 
     if (!string.IsNullOrEmpty(conversationId) && !string.IsNullOrEmpty(channelId)) 
     { 
      message.ChannelId = channelId; 
     } 
     else 
     { 
      conversationId = (await connector.Conversations.CreateDirectConversationAsync(botAccount, userAccount)).Id; 
     } 
     message.From = botAccount; 
     message.Recipient = userAccount; 
     message.Conversation = new ConversationAccount(id: conversationId); 
     message.Text = "Hello, this is a notification"; 
     message.Locale = "en-Us"; 
     await connector.Conversations.SendToConversationAsync((Activity)message); 
    } 

serviceUrl,channelId,conversationId,toId,fromI等等是從用戶以前通信到機器人(這些在本例中靜態存儲的,因此僅適用於一個用戶)緩存的。這個例子展示瞭如何從機器人主動發送消息給用戶。 Direct Line api不是必需的。