Build message extensions for Microsoft Teams and Copilot
What are message extensions?
Message extensions are a way to enhance the messaging functionality of Microsoft Teams beyond what is available out-of-the-box. It enables users to easily search for and share information through rich cards, capture data, and preview app content right within Teams. This enhances the overall user experience while using your app within Teams.
💡Did you know? If you already have a Teams message extension, then you have a plugin that works with Copilot. Read more at the end of this article.
Why use message extensions?
So, the golden question is: Why use message extensions at all?
Imagine you’re a project manager and you are in a team chat. You need a specific update on a work item in Azure DevOps. Typically, you’d open your browser, search for the item, copy the link, return to the chat, and share it. Then you’d write a message to ask for the update.
Your teammate, perhaps out walking her dog, clicks the link. Her mobile browser opens, but she’s not logged into Azure DevOps, so it prompts her to sign in. Frustrated, she gives up due to a forgotten password. Later, she abandons the task, planning to try again at home but forgets.
Reimagine this with message extension for Azure DevOps (which you can also build).
As a project manager in a team chat, you need an update on an Azure DevOps work item. You use the Azure DevOps message extension in the channel to find the item, insert an actionable card with edit/view buttons into the chat, and mention your teammate responsible for it. Your teammate sees the mention, clicks “Edit,” updates the status to “done,” shares the updated card, and informs you. Task complete!
As seen in the above scenario, message extensions help streamline communication and workflows by allowing users to easily access and interact with external apps and services directly within Teams. With over 300 million MAU in Teams, this is also a great way for your app to reach a bigger audience organically.
What are the capabilities of message extensions?
Message extensions can have two main capabilities:
Search commands: allow users to search for information or content from your app or service and insert the results into their conversations as rich cards.
Action commands: allow users to perform an action or a task from your app or service and optionally insert the results into their conversations as rich cards. You can also use message extensions to initiate a task module, which is a modal dialog that can display an Adaptive Card or a web page and collect user inputs.
Another capability of message extensions is link unfurling: enrich the user experience by offering previews of the contents. This capability can be seen in most messaging apps, social media platforms, and various online communication tools to make shared links more informative and visually appealing.
How to build message extensions?
If you want to try out a sample, you’ll only need Teams Toolkit and a developer tenant to develop one today.
Typically to build your own based on your app/webservice, you’ll need Teams Toolkit, a developer tenant to test your app and your API endpoint to search/add /update information from your app.
This blog focuses on building search command message extension application using Visual Studio Code’s extension Teams Toolkit. If you prefer Visual Studio, scroll down to References to see the documentation for Visual Studio’s Teams Toolkit extension.
- Make sure you have a developer tenant for Microsoft 365, you’ll need this to configure and test your app using Teams toolkit.
- Make sure your node version is set to 18 or 16 to support Teams Toolkit.
Open your Visual Studio Code and install the Teams Toolkit extension.
Create a message extension from existing app template
Start the app scaffolding by selecting “Create an app using the extension”
- For New Project, select option message extension
- For App features using Message extensions, select option Custom Search Results
- For Workspace folder, select Default
- For Application name, type npm search app and select Enter to kick-off app scaffold
The app template we chose here is a search command. This app as-is searches within npm packages and insert the selected package information in the form of a card into the conversation. You can re-imagine this with your API endpoint/webservice.
💡Did you know? Teams Toolkit has many samples you can pick and scaffold as your base app.
Prepare to run your application
Once app project is scaffolded, using the Microsoft 365 developer tenant account login to Teams Toolkit
Ensure that your tenant has sideloading enabled, allowing the Teams Toolkit to locally install your app while it runs, providing an F5 development experience.
Run your app
Press F5 and see the magic happen. The browser will open your app in an install dialog. Select Add and start testing.
💡Your app is named npm search app, but it appears as npm search app-local due to the Teams Toolkit adding a suffix to indicate its local hosting status.
To test the search command, once the app added, you can start searching. Let’s search for the npm package “react”.
You can select “react” as shown above and it will insert the card into the message compose area, ready to be shared in the conversation.
💡Did you know? The search command message extensions like this developed using Teams Toolkit also work on Outlook compose area.
Behind the scenes
In the project scaffolded, the file
teamsBot.js contains the bot code for the message extension.
When a user searches “react”:
handleTeamsMessagingExtensionQuerymethod is invoked.
- This method receives the query parameter, which is “react”.
- The method then calls the npmjs.com registry search API to search for packages that match text “react”.
- The method then returns a list of hero cards to be displayed in the search results.
- The tap handler is set on the preview card.
- The tap handler invokes the
When a user taps on “react”:
handleTeamsMessagingExtensionSelectItemmethod is invoked.
- This method returns the selected hero card only which is for “react”.
How did Teams know about the query parameter and how to invoke activities?
- Your teams app is basically a zip file containing a
manifest.jsonfile and two icons. You can find these under folder
- Manifest file contains all the definitions needed to interact with Teams client app and your web service.
- The message extension definition is under the
composeExtension property, Command id (1)
"searchQuery" is the property denoting a search command message extension of type (2)
“searchQuery” in the parameters object is the query parameter.
The context (4) where the search command can be invoked are
Why a BOT is necessary
The project here creates the bot code in
teamsBot.js file. Now you must wonder, why does this app template create a bot for my message extension feature? A bot serves as the intermediary that enables communication between the user (via the messaging platform like Teams) and webservices/app (In our case the npm search API).
When a user initiates a search within the message extension, the bot is responsible for processing that request and relaying it to the webservice via the Azure Bot Channel.
The bot also handles the processing of data received from your webservice, such as formatting data into a rich card that can be inserted into the chat as a response.
Azure DevOps sample
Did you like our screenshots showing the Azure DevOps work items which has all three capabilities like search, action commands and link unfurling?
If you do, head to https://aka.ms/me-sample where you can download the source or clone and run the app within Teams Toolkit.
💡 Did you know? While message extensions can bring your application data into Teams, it can also power Microsoft 365 Copilot to bring the same data to you in response to your natural language queries. Learn more: How to Extend Microsoft 365 Copilot – Teams | Microsoft Learn
Follow us on X (@Microsoft365Dev) for the latest news and updates