问题
I'm working on a Teams bot that needs the ability to start a new 1:1 conversation with a known user (i.e., we know the Teams user ID).
I've looked at the "complete-csharp" OfficeDev samples on GitHub (https://github.com/OfficeDev/microsoft-teams-sample-complete-csharp) as well as the Teams-related parts of the Graph API but I don't see any affordance for starting a new conversation.
Our goal is to have our bot ping a known user on a schedule by inviting them into a 1:1 chat and requesting their feedback. A button in the bot's message will reveal the feedback form (via task module).
回答1:
Teams calls that a "Proactive Message". So long as you get the user ID that Teams uses, it's fairly easy to do.
Per the docs, 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.
The easiest way to do this is through the Microsoft.Bot.Builder.Teams
middleware.
Note: The Microsoft.Bot.Builder.Teams extension is still in Prerelease for V4, which is why samples and code are kind of hard to find for it.
Adding the Middleware
In 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)));
[...]
Prepping Your Bot
In your main <YourBot>.cs
:
private readonly SimpleCredentialProvider _credentialProvider;
[...]
public <YourBot>(ConversationState conversationState, SimpleCredentialProvider CredentialProvider)
{
_credentialProvider = CredentialProvider;
[...]
Sending the Message
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);
Note: If you need to get user ID's, you can use:
var members = (await turnContext.TurnState.Get<IConnectorClient>().Conversations.GetConversationMembersAsync(
turnContext.Activity.GetChannelData<TeamsChannelData>().Team.Id).ConfigureAwait(false)).ToList();
Also, I didn't need this in my testing, but if you get 401 errors, you may need to trust the Teams ServiceUrl:
MicrosoftAppCredentials.TrustServiceUrl(turnContext.Activity.ServiceUrl);
Resources
- Teams Extension on MyGet
- Teams Extension MyGet Package Repo
- Samples using the extension
- Proactive Teams Sample
- Useful, unofficial blog post
来源:https://stackoverflow.com/questions/57120193/how-can-my-teams-bot-start-a-new-11-chat-with-a-known-user