Send a notification to a Microsoft Teams user from an app

Problem

This article describes a solution for the scenario where an app needs to send a notification to a user in Microsoft Teams.

Overview of the solution

This can be accomplished by utilizing bot support in Microsoft Teams as illustrated in the diagram below.

appsnotificationsdiagram

  1. Bot Framework SDK sends an Activity object to the bot whenever a new message is received by the bot from a user.
  2. This Activity object contains a bunch of information, but of most interest to us for this scenario is the conversationId and serviceUrl. It is referred to as CallbackInfo in this diagram.
    1. conversationId: Each bot:user 1:1 chat has a unique conversationId.
    2. serviceUrl: serviceUrl informs the Bot Framework SDK where to send the HTTP request with bot’s reply.
  3. ConversationId and ServiceUrl (and bot-id + bot-secret) are enough to post a message to the conversation. So the idea is to persist the combination of ConversationId and ServiceUrl mapped to the userId of the user.
  4. When an event occurs in the system that’s of interest to a user, now it is possible to lookup the corresponding CallbackInfo and post a message to bot’s conversation with that user.
  5. The sample code below illustrates how to compactly store the CallbackInfo as a token in a webhookUrl and how to implement the webhook handler to post to the conversation of the bot with the user.

 

Sample code

Here is some code to illustrate the key parts of the solution.

First, here’s the class that captures the CallbackInfo.

public class CallbackInfo
{
    public string ConversationId { get; set; }
    public string ServiceUrl { get; set; }
}

Here is how one can construct a webhook URL that contains the encoded CallbackInfo based on the incoming activity received when a user sends a message.

 var callBackInfo = new CallbackInfo() 
 { 
     ConversationId = activity.Conversation.Id, 
     ServiceUrl = activity.ServiceUrl
 };
 var token = Convert.ToBase64String(
     Encoding.Default.GetBytes(
         JsonConvert.SerializeObject(callBackInfo)));

 var webhookUrl = host + "/v1/hook/" + token;

And finally, here’s a sample webhook controller that can post to conversation with user:

public class WebhookController : ApiController
{
    [Route("v1/hook/{token}")]
    public async Task<HttpResponseMessage> Handle([FromUri]string token, [FromBody]IncomingMessage message)
    {
        // Unpack the callback information
        var jsonString = Encoding.Default.GetString(Convert.FromBase64String(token));
        var callbackInfo = JsonConvert.DeserializeObject<CallbackInfo>(jsonString);

        // Post the message onto the conversation with the user
        ConnectorClient connector = new ConnectorClient(new Uri(callbackInfo.ServiceUrl));
 
        var newMessage = Activity.CreateMessageActivity();
        newMessage.Type = ActivityTypes.Message;
        newMessage.Conversation = new ConversationAccount(id: callbackInfo.ConversationId);
        newMessage.TextFormat = "xml";
        newMessage.Text = message.Text;

        await connector.Conversations.SendToConversationAsync(newMessage as Activity);

        return new HttpResponseMessage(HttpStatusCode.OK);
     }
 }

Using this approach in the real world

  • Securing the webhook: Use an HMAC in the webhook URL to ensure that POST to webhook is coming from the legitimate app (example).
  • Slack message schema: Is the app/service only able to send messages in Slack webhook format due to legacy reasons? Consider using classes already defined in an existing nuget package to deserialize messages coming in. Slack.Webhooks looks promising, though I have no personal experience with it.
  • Consider cards: You also have the option to post cards from your bots to get the attention of users. Take a look here.
  • Authentication: Look at AuthBot for how to utilize OAuth within bots to authenticate users (link).
  • More about activities: Read up about Activities in Bot Framework documentation here.
  • Write your first bot: Looking for a step-by-step instructions on how to create a Microsoft Teams bot? Take a look here.
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s