Build Search Based Messaging Extension With Microsoft Teams App

Introduction

 
Messaging extensions enable users to execute search queries or trigger actions within a designed external system. As a result, messages are received from custom web services or API to the Microsoft Teams Client.
 

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 extenions that can be build for Microsoft Teams:
  1. Search based messaging extenion for Microsoft Teams
  2. Action based messaging extenion for Microsoft Teams
  3. Unfurl Url with messaging extension for Microsoft Teams 
How Messaging Extension works
  1. Command box: This is the area at the top of the Microsoft Teams client
  2. Compose message box: This is the area at the bottom of a 1:1 or group chat and at the bottom of the Conversations tab in a channel
  3. More Actions menu: It is accessible, when users hover over a message in a conversation chat
When the messaging extension is invoked, Microsoft Teams will send, via the Bot Framework, an HTTPS message with a JSON payload that includes all relevant information.
 
Your web service will respond with a JSON payload, via the Bot Framework, that informs the Microsoft Teams client what interaction to enable next.
 
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 Messaging 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"
 Build Search Based Messaging Extension With Microsoft Teams App
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 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.
Build Search Based Messaging Extension With Microsoft Teams App 
 
Step 3 - Enable Microsoft Teams Channel for your Bot
 
In order for the bot to interact with MS Teams, you must enable the Teams Channel.
 
 Build Search Based Messaging Extension With Microsoft Teams App
 
To complete the process, MS Teams and Webchat should be available and should be listed in your channel lists.
 
Build Search Based Messaging Extension With Microsoft Teams App
 
Step 4 - Create a Bot Framework
 
In this section, we are going to create a 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
    Build Search Based Messaging Extension With Microsoft Teams App
Step 5 - Update Default Bot Code
  1. Select EchoBot.cs 
  2. Remove all default methods defined into EchoBot Class
  3. Inherit Team Activity Handler to EchoBot Class to implement messaging extension related method.
  4. Add Query Async method to pass query parameter to external api.
  5. Select Item Async method used to post the selected message into team channel conversation area via adaptive card.
Build Search Based Messaging Extension With Microsoft Teams App
 
