Create Action Based Messaging Extension With Microsoft Teams App

Introduction

 
The messaging extensions action command allows users to collect information using modal popup, process their information, and send it back to the Teams channel conversation area.
 

Messaging Extension

 
Messaging extensions take advantage of the Bot Framework's messaging schema and secure communication protocol to connect with Microsoft Teams Client App.
 


There are three type of messaging extensions that can be build for Microsoft Teams:
  1. Search based messaging extension for Microsoft Teams
  2. Action based messaging extension for Microsoft Teams
  3. Unfurl Url with messaging extenssion for Microsoft Teams.
In this article, I am going to explain "Action based messaging extesnion for Microsoft Teams".
 
Previous arcticle
 
Search based messaging extension can be find here.
 

How Messaging Extension Action Command works






Prerequisites
  • Microsoft Teams
  • Azure Bot Framework, .NetCore
  • Azure Web API .Net Standard
  • Microsoft 365 tenant
  • Microsoft Azure subscription
Let's get started.
 
To create Microsoft Team Messarging Extension requires two activities,
  1. Create Microsoft Azure Bot.
  2. Create manifest file with bot reference
  3. Upload manifest file to MS Team Client App.
Step 1 - Create Microsoft Azure Bot
  1. Browse the https://portal.azure.com with your work or school account.
  2. Click "+Create Resource"
  3. Select "AI + Machine Learning"
  4. Select "Web App Bot"
Step 2 - Complete all required information and click create to provision the bot
  1. Bot handle:- The  unique name of your bot.
  2. Subscription:- Select a valid available subscription.
  3. Resource Group:- Select an appropriate resource group or create a new one as per your requirement.
  4. Location:- Select your closed azure location or the preferred location.
  5. Pricing:- Select the required pricing tier or F0 as free for POC activity.
  6. App Name:- Leave it as-is for this demo purpose.
  7. Service Plan:- Leave it as-is for this demo purpose.
  8. Bot Template:- Leave it as-is for this demo purpose.
  9. Application insight: Select off for this demo purpose
  10. Microsoft App Id and Password:- Leave it as-is for this demo purpose.
  11. Click create to provision.


Step 3 - Enable Microsoft Team Channel for your Bot
 
In order for the bot to interact with MS Teams, you must enable the Teams Channel

 To complete the process, MS Teams and Webchat should be available and should be listed in your channel lists.




Step 4 - Create a Bot Framework
 
In this section, we are going to create an echo bot using Visual Studio 2019
  • Open the Visual Studio, Select create project and navigate to the desired directory to create a project.
  • Select Echo Bot (Bot Framework v4) .Net Core


Step 5 - Update Default Bot Code
  1. Select EchoBot.cs and Remove all default methods implemented into RchoBot class.
  2. Inherit Team Activity Handler to Echo Bot Class to implement messaging extension related method.
  3. Add Submit Action Async method to captur defined command Id. 
  4. Execute custom logic based on action command id.
  5. CreateCard allow user to choose card, share and interact with teams channel conversation.
  6. ShareMessage allow user to choose card, share and interact using "More Action" context menu.

  1. protected override async Task<MessagingExtensionActionResponse> OnTeamsMessagingExtensionSubmitActionAsync(ITurnContext<IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken)  
  2.         {  
  3.             switch (action.CommandId)  
  4.             {  
  5.                 // These commandIds are defined in the Teams App Manifest.  
  6.                 case "createCard":  
  7.                     return CreateCardCommand(turnContext, action);  
  8.   
  9.                 case "shareMessage":  
  10.                     return ShareMessageCommand(turnContext, action);  
  11.                 default:  
  12.                     throw new NotImplementedException($"Invalid CommandId: {action.CommandId}");  
  13.             }  
  14.         }  
Create Card Command capture data from modal popup convert into JSON object and mapped with Hero Card, return with attachement as Messaging Extesnion Action Response.
  1. private MessagingExtensionActionResponse CreateCardCommand(ITurnContext<IInvokeActivity> turnContext, MessagingExtensionAction action)  
  2.         {  
  3.             // The user has chosen to create a card by choosing the 'Create Card' context menu command.  
  4.             var createCardData = ((JObject)action.Data).ToObject<CreateCardData>();  
  5.   
  6.             var card = new HeroCard  
  7.             {  
  8.                 Title = createCardData.Title,  
  9.                 Subtitle = createCardData.Subtitle,  
  10.                 Text = createCardData.Text,  
  11.             };  
  12.   
  13.             var attachments = new List<MessagingExtensionAttachment>();  
  14.             attachments.Add(new MessagingExtensionAttachment  
  15.             {  
  16.                 Content = card,  
  17.                 ContentType = HeroCard.ContentType,  
  18.                 Preview = card.ToAttachment(),  
  19.             });  
  20.   
  21.             return new MessagingExtensionActionResponse  
  22.             {  
  23.                 ComposeExtension = new MessagingExtensionResult  
  24.                 {  
  25.                     AttachmentLayout = "list",  
  26.                     Type = "result",  
  27.                     Attachments = attachments,  
  28.                 },  
  29.             };  
  30.         }  
