简体   繁体   English

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

[英]How can I process data from a websocket stream and conditionally send a proactive message in Azure Bot?

I have a data provider who provides their data over WebSocket.我有一个数据提供者通过 WebSocket 提供他们的数据。 I need to process it in real-time and then based on some criteria, I'll have to trigger an alert which needs to be sent as a proactive message in Azure Bot Framework.我需要实时处理它,然后根据一些标准,我必须触发一个警报,该警报需要在 Azure Bot Framework 中作为主动消息发送。 Now my questions are: 1. Can we process data from a WebSocket stream within Azure Bot Project and use it to conditionally trigger a proactive message?现在我的问题是: 1. 我们能否在 Azure Bot 项目中处理来自 WebSocket stream 的数据并使用它来有条件地触发主动消息? 2. If not possible, what is the best approach to accomplish something like this? 2. 如果不可能,完成这样的事情的最佳方法是什么? Create a separate project to process WebSocket data stream and post alerts via a web-hook?创建一个单独的项目来处理 WebSocket 数据 stream 并通过网络挂钩发布警报? In such case, how can I send proactive messages based on alerts received via webhook?在这种情况下,如何根据通过 webhook 收到的警报发送主动消息?

All my web-searches pointed me to results for sending activities to Azure Bot via WebSockets wr ways to Connect Bot to third-party services via webhook.我所有的网络搜索都指向我通过 WebSockets 向 Azure Bot 发送活动的结果,以及通过 webhook 将 Bot 连接到第三方服务的方法。

For this, you would want to create an API in your bot that accepts and processes any proactive messages.为此,您需要在您的机器人中创建一个 API 来接受和处理任何主动消息。 You can reference this dotnet doc and this sample, 16.proactive-messages , for guidance.您可以参考此 dotnet 文档和此示例16.proactive-messages以获得指导。

For the WebSocket data to be processed, you would want to set this up in a separate service.对于要处理的 WebSocket 数据,您需要在单独的服务中进行设置。 As a trigger passes thru, the proactive message would be generated and sent to the API you set up to be consumed by the bot.当触发器通过时,将生成主动消息并将其发送到您设置的 API 以供机器人使用。

In short (borrowing from the docs):简而言之(借用文档):

First, you create a conversationReference which is derived from the activity during the OnConversationUpdateActivityAsync activity handler.首先,您创建一个从OnConversationUpdateActivityAsync活动处理程序期间的activity派生的conversationReference参考。

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

Next, you design the route that handles the incoming request.接下来,您设计处理传入请求的路由。 The conversationReference is retrieved and ContinueConversationAsync along with BotCallback are called to process the incoming message.检索conversationReference并调用ContinueConversationAsync以及BotCallback来处理传入消息。

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

Lastly, to avoid 401 'Unauthorized' errors, you'll want to include TrustServiceUrl() just prior to the code that sends the proactive message.最后,为了避免 401 'Unauthorized' 错误,您需要在发送主动消息的代码之前包含TrustServiceUrl()

MicrosoftAppCredentials.TrustServiceUrl(serviceUrl);

Hope of help!希望有帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM