如何处理来自 websocket 流的数据并有条件地在 Azure Bot 中发送主动消息?

Posted

技术标签:

【中文标题】如何处理来自 websocket 流的数据并有条件地在 Azure Bot 中发送主动消息?【英文标题】:How can I process data from a websocket stream and conditionally send a proactive message in Azure Bot? 【发布时间】:2020-04-25 10:39:07 【问题描述】:

我有一个通过 WebSocket 提供数据的数据提供者。我需要实时处理它,然后根据一些标准,我必须触发一个警报,该警报需要在 Azure Bot Framework 中作为主动消息发送。 现在我的问题是: 1. 我们能否在 Azure Bot Project 中处理来自 WebSocket 流的数据并使用它来有条件地触发主动消息? 2. 如果不可能,完成此类事情的最佳方法是什么?创建一个单独的项目来处理 WebSocket 数据流并通过 web-hook 发布警报?在这种情况下,如何根据通过 webhook 收到的警报发送主动消息?

我所有的网络搜索都指向我通过 WebSockets 向 Azure Bot 发送活动的结果,以及通过 webhook 将 Bot 连接到第三方服务的方法。

【问题讨论】:

接受/赞成一个答案服务于更大的 Stack Overflow 社区和任何有类似问题的人。如果您觉得我的回答足够,请“接受”并点赞。如果没有,请告诉我我还能提供哪些帮助! 【参考方案1】:

为此,您需要在您的机器人中创建一个 API,以接受和处理任何主动消息。您可以参考此 dotnet doc 和此示例 16.proactive-messages 以获得指导。

对于要处理的 WebSocket 数据,您可能希望在单独的服务中进行设置。当触发器通过时,将生成主动消息并将其发送到您设置的 API 以供机器人使用。

简而言之(借用文档):

首先,您在OnConversationUpdateActivityAsync 活动处理程序期间创建一个派生自activityconversationReference

private void AddConversationReference(Activity activity)

    var conversationReference = activity.GetConversationReference();
    _conversationReferences.AddOrUpdate(conversationReference.User.Id, conversationReference, (key, newValue) => conversationReference);


protected override Task OnConversationUpdateActivityAsync(ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)

    AddConversationReference(turnContext.Activity as Activity);

    return base.OnConversationUpdateActivityAsync(turnContext, cancellationToken);

接下来,您设计处理传入请求的路由。检索到conversationReference,并调用ContinueConversationAsyncBotCallback 来处理传入的消息。

[Route("api/notify")]
[ApiController]
public class NotifyController : ControllerBase

    private readonly IBotFrameworkHttpAdapter _adapter;
    private readonly string _appId;
    private readonly ConcurrentDictionary<string, ConversationReference> _conversationReferences;

    public NotifyController(IBotFrameworkHttpAdapter adapter, IConfiguration configuration, ConcurrentDictionary<string, ConversationReference> conversationReferences)
    
        _adapter = adapter;
        _conversationReferences = conversationReferences;
        _appId = configuration["MicrosoftAppId"];

        // If the channel is the Emulator, and authentication is not in use,
        // the AppId will be null.  We generate a random AppId for this case only.
        // This is not required for production, since the AppId will have a value.
        if (string.IsNullOrEmpty(_appId))
        
            _appId = Guid.NewGuid().ToString(); //if no AppId, use a random Guid
        
    

    public async Task<IActionResult> Get()
    
        foreach (var conversationReference in _conversationReferences.Values)
        
            await ((BotAdapter)_adapter).ContinueConversationAsync(_appId, conversationReference, BotCallback, default(CancellationToken));
        

        // Let the caller know proactive messages have been sent
        return new ContentResult()
        
            Content = "<html><body><h1>Proactive messages have been sent.</h1></body></html>",
            ContentType = "text/html",
            StatusCode = (int)HttpStatusCode.OK,
        ;
    

    private async Task BotCallback(ITurnContext turnContext, CancellationToken cancellationToken)
    
        // If you encounter permission-related errors when sending this message, see
        // https://aka.ms/BotTrustServiceUrl
        await turnContext.SendActivityAsync("proactive hello");
    

最后,为了避免 401 'Unauthorized' 错误,您需要在发送主动消息的代码之前包含 TrustServiceUrl()

MicrosoftAppCredentials.TrustServiceUrl(serviceUrl);

希望有帮助!

【讨论】:

以上是关于如何处理来自 websocket 流的数据并有条件地在 Azure Bot 中发送主动消息?的主要内容,如果未能解决你的问题,请参考以下文章

如何处理 Spring 集成流的事务(Java DSL)

如何处理奇怪组合的 websocket 消息?

WebSocket 服务器如何处理多个传入的连接请求?

Android 中的两个并发 AsyncTasks - 如何处理竞争条件?

如何处理 Azure App Service WebSockets 超时?

Core Data + iCloud 如何处理来自云端的数据更新