所以为了解释我的问题,我必须给你上下文。
我得到了一个用松弛部署的微软机器人框架构建的Bot。现在它可能发生在我的后端,机器人与之通信的这些“事件”。当一个事件发生时,我想通知我的机器人它然后让它发送一条消息给它所发生的所有事情的对话。所以基本上:
Backend>Microserivce>Bot>users
要做到这一点,我必须将所有对话存储在我的后端,我在那里的数据库中进行。当一个事件发生时,后端会将一个活动发布到机器人,所有的对话(基本上都是他们的id)和它应该显示的事件。
所以从本质上讲,我的后端需要向我的机器人发送消息。
为此,我发现了microsoft directline api,它充当了这里的中间人,一种更抽象的方式与机器人交谈。问题是我不知道该怎么做。我跟着microsofts自己的教程,但它似乎不适合我:
这是我的后端用于通知机器人的端点。 “content”包含作为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);
}
基本上执行得到了var conversation = await client.Conversations.StartConversationAsync();
,它只是永远等待。
我尝试将其更改为var conversation = await client.Conversations.StartConversationAsync().ConfigureAwait(continueOnCapturedContext: false);
'执行继续,但活动似乎没有发布。
答案 0 :(得分: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文档的更多详细信息。
答案 1 :(得分:0)
我不确定为什么调用.StartConversationAsync()会冻结你的情况。也许您尚未启用dev.botframework.com/bots上的Direct Line
频道?尽管如此,正如谢尔盖所指出的那样,Direct Line
是一个频道,而不是在其他频道上与机器人通信的手段。
查看Connector Client: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,fromId等从用户之前的通信缓存到机器人(这些静态存储在此示例中,因此仅适用于一个用户)。此示例显示了如何主动从机器人向用户发送消息。 <{1}} api不是必需的。