Monday, 20 July 2020

Microsoft Teams Bot Framework: Mention a user in an Adaptive Card

Microsoft Teams announced support for Adaptive Cards 1.2 recently. With that, a nifty feature to allow mentioning users in Adaptive Cards posted in Teams was also introduced. This allows us the ability to send a notification to the user and can draw their attention towards the card.

User gets a notification of the mention:


(click to zoom)

Other users are able to contact the user directly from the mention in the card:


(click to zoom)


In the docs, there is a great example of the JSON we need to send to Teams to post the card containing the mention. So in this post, lets see how we can do this when using the Bot Framework .NET Core SDK:

For this code to work, we will need the following Nuget packages:



using AdaptiveCards;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Connector;
using Microsoft.Bot.Connector.Authentication;
using Microsoft.Bot.Schema;
using Microsoft.Bot.Schema.Teams;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Teams.AdaptimeCard.Mentions
{
class Program
{
static async Task Main(string[] args)
{
//The Bot Service Url needs to be dynamically stored and fetched from the Team.
//This Url is present in every payload which Teams sends to the Bot after the Bot is added to the Team.
//Recommendation is to store the serviceUrl from the bot payload and later re-use it to send proactive messages.
string serviceUrl = "https://smba.trafficmanager.net/emea/";
//From the Bot Channel Registration
string botClientID = "<client-id>";
string botClientSecret = "<client-secret>";
//Teams channel id in which to create the post.
string teamsChannelId = "19:f2a953307f4644aea79d23dacde2d3a3@thread.tacv2";
string userName = "user@tenant.onmicrosoft.com";
MicrosoftAppCredentials.TrustServiceUrl(serviceUrl);
var connectorClient = new ConnectorClient(new Uri(serviceUrl), new MicrosoftAppCredentials(botClientID, botClientSecret));
var userToMention = await ((Conversations)connectorClient.Conversations).GetConversationMemberAsync(userName, teamsChannelId);
var mention = new Mention
{
Mentioned = userToMention,
Text = $"<at>{userToMention.Name}</at>",
};
AdaptiveCard adaptiveCard = new AdaptiveCard(new AdaptiveSchemaVersion("1.2"));
adaptiveCard.Body.Add(new AdaptiveTextBlock()
{
Text = $"Mentioning {mention.Text} in an Adaptive Card posted in Teams",
Size = AdaptiveTextSize.ExtraLarge,
Spacing = AdaptiveSpacing.Large,
Wrap = true
});
//Create a user entitiy and add it to the Adaptive Card payload
var entities = new { entities = new List<Entity> { mention } };
adaptiveCard.AdditionalProperties.Add("msteams", entities);
var cardAttachment = new Attachment
{
Content = adaptiveCard,
ContentType = AdaptiveCard.ContentType,
};
var messageActivity = MessageFactory.Attachment(cardAttachment);
//Send the activity to Teams.
var conversationParameters = new ConversationParameters
{
IsGroup = true,
ChannelData = new TeamsChannelData
{
Channel = new ChannelInfo(teamsChannelId),
},
Activity = (Activity)messageActivity
};
await connectorClient.Conversations.CreateConversationAsync(conversationParameters);
}
}
}

Quick note: I noticed that the user mentioned is only notified when the Adaptive card is first created. If you update the same adaptive card later and mention the same user again, they are not notified. This is probably for the best as the Adaptive card might be updated several times and if you got a notification every time, it might be really annoying to the user.

Hope you found this post useful!