0

所以为了解释我的问题,我必须给你背景。

我得到了一个使用 slack 上部署的 microsoft bot 框架构建的 Bot。现在它可以在机器人与之通信的我的后端发生这些“事件”。当一个事件发生时,我想通知我的机器人,然后让它向所有的对话发送一条消息,告诉它发生了什么事。所以基本上:

Backend>Microserivce>Bot>users

为此,我必须将所有对话存储在我的后端,我在那里的数据库中进行。当事件发生时,后端将向机器人发布一个活动,其中包含所有对话(基本上是他们的 id)以及它应该显示的事件。

所以本质上我的后端需要向我的机器人发布消息。

为此,我在这里找到了充当中间人的 microsoft directline api,这是一种与机器人交谈的更抽象的方式。问题是我不知道该怎么做。我遵循了微软自己的教程,但它似乎对我不起作用:

这是我的后端用来通知机器人的端点。“内容”包含作为 json 格式字符串的对话和事件。

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

NotifyBot.Notify(content) 看起来像这样:

        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);
    }

基本上执行被卡在var conversation = await client.Conversations.StartConversationAsync();,它只是永远等待。我尝试将其更改为var conversation = await client.Conversations.StartConversationAsync().ConfigureAwait(continueOnCapturedContext: false);“执行继续,但活动似乎没有发布。

4

2 回答 2

0

您不需要使用 DirectLine,它专为创建替代机器人 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 文档的更多详细信息。

于 2017-05-14T19:42:34.157 回答
0

我不确定为什么在您的情况下对 .StartConversationAsync() 的调用会冻结。也许您还没有启用dev.botframework.com/botsDirect Line上的频道?尽管如此,正如 Sergey 所指出的,这是一个频道,而不是在其他频道上与您的机器人进行通信的一种方式。Direct Line

查看连接器客户端:bot-builder-dotnet-connector

这是一个使用它从机器人主动向用户发送消息的静态示例:MicrosoftDX/botFramework-proactiveMessages - 示例: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 等从用户先前与机器人的通信中缓存(这些在本示例中静态存储,因此仅适用于一个用户)。此示例展示了如何从机器人主动向用户发送消息。该Direct Lineapi 不是必需的。

于 2017-05-15T00:15:30.147 回答