2017-05-14 82 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不是必需的。