我的 Teams 机器人如何与已知用户开始新的 1:1 聊天

How can my Teams bot start a new 1:1 chat with a known user

我正在开发一个 Teams 机器人,它需要能够与已知用户(即我们知道 Teams 用户 ID)开始新的 1:1 对话。

我查看了 GitHub (https://github.com/OfficeDev/microsoft-teams-sample-complete-csharp) 上的 "complete-csharp" OfficeDev 示例以及图表中与 Teams 相关的部分 API,但我没有'看到任何开始新对话的启示。

我们的目标是让我们的机器人按计划通过邀请已知用户加入 1:1 聊天并征求他们的反馈。机器人消息中的一个按钮将显示反馈表(通过任务模块)。

更新

Bot Framework 添加了特定于 Teams 的代码,这使得此答案中的很多代码没有实际意义或不正确。现在,请参阅 this sample 在 Teams 中发送主动消息。

Teams 称之为 "Proactive Message"。只要你得到Teams使用的用户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 中间件。

注意: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); 

资源