从群聊到 MS Teams 中的个人聊天,使用 Bot Framework 进行主动对话
Proactive Dialog with the Bot Framework from Group chat to Personal chat in MS Teams
可以使用下一部分代码向团队群组聊天中的消息发送者发送主动消息(=私人):
if (stepContext.Context.Activity.ChannelId == Channels.Msteams &&
stepContext.Context.Activity.Conversation.IsGroup.HasValue &&
stepContext.Context.Activity.Conversation.IsGroup.Value) {
var teamConversationData = stepContext.Context.Activity.GetChannelData<TeamsChannelData>();
var connectorClient = new ConnectorClient(new Uri(stepContext.Context.Activity.ServiceUrl), _credentialOptions.MicrosoftAppId, _credentialOptions.MicrosoftAppPassword);
var userId = stepContext.Context.Activity.From.Id;
var tenantId = teamConversationData.Tenant.Id;
var parameters = new ConversationParameters
{
Members = new[] { new ChannelAccount(userId) },
ChannelData = new TeamsChannelData
{
Tenant = new TenantInfo(tenantId),
},
};
var conversationResource = await connectorClient.Conversations.CreateConversationAsync(parameters, cancellationToken: cancellationToken);
var message = Activity.CreateMessageActivity();
message.Text = "This is a proactive message. I've sent it from a group conversation.";
await connectorClient.Conversations.SendToConversationAsync(conversationResource.Id, (Activity)message, cancellationToken: cancellationToken);
}
但问题是 我还希望能够为该呼叫用户触发对话,而不是 发送 Activity。网上查了下好像不行?
我玩了一下代码,发现我可以替换
await connectorClient.Conversations.SendToConversationAsync(conversationResource.Id, (Activity)message, cancellationToken: cancellationToken);
和
stepContext.Context.Activity.Conversation.Id = conversationResource.Id;
stepContext.Context.Activity.Conversation.IsGroup = false;
这样可以将对话发送到发送用户的私人聊天。
当我查看数据库时,我可以看到已保存的用户对话框堆栈,其中填充了对话框(等待用户交互)。
我还可以看到仍然为空的群对话对话框堆栈,因此该机器人在群聊和其他用户中仍然有响应。
当对话结束时,我将 Conversation.Id 和 .IsGroup 放回到我保存在上下文中的前一个群聊值,它能够在群聊中传递最终答案就像我希望的那样。
基本上我的代码可以切换到在私人中间对话中发送内容,并且在对话中的任何其他点它可以切换回群组对话。
问题是关于我在对话框中更改对话 ID。这是正常的事情吗?这会破坏我还没有想到的东西吗?
我认为这种方法没有任何问题,但我认为您通常会启动一个新对话框而不是继续使用同一个对话框。
我认为在保存状态时,任何在 hack 之前访问状态的代码都将保留在新 ID 下。中间件 运行 在回合之前,vs 在回合完成之后,会有两个单独的对话 ID。
可以使用下一部分代码向团队群组聊天中的消息发送者发送主动消息(=私人):
if (stepContext.Context.Activity.ChannelId == Channels.Msteams &&
stepContext.Context.Activity.Conversation.IsGroup.HasValue &&
stepContext.Context.Activity.Conversation.IsGroup.Value) {
var teamConversationData = stepContext.Context.Activity.GetChannelData<TeamsChannelData>();
var connectorClient = new ConnectorClient(new Uri(stepContext.Context.Activity.ServiceUrl), _credentialOptions.MicrosoftAppId, _credentialOptions.MicrosoftAppPassword);
var userId = stepContext.Context.Activity.From.Id;
var tenantId = teamConversationData.Tenant.Id;
var parameters = new ConversationParameters
{
Members = new[] { new ChannelAccount(userId) },
ChannelData = new TeamsChannelData
{
Tenant = new TenantInfo(tenantId),
},
};
var conversationResource = await connectorClient.Conversations.CreateConversationAsync(parameters, cancellationToken: cancellationToken);
var message = Activity.CreateMessageActivity();
message.Text = "This is a proactive message. I've sent it from a group conversation.";
await connectorClient.Conversations.SendToConversationAsync(conversationResource.Id, (Activity)message, cancellationToken: cancellationToken);
}
但问题是 我还希望能够为该呼叫用户触发对话,而不是 发送 Activity。网上查了下好像不行? 我玩了一下代码,发现我可以替换
await connectorClient.Conversations.SendToConversationAsync(conversationResource.Id, (Activity)message, cancellationToken: cancellationToken);
和
stepContext.Context.Activity.Conversation.Id = conversationResource.Id;
stepContext.Context.Activity.Conversation.IsGroup = false;
这样可以将对话发送到发送用户的私人聊天。
当我查看数据库时,我可以看到已保存的用户对话框堆栈,其中填充了对话框(等待用户交互)。 我还可以看到仍然为空的群对话对话框堆栈,因此该机器人在群聊和其他用户中仍然有响应。
当对话结束时,我将 Conversation.Id 和 .IsGroup 放回到我保存在上下文中的前一个群聊值,它能够在群聊中传递最终答案就像我希望的那样。
基本上我的代码可以切换到在私人中间对话中发送内容,并且在对话中的任何其他点它可以切换回群组对话。
问题是关于我在对话框中更改对话 ID。这是正常的事情吗?这会破坏我还没有想到的东西吗?
我认为这种方法没有任何问题,但我认为您通常会启动一个新对话框而不是继续使用同一个对话框。
我认为在保存状态时,任何在 hack 之前访问状态的代码都将保留在新 ID 下。中间件 运行 在回合之前,vs 在回合完成之后,会有两个单独的对话 ID。