如何使用 Bot Framework V4 C# SDK 在 Teams 中迁移 1:1 主动消息功能
How to migrate 1:1 proactive messages functionality in Teams with Bot Framework V4 C# SDK
我有一个 Bot Framework V3 SDK 实现(工作正常),它可以使用 Microsoft Teams Bot(安装在同一个团队)与特定团队中的任何用户发起 1:1 私人聊天。
我在尝试将其迁移到 V4 SDK 时遇到问题。
我阅读了各种文章和其他问题,除非用户首先联系机器人(以避免向用户发送垃圾邮件),否则无法做到这一点,但 V3 版本并非如此,也不是一个选项我需要的功能。
原方案使用Microsoft.Bot.Connector.Teams
程序集的“CreateOrGetDirectConversation
”扩展方法,但在程序集的V4版本中不可用。
我尝试使用 CreateDirectConversation
/CreateDirectConversationAsync
方法但没有成功(它们总是导致 "Bad Request" 错误)。
这是使用 V3 库实际工作的代码:
// Create 1:1 conversation
var conversation = connectorClient.Conversations.CreateOrGetDirectConversation(botAccount, user, tenantId);
// Send message to the user
var message = Activity.CreateMessageActivity();
message.Type = ActivityTypes.Message;
message.Text = "My message";
connectorClient.Conversations.SendToConversation((Activity)message, conversation.Id);
而且我发现迁移非常困难。我错过了什么吗?
根据文档,Proactive messaging for bots:
Bots can create new conversations with an individual Microsoft Teams user as long as your bot has user information obtained through previous addition in a personal, groupChat or team scope. This information enables your bot to proactively notify them. For instance, if your bot was added to a team, it could query the team roster and send users individual messages in personal chats, or a user could @mention another user to trigger the bot to send that user a direct message.
注意:Microsoft.Bot.Builder.Teams 扩展仍在 V4 的预发行版中,这就是为什么很难找到它的示例和代码的原因。
添加中间件
在Startup.cs
中:
var credentials = new SimpleCredentialProvider(Configuration["MicrosoftAppId"], Configuration["MicrosoftAppPassword"]);
services.AddSingleton(credentials);
[...]
services.AddBot<YourBot>(options =>
{
options.CredentialProvider = credentials;
options.Middleware.Add(
new TeamsMiddleware(
new ConfigurationCredentialProvider(this.Configuration)));
[...]
准备你的机器人
在你的主要 <YourBot>.cs
:
private readonly SimpleCredentialProvider _credentialProvider;
[...]
public <YourBot>(ConversationState conversationState, SimpleCredentialProvider CredentialProvider)
{
_credentialProvider = CredentialProvider;
[...]
正在发送消息
var teamConversationData = turnContext.Activity.GetChannelData<TeamsChannelData>();
var connectorClient = new ConnectorClient(new Uri(activity.ServiceUrl), _credentialProvider.AppId, _credentialProvider.Password);
var userId = <UserIdToSendTo>;
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);
var message = Activity.CreateMessageActivity();
message.Text = "This is a proactive message.";
await connectorClient.Conversations.SendToConversationAsync(conversationResource.Id, (Activity)message);
注意:如果需要获取用户ID,可以使用:
var members = (await turnContext.TurnState.Get<IConnectorClient>().Conversations.GetConversationMembersAsync(
turnContext.Activity.GetChannelData<TeamsChannelData>().Team.Id).ConfigureAwait(false)).ToList();
另外,我在测试中不需要这个,但是如果你得到 401 错误,你可能需要 trust the Teams ServiceUrl:
MicrosoftAppCredentials.TrustServiceUrl(turnContext.Activity.ServiceUrl);
资源
我有一个 Bot Framework V3 SDK 实现(工作正常),它可以使用 Microsoft Teams Bot(安装在同一个团队)与特定团队中的任何用户发起 1:1 私人聊天。 我在尝试将其迁移到 V4 SDK 时遇到问题。
我阅读了各种文章和其他问题,除非用户首先联系机器人(以避免向用户发送垃圾邮件),否则无法做到这一点,但 V3 版本并非如此,也不是一个选项我需要的功能。
原方案使用Microsoft.Bot.Connector.Teams
程序集的“CreateOrGetDirectConversation
”扩展方法,但在程序集的V4版本中不可用。
我尝试使用 CreateDirectConversation
/CreateDirectConversationAsync
方法但没有成功(它们总是导致 "Bad Request" 错误)。
这是使用 V3 库实际工作的代码:
// Create 1:1 conversation
var conversation = connectorClient.Conversations.CreateOrGetDirectConversation(botAccount, user, tenantId);
// Send message to the user
var message = Activity.CreateMessageActivity();
message.Type = ActivityTypes.Message;
message.Text = "My message";
connectorClient.Conversations.SendToConversation((Activity)message, conversation.Id);
而且我发现迁移非常困难。我错过了什么吗?
根据文档,Proactive messaging for bots:
Bots can create new conversations with an individual Microsoft Teams user as long as your bot has user information obtained through previous addition in a personal, groupChat or team scope. This information enables your bot to proactively notify them. For instance, if your bot was added to a team, it could query the team roster and send users individual messages in personal chats, or a user could @mention another user to trigger the bot to send that user a direct message.
注意:Microsoft.Bot.Builder.Teams 扩展仍在 V4 的预发行版中,这就是为什么很难找到它的示例和代码的原因。
添加中间件
在Startup.cs
中:
var credentials = new SimpleCredentialProvider(Configuration["MicrosoftAppId"], Configuration["MicrosoftAppPassword"]);
services.AddSingleton(credentials);
[...]
services.AddBot<YourBot>(options =>
{
options.CredentialProvider = credentials;
options.Middleware.Add(
new TeamsMiddleware(
new ConfigurationCredentialProvider(this.Configuration)));
[...]
准备你的机器人
在你的主要 <YourBot>.cs
:
private readonly SimpleCredentialProvider _credentialProvider;
[...]
public <YourBot>(ConversationState conversationState, SimpleCredentialProvider CredentialProvider)
{
_credentialProvider = CredentialProvider;
[...]
正在发送消息
var teamConversationData = turnContext.Activity.GetChannelData<TeamsChannelData>();
var connectorClient = new ConnectorClient(new Uri(activity.ServiceUrl), _credentialProvider.AppId, _credentialProvider.Password);
var userId = <UserIdToSendTo>;
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);
var message = Activity.CreateMessageActivity();
message.Text = "This is a proactive message.";
await connectorClient.Conversations.SendToConversationAsync(conversationResource.Id, (Activity)message);
注意:如果需要获取用户ID,可以使用:
var members = (await turnContext.TurnState.Get<IConnectorClient>().Conversations.GetConversationMembersAsync(
turnContext.Activity.GetChannelData<TeamsChannelData>().Team.Id).ConfigureAwait(false)).ToList();
另外,我在测试中不需要这个,但是如果你得到 401 错误,你可能需要 trust the Teams ServiceUrl:
MicrosoftAppCredentials.TrustServiceUrl(turnContext.Activity.ServiceUrl);