如何处理来自 websocket 流的数据并有条件地在 Azure Bot 中发送主动消息?
How can I process data from a websocket stream and conditionally send a proactive message in Azure Bot?
我有一个数据提供者通过 WebSocket 提供他们的数据。我需要实时处理它,然后根据某些条件,我必须触发一个警报,该警报需要在 Azure Bot Framework 中作为主动消息发送。
现在我的问题是:
1. 我们能否在 Azure Bot Project 中处理来自 WebSocket 流的数据并使用它有条件地触发主动消息?
2. 如果不可能,完成这样的事情的最佳方法是什么?创建一个单独的项目来通过网络挂钩处理 WebSocket 数据流和 post 警报?在这种情况下,我如何根据通过 webhook 收到的警报发送主动消息?
我所有的网络搜索都指向了通过 WebSockets 将活动发送到 Azure Bot 的结果,以及通过 webhook 将 Bot 连接到第三方服务的方法。
为此,您需要在您的机器人中创建一个 API 来接受和处理任何主动消息。您可以参考此 dotnet doc and this sample, 16.proactive-messages 作为指导。
对于要处理的 WebSocket 数据,您可能希望在单独的服务中进行设置。当触发器通过时,将生成主动消息并将其发送到您设置为由机器人使用的 API。
简而言之(借用文档):
首先,您创建一个 conversationReference
,它在 OnConversationUpdateActivityAsync
activity 处理程序期间从 activity
派生。
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
并调用 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");
}
}
最后,为避免 401 'Unauthorized' 错误,您需要在发送主动消息的代码之前包含 TrustServiceUrl()
。
MicrosoftAppCredentials.TrustServiceUrl(serviceUrl);
希望得到帮助!
我有一个数据提供者通过 WebSocket 提供他们的数据。我需要实时处理它,然后根据某些条件,我必须触发一个警报,该警报需要在 Azure Bot Framework 中作为主动消息发送。 现在我的问题是: 1. 我们能否在 Azure Bot Project 中处理来自 WebSocket 流的数据并使用它有条件地触发主动消息? 2. 如果不可能,完成这样的事情的最佳方法是什么?创建一个单独的项目来通过网络挂钩处理 WebSocket 数据流和 post 警报?在这种情况下,我如何根据通过 webhook 收到的警报发送主动消息?
我所有的网络搜索都指向了通过 WebSockets 将活动发送到 Azure Bot 的结果,以及通过 webhook 将 Bot 连接到第三方服务的方法。
为此,您需要在您的机器人中创建一个 API 来接受和处理任何主动消息。您可以参考此 dotnet doc and this sample, 16.proactive-messages 作为指导。
对于要处理的 WebSocket 数据,您可能希望在单独的服务中进行设置。当触发器通过时,将生成主动消息并将其发送到您设置为由机器人使用的 API。
简而言之(借用文档):
首先,您创建一个 conversationReference
,它在 OnConversationUpdateActivityAsync
activity 处理程序期间从 activity
派生。
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
并调用 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");
}
}
最后,为避免 401 'Unauthorized' 错误,您需要在发送主动消息的代码之前包含 TrustServiceUrl()
。
MicrosoftAppCredentials.TrustServiceUrl(serviceUrl);
希望得到帮助!