Shared Message can be invoked using "More Action" context menu and allow user to repond over existing message. This example is used to send custom parameters using message payload and return with attachement as Messaging Extesnion Action Response.
  1. private MessagingExtensionActionResponse ShareMessageCommand(ITurnContext<IInvokeActivity> turnContext, MessagingExtensionAction action)  
  2.         {  
  3.             // The user has chosen to share a message by choosing the 'Share Message' context menu command.  
  4.             var heroCard = new HeroCard  
  5.             {  
  6.                 Title = $"{action.MessagePayload.From?.User?.DisplayName} orignally sent this message:",  
  7.                 Text = action.MessagePayload.Body.Content,  
  8.             };  
  9.   
  10.             if (action.MessagePayload.Attachments != null && action.MessagePayload.Attachments.Count > 0)  
  11.             {  
  12.                 heroCard.Subtitle = $"({action.MessagePayload.Attachments.Count} Attachments not included)";  
  13.             }  
  14.   
  15.             var includeImage = ((JObject)action.Data)["includeImage"]?.ToString();  
  16.             if (!string.IsNullOrEmpty(includeImage) && bool.TrueString == includeImage)  
  17.             {  
  18.                 heroCard.Images = new List<CardImage>  
  19.                 {  
  20.                     new CardImage { Url = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQtB3AwMUeNoq4gUBGe6Ocj8kyh3bXa9ZbV7u1fVKQoyKFHdkqU" },  
  21.                 };  
  22.             }  
  23.   
  24.             return new MessagingExtensionActionResponse  
  25.             {  
  26.                 ComposeExtension = new MessagingExtensionResult  
  27.                 {  
  28.                     Type = "result",  
  29.                     AttachmentLayout = "list",  
  30.                     Attachments = new List<MessagingExtensionAttachment>()  
  31.                     {  
  32.                         new MessagingExtensionAttachment  
  33.                         {  
  34.                             Content = heroCard,  
  35.                             ContentType = HeroCard.ContentType,  
  36.                             Preview = heroCard.ToAttachment(),  
  37.                         },  
  38.                     },  
  39.                 },  
  40.             };  
  41.         }  
Build and Publish the Bot Code to Publishing Profile.
 
Step 5 - Create Manifest
  1. Create folder within solution with the name "TeamAppManifest"
  2. Create and add icon-color.png file
  3. Create and add icon-outline.png file
  4. Create manifest.json file and Update compose Extension with Command Context "Compose" and "CommandBox
  1. "composeExtensions": [  
  2.   {  
  3.     "botId""4c961f60-bb20-44a9-913d-2177652ddb3b",  
  4.     "commands": [  
  5.       {  
  6.         "id""createCard",  
  7.         "type""action",  
  8.         "context": [ "compose" ],  
  9.         "description""Command to run action to create a Card from Compose Box",  
  10.         "title""Create Card",  
  11.         "parameters": [  
  12.           {  
  13.             "name""title",  
  14.             "title""Card title",  
  15.             "description""Title for the card",  
  16.             "inputType""text"  
  17.           },  
  18.           {  
  19.             "name""subTitle",  
  20.             "title""Subtitle",  
  21.             "description""Subtitle for the card",  
  22.             "inputType""text"  
  23.           },  
  24.           {  
  25.             "name""text",  
  26.             "title""Text",  
  27.             "description""Text for the card",  
  28.             "inputType""textarea"  
  29.           }  
  30.         ]  
  31.       },  
  32.       {  
  33.         "id""shareMessage",  
  34.         "type""action",  
  35.         "context": [ "message" ],  
  36.         "description""Test command to run action on message context (message sharing)",  
  37.         "title""Share Message",  
  38.         "parameters": [  
  39.           {  
  40.             "name""includeImage",  
  41.             "title""Include Image",  
  42.             "description""Include image in Hero Card",  
  43.             "inputType""toggle"  
  44.           }  
  45.         ]  
  46.       }  
  47.     ]  
  48.   }  
  49. ],  
Step 6 - Upload Manifest into Microsoft Teams App
 
Navigate to manifest folder /src/manifest. Select both .png files and manifest.jon file and zip all three files. Give the name of zip file "manifest"
 
Login to https://teams.microsoft.com
  1. Navigate to App Studio
  2. Select Import an existing app
  3. Select the manifest.zip file
  4. Bot name with the icon will appear at the screen




Browse and check Command Added to Message Extension via message extension.json file; i.e., create card and share message.
 

Step 7 - Install Custom App to Teams Solution
  1. Select the install App using Manifest file and It will navigate to create an app page will all pre-filled information and Select test and distribute
  2. Click Add to add app to teams.



Once bot deployment and Manifest configuration are complete, now it's time to test the messaging extension.
 
Output
  1. Navigate to teams and select channel
  2. Below compose message box click "..." and select deployed app i.e. "Action-extension-settigns"
  3. Modal popup will appear;  and fill in the message payload information and click submit.
  4. Message or request will post to Teams Channel conversation section.



Reposnd to existing message; i.e. ShareMessage using Action command with Context Menu.
 
Step 1
 
Select exisitng message
  1. click "..." section
  2. Select more actions
  3. Select ShareMessage.
Step 2
 
Design Modal popup; i.e. Include image or not and click submit.
 
Step 3
 
Message posted using adaptive card as response thread to existing message.

 
I hope you have enjoyed and learned something new in this article. Thanks for reading and stay tuned for the next article.