2017-05-14 6 views
0

私の問題を説明するために、私は文脈を伝えなければなりません。ボットへのMicrosoft DirectLine APIは動作しません

私は、Microsoftのボットフレームワークをスラックに配備したBotを手に入れました。今では、ボットが通信するバックエンドのこれらの "イベント"が発生する可能性があります。イベントが発生すると、そのボットにボットに通知し、何か起こっていることを会話のすべてに伝えるようにします。だから基本的に:

Backend>Microserivce>Bot>users 

これを行うには、私はそこにデータベース内で行うバックエンドにすべての会話を保存する必要があります。イベントが発生すると、バックエンドはボットにすべての会話(基本的に自分のID)とそのイベントを表示するように活動を通知します。

本質的に私のバックエンドはボットにメッセージを投稿する必要があります。

これを行うために、私はここで仲介人として働くマイクロソフトのdirectline apiを見つけました。これはもっと抽象的な方法でボットと話すことです。問題は私がそれをやる方法を知らないことです。私はマイクロソフト自身のチュートリアルに従ったが、それは私にとってはうまくいかないようだ。

これは私のバックエンドがボットに通知するのに使うエンドポイントである。 "content"には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実行取得のスタックvar conversation = await client.Conversations.StartConversationAsync();で、それだけで永遠に待ちます。 私はそれをvar conversation = await client.Conversations.StartConversationAsync().ConfigureAwait(continueOnCapturedContext: false);に変更しようとしましたが、実行は続きますが、アクティビティは投稿されていないようです。

答えて

0

DirectLineを使用する必要はありません。代わりのボットUIを作成するために設計されています。

何あなたの希望実装するには、次のことを試してください:

まず、あなたがメッセージを送信する相手にユーザーのアドレスを格納する必要があります。それは私のバックエンドデータベースにユーザーの最後のメッセージのResumptionCookieを格納することによって行われます。あなたのPostConversationsEventsが呼び出されると

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

、あなたはそれぞれのユーザーと最新の時点で会話を再開してもよいです。

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

これは唯一の解決策ではありません。私が言ったように、この場合、あなたはちょうどその時点でユーザーと会話を再開しました。

 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マニュアルの詳細を参照してください:あなたがする必要があるときに別の解決策は、ユーザアドレス(ユーザー同じResumptionCookieクラス)を保存して、会話を開始することです。

+0

私はダイレクトラインAPIを使用すると良い練習だと思った。私は呼ぶことができるボットの内部に「通常の」エンドポイントを定義しようと試みただけですが、同じ結果が得られます。私はあなたの事例を調べます。 – 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、fromIdなどは、ユーザーによるボットへの以前の通信からキャッシュされます(これらはこの例では静的に格納されているため、1人のユーザーのみが機能します)。この例は、ボットから事前にメッセージをユーザに送信する方法を示しています。 Direct Line apiは必須ではありません。

関連する問題