A sample bot demonstrating Teams message extension handlers.
- Bot registered and installed in Teams.
{
"bots": [
{
"botId": "YOUR_BOT_ID",
"scopes": [
"personal",
"team",
"groupChat"
],
"isNotificationOnly": false,
"supportsCalling": false,
"supportsVideo": false,
"supportsFiles": false
}
],
"composeExtensions": [
{
"botId": "YOUR_BOT_ID",
"canUpdateConfiguration": true,
"commands": [
{
"id": "searchQuery",
"type": "query",
"title": "searchQuery",
"description": "Enter search text",
"initialRun": true,
"fetchTask": false,
"context": [
"commandBox",
"compose",
"message"
],
"parameters": [
{
"name": "searchText",
"title": "searchText",
"description": "Enter search text",
"inputType": "text"
}
]
},
{
"id": "createAction",
"type": "action",
"title": "createAction",
"description": "Create a new item",
"initialRun": true,
"fetchTask": true,
"context": [
"commandBox",
"compose",
"message"
],
"parameters": [
{
"name": "createAction",
"title": "createAction",
"description": "Create a new item",
"inputType": "text"
}
]
}
],
"messageHandlers": [
{
"type": "link",
"value": {
"domains": [
"*.example.com",
"*.microsoft.com"
],
"supportsAnonymizedPayloads": true
}
}
]
}
],
"validDomains": [
"*.botframework.com",
"xxx.devtunnels.ms"
]
}Manifest: composeExtensions.commands with type: "query"
- Open message compose box
- Select the message extension
- Type a search term
- Verify results display in list format
- Type "help" to test message response
Manifest: No specific requirement (works with OnQuery results)
- After running a search (OnQuery)
- Click on any search result
- Verify adaptive card preview appears
Manifest: No specific requirement (works with any message extension result card that has Action buttons)
- Click the View Details button on the adaptive card
- Verify
OnCardButtonClickedfires — link opens)
Manifest: composeExtensions.commands with type: "action" and fetchTask: true
- Click the message extension action button (createAction)
- Verify task module opens with input form
Manifest: No specific requirement (works with OnFetchTask)
- Fill form in task module
- Click submit
- Verify preview card appears with Edit/Send buttons
- Click Edit - verify form reopens with values
- Click Send - verify final card posts to conversation — currently only works when started from the command box
Manifest: composeExtensions.messageHandlers with type: "link" and domains
- Paste a URL in compose box that matches the unfurl domain in manifest (*.example.com)
- Verify card unfurls automatically
Manifest: composeExtensions.canUpdateConfiguration: true (must be at the top level of the compose extension, not inside a command)
Important: Add your bot's domain to
validDomainsin the manifest, otherwise Teams will block the settings page from loading in the iframe:"validDomains": [ "YOUR_DEVTUNNEL_SOMAIN" ]
- Right-click the message extension icon in the compose box
- Select Settings — Teams calls
OnQuerySettingUrlwhich returns the settings page URL - A popup opens at
{BOT_ENDPOINT}/tabs/settings - Select an option and click Save Settings — Teams calls
OnSettingswithValue.Stateset to the submitted value - If the user dismisses the dialog,
Value.Statewill be"CancelledByUser"
dotnet run --project samples/MessageExtensionBot/MessageExtensionBot.csproj