Query Async Method - Take typed query as parameter and pass it to api to get JSON Payload, render the JSON Payload into hero card with list; i.e., attachment layout.
  1. protected override async Task<MessagingExtensionResponse> OnTeamsMessagingExtensionQueryAsync(ITurnContext<IInvokeActivity> turnContext, MessagingExtensionQuery query, CancellationToken cancellationToken)  
  2.         {  
  3.             var text = query?.Parameters?[0]?.Value as string ?? string.Empty;  
  4.   
  5.             var packages = await FindPackages(text);  
  6.   
  7.             var attachments = packages.Select(package => {  
  8.                 var previewCard = new ThumbnailCard { Title = package.Item1, Tap = new CardAction { Type = "invoke", Value = package } };  
  9.                 if (!string.IsNullOrEmpty(package.Item5))  
  10.                 {  
  11.                     previewCard.Images = new List<CardImage>() { new CardImage(package.Item5, "Icon") };  
  12.                 }  
  13.   
  14.                 var attachment = new MessagingExtensionAttachment  
  15.                 {  
  16.                     ContentType = HeroCard.ContentType,  
  17.                     Content = new HeroCard { Title = package.Item1 },  
  18.                     Preview = previewCard.ToAttachment()  
  19.                 };  
  20.   
  21.                 return attachment;  
  22.             }).ToList();  
  23.   
  24.             return new MessagingExtensionResponse  
  25.             {  
  26.                 ComposeExtension = new MessagingExtensionResult  
  27.                 {  
  28.                     Type = "result",  
  29.                     AttachmentLayout = "list",  
  30.                     Attachments = attachments  
  31.                 }  
  32.             };  
  33.         }  
 Call External API based on provided query parameter.
  1. private async Task<IEnumerable<(string, string, string, string, string)>> FindPackages(string text)  
  2.         {  
  3.             var obj = JObject.Parse(await (new HttpClient()).GetStringAsync($"https://azuresearch-usnc.nuget.org/query?q=id:{text}"));  
  4.             return obj["data"].Select(item => (item["id"].ToString(), item["version"].ToString(), item["description"].ToString(), item["projectUrl"]?.ToString(), item["iconUrl"]?.ToString()));  
  5.         }  
 Select Item Async used to post bot framework thumbnail card based on selected item information into teams channel conversation.
  1. protected override Task<MessagingExtensionResponse> OnTeamsMessagingExtensionSelectItemAsync(ITurnContext<IInvokeActivity> turnContext, JObject query, CancellationToken cancellationToken)  
  2.        {  
  3.            var (packageId, version, description, projectUrl, iconUrl) = query.ToObject<(string, string, string, string, string)>();  
  4.            var card = new ThumbnailCard  
  5.            {  
  6.                Title = $"{packageId}, {version}",  
  7.                Subtitle = description,  
  8.                Buttons = new List<CardAction>  
  9.                    {  
  10.                        new CardAction { Type = ActionTypes.OpenUrl, Title = "Nuget Package", Value = $"https://www.nuget.org/packages/{packageId}" },  
  11.                        new CardAction { Type = ActionTypes.OpenUrl, Title = "Project", Value = projectUrl },  
  12.                    },  
  13.            };  
  14.   
  15.            if (!string.IsNullOrEmpty(iconUrl))  
  16.            {  
  17.                card.Images = new List<CardImage>() { new CardImage(iconUrl, "Icon") };  
  18.            }  
  19.   
  20.            var attachment = new MessagingExtensionAttachment  
  21.            {  
  22.                ContentType = ThumbnailCard.ContentType,  
  23.                Content = card,  
  24.            };  
  25.   
  26.            return Task.FromResult(new MessagingExtensionResponse  
  27.            {  
  28.                ComposeExtension = new MessagingExtensionResult  
  29.                {  
  30.                    Type = "result",  
  31.                    AttachmentLayout = "list",  
  32.                    Attachments = new List<MessagingExtensionAttachment> { attachment }  
  33.                }  
  34.            });  
  35.        }  
 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.     "canUpdateConfiguration"true,  
  5.     "commands": [  
  6.       {  
  7.         "id""searchQuery",  
  8.         "context": [ "compose""commandBox" ],  
  9.         "description""Test command to run query",  
  10.         "title""Search",  
  11.         "type""query",  
  12.         "parameters": [  
  13.           {  
  14.             "name""searchQuery",  
  15.             "title""Search Query",  
  16.             "description""Your search query",  
  17.             "inputType""text"  
  18.           }  
  19.         ]  
  20.       }  
  21.     ]  
  22.   }  
  23. ]  

 Select all three files and make it as .zip file and name it manifest.

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
Build Search Based Messaging Extension With Microsoft Teams App
 
Step 7 - Install Custom App to Teams Solution
  1. Select the install App using Manifets file and It will navigate to create an app page will all pre-filled information.
  2. Select test and distribute
  3. Click Add to add app to teams. 
Build Search Based Messaging Extension With Microsoft Teams App
 
Once bot deployment and Manifest configuration is done, now it's time to test the messaging extension.
 
Output 
  1. Navigate to teams and select channel
  2. Click on below compose message box "..." and select deployed app i.e. "searc-extension-settigns"
  3. Type keyword which will get searched from external api
Here we used nuget.org as external api. 
 
Build Search Based Messaging Extension With Microsoft Teams App
 
Select any item from messaging extension and the same will be posted as adaptive card to Teams Channel Conversation area. 
 
Build Search Based Messaging Extension With Microsoft Teams App
 
Code base exists here.
 
I hope you have enjoyed and learned something new in this article. Thanks for reading and stay tuned for the next article.