Service | Microsoft Docs article | Related commit history on GitHub | Change details |
---|---|---|---|
platform | Bot Configuration Experience | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/bots/how-to/bot-configuration-experience.md | ms.localizationpriority: high # Bot configuration experience -> [!NOTE] -> -> * Bot configuration experience is available in [public developer preview](../../resources/dev-preview/developer-preview-intro.md). -> * Bot configuration experience is supported in channel or group chat scopes only. +Bot configuration experience allows users to set up and reconfigure their bots' settings directly within the channel or group chat post-installation, enhancing operational efficiency from the start. This functionality eliminates the need for repeated user interventions that previously hampered timely benefits realization from apps. Users can now tailor the bot to their specific workflows and preferences during installation and reconfigure settings as needed to adapt to changing requirements, ensuring the bot's ongoing relevance and value. ++For instance, consider a bot that tracks and shares news topics, or monitors GitHub repositories. Initially configured to align with user workflows, these bots can easily be reconfigured to respond to new topics or repositories directly from the group chat, streamlining content management, and interaction without leaving the Teams environment. This flexible configuration experience significantly enhances user experience and productivity by integrating bots seamlessly into daily operations. ++Here's an example, where a user adds the bot to a group chat and then configures it to align with their specific requirements. The user then reconfigures the bot to change the status. ++**Configure** -You can create a bot to enable the bot configuration settings for the user during the bot installation and also from the channel or group chat scope after the bot is installed. -In the following graphic, the bot is installed in a group chat. When the user hovers over the bot, an Adaptive Card appears. The user can select the settings icon in the Adaptive Card to update or change the bot's configuration settings: +**Reconfigure** -## Enable bot configuration experience +## Build bot configuration experience -To enable the bot configuration settings from a channel or group chat scope, follow these steps: +> [!NOTE] +> Bot configuration experience is supported only in channel or group chat. ++When you build the bot configuration experience, you must ensure that the user must be able to configure a bot on first installation and reconfigure it at any time. ++To build the bot configuration experience, follow these steps: 1. [Update app manifest](#update-app-manifest)+ 1. [Configure your bot](#configure-your-bot) ### Update app manifest -You must configure the `fetchTask` property under `bots.configuration` object in the app manifest (previously called Teams app manifest) file as follows: +In the app manifest (previously called Teams app manifest) file, update the `fetchTask` property under the `bots.configuration` object as follows: ```json "bots": [ You must configure the `fetchTask` property under `bots.configuration` object in ], ``` -For more information, see [public developer preview app manifest schema](../../resources/schem#botsconfiguration). +For more information, see [app manifest schema](../../resources/schem#botsconfiguration). ### Configure your bot -When a user installs the bot in a team or group chat scope, the `fetchTask` property in the app manifest file initiates `config/fetch` defined in the `teamsBot.js` file. The bot responds with an Adaptive Card and the user provides relevant information in the Adaptive Card and selects **Submit**. After the user selects **Submit**, a `config/submit` is returned to the bot and the bot configuration is complete. --You can use `config/fetch` and `config/submit` properties in the `teamsBot.js` file to enable the bot configuration experience in a team or group chat. --* Invoke `config/fetch`: You must invoke `config/fetch` task to start the bot configuration flow and define the bot response as required. -- In the following example, when the bot receives `config/fetch` invoke activity, the bot responds with an Adaptive Card: -- ```javascript - if (context._activity.name == "config/fetch") { - const adaptiveCard = CardFactory.adaptiveCard(this.adaptiveCardForDynamicSearch()); - try { - return { - status: 200, - body: { - config: { - type: 'continue', - value: { - card: adaptiveCard, - height: 400, - Title: 'Dialog fetch response', - width: 300 - } - } - } - } - } catch (e) { - console.log(e); - } - } - ``` --* Invoke `config/submit`: You must invoke the `config/submit` task for the bot to respond to the user's input. - In the following example, when the bot receives the `config/submit` invoke activity, the bot responds with an Adaptive Card or a message: -- ```javascript - if (context._activity.name == "config/submit") { - - const choice = context._activity.value.data.choiceselect.split(" ")[0]; - chosenFlow = choice; - - if (choice === "static_option_2") { - const adaptiveCard = CardFactory.adaptiveCard(this.adaptiveCardForStaticSearch()); - - return { - status: 200, - body: { - config: { - type: 'continue', - value: { - card: adaptiveCard, - height: 400, - Title: 'Dialog submit response', - width: 300 - } - } - } - } - } - else { - - try { - return { - status: 200, - body: { - config: { - type: 'message', - value: "end" - } - } - } - } - ``` +When a user installs the bot in channel or group chat, the `fetchTask` property in the app manifest file initiates either `config/fetch` or `config/submit` as defined in the `teamsBot.js` file. ++If you set the `fetchTask` property in the app manifest to: -## Bot configuration experience in Teams +* **false**: The bot doesn't fetch a dialog or an Adaptive Card. Instead, the bot must provide a static dialog or card that is used when the bot is invoked. For more information, see [dialogs](../../task-modules-and-cards/what-are-task-modules.md). -After you've created a bot to enable the bot configuration settings from a team or group chat scope, the user can configure and reconfigure the bot in Teams. +* **true**: The bot initiates either `config/fetch` or `config/submit` as defined. When the bot is invoked, you can return an Adaptive Card or a dialog depending on the context provided in [channelData and userdata](../../messaging-extensions/how-to/action-commands/create-task-module.md#payload-activity-properties-when-a-dialog-is-invoked-from-a-group-chat). -To configure the bot, follow these steps: +The following table lists the response type associated with the invoke requests: -1. Go to **Microsoft Teams**. +|Invoke request |Response type | +| | | +| `config/fetch` | `Type: "continue"` or `Type = "auth"` | +| `config/submit` | `Type: "continue"` or `Type: "message"` | -1. Select **Apps**. +* `type: "continue"`: `type: "continue"` is used to define a continuation of a dialog or Adaptive Card within a bot configuration. When the type is set to `continue`, it indicates that the bot is expecting further interaction from the user to continue with the configuration process. -1. From the Teams store, select a bot app you want to install. + The `adaptiveCardForContinue` is a custom function that returns the JSON for an Adaptive Card to be used in different stages of a botΓÇÖs workflow. These functions are used to return Adaptive Cards for different scenarios based on the userΓÇÖs interaction with the bot. -1. From the dropdown next to **Add**, select **Add to a team** or **Add to a chat**. + When the user submits the configuration, the `config/submit` invoke is triggered. It reads the user's input and returns a different Adaptive Card. You can also update the bot configuration to return a [dialog](../../task-modules-and-cards/what-are-task-modules.md). - :::image type="content" source="../../assets/images/bots/group-chat-add-Bot.png" alt-text="Screenshot shows add your bot to chat."::: + # [C#](#tab/teams-bot-sdk1) -1. Enter the name of a chat in the search field. + [Sample code reference](https://github.com/OfficeDev/Microsoft-Teams-Samples/blob/main/samples/bot-configuration-app/csharp/Bot%20configuration/Bots/TeamsBot.cs#L78) - :::image type="content" source="../../assets/images/bots/add-bot-to-chat.png" alt-text="Screenshot shows bot added to a chat."::: + ```csharp + protected override Task<ConfigResponseBase>OnTeamsConfigFetchAsync(ITurnContext<IInvokeActivity> turnContext, JObject configData, CancellationToken cancellationToken) + { + ConfigResponseBase response = adaptiveCardForContinue(); + return Task.FromResult(response); + } + ``` -1. Select **Set up a bot**. + # [JavaScript](#tab/JS1) - :::image type="content" source="../../assets/images/bots/set-up-a-bot.png" alt-text="Screenshot shows set up a bot in chat."::: + [Sample code reference](https://github.com/OfficeDev/Microsoft-Teams-Samples/blob/main/samples/bot-configuration-app/nodejs/teamsBot.js#L52) - The bot is installed in the chat. + ```javascript + async handleTeamsConfigFetch(_context, _configData) { + let response = {}; + const adaptiveCard = CardFactory.adaptiveCard(this.adaptiveCardForContinue()); + response = { + config: { + value: { + card: adaptiveCard, + height: 500, + width: 600, + Title: 'test card', + }, + type: 'continue', + }, + }; + return response; + } + ``` -### Reconfigure the bot +++* `type: "auth"`: You can also request the user to authenticate as a response to `config/fetch` request. The `type: "auth"` configuration prompts the user to sign in through a specified URL, which must be linked to a valid authentication page that can be opened in a browser. Authentication is essential for scenarios where the bot requires the user to be authenticated. It ensures that the userΓÇÖs identity is verified, maintaining security, and personalized experiences within the botΓÇÖs functionality. ++ > [!NOTE] + > For `type: "auth"` only third party authentication is supported. Single sign-on (SSO) isn't supported. For more information on third party authentication, see [add authentication.](../../messaging-extensions/how-to/add-authentication.md) ++ # [C#](#tab/teams-bot-sdk2) ++ [Sample code reference](https://github.com/OfficeDev/Microsoft-Teams-Samples/blob/main/samples/bot-configuration-app-auth/csharp/Bot%20configuration/Bots/TeamsBot.cs#L78) ++ ```csharp + protected override Task<ConfigResponseBase>OnTeamsConfigFetchAsync(ITurnContext<IInvokeActivity> turnContext, JObject configData, CancellationToken cancellationToken) + { + ConfigResponseBase response = new ConfigResponse<BotConfigAuth> { + Config = new BotConfigAuth { + SuggestedActions = new SuggestedActions { + Actions = new List<CardAction> { + new CardAction { + type: "openUrl", + value: "https://example.com/auth", + Title: "Sign in to this app" + } + } + }, + Type = "auth" + } + }; + ``` ++ # [JavaScript](#tab/JS2) ++ [Sample code reference](https://github.com/OfficeDev/Microsoft-Teams-Samples/blob/main/samples/bot-configuration-app-auth/nodejs/teamsBot.js#L51) ++ ```javascript + async handleTeamsConfigFetch(_context, _configData) { + let response = {}; + response = { + config: { + type: "auth", + suggestedActions: { + actions: [{ + type: "openUrl", + value: "https://example.com/auth", + Title: "Sign in to this app" + }] + }, + }, + }; + return response; + } + ``` ++++* `type="message"`: When the type is set to message, it indicates that the bot is sending a simple message back to the user, indicating the end of the interaction or providing information without requiring further input. ++ # [C#](#tab/teams-bot-sdk3) ++ [Sample code reference](https://github.com/OfficeDev/Microsoft-Teams-Samples/blob/main/samples/bot-configuration-app-auth/csharp/Bot%20configuration/Bots/TeamsBot.cs#L102-L114) ++ ```csharp + protected override Task<ConfigResponseBase> OnTeamsConfigSubmitAsync(ITurnContext<IInvokeActivity> turnContext, JObject configData, CancellationToken cancellationToken) + { + ConfigResponseBase response = new ConfigResponse<TaskModuleResponseBase> + { + Config = new TaskModuleMessageResponse + { + Type = "message", + Value = "You have chosen to finish setting up bot" + } + }; + return Task.FromResult(response); + } + ``` ++ # [JavaScript](#tab/JS3) ++ [Sample code reference](https://github.com/OfficeDev/Microsoft-Teams-Samples/blob/main/samples/bot-configuration-app-auth/nodejs/teamsBot.js#L72-L83) ++ ```javascript + async handleTeamsConfigSubmit(context, _configData) { + let response = {}; + response = { + config: { + type: 'message', + value: 'You have chosen to finish setting up bot', + }, + } + return response; + } + ``` ++ -To reconfigure the bot, follow these steps: +When a user reconfigures the bot, the `fetchTask` property in the app manifest file initiates `config/fetch` in the bot logic. The user can reconfigure the bot settings post-installation in two ways: -1. Go to the chat and **@mention** the bot in the message compose area and select **Send**. +* @mention the bot in the message compose area. Select the **Settings** option that appears above the message compose area. A dialog appears, update, or changes the bot's configuration settings in the dialog. - :::image type="content" source="../../assets/images/bots/mention-bot.png" alt-text="Screenshot shows the interaction of bot."::: + :::image type="content" source="../../assets/images/bots/reconfiguration-mention-bot.gif" alt-text="Screenshot shows the configuration option for the bot in the message compose area."::: -1. When you hover over the bot from the conversation, an Adaptive Card appears. Select the **Settings** icon in the Adaptive Card. +* Hover over the bot, the bot profile card appears. To update or change the bot's configuration settings, select the settings icon in the bot profile card. - :::image type="content" source="../../assets/images/bots/bot-adaptive-card-interaction.png" alt-text="Screenshot shows the Adaptive Card with settings icon."::: + :::image type="content" source="../../assets/images/bots/reconfiguration-hover.gif" alt-text="Screenshot shows the configuration option for the bot in a Teams group chat."::: - A bot configuration Adaptive Card appears. +## Best practices -1. Reconfigure the bot settings and select **Submit**. +* If you want to have an individual channel-level configuration of your bot, ensure that you track the configuration as per the channel. Configuration data isn't stored and the invoke payload includes the sufficient [channelData](../../messaging-extensions/how-to/action-commands/create-task-module.md#payload-activity-properties-when-a-dialog-is-invoked-from-a-group-chat). - :::image type="content" source="../../assets/images/bots/reconfigure-bot-settings.png" alt-text="Screenshot shows the Adaptive Card with settings icon to reconfigure."::: +* Provide a clear and user-friendly dialog that prompts the user to enter the required information for the bot to operate properly, such as a URL, an area path, or a dashboard link. - The bot sends a response message. +* Avoid sending multiple notifications or requests for configuration after the installation, as it might confuse the users. ## Code sample -| **Sample name** | **Description** |**Node.js** | -|--|--|-| -| Bot configuration experience | This sample code describes the configuration and reconfiguration for bots in team and group chat. |[View](https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/bot-configuration-app/nodejs)| +| **Sample name** | **Description** |**.NET** |**Node.js** |**Manifest**| +|--|--|-|-| +| Bot configuration app | This sample code describes the configuration and reconfiguration for bots in team and group chat with `continue` and `message` response types. |[View](https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/bot-configuration-app/csharp)|[View](https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/bot-configuration-app/nodejs)|[View](https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/bot-configuration-app/csharp/demo-manifest)| +| Bot configuration app with auth | This sample code describes the configuration and reconfiguration for bots in team and group chat with `auth` and `message` response types. |[View](https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/bot-configuration-app-auth/csharp)|[View](https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/bot-configuration-app-auth/nodejs)|[View](https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/bot-configuration-app-auth/csharp/demo-manifest)| ## Step-by-step guide |
platform | What Are Bots | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/bots/what-are-bots.md | With Microsoft Graph APIs for calls and online meetings, Teams apps can now inte You can use the Teams bot APIs to get information for members of a chat or team. See [changes to Teams bot APIs for fetching team or chat members](~/resources/team-chat-member-api-changes.md). +You can change the bot name displayed in Teams environment, and you need to update it in the following occurrences: ++* The bot name displayed as a title in the chat window is managed within your app manifest (previously called Teams app manifest) and you can update the bot name in your app manifest. ++* The bot name that's displayed in your Teams chat list and in the chat window with each message are managed within Microsoft Azure portal. For custom uploaded apps, you can update the bot name in the **Bot profile** page in Azure portal. ++ :::image type="content" source="~\assets\images\bot_name.png" alt-text="The screenshot shows the bot name displayed in a Teams window."::: + ## Add SSO authentication to your conversation bots You can add single sign-on authentication to your conversation bot using the following steps: You can add single sign-on authentication to your conversation bot using the fol ## Bot configuration experience -Bot configuration experience helps the users to interact with the bot in Teams. Users can interact with the bot either by sending a message or selecting a command from the command list. After the bot is installed in a channel or team, all the members from the channel or team can provide inputs to the bot at the same time, the bot only considers the last input provided by the user. For more information, see [bot configuration experience](how-to/bot-configuration-experience.md). --You can change the bot name displayed in Teams environment, and you need to update it in the following occurrences: --* The bot name displayed as a title in the chat window is managed within your app manifest (previously called Teams app manifest) and you can update the bot name in your app manifest. --* The bot name that's displayed in your Teams chat list and in the chat window with each message are managed within Microsoft Azure portal. For custom uploaded apps, you can update the bot name in the **Bot profile** page in Azure portal. -- :::image type="content" source="~\assets\images\bot_name.png" alt-text="The screenshot shows the bot name displayed in a Teams window."::: +Bot configuration experience helps you to enable the bot settings for users to configure their bot during installation and reconfigure the bot from the channel or group chat scope where the bot is installed. Bot configuration is an important functionality for apps within the Teams platform, laying the foundation for their operational effectiveness. For more information, see [bot configuration experience](how-to/bot-configuration-experience.md). ## Code samples |
platform | Api Based Overview | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/messaging-extensions/api-based-overview.md | Last updated 10/19/2023 # Build message extensions using API > [!NOTE]-> -> * API-based message extensions only support search commands. -> * API-based message extensions are available only in [public developer preview](../resources/dev-preview/developer-preview-intro.md). +> API-based message extensions only support search commands. -Message extensions built using API (API-based) use a web service to manage user requests and responses and don't require a bot registration or a Bot Framework. You can configure and deploy API-based message extensions using Developer Portal for Teams, Visual Studio Code, Teams Toolkit command line interface (CLI), or Visual Studio. API-based message extensions help your apps to interact directly with third-party data, apps, and services, enhancing its capabilities. With APIs for message extension, you can: +Message extensions built using API (API-based) use a web service to manage user requests and responses and don't require a bot registration. You can configure and deploy API-based message extensions using Developer Portal for Teams and Teams Toolkit for Visual Studio Code, command line interface (CLI), or Visual Studio. API-based message extensions help your apps to interact directly with third-party data, apps, and services, enhancing its capabilities. With API-based message extension, you can: * Retrieve real-time information, such as latest news coverage on a product launch. * Retrieve knowledge-based information, for example, my teamΓÇÖs design files in Figma.-* Perform actions on behalf of the user, for example, create a Contoso ticket. You can create an API-based message extension using an [OpenAPI Description (OAD)](https://learn.openapis.org/specification/) document. After you've created an OpenAPI Description document, use the OpenAPI Description document to generate and integrate the client code in your app's project. Create or generate a response rendering template to manage the responses from the API. Before you get started, ensure that you adhere to the following requirements: The OpenAPI Description (OAD) is the industry-standard specification that details the structure and outline of OpenAPI files. It's a language-agnostic, human-readable format for describing APIs. Both humans and machines can easily read and write the openAPI Description. The schema is machine-readable and can be represented in either YAML or JSON. An OpenAPI Description document is required before creating an API-driven message extension. -The following code is an example of an OpenAPI Description document: <br/> -<br/> -<details><summary>OpenAPI Description example</summary> -- ```yml -openapi: 3.0.1 -info: - Title: OpenTools Plugin - description: A plugin that allows the user to find the most appropriate AI tools for their use cases, with their pricing information. - version: 'v1' -servers: - - url: https://gptplugin.opentools.ai -paths: - /tools: - get: - operationId: searchTools - summary: Search for AI Tools - parameters: - - in: query - name: search - required: true - schema: - type: string - description: Used to search for AI tools by their category based on the keywords. For example, ?search="tool to create music" will give tools that can create music. - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/searchToolsResponse' - "400": - description: Search Error - content: - application/json: - schema: - $ref: '#/components/schemas/searchToolsError' -components: - schemas: - searchToolsResponse: - required: - - search - type: object - properties: - tools: - type: array - items: - type: object - properties: - name: - type: string - description: The name of the tool. - opentools_url: - type: string - description: The URL to access the tool. - main_summary: - type: string - description: A summary of what the tool is. - pricing_summary: - type: string - description: A summary of the pricing of the tool. - categories: - type: array - items: - type: string - description: The categories assigned to the tool. - platforms: - type: array - items: - type: string - description: The platforms that this tool is available on. - description: The list of AI tools. - searchToolsError: - type: object - properties: - message: - type: string - description: Message of the error. - ``` -- For more information, see [OpenAPI structure.](https://swagger.io/docs/specification/basic-structure/) --</details> - ### Response rendering template A response rendering template maps JSON responses to a preview card and an Adaptive Card. When a user selects a search result, the preview cards appear as results. The preview card then expands into an Adaptive Card in the message compose box. -Each search command must have a corresponding response rendering template, and each command must correspond to an operation in the OpenAPI Description. However, not every operation defined in an OpenAPI Description must be a command. The response rendering template consists of an Adaptive Card template, preview card template, and metadata and must conform to the Response rendering template schema hosted at [`https://developer.microsoft.com/json-schemas/teams/vDevPreview/MicrosoftTeams.ResponseRenderingTemplate.schema.json`](https://developer.microsoft.com/json-schemas/teams/vDevPreview/MicrosoftTeams.ResponseRenderingTemplate.schema.json) --**Preview Card** ---**Expanded Adaptive Card** ---The following code is an example of a Response rendering template: <br/> -<br/> -<details><summary>Response rendering template example</summary> --```json - { - "version": "1.0", - "responseLayout": "grid", - "responseCardTemplate": { - "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", - "type": "AdaptiveCard", - "version": "1.4", - "body": [ - { - "type": "Container", - "items": [ - { - "type": "ColumnSet", - "columns": [ - { - "type": "Column", - "width": "stretch", - "items": [ - { - "type": "TextBlock", - "text": "Title: ${if(title, title, 'N/A')}", - "wrap": true - }, - { - "type": "TextBlock", - "text": "Description: ${if(description, description, 'N/A')}", - "wrap": true - }, - { - "type": "TextBlock", - "text": "Assigned To: ${if(assignedTo, assignedTo, 'N/A')}", - "wrap": true - }, - { - "type": "Image", - "url": "${image}", - "size": "Medium", - "$when": "${image != null}" - } - ] - }, - { - "type": "Column", - "width": "auto", - "items": [ - { - "type": "Image", - "url": "${if(image, image, '')}", - "size": "Medium" - } - ] - } - ] - }, - { - "type": "FactSet", - "facts": [ - { - "title": "Repair ID:", - "value": "${if(id, id, 'N/A')}" - }, - { - "title": "Date:", - "value": "${if(date, date, 'N/A')}" - } - ] - } - ] - } - ] - }, - "previewCardTemplate": { - "title": "Title: ${if(title, title, 'N/A')}", - "subtitle": "Description: ${if(description, description, 'N/A')}", - "text": "Assigned To: ${if(assignedTo, assignedTo, 'N/A')}", - "image": { - "url": "${image}", - "$when": "${image != null}" - } - } - } - } -``` --</details> --#### Parameters --|Property |Type |Description |Required | -| |||| -|`version` | `string` | The schema version of the current response rendering template. | Yes | -|`jsonPath` | `string` | The path to the relevant section in the results to which the responseCardTemplate and previewCardTemplate should be applied. If not set, the root object is treated as the relevant section. If the relevant section is an array, each entry is mapped to the responseCardTemplate and the previewCardTemplate. | No | -|`responseLayout` | `responseLayoutType` | Specifies the layout of the results in the message extension flyout. The Supported types are `list` and `grid`. | Yes | -|`responseCardTemplate` | `adaptiveCardTemplate` | A template for creating an Adaptive Card from a result entry. | Yes | -|`previewCardTemplate` | `previewCardTemplate` | A template for creating a preview card from a result entry. The resulting preview card is displayed in the message extension flyout menu. | Yes | --#### Schema mapping --The properties in OpenAPI Description document are mapped to the Adaptive Card template as follows: --* `string`, `number`, `integer`, `boolean` types are converted to a TextBlock. -- <details><summary>Example</summary> - - * **Source Schema**: `string`, `number`, `integer`, and `boolean` -- ```yml - name: - type: string - example: doggie -- * **Target Schema**: `Textblock` -- ```json - { - "type": "TextBlock", - "text": "name: ${if(name, name, 'N/A')}", - "wrap": true - } - ``` --</details> --* `array`: An array is converted to a container inside Adaptive Card. -- <details><summary>Example</summary> -- * **Source schema**: `array` -- ```yml - type: array - items: - required: - - name - type: object - properties: - id: - type: integer - category: - type: object - properties: - name: - type: string - ``` -- * **Target Schema**: `Container` -- ```json - { - "type": "Container", - "$data": "${$root}", - "items": [ - { - "type": "TextBlock", - "text": "id: ${if(id, id, 'N/A')}", - "wrap": true - }, - { - "type": "TextBlock", - "text": "category.name: ${if(category.name, category.name, 'N/A')}", - "wrap": true - } - ] - } - - ``` --</details> --* `object`: An object is converted to a nested property in Adaptive Card. -- <details><summary>Example</summary> -- * **Source Schema**: `object` -- ```yml - components: - schemas: - Pet: - category: - type: object - properties: - id: - type: integer - name: - type: string -- ``` -- * **Target Schema**: Nested property in an Adaptive Card -- ```json - { - "type": "TextBlock", - "text": "category.id: ${if(category.id, category.id, 'N/A')}", - "wrap": true - }, - { - "type": "TextBlock", - "text": "category.name: ${if(category.name, category.name, 'N/A')}", - "wrap": true - } -- ``` --</details> --* `image`: If a property is an image URL, then it converts to an Image element in the Adaptive Card. -- <details><summary>Example</summary> -- * **Source schema**: `image` -- ```yml - image: - type: string - format: uri - description: The URL of the image of the item to be repaired -- ``` -- * **Target Schema**: `"Image"` -- ```json - { - "type": "Image", - "url": "${image}", - "$when": "${image != null}" - } -- ``` --</details> +Each search command must have a corresponding response rendering template, and each command must correspond to an operation in the OpenAPI Description. However, not every operation defined in an OpenAPI Description must be a command. The response rendering template consists of an Adaptive Card template, preview card template, and metadata and must conform to the Response rendering template schema hosted at [`https://developer.microsoft.com/json-schemas/teams/vDevPreview/MicrosoftTeams.ResponseRenderingTemplate.schema.json`](https://developer.microsoft.com/json-schemas/teams/vDevPreview/MicrosoftTeams.ResponseRenderingTemplate.schema.json). ### Update app manifest Update app manifest (previously called Teams app manifest) with the `composeExte ```json {- "$schema": "https://developer.microsoft.com/json-schemas/teams/vDevPreview/MicrosoftTeams.schema.json", - "manifestVersion": "devPreview", - "version": "1.0.0", - "id": "04805b4b-xxxx-xxxx-xxxx-4dbc1cac8f89", - "packageName": "com.microsoft.teams.extension", - "developer": { - "name": "Teams App, Inc.", - "websiteUrl": "https://www.example.com", - "privacyUrl": "https://www.example.com/termofuse", - "termsOfUseUrl": "https://www.example.com/privacy" - }, - "icons": { - "color": "color.png", - "outline": "outline.png" - }, - "name": { - "short": "AI tools", - "full": "AI tools" - }, - "description": { - "short": "AI tools", - "full": "AI tools" - }, - "accentColor": "#FFFFFF", "composeExtensions": [ { "composeExtensionType": "apiBased", Update app manifest (previously called Teams app manifest) with the `composeExte } ] }- ], - "validDomains": [] + ] } ``` -|Name |Description | -||| -|`composeExtensions.composeExtensionType` | Compose extension type. Update the value to `apiBased`. | -|`composeExtensions.apiSpecificationFile` | References an OpenAPI Description file in the app package. Include when type is `apiBased`. | -|`composeExtensions.commands.id` | Unique ID that you assign to search command. The user request includes this ID. The ID must match the `OperationId` available in the OpenAPI Description. | -|`composeExtensions.commands.context` | Array where the entry points for message extension is defined. The default values are `compose` and `commandBox`. | -|`composeExtensions.commands.parameters` | Defines a static list of parameters for the command. The name must map to the `parameters.name` in the OpenAPI Description. If you're referencing a property in the request body schema, then the name must map to `properties.name` or query parameters. | -|`composeExtensions.commands.apiResponseRenderingTemplateFile`| Template used to format the JSON response from developerΓÇÖs API to Adaptive Card response. *[Mandatory]* | --For more information, see [composeExtensions](../resources/schem#composeextensions). - ## Next step > [!div class="nextstepaction"] |
platform | Build Api Based Message Extension | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/messaging-extensions/build-api-based-message-extension.md | Title: Build API-based message extension -description: Learn how to build an API message extension using Teams Visual Studio, Visual Studio Code, and Teams Toolkit. +description: Learn about the requirements and troubleshooting guidelines for an API-based message extension. ms.localizationpriority: medium Last updated 10/19/2023 # Build API-based message extension > [!NOTE]-> -> * API-based message extensions only support search commands. -> * API-based message extensions are available only in [public developer preview](../resources/dev-preview/developer-preview-intro.md). +> API-based message extensions only support search commands. -API-based message extensions are a type of Teams app that integrates your chat functionality directly into Teams, enhancing your app's usability and offering a seamless user experience. +API-based message extensions are a Microsoft Teams app capability that integrates external APIs directly into Teams, enhancing your app's usability and offering a seamless user experience. API-based message extensions support search commands and can be used to fetch and display data from external services within Teams, streamlining workflows by reducing the need to switch between applications. Before you get started, ensure that you meet the following requirements:+ </br>-<details><summary>1. OpenAPI Description (OAD)</summary> +<details><summary id="oad">1. OpenAPI Description (OAD) </summary> -Users must not enter a parameter for a header or cookie. If you need to pass headers, a default value for the header can be set in the specification. This simplifies the user experience and reduces the risk of errors. +Ensure that you adhere to following guidelines for OpenAPI Description (OAD) document: -* The `auth` property must not be specified. -* JSON and YAML are the supported formats. * OpenAPI versions 2.0 and 3.0.x are supported.-* Teams doesn't support the `oneOf`, `anyOf`, `allOf`, and `not` (swagger.io) constructs. -* Constructing arrays for the request isn't supported, however, nested objects within a JSON request body are supported. -* The request body, if present, must be application/Json to ensure compatibility with a wide range of APIs. +* JSON and YAML are the supported formats. +* The request body, if present, must be application/Json. * Define an HTTPS protocol server URL for the `servers.url` property.-* Only single parameter search is supported. -* Only one required parameter without a default value is allowed. * Only POST and GET HTTP methods are supported.-* OpenAPI Description document must have an `operationId`. -* The operation must not have required Header or Cookie parameters without default values. -* A command must have exactly one parameter. -* Ensure that there are no remote references in the OpenAPI Description document. +* The OpenAPI Description document must have an `operationId`. +* Only one required parameter without a default value is allowed. * A required parameter with a default value is considered optional.+* Users must not enter a parameter for a header or cookie. +* The operation must not have a required header or cookie parameters without default values. +* Ensure that there are no remote references in the OpenAPI Description document. +* Constructing arrays for the request isnΓÇÖt supported; however, nested objects within a JSON request body are supported. +* Teams doesn't support the `oneOf`, `anyOf`, `allOf`, and `not` (swagger.io) constructs. ++The following code is an example of an OpenAPI Description document: ++```yml +openapi: 3.0.1 +info: + Title: OpenTools Plugin +description: A plugin that allows the user to find the most appropriate AI tools for their use cases, with their pricing information. +version: 'v1' +servers: +- url: https://gptplugin.opentools.ai +paths: +/tools: + get: + operationId: searchTools + summary: Search for AI Tools + parameters: + - in: query + name: search + required: true + schema: + type: string + description: Used to search for AI tools by their category based on the keywords. For example, ?search="tool to create music" will give tools that can create music. + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/searchToolsResponse' + "400": + description: Search Error + content: + application/json: + schema: + $ref: '#/components/schemas/searchToolsError' +components: +schemas: + searchToolsResponse: + required: + - search + type: object + properties: + tools: + type: array + items: + type: object + properties: + name: + type: string + description: The name of the tool. + opentools_url: + type: string + description: The URL to access the tool. + main_summary: + type: string + description: A summary of what the tool is. + pricing_summary: + type: string + description: A summary of the pricing of the tool. + categories: + type: array + items: + type: string + description: The categories assigned to the tool. + platforms: + type: array + items: + type: string + description: The platforms that this tool is available on. + description: The list of AI tools. + searchToolsError: + type: object + properties: + message: + type: string + description: Message of the error. +``` ++For more information, see [OpenAPI structure.](https://swagger.io/docs/specification/basic-structure/) </details> </br> -<details><summary>2. App manifest</summary> +<details><summary id="app-manifest">2. App manifest</summary> +Ensure that you adhere to following guidelines for app manifest: ++* Set the app manifest version to `1.17`. * Set `composeExtensions.composeExtensionType` to `apiBased`.-* Define `composeExtensions.apiSpecificationFile` as the relative path to the OpenAPI Description file within the folder. -* Define `apiResponseRenderingTemplateFile` as the relative path to the response rendering template. -* Each command must have a link to the response rendering template. +* Define `composeExtensions.apiSpecificationFile` as the relative path to the OpenAPI Description file within the folder. This links the app manifest to the API specification. +* Define `apiResponseRenderingTemplateFile` as the relative path to the response rendering template. This specifies the location of the template used for rendering API responses. +* Each command must have a link to the response rendering template. This connects each command to its corresponding response format. +* The `Commands.id` property in the app manifest must match the `operationId` in the OpenAPI Description. +* If a required parameter is without a default value, the command `parameters.name` in the app manifest must match the `parameters.name` in the OpenAPI Description document. +* If thereΓÇÖs no required parameter, the command `parameters.name` in the app manifest must match the optional `parameters.name` in the OpenAPI Description. +* Make sure that the parameters for each command match exactly with the names of the parameters defined for the operation in the OpenAPI spec. +* A [response rendering template](#response-template) must be defined per command, which is used to convert responses from an API. * Full description must not exceed 128 characters.-* A command must have exactly one parameter. ++ ```json + { + "$schema": "https://developer.microsoft.com/json-schemas/teams/vDevPreview/MicrosoftTeams.schema.json", + + "manifestVersion": "devPreview", + "version": "1.0.0", + "id": "04805b4b-xxxx-xxxx-xxxx-4dbc1cac8f89", + "packageName": "com.microsoft.teams.extension", + "developer": { + "name": "Teams App, Inc.", + "websiteUrl": "https://www.example.com", + "privacyUrl": "https://www.example.com/termofuse", + "termsOfUseUrl": "https://www.example.com/privacy" + }, + "icons": { + "color": "color.png", + "outline": "outline.png" + }, + "name": { + "short": "AI tools", + "full": "AI tools" + }, + "description": { + "short": "AI tools", + "full": "AI tools" + }, + "accentColor": "#FFFFFF", + "composeExtensions": [ + { + + "composeExtensionType": "apiBased", + + "authorization": { + + "authType": "apiSecretServiceAuth ", + + "apiSecretServiceAuthConfiguration": { + + "apiSecretRegistrationId": "96270b0f-7298-40cc-b333-152f84321813" + + } + + }, + + "apiSpecificationFile": "aitools-openapi.yml", + "commands": [ + { + "id": "searchTools", + "type": "query", + "context": [ + "compose", + "commandBox" + ], + "title": "search for AI tools", + "description": "search for AI tools", + "parameters": [ + { + "name": "search", + "title": "search query", + "description": "e.g. search='tool to create music'" + } + ], + + "apiResponseRenderingTemplateFile": "response-template.json" + } + ] + } + ], + "validDomains": [] + } + ``` ++### Parameters ++|Name |Description | +|:| | +|`composeExtensions.composeExtensionType` | Compose extension type. Update the value to `apiBased`. | +|`composeExtensions.authorization`|Authorization related information for the API-based message extension| +|`composeExtensions.authorization.authType`|Enum of possible authorization types. Supported values are `none`, `apiSecretServiceAuth`, and `microsoftEntra`.| +|`composeExtensions.authorization.apiSecretServiceAuthConfiguration`|Object capturing details needed to do service auth. Applicable only when auth type is `apiSecretServiceAuth`.| +|`composeExtensions.authorization.apiSecretServiceAuthConfiguration.apiSecretRegistrationId`| Registration ID returned when developer submits the API key through Developer Portal.| +|`composeExtensions.apiSpecificationFile` | References an OpenAPI Description file in the app package. Include when type is `apiBased`. | +|`composeExtensions.commands.id` | Unique ID that you assign to search command. The user request includes this ID. The ID must match the `OperationId` available in the OpenAPI Description. | +|`composeExtensions.commands.context` | Array where the entry points for message extension is defined. The default values are `compose` and `commandBox`. | +|`composeExtensions.commands.parameters` | Defines a static list of parameters for the command. The name must map to the `parameters.name` in the OpenAPI Description. If you're referencing a property in the request body schema, then the name must map to `properties.name` or query parameters. | +|`composeExtensions.commands.apiResponseRenderingTemplateFile`| Template used to format the JSON response from developerΓÇÖs API to Adaptive Card response. *[Mandatory]* | ++For more information, see [composeExtensions](../resources/schem#composeextensions). </details> </br> -<details><summary>3. Response rendering template</summary> +<details><summary id="response-template">3. Response rendering template</summary> -* Define the schema reference URL in the `$schema` property. -* Define `jsonPath` as the path to the relevant data/array in API response. if the path points to an array, then each entry in the array will be a separate result and if the path points to an object, there will only be a single result. *[Optional]* -* The supported values for `responseLayout` are `list` and `grid`. +> [!NOTE] +> +> Teams supports Adaptive Cards up to version 1.5 and the Adaptive Cards Designer supports up to version 1.6. ++* **Define the schema reference URL** in the `$schema` property to establish the structure of your template. +* **The supported values for `responseLayout`** are `list` and `grid`, which determine how the response is visually presented. +* **A `jsonPath` is recommended** for arrays or when the data for the Adaptive Card isn't the root object. For example, if your data is nested under `productDetails`, your JSON path would be `productDetails`. +* **Define `jsonPath` as the path** to the relevant data or array in the API response. If the path points to an array, then each entry in the array binds with the Adaptive Card template and returns as a separate result. *[Optional]* +* **Get a sample response** for validating the response rendering template. This serves as a test to ensure your template works as expected. +* **Use tools such as Fiddler or Postman** to call the API and ensure that the request and the response are valid. This step is crucial for troubleshooting and confirming that your API is functioning correctly. +* **You can use the Adaptive Card Designer** to bind the API response to the response rendering template and preview the Adaptive Card. Insert the template in the **CARD PAYLOAD EDITOR** and insert the sample response entry in the **SAMPLE DATA EDITOR**. ++The following code is an example of a Response rendering template: <br/> +<br/> + <details><summary>Response rendering template example</summary> ++ ```json + { + "version": "1.0", + "jsonPath": "repairs", + "responseLayout": "grid", + "responseCardTemplate": { + "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", + "type": "AdaptiveCard", + "version": "1.4", + "body": [ + { + "type": "Container", + "items": [ + { + "type": "ColumnSet", + "columns": [ + { + "type": "Column", + "width": "stretch", + "items": [ + { + "type": "TextBlock", + "text": "Title: ${if(title, title, 'N/A')}", + "wrap": true + }, + { + "type": "TextBlock", + "text": "Description: ${if(description, description, 'N/A')}", + "wrap": true + }, + { + "type": "TextBlock", + "text": "Assigned To: ${if(assignedTo, assignedTo, 'N/A')}", + "wrap": true + }, + { + "type": "Image", + "url": "${image}", + "size": "Medium", + "$when": "${image != null}" + } + ] + }, + { + "type": "Column", + "width": "auto", + "items": [ + { + "type": "Image", + "url": "${if(image, image, '')}", + "size": "Medium" + } + ] + } + ] + }, + { + "type": "FactSet", + "facts": [ + { + "title": "Repair ID:", + "value": "${if(id, id, 'N/A')}" + }, + { + "title": "Date:", + "value": "${if(date, date, 'N/A')}" + } + ] + } + ] + } + ] + }, + "previewCardTemplate": { + "title": "Title: ${if(title, title, 'N/A')}", + "subtitle": "Description: ${if(description, description, 'N/A')}", + "text": "Assigned To: ${if(assignedTo, assignedTo, 'N/A')}", + "image": { + "url": "${image}", + "$when": "${image != null}" + } + } + } + ``` -The `JsonPath` property in response rendering template is $ to indicate the root object of the response data is used to render the Adaptive Card, and you can update the `jsonPath` property to point another property in response data. + </details> -If the root object of the OpenAPI schema contains well-known array property name, then Teams Toolkit uses the array property as root element to generate an Adaptive Card, and the array property name is used as `JsonPath` property for response rendering template. For example, if the property name contains `result`, `data`, `items`, `root`, `matches`, `queries`, `list`, `output` and the type is `array`, then it's used as root element. + **Preview Card** -</details> -</br> + :::image type="content" source="../assets/images/Copilot/api-based-message-extension-preview-card.png" alt-text="Screenshot shows an example of compose extension displaying an array of preview cards when searching for a specific word. In this case, searching for 'a' in the 'SME test app' returns five cards showing 'Title', 'Description' (truncated) and 'AssignedTo' properties and values in each one."::: -<details><summary>4. API message extension</summary> + **Expanded Adaptive Card** -API-based message extensions are a potent tool that enhances your Teams app's functionality by integrating with external APIs. This enhances the capabilities of your app and provides a richer user experience. To implement message extension from an API, you need to follow these guidelines: + :::image type="content" source="../assets/images/Copilot/api-based-message-extension-expanded-adaptive-card.png" alt-text="Example of how the Adaptive Card looks like expanded once a user selects a preview card. The Adaptive Card shows the Title, the full Description, AssignedTo, RepairId, and Date values."::: -* The `Commands.id` property in app manifest must match the corresponding `operationId` in the OpenAPI Description. -* If a required parameter is without a default value, the command `parameters.name` in the app manifest must match the `parameters.name` in the OpenAPI Description. -* If there's no required parameter, the command `parameters.name` in the app manifest must match the optional `parameters.name` in the OpenAPI Description. -* A command can't have more than one parameter. -* A response rendering template must be defined per command, which is used to convert responses from an API. The command section of the manifest must point to this template file under `composeExtensions.commands.apiResponseRenderingTemplateFile` within the app manifest. Each command points to a different response rendering template file. +#### Parameters ++|Property |Type |Description |Required | +| |||| +|`version` | `string` | The schema version of the current response rendering template. | Yes | +|`jsonPath` | `string` | The path to the relevant section in the results to which the responseCardTemplate and previewCardTemplate should be applied. If not set, the root object is treated as the relevant section. If the relevant section is an array, each entry is mapped to the responseCardTemplate and the previewCardTemplate. | No | +|`responseLayout` | `responseLayoutType` | Specifies the layout of the results in the message extension flyout. The supported types are `list` and `grid`. | Yes | +|`responseCardTemplate` | `adaptiveCardTemplate` | A template for creating an Adaptive Card from a result entry. | Yes | +|`previewCardTemplate` | `previewCardTemplate` | A template for creating a preview card from a result entry. The resulting preview card is displayed in the message extension flyout menu. | Yes | -</details> +#### Json path -You can create an API-based message extension using Developer Portal for Teams, Visual Studio Code, Teams Toolkit command line interface (CLI), or Visual Studio. +The JSON path is optional but should be used for arrays or where the object to be used as the data for the adaptive card isn't the root object. The JSON path should follow the format defined by Newtonsoft. If the JSON path points to an array, then each entry in that array is bound with the adaptive card template and returns as separate results. -# [Developer Portal for Teams](#tab/developer-portal-for-teams) +**Example** +Let's say you have the below JSON for a list of products and you want to create a card result for each entry. -To create an API-based message extension using Developer Portal for Teams, follow these steps: +```json +{ + "version": "1.0", + "title": "All Products", + "warehouse": { + "products": [ + ... + ] + } +} +``` ++As you can see, the array of results is under "products", which is nested under "warehouse", so the JSON path would be "warehouse.products". -1. Go to **[Teams Developer Portal](https://dev.teams.microsoft.com/home)**. -1. Go to **Apps**. -1. Select **+ New apps**. -1. Enter a name of the app and select the **Manifest version** as **Latest prerelease (devPreview)**. +Use <https://adaptivecards.io/designer/> to preview the adaptive card by inserting the template into Card Payload Editor, and take a sample response entry from your array or for your object and insert it into the Same Data editor on the right. Make sure that the card renders properly and is to your liking. +Note that Teams supports cards up to version 1.5 while the designer supports 1.6. ++#### Schema mapping ++The properties in OpenAPI Description document are mapped to the Adaptive Card template as follows: ++* `string`, `number`, `integer`, `boolean` types are converted to a TextBlock. ++ <details><summary>Example</summary> + + * **Source Schema**: `string`, `number`, `integer`, and `boolean` ++ ```yml + name: + type: string + example: doggie + ``` -1. Select **Add**. + * **Target Schema**: `Textblock` - :::image type="content" source="../assets/images/Copilot/api-based-me-tdp-manifest-version.png" alt-text="Screenshot shows the app name and the manifest version selected as Latest prerelease (devPreview) in Developer Portal."::: + ```json + { + "type": "TextBlock", + "text": "name: ${if(name, name, 'N/A')}", + "wrap": true + } + ``` -1. In the left pane, under **Configure**, update the following **Basic information**: + </details> - 1. Full name - 1. Short description - 1. Long description - 1. Developer or company name - 1. Website (must be a valid HTTPS URL) - 1. Privacy policy - 1. Terms of use +* `array`: An array is converted to a container inside Adaptive Card. -1. Select **Save**. + <details><summary>Example</summary> -1. Select **App features**. -1. Select **Messaging extension**. + * **Source schema**: `array` - :::image type="content" source="../assets/images/Copilot/api-based-me-tdp-app-feature.png" alt-text="Screenshot shows the message extension option in Teams Developer Portal."::: + ```yml + type: array + items: + required: + - name + type: object + properties: + id: + type: integer + category: + type: object + properties: + name: + type: string + ``` -1. Under **Message extension type**, select **API**. + * **Target Schema**: `Container` - 1. If you get a disclaimer, which reads **Bot message extension is already in use by users. Would you like to change message extension type to API?**. Select **Yes, change**. + ```json + { + "type": "Container", + "$data": "${$root}", + "items": [ + { + "type": "TextBlock", + "text": "id: ${if(id, id, 'N/A')}", + "wrap": true + }, + { + "type": "TextBlock", + "text": "category.name: ${if(category.name, category.name, 'N/A')}", + "wrap": true + } + ] + } + + ``` ++ </details> ++* `object`: An object is converted to a nested property in Adaptive Card. ++ <details><summary>Example</summary> ++ * **Source Schema**: `object` ++ ```yml + components: + schemas: + Pet: + category: + type: object + properties: + id: + type: integer + name: + type: string ++ ``` -1. Under **OpenAPI spec**, select **Upload now**. + * **Target Schema**: Nested property in an Adaptive Card ++ ```json + { + "type": "TextBlock", + "text": "category.id: ${if(category.id, category.id, 'N/A')}", + "wrap": true + }, + { + "type": "TextBlock", + "text": "category.name: ${if(category.name, category.name, 'N/A')}", + "wrap": true + } ++ ``` ++ </details> ++* `image`: If a property is an image URL, then it converts to an Image element in the Adaptive Card. ++ <details><summary>Example</summary> ++ * **Source schema**: `image` ++ ```yml + image: + type: string + format: uri + description: The URL of the image of the item to be repaired ++ ``` ++ * **Target Schema**: `"Image"` ++ ```json + { + "type": "Image", + "url": "${image}", + "$when": "${image != null}" + } ++ ``` ++ </details> - :::image type="content" source="../assets/images/Copilot/api-based-me-tdp-upload.png" alt-text="Screenshot shows the Upload now option in Teams Developer Portal."::: +</details> -1. Select the OpenAPI Description document in the JSON or YAML format and select **Open**. +## Authentication -1. Select **Save**. A pop-up appears with the message **API spec saved successfully**. -1. Select **Got it**. +You can implement authentication in API-based message extensions to provide secure and seamless access to applications. If your message extension requires authentication, add the `authorization` property under `composeExtensions` in app manifest and define the type of authentication for your application by setting the `authType` property under `authorization`. To enable authentication for your message extension, update your app manifest with any of the following authentication methods: - :::image type="content" source="../assets/images/Copilot/api-based-me-tdp-api-saved.png" alt-text="Screenshot shows an example of the API spec saved successfully message and Got it button."::: +<details><summary id="none">none</summary> +<br> -**Add commands** +You can update `none` as a value for `authorization` in an API-based message extension when the message extension doesn't require any authentication for the user to access the API. -> [!NOTE] -> Message extensions built from an API only support a single parameter. +```json + "authorization": { + "authType": "none" + } + }, +``` -You can add commands and parameters to your message extension, to add commands: +</details> +<br/> -1. Under **Message extension type**, select **Add**. +<details><summary id="secret-service-auth">Secret service auth</summary> - :::image type="content" source="../assets/images/Copilot/api-based-me-tdp-add-commands.png" alt-text="Screenshot shows the add option to add commands in Teams Developer Portal."::: +API secret service authentication is a secure method for your app to authenticate with API. You can [register an API key](#register-an-api-key) through the Developer Portal for Teams, and generate an API key registration ID. [Update the app manifest](#update-app-manifest) with the `apiSecretServiceAuthConfiguration` object with an `apiSecretRegistrationId` property. This property should contain the reference ID returned when you submitted the API key through the portal. - An **Add command** pop-up appears with a list of all the available APIs from the OpenAPI Description document. +When an API request is initiated, the system retrieves the API key from a secure storage location and includes it in the authorization header using the bearer token scheme. The API endpoint, upon receiving the request, verifies the validity of the API key. If the verification is successful, the endpoint processes the request and returns the desired response, ensuring that only authenticated requests receive access to the APIΓÇÖs resources. -1. Select an API from the list and select **Next**. +### Register an API key - :::image type="content" source="../assets/images/Copilot/api-based-me-tdp-commands-api-list.png" alt-text="Screenshot shows the list of APIs from the OpenAPI Description Document in the Add a command pop-up window."::: +API key registration allows you to secure their APIs that are behind an auth and use in message extensions. You can register an API key and specify the domain, tenant, and app that can access the APIs, and provide the secrets that are needed to authenticate the API calls. You can then paste the API key ID in the simplified message extension and the API key ID enables the authentication for the API calls that are behind an auth. - A **Command details** appears. +To register an API Key, follow these steps: -1. Under **Command details**, go to **Adaptive card template** and select **Upload now**. +1. Go to **Tools** > **API key registration**. - :::image type="content" source="../assets/images/Copilot/api-based-me-tdp-adaptive-card-template.png" alt-text="Screenshot shows the Upload now option to add the adaptive Card template in for the command."::: + :::image type="content" source="../assets/images/Copilot/api-based-me-api-key-registration.png" alt-text="Screenshot shows the API key registration option in Developer Portal for Teams."::: ++1. Select **+ New API key**. ++1. In the **API key registration** page, under **Register an API key**, update the following: ++ 1. **Description**: Description of the API Key. + 1. **Add domain**: Update the base path for API endpoints. The path must be a secure HTTPS URL, include a fully qualified domain name, and can optionally include a specific path. For example, `https://api.yelp.com`. ++ :::image type="content" source="../assets/images/Copilot/api-based-me-register-key-domain.png" alt-text="Screenshot shows the Description and Add domain options in the API key registration page in Developer Portal for Teams."::: ++1. Under **Set a target tenant**, select any of the following: ++ * **Home tenent** + * **Any tenant** ++ |Option |When to use | Description| + |||-| + |**Home tenant** | When you develop your app in your tenant and test the app as a custom app or custom app built for your org. | The API key is only usable within the tenant where the the API is registered. | + |**Any tenant** | After you've completed testing the app and want to enable the app across different tenants. Ensure that you update your target tenant to **Any tenant** before submitting your app package to the Partner Center. | The API key can be used in other tenants after the app is available in the Teams Store. | ++ :::image type="content" source="../assets/images/Copilot/api-based-me-api-key-tenant.png" alt-text="Screenshot shows the Home tenant and Any tenant options under set a target tenant heading in Developer Portal for Teams."::: ++1. Under **Set a Teams app**, select any of the following: ++ * **Any Teams app** + * **Existing Teams app ID** ++ |Option |When to use | Description| + |||-| + |**Any Teams app** | When you develop your app in your tenant and test the app as a custom app or custom app built for your org. | The API key can be used with any Teams app. It's useful when custom app or custom app built for your org have IDs generated after app upload. | + |**Existing Teams app ID** | After you've completed testing of your app within your tenant as a custom app or custom app built for your org. Update your API key registration and select **Existing Teams app** and input your appΓÇÖs manifest ID. |The **Existing Teams app** option binds the API secret registration to your specific Teams app. | ++ :::image type="content" source="../assets/images/Copilot/api-based-me-api-key-teams-app.png" alt-text="Screenshot shows the Any Teams app and Existing Teams app options under Set a Teams app heading in Developer Portal for Teams."::: ++1. Select **+ Add Secret**. A **Add an API key** dialog appears. ++1. Enter a value for the secret and select **Save**. > [!NOTE]- > If you have more than one API, ensure that you upload the **Adaptive card template** for each API. + > + > * You can maintain up to two secrets for each API key registration. If one key is compromised, it can be promptly removed and allows Teams to switch to the second key. + > * The secret value must have at least 10 characters and at most 128 characters. + > * If the first key results in a 401 error, Teams automatically attempts to use the second key. It helps with uninterrupted service for users and eliminates any potential downtime during the creation of a new secret. -1. Select the Adaptive Card template file in JSON format and select **Open**. + :::image type="content" source="../assets/images/Copilot/api-based-me-api-key-secret.png" alt-text="Screenshot shows the Enter the value for this secret option to add a secret to the API key."::: - The following attributes are updated automatically from the Adaptive Card template: - * Command Type - * Command ID - * Command title - * Parameter name - * Parameter description +An **API key registration ID** is generated. - :::image type="content" source="../assets/images/Copilot/api-based-me-tdp-command-details.png" alt-text="Screenshot shows the fields available in the command details page."::: -1. Under **Details**, update the **Command description**. +Copy and save the API key registration ID and update it as a value for the `apiSecretRegistrationId` property in the app manifest. - 1. If you want to launch a command using a trigger in Microsoft 365 chat, turn on the **Automatically run the command when a user opens the extension** toggle. +### Update app manifest -1. Select **Add**. The command is added successfully. +You can authorize incoming requests to your service by configuring a static API key. The API key is stored securely and added to the API call. Add an `apiSecretServiceAuthConfiguration` object with an `apiSecretRegistrationId` property, which contains the reference ID when you submit the API key through the Developer portal for Teams. For more information, see [composeExtensions.commands.](../resources/schem#composeextensionscommands) -1. Select **Save**. +```json +"composeExtensions": [ + { + "composeExtensionType": "apiBased", + "authorization": { + "authType": "apiSecretServiceAuth", + "apiSecretServiceAuthConfiguration": { + "apiSecretRegistrationId": "9xxxxb0f-xxxx-40cc-xxxx-15xxxxxxxxx3" + } + }, +``` -An API-based message extension is created. +</details> +<br/> +<details><summary id="microsoft-entra">Microsoft Entra </summary> -To test your API-based message extension created in the Developer Portal for Teams, you can use the following methods: +`microsoftEntra` authentication method uses an app user's Teams identity to provide them with access to your app. A user who has signed into Teams doesn't need to sign in again to your app within the Teams environment. With only a consent required from the app user, the Teams app retrieves access details for them from Microsoft Entra ID. After the app user has given consent, they can access the app even from other devices without having to be validated again. -* **Preview in Teams**: In Developer Portal, open your message extension and select **Preview in Teams** in the upper-right corner. You'll be redirected to Teams, where you can add the app to Teams to preview the app. +### Prerequisites -* **Download app package**: On the message extension page, select **App package** from the left pane and then, in the upper-left corner of the window, select **Download app package**. The app package is downloaded to your local machine in a .zip file. You can upload the app package to teams and test the message extension. +Before you start, ensure you have the following: -# [Visual Studio Code](#tab/visual-studio-code) +* An Azure account with an active subscription. +* Basic familiarity with Microsoft Entra ID and Teams app development. -> [!NOTE] -> Teams Toolkit support for API-based message extension is available only in Teams Toolkit pre-release version. Before you get started, ensure that you've installed a [Teams Toolkit pre-release version](../toolkit/install-Teams-Toolkit.md#install-a-pre-release-version) +The following image shows how SSO works when a Teams app user attempts to access API-bsed message extension app: -To build am API-based message extension using Teams Toolkit for Visual Studio Code, follow these steps: -1. Open **Visual Studio Code**. -1. From the left pane, Select **Teams Toolkit**. -1. Select **Create a New App**. -1. Select **Message Extension**. +* The user invokes the API-based message extension app from a message extension in Teams and requests a command that requires authentication. +* The app sends a request to the Teams backend service with the app ID and the required scope (access_as_user). +* The Teams backend service checks if the user consented to the app and the scope. If not, it shows a consent screen to the user and asks for permission. +* If the user consents, the Teams backend service generates an access token for the user and the app, and sends it to the app in the authorization header of the request. +* The app validates the token. The user can extract the user information from the token, such as the name, email, and object ID. +* The app can use the token to call its own API. +* The app returns the response to the user in Teams. - :::image type="content" source="../assets/images/Copilot/api-based-me-ttk-plugin-copilot.png" alt-text="Screenshot shows the message extension option in Team Toolkit."::: +To enable `microsoftEntra` authentication method for API-based message extension, follow these steps: -1. Select **Custom Search Results**. +### Register a new app in Microsoft Entra ID -1. Select one of the following options: - 1. To build from the beginning, select **Start with a new API**. - 1. If you already have an OpenAPI description document, select **Start with an OpenAPI Description Document**. +1. Open the [Azure portal](https://ms.portal.azure.com/) on your web browser. - :::image type="content" source="../assets/images/Copilot/api-based-me-ttk-plugin-copilot-options.png" alt-text="Screenshot shows the options to create a search based message extension."::: +2. Select the **App registrations** icon. -1. Based on the options selected in **step 6**, select the following: + :::image type="content" source="../assets/images/authentication/teams-sso-tabs/azure-portal.png" alt-text="Microsoft Entra admin center page."::: - # [New API](#tab/new-api) + The **App registrations** page appears. - 1. Select a programming language. +3. Select **+ New registration** icon. - :::image type="content" source="../assets/images/Copilot/api-based-me-ttk-plugin-programming language.png" alt-text="Screenshot shows the programming language options."::: + :::image type="content" source="../assets/images/authentication/teams-sso-tabs/app-registrations.png" alt-text="New registration page on Microsoft Entra admin center."::: - 1. Select **Default folder**. + The **Register an application** page appears. - 1. Enter the name of your app and select **Enter**. Teams Toolkit creates a new plugin with API from Azure functions. - 1. To get started, you must update the source code in the following files: +4. Enter the name of your app that you want to be displayed to the app user. You can change the name at a later stage, if you want to. - |File |Contents | - ||| - |`repair/function.json` |A configuration file that defines the functionΓÇÖs trigger and other settings. For more information, see [Azure Functions](/azure/azure-functions/functions-bindings-http-webhook-trigger?tabs=python-v2%2Cisolated-process%2Cnodejs-v4%2Cfunctionsv2&pivots=programming-language-csharp) | - |`repair/index.ts` | The main file of a function in Azure Functions. | - |`appPackage/apiSpecificationFiles/repair.yml` | A file that describes the structure and behavior of the repair API. | - |`appPackage/responseTemplates/repair.json` | A generated Adaptive Card that used to render API response. | - |`repairsData.json` | The data source for the repair API. | + :::image type="content" source="../assets/images/authentication/teams-sso-tabs/register-app.png" alt-text="App registration page on Microsoft Entra admin center."::: - # [OpenAPI Description](#tab/openapi-specification) +5. Select the type of user account that can access your app. You can select from single or multitenant options in organizational directories, or restrict the access to personal Microsoft accounts only. - 1. Enter or browse the OpenAPI Description document location. + <details> + <summary><b>Options for supported account types</b></summary> - :::image type="content" source="../assets/images/Copilot/api-based-me-ttk-plugin-copilot-openapi-spec-location.png" alt-text="Screenshot shows the option to select OpenAPI Description document location."::: + | Option | Select this to... | + | | | + | Accounts in this organizational directory only (Microsoft only - Single tenant) | Build an application for use only by users (or guests) in your tenant. <br> Often called custom app built for your org (LOB app), this app is a single-tenant application in the Microsoft identity platform. | + | Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant) | Let users in any Microsoft Entra tenant use your application. This option is appropriate if, for example, you're building a SaaS application, and you intend to make it available to multiple organizations. <br> This type of app is known as a multitenant application in the Microsoft identity platform.| + | Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant) and personal Microsoft accounts (for example, Skype, Xbox) | Target the widest set of customers. <br> By selecting this option, you're registering a multitenant application that can support app users who have personal Microsoft accounts also. | + | Personal Microsoft accounts only | Build an application only for users who have personal Microsoft accounts. | - 1. From the API list, select the GET API and select **OK**. + </details> - > [!NOTE] - > GET and POST APIs are supported for API based message extensions. + > [!NOTE] + > You don't need to enter **Redirect URI** for enabling SSO for an API-based message extension app. - 1. Select **Default folder**. - 1. Enter the name of your app and select **Enter**. Teams Toolkit scaffolds the OpenAPI Description document and created an API-based message extension. +7. Select **Register**. + A message pops up on the browser stating that the app was created. - + :::image type="content" source="../assets/images/Copilot/api-me-entra-sso-register.png" alt-text="Screenshot shows an example of the notification after the app registration is successful on Azure portal."::: -1. From the left pane, select **Teams Toolkit**. -1. Under **ACCOUNTS**, sign in with your [Microsoft 365 account](/microsoftteams/platform/toolkit/accounts) and Azure account if you haven't already. + The page with app ID and other configurations is displayed. - :::image type="content" source="../assets/images/Copilot/api-based-me-ttk-accounts.png" alt-text="Screenshot shows the Microsoft 365 and Azure sign in option in Teams Toolkit."::: + :::image type="content" source="../assets/images/Copilot/api-me-entra-sso-app-details.png" alt-text="Screenshot shows the app details page in Azure portal."::: -1. From the left pane, Select **Run and Debug (Ctrl+Shift+D)**. -1. From the launch configuration dropdown, select `Preview in Teams (Edge)` or `Preview in Teams (Chrome)`. Teams Toolkit launches Teams web client in a browser window. -1. Go to a chat message and select the **Actions and apps** icon. In the flyout menu, search for your app. -1. Select your message extension from the list and enter a search command in the search box. -1. Select an item from the list. The item unfurls into an Adaptive Card in the message compose area. +8. Note and save the app ID from **Application (client) ID** to update the app manifest later. - :::image type="content" source="../assets/images/Copilot/api-based-me-ttk-invoke-teams.png" alt-text="Screenshot shows that a message extension app is invoked from the plus icon in the chat and the app is displayed in the message extension flyout menu."::: + Your app is registered in Microsoft Entra ID. You now have app ID for your API-based message extension app. -1. Select **Send**. Teams sends the search result as an Adaptive Card in the chat message. +### Configure scope for access token +After you've created a new app registration, configure scope (permission) options for sending access token to Teams client, and authorizing trusted client applications to enable SSO. -# [Teams Toolkit CLI](#tab/teams-toolkit-cli) +To configure scope and authorize trusted client applications, you need: -To create an API-based message extension using Teams Toolkit CLI, follow these steps: +* [Add Application ID URI](#application-id-uri): Configure scope (permission) options for your app. Expose a web API and configure the application ID URI. +* [Configure API scope](#configure-api-scope): Define scope for the API, and the users who can consent for a scope. You can let only admins provide consent for higher-privileged permissions. +* [Configure authorized client application](#configure-authorized-client-application): Create authorized client IDs for applications that you want to preauthorize. It allows the app user to access the app scopes (permissions) you've configured, without requiring any further consent. Preauthorize only those client applications you trust as your app users won't have the opportunity to decline consent. -1. Go to **Command Prompt**. +#### Application ID URI -1. Enter the following command: +1. Select **Manage** > **Expose an API** from the left pane. - ``` - npm install -g @microsoft/teamsfx-cli@beta - ``` + The **Expose an API** page appears. -1. Type `teamsfx new` in the terminal +1. Select **Add** to generate application ID URI in the form of `api://{AppID}`. -1. Select **Message Extension**. + :::image type="content" source="../assets/images/Copilot/api-based-me-entra-sso-expose-api.png" alt-text="Set app ID URI"::: - :::image type="content" source="../assets/images/Copilot/api-based-me-CLI-new-project-me.png" alt-text="Screenshot shows Teams capabilities as options in the CLI interface."::: + The section for setting application ID URI appears. -1. Select **Custom Search Results**. +1. Enter the **Application ID URI** in the format explained here. -1. Select **Start from an OpenAPI Description Document**. + :::image type="content" source="../assets/images/Copilot/api-based-me-entra-sso-app-id-uri.png" alt-text="Application ID URI"::: -1. Enter a valid URL or local path of your OpenAPI Description document. + * The **Application ID URI** is prefilled with app ID (GUID) in the format `api://{AppID}`. + * The application ID URI format must be: `api://fully-qualified-domain-name.com/{AppID}`. + * Insert the `fully-qualified-domain-name.com` between `api://` and `{AppID}` (which is, GUID). For example, api://example.com/{AppID}. -1. Select the APIs from the list and select **Enter**. + > [!IMPORTANT] + > + > * **Sensitive information**: The application ID URI is logged as part of the authentication process and mustn't contain sensitive information. + > + > * **Application ID URI for app with multiple capabilities**: If you're building an API-based message extension, enter the application ID URI as `api://fully-qualified-domain-name.com/{YourClientId}`, where {YourClientId} is your Microsoft Entra app ID. + > + > * **Format for domain name**: Use lower case letters for domain name. Don't use upper case. + > + > For example, to create an app service or web app with resource name, `demoapplication`: + > + > | If base resource name used is | URL will be... | Format is supported on... | + > | | | | + > | *demoapplication* | `https://demoapplication.example.net` | All platforms.| + > | *DemoApplication* | `https://DemoApplication.example.net` | Desktop, web, and iOS only. It isn't supported in Android. | + > + > Use the lower case option *demoapplication* as base resource name. - :::image type="content" source="../assets/images/Copilot/api-based-me-CLI-API-options-me.png" alt-text="Screenshot shows the list of API extracted from the OprnOpenAPI Description document in the command prompt."::: +1. Select **Save**. -1. Enter the location for your project and select **Enter**. + A message pops up on the browser stating that the application ID URI was updated. -1. Enter the name of your application and select **Enter**. + :::image type="content" source="../assets/images/authentication/teams-sso-tabs/app-id-uri-msg.png" alt-text="Application ID URI message"::: - :::image type="content" source="../assets/images/Copilot/api-based-CLI-project-done-me.png" alt-text="Screenshot shows the message that the project is created in the required project folder."::: + The application ID URI displays on the page. -1. Go to the folder path where your project is created and enter the following command to provision your app in Azure: + :::image type="content" source="../assets/images/Copilot/api-based-me-entra-sso-app-id-uri-final.png" alt-text="Application ID URI updated"::: - ```teamsfx provision --env dev``` - Teams Toolkit CLI opens a browser window and requests you to sign in to your Microsoft Account. +1. Note and save the Application ID URI to update the app manifest later. -1. Sign in to your Microsoft account. Teams Toolkit CLI will execute validation and provisions your app on Azure. +#### Configure API scope - :::image type="content" source="../assets/images/Copilot/api-based-CLI-provision-me.png" alt-text="Screenshot shows the sign in request and the provision stages in the command prompt window."::: +> [!NOTE] +> API-based message extension support **access_as_user** scope only. ++1. Select **+ Add a scope** in the **Scopes defined by this API** section. -1. In the command prompt window, enter the following command to preview your app in Teams: + :::image type="content" source="../assets/images/authentication/teams-sso-tabs/select-scope.png" alt-text="Select scope"::: - ```Preview the app: teamsfx preview --env dev``` + The **Add a scope** page appears. - A new browser window with Teams web client opens. You can add your app to Teams. +1. Enter the details for configuring scope. -# [Visual Studio](#tab/visual-studio) + :::image type="content" source="../assets/images/authentication/teams-sso-tabs/add-scope.png" alt-text="The screenshot shows how to add scope details in Azure."::: -Before you get started, ensure that you install Visual Studio Enterprise 2022 Preview version 17.9.0 Preview 1.0 and install the **Microsoft Teams development tools** under **ASP.NET and web development** workload. + 1. Enter the scope name. This field is mandatory. + 2. Select the user who can give consent for this scope. The default option is **Admins only**. + 3. Enter the **Admin consent display name**. This field is mandatory. + 4. Enter the description for admin consent. This field is mandatory. + 5. Enter the **User consent display name**. + 6. Enter the description for user consent description. + 7. Select the **Enabled** option for state. + 8. Select **Add scope**. -To create an API-based message extension using Teams Toolkit for Visual Studio, follow these steps: + A message pops up on the browser stating that the scope was added. -1. Open **Visual Studio**. -1. Go to **File** > **New** > **Project...** or **New Project**. + :::image type="content" source="../assets/images/authentication/teams-sso-tabs/scope-added-msg.png" alt-text="Scope added message"::: -1. Search for **Teams** and select **Microsoft Teams App**. + The new scope you defined displays on the page. - :::image type="content" source="../assets/images/Copilot/api-based-me-vs-teams.png" alt-text="Screenshot shows the Microsoft Teams app option in Visual Studio."::: + :::image type="content" source="../assets/images/Copilot/api-based-me-entra-sso-scopes.png" alt-text="Screenshot shows an example of the scope added to the app in Azure portal."::: -1. Enter the **Project name** and **Location**. -1. Select **Create**. +#### Configure authorized client application - :::image type="content" source="../assets/images/Copilot/api-based-me-vs-new-app.png" alt-text="Screenshot shows the project name, Location, and Create option in Visual Studio."::: +1. Move through the **Expose an API** page to the **Authorized client application** section, and select **+ Add a client application**. -1. Select **Search Results from API**. + :::image type="content" source="../assets/images/authentication/teams-sso-tabs/auth-client-apps.png" alt-text="Authorized client application"::: -1. Select any of the following options: - * If you want to start without an API, select **Start with a new API**. - * If you have an existing OpenAPI Description document, select **Start with an OpenAPI Description**. + The **Add a client application** page appears. -1. Select **Next**. +1. Enter the appropriate Microsoft 365 client ID for the applications that you want to authorize for your appΓÇÖs web application. - :::image type="content" source="../assets/images/Copilot/api-based-me-vs-create-project.png" alt-text="Screenshot shows the Search results from API, New API, OpenAPI Description Document, and Create options in Visual Studio to create a new Project."::: + :::image type="content" source="../assets/images/Copilot/api-based-me-entra-sso-client-app.png" alt-text="Screenshot shows the Client ID and Authorized scopes option to add a client application to the app in Azure portal.Add a client application"::: -1. Based on the options selected in **step 7**, select the following: + > [!NOTE] + > + > * The Microsoft 365 client IDs for mobile, desktop, and web applications for Teams are the actual IDs that you must add. + > * For a Teams API-based message extension app, you need either Web or SPA, as you can't have a mobile or desktop client application in Teams. - # [New API](#tab/new-api2) + 1. Select one of the following client IDs: - 1. To get started, you must update the source code in the following files: + | Use client ID | For authorizing... | + | | | + | 1fec8e78-bce4-4aaf-ab1b-5451cc387264 | Teams mobile or desktop application | + | 5e3ce6c0-2b1f-4285-8d4b-75ee78787346 | Teams web application | - |File |Contents | - ||| - |`repair.cs` | The main file of a function in Azure Functions. Defines an Azure Function that retrieves and filters repair records based on a query parameter from an HTTP GET request, and returns the results as a JSON response.| - |`RepairData.cs`|The data source for the repair API. Contains a method that returns a hardcoded list of car repair tasks. | - |`Models/RepairModel.cs`|Defines a data model that represents a repair task with properties such as ID, Title, Description, AssignedTo, Date, and Image.| - |`appPackage/apiSpecificationFiles/repair.yml` | A file that describes the structure and behavior of the repair API.| - |`appPackage/responseTemplates/repair.json` | A generated Adaptive Card that used to render API response.| + 1. Select the application ID URI you created for your app in **Authorized scopes** to add the scope to the web API you exposed. - 1. After you've updated the source code, in the debug dropdown menu, select **Dev Tunnels (no active tunnel)** > **Create a Tunnel...**. + 1. Select **Add application**. - :::image type="content" source="../assets/images/Copilot/bot-based-VS-dev-tunnel.png" alt-text="Screenshot shows the create a tunnel option in Visual Studio."::: + A message pops up on the browser stating that the authorized client app was added. - 1. Select the account to create the tunnel. The supported account types are Azure, Microsoft Account (MSA), and GitHub. - 1. **Name**: Enter a name for the tunnel. - 1. **Tunnel Type**: Select **Persistent** or **Temporary**. - 1. **Access**: Select **Public**. - 1. Select **OK**. Visual Studio displays a confirmation message that a tunnel is created. + :::image type="content" source="../assets/images/authentication/teams-sso-tabs/update-app-auth-msg.png" alt-text="Client application added message"::: - The tunnel you've created is listed under **Dev Tunnels**. + The authorized app's client ID displays on the page. - 1. Go to **Solution Explorer** and select your project. - 1. Right-click the menu and select **Teams Toolkit** > **Prepare Teams App Dependencies**. + :::image type="content" source="../assets/images/authentication/teams-sso-tabs/client-app-added.png" alt-text="Client app added and displayed"::: - If prompted, sign in with a Microsoft 365 account. A message appears that the app is successfully prepared. +> [!NOTE] +> You can authorize more than one client application. Repeat the steps of this procedure for configuring another authorized client application. - 1. Select the **F5** key or select **Debug** > **Start Debugging**. Visual Studio launches a Teams web client. +You've successfully configured app scope, permissions, and client applications. Ensure that you note and save the application ID URI. Next, you configure the access token version. - # [OpenAPI Description](#tab/openapi-specification2) +### Update app manifest - 1. Enter OpenAPI specification URL or select **Browse..** to upload a file from your local machine. - 1. Select the dropdown and select the APIs from the list. - 1. Select **Create**. The project is scaffolded and you can find API specification, manifest, and response template files in the **appPackage** folder. - 1. Go to **Solution Explorer** and select your project. - 1. Right-click the menu and select **Teams Toolkit** > **Provision in the Cloud**. +> [!NOTE] +> `webApplicationInfo` is supported in the app manifest version 1.5 or later. ++Update the following properties in the app manifest file: ++* `webApplicationInfo`: Enables SSO for your app to help app users access your API-based message extension app seamlessly. section, which contains crucial details about your app. The application ID URI that you registered in Microsoft Entra ID is configured with the scope of the API you exposed. Configure your app's subdomain URI in `resource` to ensure that the authentication request using `getAuthToken()` is from the domain given in the app manifest. For more information, see [webApplicationInfo](../resources/schem#webapplicationinfo). ++ :::image type="content" source="../assets/images/authentication/teams-sso-tabs/sso-manifest.png" alt-text="Screenshot shows the app manifest configuration."::: ++* `microsoftEntraConfiguration`: Enables Single sign-on authentication for your app. Configure the `supportsSingleSignOn` property to `true` to support SSO and reduce the need for multiple authentications. ++To configure app manifest: ++1. Open the API-based message extension app project. +2. Open the app manifest folder. ++ > [!NOTE] + > + > * The app manifest folder should be at the root of your project. For more information, see [Create a Microsoft Teams app package](../concepts/build-and-test/apps-package.md). + > * For more information on learning how to create a manifest.json, see [the app manifest schema](../resources/schem). ++1. Open the `manifest.json` file +1. Add the following code snippet to the app manifest file: ++ **webApplicationInfo** ++ ```json + "webApplicationInfo": + { + "id": "{Microsoft Entra AppId}", + "resource": "api://subdomain.example.com/{Microsoft Entra AppId}" + } + ``` ++ where, + * `{Microsoft Entra AppId}` is the app ID you created when you registered your app in Microsoft Entra ID. It's the GUID. + * `subdomain.example.com` is the application ID URI that you registered when creating scope in Microsoft Entra ID. ++ **MicrosoftEntraConfiguration** ++ ```json + "authorization": { + "authType": "microsoftEntra", + ΓÇ£microsoftEntraConfigurationΓÇ¥: { + ΓÇ£supportsSingleSignOnΓÇ¥: true + } + }, + ``` ++1. Update the subdomain URL in the following properties: + 1. `contentUrl` + 2. `configurationUrl` + +1. Save the app manifest file. ++For more information, see [composeExtensions.commands](../resources/schem#composeextensionscommands). ++#### Authenticate token ++When the message extension calls the API during authentication, it receives a request with the userΓÇÖs authentication token (AED token). The message extension then adds the token in the authorization header of the outgoing HTTP request. The header format is `Authorization: Bearer <token_value>`. For example, when a message extension makes an API call to a service that requires authentication. The extension constructs an HTTP request as follows: ++```http +GET /api/resource HTTP/1.1 +Host: api.example.com +Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c +``` ++After the API-based message extension gets a request header with token, perform the following steps: ++* **Authenticate**: Verify the token for the audience, scope, issuer, and signature claims to check if the token is for your app. ++ The following is an example of a JSON Web Token (JWT) with a header and response: ++ # [Token V2](#tab/token-v2) ++ ```json + { + "typ": "JWT", + "rh": "0.AhoAv4j5cvGGr0GRqy180BHbR6Rnn7s7iddIqxdA7UZsDxYaABY.", + "alg": "RS256", + "kid": "q-23falevZhhD3hm9CQbkP5MQyU" + }.{ + "aud": "00000002-0000-0000-c000-000000000000", + "iss": "https://login.microsoftonline.com/72f988bf-86f1-41af-91ab-2d7cd011db47/v2.0", + "iat": 1712509315, + "nbf": 1712509315, + "exp": 1712513961, + "aio": "Y2NgYEjJqF0stqv73u41a6ZmxPEvBgA=", + "azp": "1fec8e78-bce4-4aaf-ab1b-5451cc387264", + "azpacr": "0", + "name": "John Doe", + "oid": "00000000-0000-0000-0000-000000000000", + "preferred_username": "john.doe@contoso.com", + "rh": "I", + "scp": "access_as_user", + "sub": "e4uM7JgAEm08GBuasSltQjvPuMX1fR5TqxopJpqZJB8", + "tid": "12345678-aaaa-bbbb-cccc-9876543210ab", + "uti": "h7DMQwSPAEeiEe62JJUGAA", + "ver": "2.0" + } + ``` ++ # [Token V1](#tab/token-v1) ++ ```json + { + "typ": "JWT", + "rh": "0.AhoAv4j5cvGGr0GRqy180BHbR6Rnn7s7iddIqxdA7UZsDxYaABY.", + "alg": "RS256", + "kid": "q-23falevZhhD3hm9CQbkP5MQyU" + }.{ + "aud": "api://00000002-0000-0000-c000-000000000000", + "iss": "https://sts.windows.net/{tenantid}/", + "iat": 1537231048, + "nbf": 1537231048, + "exp": 1537234948, + "acr": "1", + "aio": "AXQAi/8IAAAA", + "amr": ["pwd"], + "appid": "c44b4083-3bb0-49c1-b47d-974e53cbdf3c", + "appidacr": "0", + "ipaddr": "192.168.1.1", + "name": "John Doe", + "oid": "00000000-0000-0000-0000-000000000000", + "scp": "access_as_user", + "sub": "AAAAAAAAAAAAAAAAAAAAAIkzqFVrSaSaFHy782bbtaQ", + "tid": "12345678-aaaa-bbbb-cccc-9876543210ab", + "uti": "fqiBqXLPj0eQa82S-IYFAA", + } + ``` ++* **Use the token**: Extract the user information from the token, such as name, email, and object ID and use the token to call the message extension app's own API. ++ > [!NOTE] + > The API receives an Microsoft Entra token with the scope set to `access_as_user` as registered in the Azure portal. However, the token isn't authorized to call any other downstream APIs, such as Microsoft Graph. - :::image type="content" source="../assets/images/Copilot/api-based-VS-provision-cloud.png" alt-text="Screenshot shows the Provision in the Cloud option under Teams Toolkit in Visual Studio."::: +</details> +<br/> - If prompted, sign in with a Microsoft 365 account. A message appears that the app is successfully prepared. +### Troubleshooting - 1. Right-click your project and select **Teams Toolkit** > **Preview in** > **Teams**. - 1. Select the **manifest.json** file and select **Open**. Visual Studio launches a Teams web client. +* If you get a **Manifest parsing has failed** error message when uploading the app to teams, use [Teams app validator](https://dev.teams.microsoft.com/validation) to validate the app package, including the app manifest and OpenAPI spec file. Review the [app manifest](#app-manifest) and the [OpenAPI Description document](#oad) requirements to resolve errors or warnings and try uploading your app. - + :::image type="content" source="../assets/images/Copilot/api-me-troubleshoot-sideload.png" alt-text="Screenshot shows the error message when uploading an app to Teams along with the option to copy the error details to clipboard."::: -1. Go to a chat and select **Actions and apps**. +* If you encounter any issues while running your app in Teams, use the following troubleshooting steps to identify and resolve your issue: -1. From the message extension fly-out menu, enter the name of your message extension in the search box. -1. Select the message extension and enter your search query. + * **Network**: Select the **Network** tab in Developer tools to inspect network activity - :::image type="content" source="../assets/images/Copilot/api-based-me-vs-invoke-app.png" alt-text="Screenshot shows an example of message extension flyout menu invoked from the Plus icon and MyTeamsApp entered in the search filed. The app is displayed in the search results."::: + 1. Open [Teams web client](https://teams.microsoft.com). + 1. Sign in with your Microsoft 365 credentials. + 1. Go to a chat, and run your message extension app. + 1. At the top-right, select **Settings and more (...)**. Go to **More tools** > **Developer tools**. + 1. Select **Network**. Select the **filter** option and enter **invoke** in the search field. + 1. Select an error from the list. + 1. In the right pane, select the **Response** tab. -1. Select an item from the list. The item unfurls into an Adaptive Card in the message compose area. + 1. A JSON object representing an error response from a service or API is displayed. It contains a `standardizedError` object with `errorCode`, `errorSubCode`, and `errorDescription`, which have more details about the error. -1. Select **Send**. Teams sends the search result as an Adaptive Card in the chat message. + :::image type="content" source="../assets/images/Copilot/api-me-troubleshoot-network.png" alt-text="Screenshots shows the network tab, the list of Invoke Errors, and the error details in the response tab in Developer tools while running a message extension in Teams and getting an error."::: - :::image type="content" source="../assets/images/Copilot/api-based-me-vs-adaptive-card-chat.png" alt-text="Screenshot shows an example of Adaptive Card sent to the user's chat in Microsoft Teams."::: + **Common HTTP Error Responses**: -+ * A 400 Bad Request error might occur if a request parameter is missing or incorrectly formatted. + * A 401 Unauthorized or 403 Forbidden error suggests issues with the API key, such as it being missing or unauthorized. + * A 500 Internal Server Error indicates that the service doesn't know how to respond, possibly due to a server-side issue. -## Step-by-step guides +* **Troubleshooting with Tools**: If the information from the network trace is insufficient, you can construct a request following the OpenAPI description document and use tools like Swagger Editor or Postman to test the request, including the authorization header for the API key if necessary. -To build an API-based message extension, follow these step-by-step guides: +If youΓÇÖre unable to resolve the errors, we recommend contacting [Microsoft Teams product support](../feedback.md#product-support-and-service-issues) for further assistance. -* [For beginners](../sbs-api-me-ttk.yml): Build an API-based message extension using Teams Toolkit. -* [For advanced users](../sbs-api-based-message-extensions.yml): Build an API-based message extension from the ground up. |
platform | Build Bot Based Message Extension | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/messaging-extensions/build-bot-based-message-extension.md | See the following video to learn how to define message extension search commands > [!VIDEO https://www.microsoft.com/en-us/videoplayer/embed/RE4OIvK] <br> -The search command in a message extension is configured using the `composeExtensions.commands` property and the `query` type in the app manifest (previously called as Teams app manifest). +The search command in a message extension is configured using the `composeExtensions.commands` property and the `query` type in the app manifest (previously called as Teams app manifest). Command and parameter descriptions enhance the usability and effectiveness of a message extension. A good command description offers a clear and concise summary of the appΓÇÖs features. The following code is an example of the `composeExtensions` property defining a search command: You must add the following parameters to your `composeExtensions.commands` array | `id` | Unique ID that you assign to search command. The user request includes this ID. | Yes | 1.0 | | `title` |Command name. This value appears in the user interface (UI). | Yes | 1.0 | | `description` | Help text indicating what this command does. This value appears in the UI. | Yes | 1.0 |+|`semanticDescription`|Semantic description of the command for consumption by the large language model.|No|1.17| | `type` | Type of command. Default is `query`. | No | 1.4 | |`initialRun` | If this property is set to **true**, it indicates this command should be executed as soon as the user selects this command in the UI. | No | 1.0 | | `context` | Optional array of values that defines the context the search action is available in. The possible values are `message`, `compose`, or `commandBox`. The default is `compose`,`commandBox`. | No | 1.5 | You must add the following search parameter details that define the text visible | `parameters` | Defines a static list of parameters for the command. | No | 1.0 | | `parameter.name` | Describes the name of the parameter. The `parameter.name` is sent to your service in the user request. | Yes | 1.0 | | `parameter.description` | Describes the parameterΓÇÖs purposes or example of the value that must be provided. This value appears in the UI. | Yes | 1.0 |+|`parameter.semanticDescription`|Semantic description of the parameter for consumption by the large language model.|No|1.17| | `parameter.title` | Short user-friendly parameter title or label. | Yes | 1.0 | | `parameter.inputType` | Set to the type of the input required. Possible values include `text`, `textarea`, `number`, `date`, `time`, `toggle`. Default is set to `text`. | No | 1.4 | | `parameters.value` | Initial value for the parameter. Currently the value isn't supported | No | 1.5 | |
platform | Build Bot Based Plugin | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/messaging-extensions/build-bot-based-plugin.md | Last updated 11/14/2023 > [!NOTE] >-> * Copilot for Microsoft 365 is in private preview. Ensure that Copilot for Microsoft 365 is available for your organization. You have two ways to get a developer environment for Copilot: +> * Ensure that Copilot for Microsoft 365 is available for your organization. You have two ways to get a developer environment for Copilot: > * A sandbox Microsoft 365 tenant with Copilot (available in limited preview through [TAP membership](https://developer.microsoft.com/microsoft-365/tap)).-> * An enterprise customer production environment with Microsoft Copilot for Microsoft 365 licenses. +> * An [eligible Microsoft 365 or Office 365 production environment](/microsoft-365-copilot/extensibility/prerequisites#customers-with-existing-microsoft-365-and-copilot-licenses) with a Copilot for Microsoft 365 license. > * Bot-based search message extension plugin is available in [**public developer preview**](../resources/dev-preview/developer-preview-intro.md).-> * Only bot-based search message extension can be extended as a plugin for Copilot for Microsoft 365. +> * Only *bot-based* message extensions with *search* commands can be extended as plugins for Copilot for Microsoft 365. Microsoft Copilot for Microsoft 365, powered by an advanced processing and orchestration engine, integrates Microsoft 365 apps, Microsoft Graph, and large language models (LLMs) to transform your words into a potent productivity tool. Although Copilot for Microsoft 365 can utilize apps and data within the Microsoft 365 ecosystem, many users rely on various external tools and services for work management and collaboration. By extending your message extension as a plugin in Copilot for Microsoft 365, you can enable users to interact with third-party tools and services, therefore empowering them to achieve more with Copilot for Microsoft 365. You can achieve this extension by developing a plugin or connecting to an external data source. A plugin allows Copilot for Microsoft 365 to interact directly with third-party * Retrieve knowledge-based information, such as a teamΓÇÖs design files in Figma. * Perform actions on behalf of the user, such as creating a Contoso ticket. -All bot-based search message extensions are eligible for plugin support, subject to validation to ensure the plugin meets quality, security, privacy, and usefulness expectations. +Descriptions enhance the usability and effectiveness of a message extension plugin. The follwoing description offer a clear and concise summary of the appΓÇÖs features: -You can create a bot-based search message extension using Teams Toolkit for Visual Studio Code, Visual Studio, Teams Toolkit command line interface (CLI), or Developer Portal for Teams and extend the message extension to function as a plugin in Copilot for Microsoft 365. +* **App description**: App description helps improve your app discoverability in the Teams Store. +* **Command description**: Command description maps user intent and utterance to search command inside a plugin and must be built based on the analysis of the user intent and keywords. +* **Parameter description**: Parameter description explains the requirements of the system in a natural language with output format. +* **Semantic description**: Semantic description helps Copilot for Micrososft 365 generate content by providing a conceptual understanding of the plugin's capabilities and scenarios where it can help achieve user goals and match userΓÇÖs intent with the plugin's capabilities. ++For more information, see [define descriptions](high-quality-message-extension.md#define-descriptions). ++All bot-based search message extensions are eligible for plugin support, subject to validation to ensure the plugin meets quality, security, privacy, and usefulness expectations. You can create a bot-based search message extension using Teams Toolkit for Visual Studio Code, Visual Studio, Teams Toolkit command line interface (CLI), or Developer Portal for Teams and extend the message extension to function as a plugin in Copilot for Microsoft 365. ## Prerequisites To test your bot-based message extension created in the Developer Portal for Tea +For more on testing your plugin in Copilot for Microsoft 365 chat, see [Debugging plugin selection](/microsoft-365-copilot/extensibility/orchestrator?tabs=tasks#debugging-plugin-selection). + ## Step-by-step guide Follow the [step-by-step guide](../sbs-messagingextension-searchcommand-plugin.yml) to build a bot-based search message extension plugin for M365 Chat. |
platform | Create Api Message Extension | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/messaging-extensions/create-api-message-extension.md | + + Title: Create API-based message extension ++description: Learn how to create an API message extension using Teams Visual Studio, Visual Studio Code, and Teams Toolkit. +ms.localizationpriority: medium ++ Last updated : 04/08/2024++# Create an API-based message extension ++You can create an API-based message extension using Developer Portal for Teams and Teams Toolkit for Visual Studio Code, command line interface (CLI), or Visual Studio. ++# [Developer Portal for Teams](#tab/developer-portal-for-teams) ++To create an API-based message extension using Developer Portal for Teams, follow these steps: ++1. Go to **[Teams Developer Portal](https://dev.teams.microsoft.com/home)**. +1. Go to **Apps**. +1. Select **+ New apps**. +1. Enter a name of the app and select the **Manifest version** as **Latest prerelease (devPreview)**. +1. Select **Add**. ++ :::image type="content" source="../assets/images/Copilot/api-based-me-tdp-manifest-version.png" alt-text="Screenshot shows the app name and the manifest version selected as Latest prerelease (devPreview) in Developer Portal."::: ++1. In the left pane, under **Configure**, update the following **Basic information**: ++ 1. Full name + 1. Short description + 1. Long description + 1. Developer or company name + 1. Website (must be a valid HTTPS URL) + 1. Privacy policy + 1. Terms of use ++1. Select **Save**. ++1. Select **App features**. +1. Select **Messaging extension**. ++ :::image type="content" source="../assets/images/Copilot/api-based-me-tdp-app-feature.png" alt-text="Screenshot shows the message extension option in Teams Developer Portal."::: ++1. Under **Message extension type**, select **API**. ++ 1. If you get a disclaimer, which reads **Bot message extension is already in use by users. Would you like to change message extension type to API?**. Select **Yes, change**. ++1. Under **OpenAPI spec**, select **Upload now**. ++ :::image type="content" source="../assets/images/Copilot/api-based-me-tdp-upload.png" alt-text="Screenshot shows the Upload now option in Teams Developer Portal."::: ++1. Select the OpenAPI Description document in the JSON or YAML format and select **Open**. ++1. Select **Save**. A pop-up appears with the message **API spec saved successfully**. +1. Select **Got it**. ++ :::image type="content" source="../assets/images/Copilot/api-based-me-tdp-api-saved.png" alt-text="Screenshot shows an example of the API spec saved successfully message and Got it button."::: ++**Add commands** ++> [!NOTE] +> Message extensions built from an API only support a single parameter. ++You can add commands and parameters to your message extension, to add commands: ++1. Under **Message extension type**, select **Add**. ++ :::image type="content" source="../assets/images/Copilot/api-based-me-tdp-add-commands.png" alt-text="Screenshot shows the add option to add commands in Teams Developer Portal."::: ++ An **Add command** pop-up appears with a list of all the available APIs from the OpenAPI Description document. ++1. Select an API from the list and select **Next**. ++ :::image type="content" source="../assets/images/Copilot/api-based-me-tdp-commands-api-list.png" alt-text="Screenshot shows the list of APIs from the OpenAPI Description Document in the Add a command pop-up window."::: ++ A **Command details** appears. ++1. Under **Command details**, go to **Adaptive card template** and select **Upload now**. ++ :::image type="content" source="../assets/images/Copilot/api-based-me-tdp-adaptive-card-template.png" alt-text="Screenshot shows the Upload now option to add the Adaptive Card template in for the command."::: ++ > [!NOTE] + > If you have more than one API, ensure that you upload the **Adaptive card template** for each API. ++1. Select the Adaptive Card template file in JSON format and select **Open**. ++ The following attributes are updated automatically from the Adaptive Card template: + * Command Type + * Command ID + * Command title + * Parameter name + * Parameter description ++ :::image type="content" source="../assets/images/Copilot/api-based-me-tdp-command-details.png" alt-text="Screenshot shows the fields available in the command details page."::: ++1. Under **Details**, update the **Command description**. ++ 1. If you want to launch a command using a trigger in Microsoft 365 chat, turn on the **Automatically run the command when a user opens the extension** toggle. ++1. Select **Add**. The command is added successfully. ++1. Select **Save**. ++An API-based message extension is created. +++To test your API-based message extension created in the Developer Portal for Teams, you can use the following methods: ++* **Preview in Teams**: In Developer Portal, open your message extension and select **Preview in Teams** in the upper-right corner. You're redirected to Teams, where you can add the app to Teams to preview the app. ++* **Download app package**: On the message extension page, select **App package** from the left pane and then, in the upper-left corner of the window, select **Download app package**. The app package is downloaded to your local machine in a .zip file. You can upload the app package to teams and test the message extension. ++# [Visual Studio Code](#tab/visual-studio-code) ++> [!NOTE] +> Teams Toolkit support for API-based message extension is available only in Teams Toolkit pre-release version. Before you get started, ensure that you've installed a [Teams Toolkit pre-release version](../toolkit/install-Teams-Toolkit.md#install-a-pre-release-version) ++To build am API-based message extension using Teams Toolkit for Visual Studio Code, follow these steps: ++1. Open **Visual Studio Code**. +1. From the left pane, Select **Teams Toolkit**. +1. Select **Create a New App**. +1. Select **Message Extension**. ++ :::image type="content" source="../assets/images/Copilot/api-based-me-ttk-plugin-copilot.png" alt-text="Screenshot shows the message extension option in Team Toolkit."::: ++1. Select **Custom Search Results**. ++1. Select one of the following options: + 1. To build from the beginning, select **Start with a new API**. + 1. If you already have an OpenAPI description document, select **Start with an OpenAPI Description Document**. ++ :::image type="content" source="../assets/images/Copilot/api-based-me-ttk-plugin-copilot-options.png" alt-text="Screenshot shows the options to create a search based message extension."::: ++1. Based on the options selected in **step 6**, select the following: ++ # [New API](#tab/new-api) ++ 1. Select the authentication type: + * **None** + * **API Key** + * **Microsoft Entra** ++ 1. Select a programming language. ++ :::image type="content" source="../assets/images/Copilot/api-based-me-ttk-plugin-programming language.png" alt-text="Screenshot shows the programming language options."::: ++ 1. Select **Default folder**. ++ 1. Enter the name of your app and select **Enter**. Teams Toolkit creates a new plugin with API from Azure functions. + 1. To get started, you must update the source code in the following files: ++ |File |Contents | + ||| + |`repair/function.json` |A configuration file that defines the functionΓÇÖs trigger and other settings. For more information, see [Azure Functions](/azure/azure-functions/functions-bindings-http-webhook-trigger?tabs=python-v2%2Cisolated-process%2Cnodejs-v4%2Cfunctionsv2&pivots=programming-language-csharp) | + |`repair/index.ts` | The main file of a function in Azure Functions. | + |`appPackage/apiSpecificationFiles/repair.yml` | A file that describes the structure and behavior of the repair API. | + |`appPackage/responseTemplates/repair.json` | A generated Adaptive Card that used to render API response. | + |`repairsData.json` | The data source for the repair API. | ++ # [OpenAPI Description](#tab/openapi-specification) ++ 1. Enter or browse the OpenAPI Description document location. ++ :::image type="content" source="../assets/images/Copilot/api-based-me-ttk-plugin-copilot-openapi-spec-location.png" alt-text="Screenshot shows the option to select OpenAPI Description document location."::: ++ 1. From the API list, select the GET API and select **OK**. ++ > [!NOTE] + > GET and POST APIs are supported for API based message extensions. ++ 1. Select **Default folder**. + 1. Enter the name of your app and select **Enter**. Teams Toolkit scaffolds the OpenAPI Description document and created an API-based message extension. ++ ++1. From the left pane, select **Teams Toolkit**. +1. Under **ACCOUNTS**, sign in with your [Microsoft 365 account](/microsoftteams/platform/toolkit/accounts) and Azure account if you haven't already. ++ :::image type="content" source="../assets/images/Copilot/api-based-me-ttk-accounts.png" alt-text="Screenshot shows the Microsoft 365 and Azure sign in option in Teams Toolkit."::: ++1. From the left pane, Select **Run and Debug (Ctrl+Shift+D)**. +1. From the launch configuration dropdown, select `Preview in Teams (Edge)` or `Preview in Teams (Chrome)`. Teams Toolkit launches Teams web client in a browser window. +1. Go to a chat message and select the **Actions and apps** icon. In the flyout menu, search for your app. +1. Select your message extension from the list and enter a search command in the search box. +1. Select an item from the list. The item unfurls into an Adaptive Card in the message compose area. ++ :::image type="content" source="../assets/images/Copilot/api-based-me-ttk-invoke-teams.png" alt-text="Screenshot shows that a message extension app is invoked from the plus icon in the chat and the app is displayed in the message extension flyout menu."::: ++1. Select **Send**. Teams sends the search result as an Adaptive Card in the chat message. +++# [Teams Toolkit CLI](#tab/teams-toolkit-cli) ++To create an API-based message extension using Teams Toolkit CLI, follow these steps: ++1. Go to **Command Prompt**. ++1. Enter the following command: ++ ``` + npm install -g @microsoft/teamsfx-cli@beta + ``` ++1. Type `teamsfx new` in the terminal ++1. Select **Message Extension**. ++ :::image type="content" source="../assets/images/Copilot/api-based-me-CLI-new-project-me.png" alt-text="Screenshot shows Teams capabilities as options in the CLI interface."::: ++1. Select **Custom Search Results**. ++1. Select **Start from an OpenAPI Description Document**. ++1. Enter a valid URL or local path of your OpenAPI Description document. ++1. Select the APIs from the list and select **Enter**. ++ :::image type="content" source="../assets/images/Copilot/api-based-me-CLI-API-options-me.png" alt-text="Screenshot shows the list of API extracted from the OprnOpenAPI Description document in the command prompt."::: ++1. Enter the location for your project and select **Enter**. ++1. Enter the name of your application and select **Enter**. ++ :::image type="content" source="../assets/images/Copilot/api-based-CLI-project-done-me.png" alt-text="Screenshot shows the message that the project is created in the required project folder."::: ++1. Go to the folder path where your project is created and enter the following command to provision your app in Azure: ++ ```teamsfx provision --env dev``` + Teams Toolkit CLI opens a browser window and requests you to sign in to your Microsoft Account. ++1. Sign in to your Microsoft account. Teams Toolkit CLI executes validation and provisions your app on Azure. ++ :::image type="content" source="../assets/images/Copilot/api-based-CLI-provision-me.png" alt-text="Screenshot shows the sign in request and the provision stages in the command prompt window."::: ++1. In the command prompt window, enter the following command to preview your app in Teams: ++ ```Preview the app: teamsfx preview --env dev``` ++ A new browser window with Teams web client opens. You can add your app to Teams. ++# [Visual Studio](#tab/visual-studio) ++Before you get started, ensure that you install Visual Studio Enterprise 2022 Preview version 17.9.0 Preview 1.0 and install the **Microsoft Teams development tools** under **ASP.NET and web development** workload. ++To create an API-based message extension using Teams Toolkit for Visual Studio, follow these steps: ++1. Open **Visual Studio**. +1. Go to **File** > **New** > **Project...** or **New Project**. ++1. Search for **Teams** and select **Microsoft Teams App**. ++ :::image type="content" source="../assets/images/Copilot/api-based-me-vs-teams.png" alt-text="Screenshot shows the Microsoft Teams app option in Visual Studio."::: ++1. Enter the **Project name** and **Location**. +1. Select **Create**. ++ :::image type="content" source="../assets/images/Copilot/api-based-me-vs-new-app.png" alt-text="Screenshot shows the project name, Location, and Create option in Visual Studio."::: ++1. Select **Search Results from API**. ++1. Select any of the following options: + * If you want to start without an API, select **Start with a new API**. + * If you have an existing OpenAPI Description document, select **Start with an OpenAPI Description**. ++1. Select **Next**. ++ :::image type="content" source="../assets/images/Copilot/api-based-me-vs-create-project.png" alt-text="Screenshot shows the Search results from API, New API, OpenAPI Description Document, and Create options in Visual Studio to create a new Project."::: ++1. Based on the options selected in **step 7**, select the following: ++ # [New API](#tab/new-api2) ++ 1. To get started, you must update the source code in the following files: ++ |File |Contents | + ||| + |`repair.cs` | The main file of a function in Azure Functions. Defines an Azure Function that retrieves and filters repair records based on a query parameter from an HTTP GET request, and returns the results as a JSON response.| + |`RepairData.cs`|The data source for the repair API. Contains a method that returns a hardcoded list of car repair tasks. | + |`Models/RepairModel.cs`|Defines a data model that represents a repair task with properties such as ID, Title, Description, AssignedTo, Date, and Image.| + |`appPackage/apiSpecificationFiles/repair.yml` | A file that describes the structure and behavior of the repair API.| + |`appPackage/responseTemplates/repair.json` | A generated Adaptive Card that used to render API response.| ++ 1. After you've updated the source code, in the debug dropdown menu, select **Dev Tunnels (no active tunnel)** > **Create a Tunnel...**. ++ :::image type="content" source="../assets/images/Copilot/bot-based-VS-dev-tunnel.png" alt-text="Screenshot shows the create a tunnel option in Visual Studio."::: ++ 1. Select the account to create the tunnel. The supported account types are Azure, Microsoft Account (MSA), and GitHub. + 1. **Name**: Enter a name for the tunnel. + 1. **Tunnel Type**: Select **Persistent** or **Temporary**. + 1. **Access**: Select **Public**. + 1. Select **OK**. Visual Studio displays a confirmation message that a tunnel is created. ++ The tunnel you've created is listed under **Dev Tunnels**. ++ 1. Go to **Solution Explorer** and select your project. + 1. Right-click the menu and select **Teams Toolkit** > **Prepare Teams App Dependencies**. ++ If prompted, sign in with a Microsoft 365 account. A message appears that the app is successfully prepared. ++ 1. Select the **F5** key or select **Debug** > **Start Debugging**. Visual Studio launches a Teams web client. ++ # [OpenAPI Description](#tab/openapi-specification2) ++ 1. Enter OpenAPI specification URL or select **Browse..** to upload a file from your local machine. + 1. Select the dropdown and select the APIs from the list. + 1. Select **Create**. The project is scaffolded and you can find API specification, manifest, and response template files in the **appPackage** folder. + 1. Go to **Solution Explorer** and select your project. + 1. Right-click the menu and select **Teams Toolkit** > **Provision in the Cloud**. ++ :::image type="content" source="../assets/images/Copilot/api-based-VS-provision-cloud.png" alt-text="Screenshot shows the Provision in the Cloud option under Teams Toolkit in Visual Studio."::: ++ If prompted, sign in with a Microsoft 365 account. A message appears that the app is successfully prepared. ++ 1. Right-click your project and select **Teams Toolkit** > **Preview in** > **Teams**. + 1. Select the **manifest.json** file and select **Open**. Visual Studio launches a Teams web client. ++ ++1. Go to a chat and select **Actions and apps**. ++1. From the message extension fly-out menu, enter the name of your message extension in the search box. +1. Select the message extension and enter your search query. ++ :::image type="content" source="../assets/images/Copilot/api-based-me-vs-invoke-app.png" alt-text="Screenshot shows an example of message extension flyout menu invoked from the Plus icon and MyTeamsApp entered in the search filed. The app is displayed in the search results."::: ++1. Select an item from the list. The item unfurls into an Adaptive Card in the message compose area. ++1. Select **Send**. Teams sends the search result as an Adaptive Card in the chat message. ++ :::image type="content" source="../assets/images/Copilot/api-based-me-vs-adaptive-card-chat.png" alt-text="Screenshot shows an example of Adaptive Card sent to the user's chat in Microsoft Teams."::: ++++## Step-by-step guides ++To build an API-based message extension, follow these step-by-step guides: ++* [For beginners](../sbs-api-me-ttk.yml): Build an API-based message extension using Teams Toolkit. +* [For advanced users](../sbs-api-based-message-extensions.yml): Build an API-based message extension from the ground up. |
platform | High Quality Message Extension | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/messaging-extensions/high-quality-message-extension.md | Microsoft 365 plugins provide integration with various Microsoft 365 products, * Search for the latest information or record. For example, the latest incident ticket or survey results. * Summarize information based on multiple records. For example, summarize all incident tickets related to the project Northwind. -We recommend that you build or upgrade your existing message extensions to maximize their usefulness and usability in Copilot for Microsoft 365. Message extensions should support one or more search commands, as Copilot for Microsoft 365 recognizes them as skills it can execute on behalf of the user. Additionally, your extensions must meet the standards for compliance, performance, security, and user experience outlined in this article. +We recommend that you build or upgrade your existing message extensions to maximize their usefulness and usability in Copilot for Microsoft 365. Message extensions must support one or more search commands, as Copilot for Microsoft 365 recognizes them as skills it can execute on behalf of the user. Additionally, your extensions must meet the standards for compliance, performance, security, and user experience outlined in this article. :::image type="content" source="../assets/images/Copilot/ailib-copilot-interface.png" alt-text="Graphic shows the user experience between Microsoft Teams and Copilot for Microsoft 365 (M365 Chat)."::: The requirements for building message extension plugins for Copilot for Microsof > > * [Define app, command, and parameter descriptions](#define-descriptions) > * [Enhance message extension to retrieve information through compound utterances](#compound-utterances)+> * [Define sample prompts](#sample-prompts) > * [Create rich Adaptive Card responses](#adaptive-card-response) ## Define descriptions A good description offers a clear and concise summary of the appΓÇÖs features an :::image type="content" source="../assets/images/Copilot/validation-guidelines-plugin-prompt-pass.png" alt-text="Screenshot shows a pass scenario with an example of a sample prompt for message extension plugin in M365 Chat."::: - :::image type="content" source="../assets/images/Copilot/validation-guidelines-plugin-prompt-fail.png" alt-text="Screenshot shows a fail scenario without an example of sample prompt for message extension usage as a plugin in M365 Chat."::: + :::image type="content" source="../assets/images/Copilot/validation-guidelines-plugin-prompt-fail.png" alt-text="Screenshot shows a fail scenario without an example of sample prompt for message extension as a plugin in M365 Chat."::: Ensure that you adhere to the description guidelines listed in the following table: Command description maps user intent and utterance to search command inside a pl * Include verbs and synonyms, if applicable. * Focus on keywords that are likely to be used in the search function of your native apps. -The following table lists the command description examples for each category: +#### Semantic description ++The [semanticDescription](../resources/schem#composeextensionscommands) property is used to provide a detailed description of a command for Microsoft Copilot. Semantic description for commands supports up to 5,000 characters and isn't displayed in the user interface. If the `semanticDescription` property is left empty, Microsoft Copilot uses the information in the `description` field. When writing a `semanticDescription`, you must include information about expected values, limits, and ranges for the command. ++The `semanticDescription` property isn't a mandatory field. However, if you add `semanticDescription` in app manifest, the existing validation checks for short, parameter, and command descriptions are also applicable for semantic descriptions. ++We recommend you to review the following guidelines for semantic description to increase the chances of your app to pass the Microsoft Teams Store submission process: ++* Avoid instructional phrases such as ΓÇ£if the user says X",ΓÇ¥ ΓÇ£ignore,ΓÇ¥ ΓÇ£delete,ΓÇ¥ ΓÇ£reset,ΓÇ¥ ΓÇ£new instructions,ΓÇ¥ ΓÇ£Answer in Bold,ΓÇ¥ or ΓÇ£Don't print anything.ΓÇ¥ *[Mandatory fix]* +* Avoid URLs, emojis, or hidden characters such as hexadecimal, binary, or unconventional symbols. *[Mandatory fix]* +* Avoid grammar and punctuation errors. *[Mandatory fix]* +* Avoid overly verbose, flowery, or marketing language. *[Suggested fix]* +* Avoid superlative claims such as ΓÇ£#1,ΓÇ¥ ΓÇ£amazing,ΓÇ¥ or ΓÇ£best.ΓÇ¥ *[Suggested fix]* ++The following table lists the command and semantic description examples for each category: # [Tasks](#tab/tasks) The following table lists the command description examples for each category: "type": "query", "title": "Tasks", "description": "Search for high priority tasks related to Northwind that are due tomorrow.",+ "SemanticDescription": "Search for issues, epics, stories, tasks, sub tasks, bugs + additional details." "initialRun": true, "fetchTask": false, "context": [ The following table lists the command description examples for each category: "type": "query", "title": "Survey", "description": "Search for surveys, drafts, and results with keywords or number of respondents.",+ "semanticDescription": "This command enables users to search for surveys, drafts, and results based on specific keywords or the number of respondents." "initialRun": true, "fetchTask": false, "context": [ The following table lists the command description examples for each category: "type": "query", "title": "CRM", "description": "Through CRM plugin, find qualified, unqualified, and quoted leads of clients and customers.",+ "semanticDescription": "This command allows users to search for leads in the CRM system based on specific criteria.", "initialRun": true, "fetchTask": false, "context": [ The following table lists the command description examples for each category: Each message extension command supports up to five parameters and first parameter must be visible in the message extension search bar. A parameter must have a good description, which must contain a combination of acceptable parameters, enums, acronyms, and output format. +The [semanticDescription](../resources/schem#composeextensionscommands) property is used to provide a detailed description of a command for Microsoft Copilot. Semantic description for parameters supports up to 2,000 characters and isn't displayed in the user interface. If the `semanticDescription` property is left empty, Copilot uses the information in the `description` field. When writing a `semanticDescription`, you must include information about expected values, limits, and ranges for the command. + A good parameter description explains the requirements of the system in a natural language with output format. The following are a few examples of basic and advanced search requests for each category: # [Tasks](#tab/tasks) Advanced search: Search for high priority tasks related to Northwind that are du { "name": "Name", "title": "Project or Task Name",- "description": "Project name or task name as keyword", + "description": "Project name or task name as keyword.", "inputType": "text" }, { "name": "Time", "title": "Time",- "description": "Date or number of days for which you need tasks for.Output: Number", + "description": "Date or number of days for which you need tasks for.", + "semanticDescription": "Date or number of days for which you need tasks for. Output: Number", "inputType": "text" }, { "name": "Priority", "title": "Priority",- "description": "Priority of tasks. Acceptable values are high, medium, low, NA ", + "description": "Priority of tasks.", + "semanticDescription": "Priority of tasks. Acceptable values are high, medium, low, NA", "inputType": "text" }] ``` Advanced search: Retrieve recent customer satisfaction survey on product Contoso { "name": "SurveyName", "title": "Name of Survey",- "description": "survey name or related keyword", + "description": "Survey name or related keyword", "inputType": "text" }, { "name": "Tags", "title": "Tags",- "description": "product name or keywords related pertaining to a question", + "description": "Product name or keywords related pertaining to a question", "inputType": "text" }, { "name": "ResponseNumber", "title": "Response number",- "description": "number of responses received for a survey. Output: Number", + "description": "Number of responses received for a survey.", + "semanticDescription": "Number of responses received for a survey. Output: Number", "inputType": "text" } ] Advanced search: Fetch qualified leads for which quotes are pending from last se { "name": "TypeofLeads", "title": "Type of Leads",- "description": "what types of leads user is looking for. Acceptable fields are: Qualified, Unqualified and New.", + "description": "Type of leads to find.", + "semanticDescription": "Type of leads to find. Acceptable fields are: Qualified, Unqualified and New.", "inputType": "text" }, { "name": "Status", "title": "Status",- "description": "status of leads. Acceptable fields are: Pending, Quote Given and Quote Rejected.", + "description": "Status of leads to find.", + "semanticDescription": "Status of leads to find. Acceptable fields are: Pending, Quote Given and Quote Rejected.", "inputType": "text" }, { "name": "Time", "title": "Time",- "description": "number of days for which you need status of leads for. Output: Number", + "description": "Number of days to search for leads with given status.", + "semanticIndex": "Number of days to search for leads with given status. Output: Number", "inputType": "text" } ] Advanced search: Find top 10 stocks in NASDAQ with P/E less than 30 and P/B less { "name": "StockIndex", "title": "Stock Index",- "description": "Name of index in which user wants to find stocks", + "description": "Name of index to search for stocks", + "semanticDescription": "Name of stock market index used to search for stocks", "inputType": "text" }, { "name": "NumberofStocks", "title": "Ranked Number of Stocks",- "description": "Provide number of stocks in ranked order. Output format: Top:<Number of stocks or bottom:<Number of stocks>", + "description": "Number of stocks to return.", + "semanticDescription": "Number of stocks to return in ranked order. Output format: Top:<Number of stocks or bottom:<Number of stocks>", "inputType": "text" }, { "name": "P/B", "title": "Price to Book Ratio",- "description": "P/B or Price to book ratio of a stock. Output format: >x.xx or <x.xx", + "description": "Price-to-book ratio of a stock.", + "semanticDescription": "Price to book (P/B) ratio of a stock. Output format: >x.xx or <x.xx", "inputType": "text" }, { "name": "P/E", "title": "Price to Earnings Ratio",- "description": "P/E or Price to Earnings ratio of a stock with comparison. Output format: >x.xx or <x.xx", + "description": "Price-to-earnings ratio of a stock with comparison.", + "semanticDescription": "Price to Earnings (P/E) ratio of a stock with comparison. Output format: >x.xx or <x.xx", "inputType": "text" } ] For M365 Chat, a search-based message extension must support more than three uni * Copilot for Microsoft 365 might pass an empty string or null value for parameters, which aren't part of user utterance, update your web service to handle the parameters. <br>-<details><summary>The following JSON code is an example of multiple parameters defined in app manifest:</summary> +<details><summary>The following code is an example of multiple parameters defined in app manifest:</summary> ```json "commands": [ For M365 Chat, a search-based message extension must support more than three uni The search parameters must have good descriptions with acceptable parameters, enums, acronyms, and output format. For more information and examples, see [Parameter description](#parameter-description). +## Sample prompts ++The [`samplePrompts`](../resources/schem#composeextensionscommands) property guides users on how to use the various plugins within Copilot. The prompts must be adaptable to different locales and clear across different commands. Sample prompts are available in the following areas within Copilot for Microsoft 365: ++* First Run Experience (FRE): When a user first installs or enables a plugin. +* Prompt library or Copilot Lab: When a user seeks help with prompts. +* Plugin suggestions: To guide users towards better utterances. +++> [!NOTE] +> +> * If the app manifest doesn't specify the `samplePrompts` property, the prompts aren't displayed. +> * The `samplePrompts` property is mandatory for app validation during the app submission process. +> * If you define multiple commands for your app, a maximum of three prompts (one from each of the top three commands) are displayed to the user. The prompts rotate to provide the user with a diverse set of prompts across different commands. ++We recommend you to follow these guidelines to increase the chances of your app to pass the Microsoft Teams Store submission process: ++* A plugin must have at least three prompts and maximum of five prompts for each command. +* Each prompt must not exceed 128 characters. +* Two commands within the same plugin must not have identical prompts. +* Sample prompts must be generic in nature and not include custom references. For example, project names and task name. +* All sample prompts must be functional and return responses. +* Prompt must be relevant to the commands. ++The following code is an example of the `samplePrompts` property in app manifest: ++```json +composeExtensions": [ + { + "canUpdateConfiguration": true, + "botId": "bxxxxxx5-xxxx-xxxx-xxxx-4xxxxxx16599", + "commands": [ + { + "id": "orders", + "title": "Orders", + "context": [ + "Commandbox", + "Compose" + ], + "description": "Search for orders", + "semanticDescription": "Search for orders", + "samplePrompts": [ + { "text": "Search for all orders" }, ++ { "text": "Search for orders related to Contoso" }, + { "text": "Search for all pending orders" }, + { "text": "Search for all completed ordered for Fabrikam" } + ], + // ... + }, + // ... + ] + } +``` + ## Adaptive Card response Message extensions respond to a user input with an Adaptive Card. An Adaptive Card for a message extension plugin must function effectively, appear rich, and meet the following requirements: |
platform | Create Task Module | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/messaging-extensions/how-to/action-commands/create-task-module.md | private static Attachment GetAdaptiveCardAttachmentFromFile(string fileName) ## See also +* [App manifest schema for Teams](../../../resources/schem) * [Cards](../../../task-modules-and-cards/what-are-cards.md)-* [People Picker in Adaptive Cards](../../../task-modules-and-cards/cards/people-picker.md) * [Dialogs](../../../task-modules-and-cards/what-are-task-modules.md)-* [App manifest schema for Teams](../../../resources/schem) * [Define message extension action commands](define-action-command.md) * [Message extensions](../../what-are-messaging-extensions.md)+* [People Picker in Adaptive Cards](../../../task-modules-and-cards/cards/people-picker.md) +* [Bot configuration experience](../../../bots/how-to/bot-configuration-experience.md) |
platform | Localization Schema | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/resources/schema/localization-schema.md | Last updated 05/20/2019 The Microsoft Teams localization file describes language translations that are served based on the client language settings. Your file must conform to the schema hosted at [`https://developer.microsoft.com/en-us/json-schemas/teams/v1.16/MicrosoftTeams.Localization.schema.json`](https://developer.microsoft.com/en-us/json-schemas/teams/v1.16/MicrosoftTeams.Localization.schema.json). > [!TIP]-> Specify the schema at the beginning of your manifest to enable `IntelliSense` or similar support from your code editor: `"$schema": "https://developer.microsoft.com/json-schemas/teams/v1.16/MicrosoftTeams.schema.json". +> Specify the schema at the beginning of your manifest to enable `IntelliSense` or similar support from your code editor: `"$schema": "<https://developer.microsoft.com/json-schemas/teams/v1.16/MicrosoftTeams.schema.json>". ## Example The schema defines the following properties: |`composeExtensions\\[0\\]\\.commands\\[[0-9]\\]\\.parameters\\[[0-4]\\]\\.description`|String|128|Replaces the corresponding strings from the app manifest with the value provided here.|| |`composeExtensions\\[0\\]\\.commands\\[[0-9]\\]\\.parameters\\[[0-4]\\]\\.value`|String|512|Replaces the corresponding string from the app manifest with the value provided here.|| |`composeExtensions\\[0\\]\\.commands\\[[0-9]\\]\\.parameters\\[[0-4]\\]\\.choices\\[[0-9]\\]\\.title`|String|128|Replaces the corresponding strings from the app manifest with the value provided here.||+|`composeExtensions\\[0\\]\\.commands\\[[0-9]\\]\\.samplePrompts\\[[0-4]\\]\\.text`|String|128|Content for the sample prompt.|| |`composeExtensions\\[0\\]\\.commands\\[[0-9]\\]\\.taskInfo\\.title`|String|64|Replaces the corresponding strings from the app manifest with the value provided here.|| |`activities.activityTypes\\[\\b([0-9]|[1-8][0-9]|9[0-9]|1[01][0-9]|12[0-7])\\b]\\.description`|String|128|A brief description of the notification.|| |`activities.activityTypes\\[\\b([0-9]|[1-8][0-9]|9[0-9]|1[01][0-9]|12[0-7])\\b]\\.templateText`|String|128|Ex: "{actor} created task {taskId} for you".|| |
platform | Manifest Schema Dev Preview | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/resources/schema/manifest-schema-dev-preview.md | The object is an array (maximum of 1 element) with all elements of type `object` |||||| |`botId`|String|||The unique Microsoft app ID for the bot that backs the message extension, as registered with the Bot Framework. The ID can be the same as the overall [app ID](#id).| |`composeExtensionType`|String|||Type of the compose extension. Enum values are `botBased` and `apiBased`.|+|`authorization`|Object|2||Authorization related information for the API-based message extension| +|`authorization.authType`|String|||Enum of possible authorization types. Supported values are `none`, `apiSecretServiceAuth`, and `microsoftEntra`.| +|`authorization.microsoftEntraConfiguration`|Object|||Object capturing details needed to do microsoftEntra auth flow. Applicable only when auth type is `microsoftEntra`.| +|`authorization.microsoftEntraConfiguration.supportsSingleSignOn`|boolean|||A value indicating whether single sign-on is configured for the app.| +|`authorization.apiSecretServiceAuthConfiguration`|Object|||Object capturing details needed to do service auth. Applicable only when auth type is `apiSecretServiceAuth`.| +|`authorization.apiSecretServiceAuthConfiguration.apiSecretRegistrationId`|String|128 characters||Registration ID returned when developer submits the API key through Developer Portal.| |`apiSpecificationFile`|String|2048 characters||A relative file path to the api specification file in the manifest package.| |`canUpdateConfiguration`|Boolean|||A value indicating whether the configuration of a message extension can be updated by the user. <br>Default value: `true`| |`commands`|Array of object|10||Array of commands the message extension supports.| Each command item is an object with the following structure: |||||| |`id`|String|64 characters|Γ£ö∩╕Å|The ID for the command.| |`type`|String|64 characters||Type of the command. One of `query` or `action`. Default: `query`|-|`apiResponseRenderingTemplateFile`|String|2048 characters||A relative file path for api response rendering template file.| +|`samplePrompts`|array|5 |No|Property used to provide sample prompts supported by the plugin.| +|`samplePrompts.text`|string|128 characters|Γ£ö∩╕Å|Content of the sample prompt.| +|`apiResponseRenderingTemplateFile`|String|2048 characters||A relative file path for api [response rendering template](https://developer.microsoft.com/json-schemas/teams/vDevPreview/MicrosoftTeams.ResponseRenderingTemplate.schema.json) file used to format the JSON response from developerΓÇÖs API to Adaptive Card response.| +|`context`|Array of Strings|3 characters||Defines where the message extension can be invoked from. Any combination of `compose`, `commandBox`, `message`. <br>Default values: `compose, commandBox`| |`title`|String|32 characters|Γ£ö∩╕Å|The user-friendly command name.| |`description`|String|128 characters||The description that appears to users to indicate the purpose of this command.|+|`semanticDescription`|String|5000 characters||Semantic description of the command for consumption by the large language model.| |`initialRun`|Boolean|||A Boolean value that indicates whether the command runs initially with no parameters. <br>Default value: `false`|-|`context`|Array of Strings|3 characters||Defines where the message extension can be invoked from. Any combination of `compose`, `commandBox`, `message`. <br>Default values: `compose, commandBox`| |`fetchTask`|Boolean|||A Boolean value that indicates if it must fetch the dialog dynamically.| |`taskInfo`|Object|||Specify the dialog to preload when using a message extension command.| |`taskInfo.title`|String|64 characters||Initial dialog title.| Each command item is an object with the following structure: |`parameter.name`|String|64 characters|Γ£ö∩╕Å|The name of the parameter as it appears in the client. This is included in the user request. </br> For Api-based message extension, The name must map to the `parameters.name` in the OpenAPI Description. If you're referencing a property in the request body schema, then the name must map to `properties.name` or query parameters. | |`parameter.title`|String|32 characters|Γ£ö∩╕Å|User-friendly title for the parameter.| |`parameter.description`|String|128 characters||User-friendly string that describes this parameterΓÇÖs purpose.|+|`parameter.semanticDescription`|String|2000 characters||Semantic description of the parameter for consumption by the large language model.| |`parameter.inputType`|String|||Defines the type of control displayed on a dialog for `fetchTask: false`. One of `text`, `textarea`, `number`, `date`, `time`, `toggle`, `choiceset`.| |`parameter.value`|String|512 characters||Initial value for the parameter.| |`parameter.choices`|Array of objects|10||The choice options for the `choiceset`. Use only when `parameter.inputType` is `choiceset`.|-|`parameter.choices.title`|String|128 characters||Title of the choice.| -|`parameter.choices.value`|String|512 characters||Value of the choice.| -|`apiResponseRenderingTemplateFile`| Template used to format the JSON response from developerΓÇÖs API to Adaptive Card response. | +|`parameter.choices.title`|String|128 characters|Γ£ö∩╕Å|Title of the choice.| +|`parameter.choices.value`|String|512 characters|Γ£ö∩╕Å|Value of the choice.| ## scopeConstraints For more information, see [Office Add-ins manifest for Microsoft 365](/office/de ### extensions.requirements -The `extensions.requirements` property specifies the [requirement sets](/javascript/api/requirement-sets) for Microsoft 365 Add-ins. If the Microsoft 365 version doesn't support the specified requirements, then the extension wonΓÇÖt be available. Requirements are supported at the object and child object level. +The `extensions.requirements` object specifies the scopes, form factors, and Office JavaScript Library requirement sets that must be supported on the Office client in order for the add-in to be installed. Requirements are also supported on the "ribbon", "runtime", "alternates", and "autoRunEvents" child properties to selectively filter out some features of the add-in. For more information, see [Specify Office Add-in requirements in the unified manifest for Microsoft 365](/office/dev/add-ins/develop/requirements-property-unified-manifest). |Name| Type| Maximum size | Required | Description| |||||| |`requirements.capabilities`| Array | | | Identifies the requirement sets. <br>Options: `name` (required), `minVersion`, `maxVersion`|-|`requirements.capabilities.name`| String | | Γ£ö∩╕Å | Identifies the name of the requirement sets. | -|`requirements.capabilities.minVersion`| String | | | Identifies the minimum version for the requirement sets. | -|`requirements.capabilities.maxVersion`| String | | | Identifies the maximum version for the requirement sets. | +|`requirements.capabilities.name`| String | | Γ£ö∩╕Å | Identifies the name of the requirement set. | +|`requirements.capabilities.minVersion`| String | | | Identifies the minimum version for the requirement set. | +|`requirements.capabilities.maxVersion`| String | | | Identifies the maximum version for the requirement set. | |`requirements.scopes`| Array of enums | 1 | | Identifies the scopes in which the add-in can run and defines the Microsoft 365 applications in which the extension can run. For example, `mail` (Outlook). <br>Supported value: `mail` | |`requirements.formFactors`| Array of enums | | | Identifies the form factors that support the add-in. <br>Supported values: `mobile`, `desktop`| ### extensions.runtimes -The `extensions.runtimes` property configures the sets of runtimes and actions that each extension point can use. +The `extensions.runtimes` array configures the sets of runtimes and actions that each extension point can use. |Name| Type| Maximum size | Required | Description| |||||| The `extensions.runtimes` property configures the sets of runtimes and actions t |`type`| String enum | | Γ£ö∩╕Å | Specifies the type of runtime. The supported enum value for [browser-based runtime](/office/dev/add-ins/testing/runtimes#browser-runtime) is `general`. | |`code`| Object | | Γ£ö∩╕Å | Specifies the location of code for the runtime. Based on `runtime.type`, add-ins can use either a JavaScript file or an HTML page with an embedded `script` tag that specifies the URL of a JavaScript file. Both URLs are necessary in situations where the `runtime.type` is uncertain. | |`code.page`| URL | | Γ£ö∩╕Å | Specifies the URL of the web page that contains an embedded `script` tag, which specifies the URL of a JavaScript file (to be loaded in a [browser-based runtime](/office/dev/add-ins/testing/runtimes#browser-runtime)). |-|`code.script`| URL | | Γ£ö∩╕Å | Specifies the URL of the JavaScript file to be loaded in [JavaScript-only runtime](/office/dev/add-ins/testing/runtimes#javascript-only-runtime). | +|`code.script`| URL | | | Specifies the URL of the JavaScript file to be loaded in [JavaScript-only runtime](/office/dev/add-ins/testing/runtimes#javascript-only-runtime). | |`lifetime`| String enum | | | Specifies the lifetime of the runtime. Runtimes with a `short` lifetime donΓÇÖt preserve state across executions while runtimes with a `long` lifetime do. For more information, see [Runtimes in Office Add-ins](/office/dev/add-ins/testing/runtimes).| |`actions`| Array | | | Specifies the set of actions supported by the runtime. An action is either running a JavaScript function or opening a view such as a task pane.| |`actions.id`| String | 64 characters | Γ£ö∩╕Å | Specifies the ID for the action, which is passed to the code file. | The `extensions.runtimes` property configures the sets of runtimes and actions t |`actions.displayName`| String | 64 characters | | Specifies the display name of the action and it isn't the label of a button or a menu item that invokes the action (which is configured with `tabs.groups.controls.label`).| |`actions.pinnable`| Boolean | | | Specifies that a task pane supports pinning, which keeps the task pane open when the user changes the selection. <br>Default value: `false`| |`actions.view`| String | 64 characters | | Specifies the view where the page must be opened. It's used only when `actions.type` is `openPage`. |+|`actions.multiselect`| Boolean | | | Specifies whether the end user can select multiple items, such as multiple email messages, and apply the action to all of them.| +|`actions.supportsNoItemContext`| Boolean | | | Allows task pane add-ins to activate without the Reading Pane enabled or a message selected. | +|`requirements`| Object | | | Specifies the scopes, formFactors, and Office JavaScript Library requirement sets that must be supported on the Office client in order for the runtime to be included in the add-in. For more information, see [Specify Office Add-in requirements in the unified manifest for Microsoft 365](/office/dev/add-ins/develop/requirements-property-unified-manifest).| +|`requirements.capabilities`| Array | | | Identifies the requirement sets. <br>Options: `name` (required), `minVersion`, `maxVersion`| +|`requirements.capabilities.name`| String | | Γ£ö∩╕Å | Identifies the name of the requirement set. | +|`requirements.capabilities.minVersion`| String | | | Identifies the minimum version for the requirement set. | +|`requirements.capabilities.maxVersion`| String | | | Identifies the maximum version for the requirement set. | +|`requirements.scopes`| Array of enums | 1 | | Identifies the scopes in which the add-in can run and defines the Microsoft 365 applications in which the extension can run. For example, `mail` (Outlook). <br>Supported value: `mail` | +|`requirements.formFactors`| Array of enums | | | Identifies the form factors that support the add-in. <br>Supported values: `mobile`, `desktop`| To use `extensions.runtimes`, see [create add-in commands](/office/dev/add-ins/develop/create-addin-commands-unified-manifest), [configure the runtime for a task pane](/office/dev/add-ins/develop/create-addin-commands-unified-manifest#configure-the-runtime-for-the-task-pane-command), and [configure the runtime for the function command](/office/dev/add-ins/develop/create-addin-commands-unified-manifest#configure-the-runtime-for-the-function-command). The `extensions.ribbons` property provides the ability to add [add-in commands]( |Name| Type| Maximum size | Required | Description| ||||||-|`contexts`| Array | 4 | | Specifies the Microsoft 365 application window in which the ribbon customization is available to the user. Each item in the array is a member of a string array. <br>Supported values: `mailRead`, `mailCompose`, `meetingDetailsOrganizer`, `meetingDetailsAttendee`| +|`contexts`| Array | 7 | | Specifies the Microsoft 365 application window in which the ribbon customization is available to the user. Each item in the array is a member of a string array. <br>Supported values: `mailRead`, `mailCompose`, `meetingDetailsOrganizer`, `meetingDetailsAttendee`, `onlineMeetingDetailsOrganizer`, `logEventMeetingDetailsAttendee`, `default`| +|`requirements`| Object | | | Specifies the scopes, formFactors, and Office JavaScript Library requirement sets that must be supported on the Office client in order for the ribbon customization to appear. For more information, see [Specify Office Add-in requirements in the unified manifest for Microsoft 365](/office/dev/add-ins/develop/requirements-property-unified-manifest).| +|`requirements.capabilities`| Array | | | Identifies the requirement sets. <br>Options: `name` (required), `minVersion`, `maxVersion`| +|`requirements.capabilities.name`| String | | Γ£ö∩╕Å | Identifies the name of the requirement set. | +|`requirements.capabilities.minVersion`| String | | | Identifies the minimum version for the requirement set. | +|`requirements.capabilities.maxVersion`| String | | | Identifies the maximum version for the requirement set. | +|`requirements.scopes`| Array of enums | 1 | | Identifies the scopes in which the add-in can run and defines the Microsoft 365 applications in which the extension can run. For example, `mail` (Outlook). <br>Supported value: `mail` | +|`requirements.formFactors`| Array of enums | | | Identifies the form factors that support the add-in. <br>Supported values: `mobile`, `desktop`| |`tabs`| Array | |Γ£ö∩╕Å| Configures the custom tabs on the Microsoft 365 application ribbon. | |`tabs.id`| String | 64 characters | | Specifies the ID for the tab within the app.|+|`tabs.builtinTabId`| String | 64 characters | | Specifies the ID of a built-in Office ribbon tab. The possible values vary by Office host application. Currently, only Outlook add-ins are supported and the only allowed value for Outlook is "TabDefault". The default tab depends on where the Outlook add-in is surfaced, as determined in the "extensions.ribbons.contexts" property. In the main Outlook window, it is the **Home** tab, in a message window, it is the **Message** tab, and in a meeting window, it is the **Meeting** tab. | |`tabs.label`| String | 64 characters | | Specifies the text displayed for the tab.| |`tabs.position`| Object | | | Configures the position of the custom tab relative to other tabs on the ribbon.|-|`tabs.position.builtinTabId`| String | 64 characters | | Specifies the ID of the built-in tab. For more information, see [find the IDs of controls and control groups](/office/dev/add-ins/design/built-in-button-integration#find-the-ids-of-controls-and-control-groups).| -|`tabs.position.align`| String enum | | | Defines the alignment of custom tab relative to the specified built-in tab. <br>Supported values: `after`, `before`| -|`tabs.groups`| String |64 characters | | Defines the tab groups.| +|`tabs.position.builtinTabId`| String | 64 characters | Γ£ö∩╕Å | Specifies the ID of the built-in tab that the custom tab should be positioned next to. For more information, see [find the IDs of controls and control groups](/office/dev/add-ins/design/built-in-button-integration#find-the-ids-of-controls-and-control-groups).| +|`tabs.position.align`| String enum | | Γ£ö∩╕Å | Defines the alignment of custom tab relative to the specified built-in tab. <br>Supported values: `after`, `before`| +|`tabs.groups`| Array | | | Defines groups of controls on a ribbon tab on a non-mobile device. For mobile devices, see `tabs.customMobileRibbonGroups` below.| |`tabs.groups.id`| String |64 characters | | Specifies the ID for the tab group within the app. It must be different from any built-in group ID in the Microsoft 365 application and any other custom group.| |`tabs.groups.label`| String | 64 characters | | Specifies the text displayed for the group. | |`tabs.groups.icons`| Array | | | Specifies the icons displayed for the group. |-|`tabs.groups.icons.size`| Number | |Γ£ö∩╕Å| Specifies the size of the icon in pixels, enumerated as `16`,`20`,`24`,`32`,`40`,`48`,`64`,`80`. <br>Required image size: `16`, `32`, `80`. | -|`tabs.groups.icons.url`| URL| | | Specifies the absolute URL of the icon.| +|`tabs.groups.icons.size`| Number | |Γ£ö∩╕Å| Specifies the size of the icon in pixels, enumerated as `16`,`20`,`24`,`32`,`40`,`48`,`64`,`80`. <br>Required image sizes: `16`, `32`, `80`. | +|`tabs.groups.icons.url`| URL| | Γ£ö∩╕Å | Specifies the absolute URL of the icon.| |`tabs.groups.controls`| Array | | | Configures the buttons and menus in the group. | |`tabs.groups.controls.id`| String | 64 characters| Γ£ö∩╕Å | Specifies the ID for the control within the app. It must be different from any built-in control ID in the Microsoft 365 application and any other custom control. | |`tabs.groups.controls.items`| Array | | | Configures the items for a menu control. | |`tabs.groups.controls.items.id`| String | | Γ£ö∩╕Å | Specifies the ID for the items within the app. |-|`tabs.groups.controls.items.type`| String enum | | Γ£ö∩╕Å | Defines the control items type. <br>Supported value: `menuItem`| +|`tabs.groups.controls.items.type`| String enum | | Γ£ö∩╕Å | Defines the control items type. <br>Supported values: `menu`, `button`| |`tabs.groups.controls.items.label`| String | 64 characters| Γ£ö∩╕Å | Specifies the text displayed for the items. | |`tabs.groups.controls.items.icons`| Array | | | Configures the icons for the custom item.|-|`tabs.groups.controls.items.icons.size`| Number | |Γ£ö∩╕Å| Specifies the size of the icon in pixels, enumerated as `16`,`20`,`24`,`32`,`40`,`48`,`64`,`80`. <br>Required image size: `16`, `32`, `80`. | -|`tabs.groups.controls.items.icons.url`| URL| | | Specifies the absolute URL of the icon.| +|`tabs.groups.controls.items.icons.size`| Number | |Γ£ö∩╕Å| Specifies the size of the icon in pixels, enumerated as `16`,`20`,`24`,`32`,`40`,`48`,`64`,`80`. <br>Required image sizes: `16`, `32`, `80`. | +|`tabs.groups.controls.items.icons.url`| URL| | Γ£ö∩╕Å | Specifies the absolute URL of the icon.| |`tabs.groups.controls.items.supertip`| | |Γ£ö∩╕Å| Configures a supertip for the custom item. A supertip is a UI feature that displays a brief box of help information about a control when the cursor hovers over it. The box may contain multiple lines of text. | |`tabs.groups.controls.items.supertip.title`| String | 64 characters | Γ£ö∩╕Å | Specifies the title text of the supertip.| |`tabs.groups.controls.items.supertip.description`| String | 128 characters | Γ£ö∩╕Å | Specifies the description of the supertip.| |`tabs.groups.controls.items.actionId`| String | 64 characters | Γ£ö∩╕Å | Specifies the ID of the action that is taken when a user selects the control or menu item. The `actionId` must match with `runtime.actions.id`. | |`tabs.groups.controls.items.enabled`| Boolean | | | Indicates whether the control is initially enabled. <br>Default value: `true`|-|`tabs.groups.controls.items.overriddenByRibbonApi`| Boolean | | | Specifies whether a group, button, menu, or menu item hidden on application and platform combinations which support the API ([Office.ribbon.requestCreateControls](/javascript/api/office/office.ribbon#office-office-ribbon-requestcreatecontrols-member(1))) that installs custom contextual tabs on the ribbon. <br>Default value: `false`| +|`tabs.groups.controls.items.overriddenByRibbonApi`| Boolean | | | Specifies whether a group, button, menu, or menu item hidden on application and platform combinations, which support the API ([Office.ribbon.requestCreateControls](/javascript/api/office/office.ribbon#office-office-ribbon-requestcreatecontrols-member(1))) that installs custom contextual tabs on the ribbon. <br>Default value: `false`| |`tabs.groups.controls.type`| String | | Γ£ö∩╕Å | Defines the control type. <br>Supported values: `button`, `menu`|-|`tabs.groups.controls.builtinControlId`| String | 64 characters | Γ£ö∩╕Å | Specifies the ID of the existing Microsoft 365 control. For more information, see [find the IDs of controls and control groups](/office/dev/add-ins/design/built-in-button-integration#find-the-ids-of-controls-and-control-groups).| +|`tabs.groups.controls.builtinControlId`| String | 64 characters | Γ£ö∩╕Å | Specifies the ID of an existing Microsoft 365 control. For more information, see [find the IDs of controls and control groups](/office/dev/add-ins/design/built-in-button-integration#find-the-ids-of-controls-and-control-groups).| |`tabs.groups.controls.label`| String | 64 characters | Γ£ö∩╕Å | Specifies the text displayed for the control.|-|`tabs.groups.controls.icons`| Array | | | Defines the icon(s) for the control. | +|`tabs.groups.controls.icons`| Array | | Γ£ö∩╕Å | Defines the icons for the control. There must be at least three child objects; one each with `size` properties of `16`, `32`, and `80` pixels. | |`tabs.groups.controls.icons.size`| Number | | Γ£ö∩╕Å | Specifies the size of the icon in pixels, enumerated as `16`,`20`,`24`,`32`,`40`,`48`,`64`,`80`. <br> Required image size: `16`, `32`, `80`| |`tabs.groups.controls.icons.url`| URL| | | Specifies the absolute URL to the icon.| |`tabs.groups.controls.supertip`| Object | | Γ£ö∩╕Å | Configures a supertip for the control. | |`tabs.groups.controls.supertip.title`| String | 64 characters | Γ£ö∩╕Å |Specifies the title text of the supertip.| |`tabs.groups.controls.supertip.description`| String | 128 characters | Γ£ö∩╕Å | Specifies the description of the supertip.|-|`tabs.groups.controls.actionId`| String | 64 characters | Γ£ö∩╕Å | Specifies the ID of the action that is taken when a user selects the control. The `actionId` must match with `runtime.actions.id`.| +|`tabs.groups.controls.actionId`| String | 64 characters | | Required if the control type is `button`. Do not use if the control type is `menu`. Specifies the ID of the action that is taken when a user selects the control. The `actionId` must match the `runtime.actions.id` property of an action in the `runtimes` object.| |`tabs.groups.controls.enabled`| Boolean | | | Indicates whether the control is initially enabled. <br>Default value: `true`|-|`tabs.groups.controls.overriddenByRibbonApi`| Boolean | | | Specifies whether a group, button, menu, or menu item hidden on application and platform combinations which support the API ([Office.ribbon.requestCreateControls](/javascript/api/office/office.ribbon#office-office-ribbon-requestcreatecontrols-member(1))) that installs custom contextual tabs on the ribbon. <br>Default value: `false`| +|`tabs.groups.controls.overriddenByRibbonApi`| Boolean | | | Specifies whether a group, button, menu, or menu item is hidden on application and platform combinations which support the API ([Office.ribbon.requestCreateControls](/javascript/api/office/office.ribbon#office-office-ribbon-requestcreatecontrols-member(1))) that installs custom contextual tabs on the ribbon. <br>Default value: `false`| |`tabs.groups.builtinGroupId`| String | 64 characters | | Specifies the ID of a built-in group. For more information, see [find the IDs of controls and control groups](/office/dev/add-ins/design/built-in-button-integration#find-the-ids-of-controls-and-control-groups).|+|`tabs.customMobileRibbonGroups`| Array | 10 | | Defines groups of controls on the default tab of the ribbon on a mobile device. This array property can only be present on tab objects that have a `tabs.builtinTabId` property that is set to "DefaultTab". For non-mobile devices, see `tabs.groups` above.| +|`tabs.customMobileRibbonGroups.id` | String | 250 characters | Γ£ö∩╕Å | Specifies the ID of the group. It must be different from any built-in group ID in the Microsoft 365 application and any other custom group.| +|`tabs.customMobileRibbonGroups.label` | String | 32 characters | Γ£ö∩╕Å | Specifies the label on the group. | +|`tabs.customMobileRibbonGroups.controls` | Array | 20 | Γ£ö∩╕Å | Defines the controls in the group. Only mobile buttons are supported.| +|`tabs.customMobileRibbonGroups.controls.id` | String | 250 characters | Γ£ö∩╕Å | Specifies the ID of the control such as "msgReadFunctionButton".| +|`tabs.customMobileRibbonGroups.controls.type` | String enum | | Γ£ö∩╕Å | Specifies the type of control. Currently only "MobileButton" is supported.| +|`tabs.customMobileRibbonGroups.controls.label` | String | 32 characters | Γ£ö∩╕Å | Specifies the label on the control.| +|`tabs.customMobileRibbonGroups.controls.actionId` | String | 64 characters |Γ£ö∩╕Å | Specifies the ID of the action that is taken when a user selects the control. The `actionId` must match the `runtime.actions.id` property of an action in the `runtimes` object.| +|`tabs.customMobileRibbonGroups.controls.icons` | Array | 9 | Γ£ö∩╕Å | Specifies the icons that will appear on the control depending on the dimensions and DPI of the mobile device screen. There must be exactly 9 icons.| +|`tabs.customMobileRibbonGroups.controls.icons.size` | Number enum | | Γ£ö∩╕Å | Size in pixels of the icon. The possible sizes are 25, 32, and 48. There must be exactly one of each size for each possible value of the icons's `scale` property. | +|`tabs.customMobileRibbonGroups.controls.icons.url` | String | 2048 characters | Γ£ö∩╕Å | The full, absolute URL of the icon's image file. | +|`tabs.customMobileRibbonGroups.controls.icons.scale` | Number enum | | Γ£ö∩╕Å | Specifies the UIScreen.scale property for iOS devices. The possible values are 1, 2, and 3. There must be exactly one of each value for each possible value of the icons's `size` property. | To use `extensions.ribbons`, see [create add-in commands](/office/dev/add-ins/develop/create-addin-commands-unified-manifest), [configure the UI for the task pane command](/office/dev/add-ins/develop/create-addin-commands-unified-manifest#configure-the-ui-for-the-task-pane-command), and [configure the UI for the function command](/office/dev/add-ins/develop/create-addin-commands-unified-manifest#configure-the-ui-for-the-function-command). The `extensions.autoRunEvents` property defines event-based activation extension |Name| Type| Maximum size | Required | Description| ||||||-|`events`| Array | | Γ£ö∩╕Å | Configures the event that cause actions in an Outlook Add-in to run automatically. For example, see [use smart alerts and the `OnMessageSend` and `OnAppointmentSend` events in your Outlook Add-ins](/office/dev/add-ins/outlook/smart-alerts-onmessagesend-walkthrough?tabs=jsonmanifest).| +|`events`| Array |20 | Γ£ö∩╕Å | Configures the event that cause actions in an Outlook Add-in to run automatically. For example, see [use smart alerts and the `OnMessageSend` and `OnAppointmentSend` events in your Outlook Add-ins](/office/dev/add-ins/outlook/smart-alerts-onmessagesend-walkthrough?tabs=jsonmanifest).| |`events.type`| String | 64 characters | | Specifies the type of event. For supported types, see [supported events](/office/dev/add-ins/outlook/autolaunch?tabs=xmlmanifest#supported-events).| |`events.actionId`| String | 64 characters | | Identifies the action that is taken when the event fires. The `actionId` must match with `runtime.actions.id`. | |`events.options`| Object | | | Configures how Outlook responds to the event.| |`events.options.sendMode`| String | | Γ£ö∩╕Å | Specifies the actions to take during a mail send action. <br>Supported values: `promptUser`, `softBlock`, `block`. For more information, see [available send mode options](/office/dev/add-ins/outlook/smart-alerts-onmessagesend-walkthrough?tabs=jsonmanifest#available-send-mode-options).|+|`requirements`| Object | | | Specifies the scopes, formFactors, and Office JavaScript Library requirement sets that must be supported on the Office client in order for the event handling code to run. For more information, see [Specify Office Add-in requirements in the unified manifest for Microsoft 365](/office/dev/add-ins/develop/requirements-property-unified-manifest).| +|`requirements.capabilities`| Array | | | Identifies the requirement sets. <br>Options: `name` (required), `minVersion`, `maxVersion`| +|`requirements.capabilities.name`| String | | Γ£ö∩╕Å | Identifies the name of the requirement set. | +|`requirements.capabilities.minVersion`| String | | | Identifies the minimum version for the requirement set. | +|`requirements.capabilities.maxVersion`| String | | | Identifies the maximum version for the requirement set. | +|`requirements.scopes`| Array of enums | 1 | | Identifies the scopes in which the add-in can run and defines the Microsoft 365 applications in which the extension can run. For example, `mail` (Outlook). <br>Supported value: `mail` | +|`requirements.formFactors`| Array of enums | | | Identifies the form factors that support the add-in. <br>Supported values: `mobile`, `desktop`| ### extensions.alternates The `extensions.alternates` property is used to hide or prioritize specific in-m |`hide.storeOfficeAddin`| Object | | | Specifies a Microsoft 365 Add-in available in Microsoft AppSource. | |`hide.storeOfficeAddin.officeAddinId`| String | 64 characters | Γ£ö∩╕Å | Specifies the ID of the in-market add-in to hide. The GUID is taken from the app manifest `id` property if the in-market add-in uses the JSON app manifest. The GUID is taken from the `<Id>` element if the in-market add-in uses the XML app manifest. | |`hide.storeOfficeAddin.assetId`| String | 64 characters | Γ£ö∩╕Å | Specifies the AppSource asset ID of the in-market add-in to hide.|-|`hide.customOfficeAddin`| | | | Configures how to hide an in-market add-in that isn't distributed through AppSource.| +|`hide.customOfficeAddin`| Object | | | Configures how to hide an in-market add-in that isn't distributed through AppSource.| |`hide.customOfficeAddin.officeAddinId`|String | 64 characters | Γ£ö∩╕Å | Specifies the ID of the in-market add-in to hide. The GUID is taken from the app manifest `id` property if the in-market add-in uses the JSON app manifest. The GUID is taken from the `<Id>` element if the in-market add-in uses the XML app manifest. |+|`requirements`| Object | | | Specifies the scopes, formFactors, and Office JavaScript Library requirement sets that must be supported on the Office client in order for the "hide", "prefer", or "alternateIcons" properties to take effect. For more information, see [Specify Office Add-in requirements in the unified manifest for Microsoft 365](/office/dev/add-ins/develop/requirements-property-unified-manifest).| +|`requirements.capabilities`| Array | | | Identifies the requirement sets. <br>Options: `name` (required), `minVersion`, `maxVersion`| +|`requirements.capabilities.name`| String | | Γ£ö∩╕Å | Identifies the name of the requirement set. | +|`requirements.capabilities.minVersion`| String | | | Identifies the minimum version for the requirement set. | +|`requirements.capabilities.maxVersion`| String | | | Identifies the maximum version for the requirement set. | +|`requirements.scopes`| Array of enums | 1 | | Identifies the scopes in which the add-in can run and defines the Microsoft 365 applications in which the extension can run. For example, `mail` (Outlook). <br>Supported value: `mail` | +|`requirements.formFactors`| Array of enums | | | Identifies the form factors that support the add-in. <br>Supported values: `mobile`, `desktop`| +|`alternateIcons`| Object | | | Specifies the main icons that are used to represent the add-in on older versions of Office. This property is **required** if the Office add-in is to be installable in Office on Mac, perpetual Office licenses, and Microsoft 365 subscription versions of Office on Windows earlier than 2304 (Build 16320.00000).| +|`alternateIcons.icon`| Object | | Γ£ö∩╕Å | Specifies properties of the image file used to represent the add-in. | +|`alternateIcons.icon.size`| Number enum | | Γ£ö∩╕Å | This property is reserved for future use. The value must be 64.| +|`alternateIcons.icon.url`| String | 2048 characters | Γ£ö∩╕Å | Specifies the full, absolute URL of the image file that is used to represent the add-in. Icon image must be 64 x 64 pixels and use one of the following file formats: GIF, JPG, PNG, EXIF, BMP, TIFF.| +|`alternateIcons.highResolutionIcon`| Object | | Γ£ö∩╕Å | Specifies properties of the image file used to represent the add-in on high DPI screens. | +|`alternateIcons.highResolutionIcon.size`| Number enum | | Γ£ö∩╕Å | This property is reserved for future use. The value must be 64 (not 128). | +|`alternateIcons.highResolutionIcon.url`| String | 2048 characters | Γ£ö∩╕Å | Specifies the full, absolute URL of the image file that is used to represent the add-in on high DPI screens. Icon image must be 128 x 128 pixels and use one of the following file formats: GIF, JPG, PNG, EXIF, BMP, TIFF.| ## actions The object is an array of action objects. This block is required only for soluti ### actions.handlers -Defines the handlers of the Action. The handlers is an array of handler objects. Each Action must have at least one handler. +Defines the handlers of the Action. The handlers are an array of handler objects. Each Action must have at least one handler. |Name| Type| Maximum size | Required | Description| |||||| The supported object types that can trigger this Action. |Name| Type| Maximum size | Required | Description| |||||| |`file`| Object | | | Supported file types. |-|`file.extensions`| Array of strings | | | Array of strings. File extensions of the file types the Action can trigger. For example, pdf and docx.| +|`file.extensions`| Array of strings | | | Array of strings. File extensions of the file type the Action can trigger. For example, pdf and docx.| ### actions.handlers.pageInfo Required if the handler type is `openPage`. Object containing metadata of the pa |`PageId`| String | | | Maps to the `EntityId` of the static tab. | |`SubPageId`| String | | | Maps to the `SubEntityId` of the static tab. | +## dashboardCards ++**Optional** – Array ++Defines a list of cards that can be pinned to a dashboard, such as Microsoft Viva Connections, to provide a summarized view of app information. For more information on creating cards for Viva Connections Dashboard, see [overview of Bot Powered Adaptive Card Extensions](/sharepoint/dev/spfx/viva/bot-powered/overview-bot-powered-aces). ++The `dashboardCards` property is an array of elements of the type `object`. ++### dashboardCards.dashboardCard ++Defines a single dashboard card and its properties. ++|Name| Type| Maximum size | Required | Description| +|||||| +|`id`| String | | Γ£ö∩╕Å | A unique identifier for this dashboard card. The ID must be a GUID. | +|`displayName`| String | 255 characters | Γ£ö∩╕Å | Display name of the card.| +|`description`| String | 255 characters | Γ£ö∩╕Å | Description of the card.| +|`pickerGroupId`| String | | Γ£ö∩╕Å | ID of the group in the card picker. The ID must be a GUID. | +|`icon`| Object | | | Specifies the icon for the card. | +|`contentSource`| Object | | Γ£ö∩╕Å | Specifies the source of the card's content | +|`defaultSize`| String | | Γ£ö∩╕Å | Rendering size for the dashboard card. Options: `medium` or `large`. | ++### dashboardCards.dashboardCard.icon ++Defines the icon properties of a given dashboard card. ++|Name| Type| Maximum size | Required | Description| +|||||| +|`iconUrl`| String | 2048 characters | | Location of the icon for the card, to be displayed in the toolbox and card bar. | +|`officeUIFabricIconName`| String | 255 characters | | Office UI Fabric or Fluent UI icon friendly name for the card. This value is used if *iconUrl* is not specified. | ++### dashboardCards.dashboardCard.contentSource ++Defines the content source of a given dashboard card. ++|Name| Type| Maximum size | Required | Description| +|||||| +|`sourceType`| String | | | Represents the source of a card's content. Options: `bot`. +|`botConfiguration`| Object | | | The configuration for the bot source. Required if the `sourceType` is set to `bot`. | ++#### dashboardCards.dashboardCard.contentSource.botConfiguration ++|Name| Type| Maximum size | Required | Description| +|||||| +|`botId`| String | | | The unique Microsoft app ID for the bot as registered with the Bot Framework. The ID must be a GUID. | + ## See also * [Understand the Microsoft Teams app structure](~/concepts/design/app-structure.md) |
platform | Manifest Schema | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/resources/schema/manifest-schema.md | Last updated 02/09/2023 # App manifest schema -The app manifest (previously called Teams app manifest) describes how your app integrates into the Microsoft Teams product. Your app manifest must conform to the schema hosted at [`https://developer.microsoft.com/json-schemas/teams/v1.16/MicrosoftTeams.schema.json`](https://developer.microsoft.com/json-schemas/teams/v1.16/MicrosoftTeams.schema.json). Previous versions 1.0, 1.1,...,1.15, and the current version is 1.16 are each supported (using "v1.x" in the URL). +The app manifest (previously called Teams app manifest) describes how your app integrates into the Microsoft Teams product. Your app manifest must conform to the schema hosted at [`https://developer.microsoft.com/json-schemas/teams/v1.17/MicrosoftTeams.schema.json`](https://developer.microsoft.com/json-schemas/teams/v1.17/MicrosoftTeams.schema.json). Previous versions 1.0, 1.1,...,1.16, and the current version is 1.17 are each supported (using "v1.x" in the URL). For more information on the changes made in each version, see [app manifest change log](https://github.com/OfficeDev/microsoft-teams-app-schema/releases) and for previous versions, see [app manifest versions](https://github.com/microsoft/json-schemas/tree/main/teams). The following table lists TeamsJS version and app manifest versions as per different app scenarios: The following is the sample app manifest schema: ```json { "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.16/MicrosoftTeams.schema.json",- "manifestVersion": "1.16", + "manifestVersion": "1.17", "version": "1.0.0", "id": "%MICROSOFT-APP-ID%", "localizationInfo": { The item is an array (maximum of only one element—currently only one bot i |`supportsCalling`|Boolean|||A value indicating where a bot supports audio calling. **IMPORTANT**: This property is currently experimental. Experimental properties might be incomplete and might undergo changes before they're fully available. The property is provided for testing and exploration purposes only and must not be used in production applications. Default: **`false`**| |`supportsVideo`|Boolean|||A value indicating where a bot supports video calling. **IMPORTANT**: This property is currently experimental. Experimental properties might be incomplete and might undergo changes before they're fully available. The property is provided for testing and exploration purposes only and must not be used in production applications. Default: **`false`**| +### bots.configuration ++|Name| Type| Maximum size | Required | Description| +|||||| +|`team.fetchTask`|Boolean||Γ£ö∩╕Å|A boolean value that indicates if it should fetch dialog (referred as task module in TeamsJS v1.x) dynamically. <br>Default value: `false`| +|`team.taskInfo.title`|String|64 characters|Γ£ö∩╕Å|Initial dialog title.| +|`team.taskInfo.width`|String|16||The dialog width is either a number in pixels or default layout such as `large`, `medium`, or `small`.| +|`team.taskInfo.height`|String|16||The dialog height is either a number in pixels or default layout such as `large`, `medium`, or `small`.| +|`team.taskInfo.url`|String|2048 characters||Initial webview URL.| +|`groupChat.fetchTask`|Boolean||Γ£ö∩╕Å|A boolean value that indicates if it should fetch dialog dynamically. <br>Default value: `false`| +|`groupChat.taskInfo`|Object|||Dialog to be launched when fetch task set to false.<br>Default value: `false`| +|`groupChat.taskInfo.title`|String|64 characters|Γ£ö∩╕Å|Initial dialog title.| +|`groupChat.taskInfo.width`|String|16||The dialog width is either a number in pixels or default layout such as `large`, `medium`, or `small`.| +|`groupChat.taskInfo.height`|String|16||The dialog height is either a number in pixels or default layout such as `large`, `medium`, or `small`.| +|`groupChat.taskInfo.url`|String|2048 characters||Initial webview URL.| + ### bots.commandLists A list of commands that your bot can recommend to users. The object is an array (maximum of two elements) with all elements of type `object`; you must define a separate command list for each scope that your bot supports. For more information, see [Bot menus](~/bots/how-to/create-a-bot-commands-menu.md). The item is an array (maximum of one element) with all elements of type `object` |Name| Type | Maximum Size | Required | Description | ||||||-|`botId`|String||Γ£ö∩╕Å|The unique Microsoft app ID for the bot that backs the message extension, as registered with the Bot Framework. The ID can be the same as the overall App ID.| +|`botId`|String|||The unique Microsoft app ID for the bot that backs the message extension, as registered with the Bot Framework. The ID can be the same as the overall App ID.| +|`composeExtensionType`|String||Γ£ö∩╕Å|Type of the compose extension. Enum values are `botBased` and `apiBased`.| +|`authorization`|Object|2||Authorization related information for the API-based message extension| +|`authorization.authType`|String|||Enum of possible authorization types. Supported values are `none`, `apiSecretServiceAuth`, and `microsoftEntra`.| +|`authorization.microsoftEntraConfiguration`|Object|||Object capturing details needed to do microsoftEntra auth flow. Applicable only when auth type is `microsoftEntra`.| +|`authorization.microsoftEntraConfiguration.supportsSingleSignOn`|boolean|||A value indicating whether single sign-on is configured for the app.| +|`authorization.apiSecretServiceAuthConfiguration`|Object|||Object capturing details needed to do service auth. Applicable only when auth type is `apiSecretServiceAuth`.| +|`authorization.apiSecretServiceAuthConfiguration.apiSecretRegistrationId`|String|128 characters||Registration ID returned when developer submits the API key through Developer Portal.| +|`apiSpecificationFile`|String|2048 characters||A relative file path to the API specification file in the manifest package.| +|`canUpdateConfiguration`|Boolean|||A value indicating whether the configuration of a message extension can be updated by the user. <br>Default value: `true`| |`commands`|Array of objects|10|Γ£ö∩╕Å|Array of commands the message extension supports.| |`canUpdateConfiguration`|Boolean|||A value indicating whether the configuration of a message extension can be updated by the user. Default: **false**.| |`messageHandlers`|Array of objects|5||A list of handlers that allow apps to be invoked when certain conditions are met.| Each command item is an object with the following structure: |Name| Type| Maximum size | Required | Description| |||||| |`id`|String|64 characters|Γ£ö∩╕Å|The ID for the command.|-|`title`|String|32 characters|Γ£ö∩╕Å|The user-friendly command name.| |`type`|String|||Type of the command. One of `query` or `action`. Default: **query**.|+|`samplePrompts`|array|5 |No|Property used to provide sample prompts supported by the plugin.| +|`samplePrompts.text`|string|128 characters|Γ£ö∩╕Å|Content of the sample prompt.| +|`apiResponseRenderingTemplateFile`|String|2048 characters||A relative file path for api [response rendering template](https://developer.microsoft.com/json-schemas/teams/vDevPreview/MicrosoftTeams.ResponseRenderingTemplate.schema.json) file used to format the JSON response from developerΓÇÖs API to Adaptive Card response.| +|`context`|Array of Strings|3 characters||Defines where the message extension can be invoked from. Any combination of `compose`, `commandBox`, `message`. <br>Default values: `compose, commandBox`| +|`title`|String|32 characters|Γ£ö∩╕Å|The user-friendly command name.| |`description`|String|128 characters||The description that appears to users to indicate the purpose of this command.|+|`semanticDescription`|String|5000 characters||Semantic description of the command for consumption by the large language model.| |`initialRun`|Boolean|||A Boolean value indicates whether the command runs initially with no parameters. Default is **false**.|-|`context`|Array of strings|3||Defines where the message extension can be invoked from. Any combination of`compose`,`commandBox`,`message`. Default is `["compose","commandBox"]`.| |`fetchTask`|Boolean|||A Boolean value that indicates if it must fetch the dialog (referred as task module in TeamsJS v1.x) dynamically. Default is **false**.| |`taskInfo`|Object|||Specify the dialog to pre-load when using a message extension command.| |`taskInfo.title`|String|64 characters||Initial dialog title.| Each command item is an object with the following structure: |`taskInfo.height`|String|||Dialog height - either a number in pixels or default layout such as 'large', 'medium', or 'small'.| |`taskInfo.url`|String|||Initial webview URL.| |`parameters`|Array of object|5 items||The list of parameters the command takes. Minimum: 1; maximum: 5.|-|`parameters.name`|String|64 characters|Γ£ö∩╕Å|The name of the parameter as it appears in the client. The parameter name is included in the user request.| -|`parameters.title`|String|32 characters|Γ£ö∩╕Å|User-friendly title for the parameter.| -|`parameters.description`|String|128 characters||User-friendly string that describes this parameterΓÇÖs purpose.| -|`parameters.value`|String|512 characters||Initial value for the parameter. Currently the value isn't supported| -|`parameters.inputType`|String|||Defines the type of control displayed on a dialog for`fetchTask: false` . Input value can only be one of `text, textarea, number, date, time, toggle, choiceset` .| -|`parameters.choices`|Array of objects|10 items||The choice options for the`choiceset`. Use only when`parameter.inputType` is `choiceset`.| -|`parameters.choices.title`|String|128 characters|Γ£ö∩╕Å|Title of the choice.| -|`parameters.choices.value`|String|512 characters|Γ£ö∩╕Å|Value of the choice.| +|`parameter.name`|String|64 characters|Γ£ö∩╕Å|The name of the parameter as it appears in the client. The parameter name is included in the user request.| +|`parameter.title`|String|32 characters|Γ£ö∩╕Å|User-friendly title for the parameter.| +|`parameter.description`|String|128 characters||User-friendly string that describes this parameterΓÇÖs purpose.| +|`parameter.semanticDescription`|String|2000 characters||Semantic description of the parameter for consumption by the large language model.| +|`parameter.value`|String|512 characters||Initial value for the parameter. Currently the value isn't supported| +|`parameter.inputType`|String|||Defines the type of control displayed on a dialog for`fetchTask: false` . Input value can only be one of `text, textarea, number, date, time, toggle, choiceset` .| +|`parameter.choices`|Array of objects|10 items||The choice options for the`choiceset`. Use only when`parameter.inputType` is `choiceset`.| +|`parameter.choices.title`|String|128 characters|Γ£ö∩╕Å|Title of the choice.| +|`parameter.choices.value`|String|512 characters|Γ£ö∩╕Å|Value of the choice.| ## permissions Delegated permissions allow the app to access data on behalf of the signed-in us |`MicrophoneStream.Read.User`| Allows the app to read user's microphone stream.| |`MeetingParticipantReaction.Read.User`| Allows the app to read user's reactions while participating in a meeting.| +## extensions ++**Optional** – Object ++The `extensions` property specifies Outlook Add-ins within an app manifest and simplify the distribution and acquisition across the Microsoft 365 ecosystem. Each app supports only one extension. ++|Name| Type| Maximum size | Required | Description| +|||||| +|`requirements`| Object | | | Specifies the set of client or host requirements for the extension. | +|`runtimes`| Array | | | Configures the set of runtimes and actions that can be used by each extension point. For more information, see [runtimes in Office Add-ins](/office/dev/add-ins/testing/runtimes). | +|`ribbons`| Array | | | Defines the ribbons extension point. | +|`autoRunEvents`| Array | | | Defines the event-based activation extension point. | +|`alternates`| Array | | | Specifies the relationship to alternate existing Microsoft 365 solutions. It's used to hide or prioritize add-ins from the same publisher with overlapping functionality. | +|`audienceClaimUrl`| String | 2048 characters | | Specifies the URL for your extension and is used to validate Exchange user identity tokens. For more information, see [inside the Exchange identity token](/office/dev/add-ins/outlook/inside-the-identity-token)| ++For more information, see [Office Add-ins manifest for Microsoft 365](/office/dev/add-ins/develop/unified-manifest-overview). ++### extensions.requirements ++The `extensions.requirements` object specifies the scopes, form factors, and Office JavaScript Library requirement sets that must be supported on the Office client in order for the add-in to be installed. Requirements are also supported on the "ribbon", "runtime", "alternates", and "autoRunEvents" child properties to selectively filter out some features of the add-in. For more information, see [Specify Office Add-in requirements in the unified manifest for Microsoft 365](/office/dev/add-ins/develop/requirements-property-unified-manifest). ++|Name| Type| Maximum size | Required | Description| +|||||| +|`requirements.capabilities`| Array | | | Identifies the requirement sets. <br>Options: `name` (required), `minVersion`, `maxVersion`| +|`requirements.capabilities.name`| String | | Γ£ö∩╕Å | Identifies the name of the requirement set. | +|`requirements.capabilities.minVersion`| String | | | Identifies the minimum version for the requirement set. | +|`requirements.capabilities.maxVersion`| String | | | Identifies the maximum version for the requirement set. | +|`requirements.scopes`| Array of enums | 1 | | Identifies the scopes in which the add-in can run and defines the Microsoft 365 applications in which the extension can run. For example, `mail` (Outlook). <br>Supported value: `mail` | +|`requirements.formFactors`| Array of enums | | | Identifies the form factors that support the add-in. <br>Supported values: `mobile`, `desktop`| ++### extensions.runtimes ++The `extensions.runtimes` array configures the sets of runtimes and actions that each extension point can use. ++|Name| Type| Maximum size | Required | Description| +|||||| +|`id`| String | 64 characters | Γ£ö∩╕Å | Specifies the ID for runtime. | +|`type`| String enum | | Γ£ö∩╕Å | Specifies the type of runtime. The supported enum value for [browser-based runtime](/office/dev/add-ins/testing/runtimes#browser-runtime) is `general`. | +|`code`| Object | | Γ£ö∩╕Å | Specifies the location of code for the runtime. Based on `runtime.type`, add-ins can use either a JavaScript file or an HTML page with an embedded `script` tag that specifies the URL of a JavaScript file. Both URLs are necessary in situations where the `runtime.type` is uncertain. | +|`code.page`| URL | | Γ£ö∩╕Å | Specifies the URL of the web page that contains an embedded `script` tag, which specifies the URL of a JavaScript file (to be loaded in a [browser-based runtime](/office/dev/add-ins/testing/runtimes#browser-runtime)). | +|`code.script`| URL | | | Specifies the URL of the JavaScript file to be loaded in [JavaScript-only runtime](/office/dev/add-ins/testing/runtimes#javascript-only-runtime). | +|`lifetime`| String enum | | | Specifies the lifetime of the runtime. Runtimes with a `short` lifetime donΓÇÖt preserve state across executions while runtimes with a `long` lifetime do. For more information, see [Runtimes in Office Add-ins](/office/dev/add-ins/testing/runtimes).| +|`actions`| Array | | | Specifies the set of actions supported by the runtime. An action is either running a JavaScript function or opening a view such as a task pane.| +|`actions.id`| String | 64 characters | Γ£ö∩╕Å | Specifies the ID for the action, which is passed to the code file. | +|`actions.type`| String | | Γ£ö∩╕Å | Specifies the type of action. The `executeFunction` type runs a JavaScript function without waiting for it to finish and the `openPage` type opens a page in a given view. | +|`actions.displayName`| String | 64 characters | | Specifies the display name of the action and it isn't the label of a button or a menu item that invokes the action (which is configured with `tabs.groups.controls.label`).| +|`actions.pinnable`| Boolean | | | Specifies that a task pane supports pinning, which keeps the task pane open when the user changes the selection. <br>Default value: `false`| +|`actions.view`| String | 64 characters | | Specifies the view where the page must be opened. It's used only when `actions.type` is `openPage`. | +|`actions.multiselect`| Boolean | | | Specifies whether the end user can select multiple items, such as multiple email messages, and apply the action to all of them.| +|`actions.supportsNoItemContext`| Boolean | | | Allows task pane add-ins to activate without the Reading Pane enabled or a message selected. | +|`requirements`| Object | | | Specifies the scopes, formFactors, and Office JavaScript Library requirement sets that must be supported on the Office client in order for the runtime to be included in the add-in. For more information, see [Specify Office Add-in requirements in the unified manifest for Microsoft 365](/office/dev/add-ins/develop/requirements-property-unified-manifest).| +|`requirements.capabilities`| Array | | | Identifies the requirement sets. <br>Options: `name` (required), `minVersion`, `maxVersion`| +|`requirements.capabilities.name`| String | | Γ£ö∩╕Å | Identifies the name of the requirement set. | +|`requirements.capabilities.minVersion`| String | | | Identifies the minimum version for the requirement set. | +|`requirements.capabilities.maxVersion`| String | | | Identifies the maximum version for the requirement set. | +|`requirements.scopes`| Array of enums | 1 | | Identifies the scopes in which the add-in can run and defines the Microsoft 365 applications in which the extension can run. For example, `mail` (Outlook). <br>Supported value: `mail` | +|`requirements.formFactors`| Array of enums | | | Identifies the form factors that support the add-in. <br>Supported values: `mobile`, `desktop`| ++To use `extensions.runtimes`, see [create add-in commands](/office/dev/add-ins/develop/create-addin-commands-unified-manifest), [configure the runtime for a task pane](/office/dev/add-ins/develop/create-addin-commands-unified-manifest#configure-the-runtime-for-the-task-pane-command), and [configure the runtime for the function command](/office/dev/add-ins/develop/create-addin-commands-unified-manifest#configure-the-runtime-for-the-function-command). ++### extensions.ribbons ++The `extensions.ribbons` property provides the ability to add [add-in commands](/office/dev/add-ins/design/add-in-commands) (buttons and menu items) to the Microsoft 365 application's ribbon. The ribbon definition is selected from the array based on the requirements and first-of order. ++|Name| Type| Maximum size | Required | Description| +|||||| +|`contexts`| Array | 7 | | Specifies the Microsoft 365 application window in which the ribbon customization is available to the user. Each item in the array is a member of a string array. <br>Supported values: `mailRead`, `mailCompose`, `meetingDetailsOrganizer`, `meetingDetailsAttendee`, `onlineMeetingDetailsOrganizer`, `logEventMeetingDetailsAttendee`, `default`| +|`requirements`| Object | | | Specifies the scopes, formFactors, and Office JavaScript Library requirement sets that must be supported on the Office client in order for the ribbon customization to appear. For more information, see [Specify Office Add-in requirements in the unified manifest for Microsoft 365](/office/dev/add-ins/develop/requirements-property-unified-manifest).| +|`requirements.capabilities`| Array | | | Identifies the requirement sets. <br>Options: `name` (required), `minVersion`, `maxVersion`| +|`requirements.capabilities.name`| String | | Γ£ö∩╕Å | Identifies the name of the requirement set. | +|`requirements.capabilities.minVersion`| String | | | Identifies the minimum version for the requirement set. | +|`requirements.capabilities.maxVersion`| String | | | Identifies the maximum version for the requirement set. | +|`requirements.scopes`| Array of enums | 1 | | Identifies the scopes in which the add-in can run and defines the Microsoft 365 applications in which the extension can run. For example, `mail` (Outlook). <br>Supported value: `mail` | +|`requirements.formFactors`| Array of enums | | | Identifies the form factors that support the add-in. <br>Supported values: `mobile`, `desktop`| +|`tabs`| Array | |Γ£ö∩╕Å| Configures the custom tabs on the Microsoft 365 application ribbon. | +|`tabs.id`| String | 64 characters | | Specifies the ID for the tab within the app.| +|`tabs.builtinTabId`| String | 64 characters | | Specifies the ID of a built-in Office ribbon tab. The possible values vary by Office host application. Currently, only Outlook add-ins are supported and the only allowed value for Outlook is "TabDefault". The default tab depends on where the Outlook add-in is surfaced, as determined in the "extensions.ribbons.contexts" property. In the main Outlook window, it is the **Home** tab, in a message window, it is the **Message** tab, and in a meeting window, it is the **Meeting** tab. | +|`tabs.label`| String | 64 characters | | Specifies the text displayed for the tab.| +|`tabs.position`| Object | | | Configures the position of the custom tab relative to other tabs on the ribbon.| +|`tabs.position.builtinTabId`| String | 64 characters | Γ£ö∩╕Å | Specifies the ID of the built-in tab that the custom tab should be positioned next to. For more information, see [find the IDs of controls and control groups](/office/dev/add-ins/design/built-in-button-integration#find-the-ids-of-controls-and-control-groups).| +|`tabs.position.align`| String enum | | Γ£ö∩╕Å | Defines the alignment of custom tab relative to the specified built-in tab. <br>Supported values: `after`, `before`| +|`tabs.groups`| Array | | | Defines groups of controls on a ribbon tab on a non-mobile device. For mobile devices, see `tabs.customMobileRibbonGroups` below.| +|`tabs.groups.id`| String |64 characters | | Specifies the ID for the tab group within the app. It must be different from any built-in group ID in the Microsoft 365 application and any other custom group.| +|`tabs.groups.label`| String | 64 characters | | Specifies the text displayed for the group. | +|`tabs.groups.icons`| Array | | | Specifies the icons displayed for the group. | +|`tabs.groups.icons.size`| Number | |Γ£ö∩╕Å| Specifies the size of the icon in pixels, enumerated as `16`,`20`,`24`,`32`,`40`,`48`,`64`,`80`. <br>Required image sizes: `16`, `32`, `80`. | +|`tabs.groups.icons.url`| URL| | Γ£ö∩╕Å| Specifies the absolute URL of the icon.| +|`tabs.groups.controls`| Array | | | Configures the buttons and menus in the group. | +|`tabs.groups.controls.id`| String | 64 characters| Γ£ö∩╕Å | Specifies the ID for the control within the app. It must be different from any built-in control ID in the Microsoft 365 application and any other custom control. | +|`tabs.groups.controls.items`| Array | | | Configures the items for a menu control. | +|`tabs.groups.controls.items.id`| String | | Γ£ö∩╕Å | Specifies the ID for the items within the app. | +|`tabs.groups.controls.items.type`| String enum | | Γ£ö∩╕Å | Defines the control items type. <br>Supported values: `menu`, `button`| +|`tabs.groups.controls.items.label`| String | 64 characters| Γ£ö∩╕Å | Specifies the text displayed for the items. | +|`tabs.groups.controls.items.icons`| Array | | | Configures the icons for the custom item.| +|`tabs.groups.controls.items.icons.size`| Number | |Γ£ö∩╕Å| Specifies the size of the icon in pixels, enumerated as `16`,`20`,`24`,`32`,`40`,`48`,`64`,`80`. <br>Required image sizes: `16`, `32`, `80`. | +|`tabs.groups.controls.items.icons.url`| URL| | Γ£ö∩╕Å | Specifies the absolute URL of the icon.| +|`tabs.groups.controls.items.supertip`| | |Γ£ö∩╕Å| Configures a supertip for the custom item. A supertip is a UI feature that displays a brief box of help information about a control when the cursor hovers over it. The box may contain multiple lines of text. | +|`tabs.groups.controls.items.supertip.title`| String | 64 characters | Γ£ö∩╕Å | Specifies the title text of the supertip.| +|`tabs.groups.controls.items.supertip.description`| String | 128 characters | Γ£ö∩╕Å | Specifies the description of the supertip.| +|`tabs.groups.controls.items.actionId`| String | 64 characters | Γ£ö∩╕Å | Specifies the ID of the action that is taken when a user selects the control or menu item. The `actionId` must match with `runtime.actions.id`. | +|`tabs.groups.controls.items.enabled`| Boolean | | | Indicates whether the control is initially enabled. <br>Default value: `true`| +|`tabs.groups.controls.items.overriddenByRibbonApi`| Boolean | | | Specifies whether a group, button, menu, or menu item hidden on application and platform combinations which support the API ([Office.ribbon.requestCreateControls](/javascript/api/office/office.ribbon#office-office-ribbon-requestcreatecontrols-member(1))) that installs custom contextual tabs on the ribbon. <br>Default value: `false`| +|`tabs.groups.controls.type`| String | | Γ£ö∩╕Å | Defines the control type. <br>Supported values: `button`, `menu`| +|`tabs.groups.controls.builtinControlId`| String | 64 characters | Γ£ö∩╕Å | Specifies the ID of an existing Microsoft 365 control. For more information, see [find the IDs of controls and control groups](/office/dev/add-ins/design/built-in-button-integration#find-the-ids-of-controls-and-control-groups).| +|`tabs.groups.controls.label`| String | 64 characters | Γ£ö∩╕Å | Specifies the text displayed for the control.| +|`tabs.groups.controls.icons`| Array | | Γ£ö∩╕Å | Defines the icons for the control. There must be at least three child objects; one each with `size` properties of `16`, `32`, and `80` pixels. | +|`tabs.groups.controls.icons.size`| Number | | Γ£ö∩╕Å | Specifies the size of the icon in pixels, enumerated as `16`,`20`,`24`,`32`,`40`,`48`,`64`,`80`. <br> Required image size: `16`, `32`, `80`| +|`tabs.groups.controls.icons.url`| URL| | | Specifies the absolute URL to the icon.| +|`tabs.groups.controls.supertip`| Object | | Γ£ö∩╕Å | Configures a supertip for the control. | +|`tabs.groups.controls.supertip.title`| String | 64 characters | Γ£ö∩╕Å |Specifies the title text of the supertip.| +|`tabs.groups.controls.supertip.description`| String | 128 characters | Γ£ö∩╕Å | Specifies the description of the supertip.| +|`tabs.groups.controls.actionId`| String | 64 characters | | Required if the control type is `button`. Do not use if the control type is `menu`. Specifies the ID of the action that is taken when a user selects the control. The `actionId` must match the `runtime.actions.id` property of an action in the `runtimes` object.| +|`tabs.groups.controls.enabled`| Boolean | | | Indicates whether the control is initially enabled. <br>Default value: `true`| +|`tabs.groups.controls.overriddenByRibbonApi`| Boolean | | | Specifies whether a group, button, menu, or menu item is hidden on application and platform combinations which support the API ([Office.ribbon.requestCreateControls](/javascript/api/office/office.ribbon#office-office-ribbon-requestcreatecontrols-member(1))) that installs custom contextual tabs on the ribbon. <br>Default value: `false`| +|`tabs.groups.builtinGroupId`| String | 64 characters | | Specifies the ID of a built-in group. For more information, see [find the IDs of controls and control groups](/office/dev/add-ins/design/built-in-button-integration#find-the-ids-of-controls-and-control-groups).| +|`tabs.customMobileRibbonGroups`| Array | 10 | | Defines groups of controls on the default tab of the ribbon on a mobile device. This array property can only be present on tab objects that have a `tabs.builtinTabId` property that is set to "DefaultTab". For non-mobile devices, see `tabs.groups` above.| +|`tabs.customMobileRibbonGroups.id` | String | 250 characters | Γ£ö∩╕Å | Specifies the ID of the group. It must be different from any built-in group ID in the Microsoft 365 application and any other custom group.| +|`tabs.customMobileRibbonGroups.label` | String | 32 characters | Γ£ö∩╕Å | Specifies the label on the group. | +|`tabs.customMobileRibbonGroups.controls` | Array | 20 | Γ£ö∩╕Å | Defines the controls in the group. Only mobile buttons are supported.| +|`tabs.customMobileRibbonGroups.controls.id` | String | 250 characters | Γ£ö∩╕Å | Specifies the ID of the control such as "msgReadFunctionButton".| +|`tabs.customMobileRibbonGroups.controls.type` | String enum | | Γ£ö∩╕Å | Specifies the type of control. Currently only "MobileButton" is supported.| +|`tabs.customMobileRibbonGroups.controls.label` | String | 32 characters | Γ£ö∩╕Å | Specifies the label on the control.| +|`tabs.customMobileRibbonGroups.controls.actionId` | String | 64 characters |Γ£ö∩╕Å | Specifies the ID of the action that is taken when a user selects the control. The `actionId` must match the `runtime.actions.id` property of an action in the `runtimes` object.| +|`tabs.customMobileRibbonGroups.controls.icons` | Array | 9 | Γ£ö∩╕Å | Specifies the icons that will appear on the control depending on the dimensions and DPI of the mobile device screen. There must be exactly 9 icons.| +|`tabs.customMobileRibbonGroups.controls.icons.size` | Number enum | | Γ£ö∩╕Å | Size in pixels of the icon. The possible sizes are 25, 32, and 48. There must be exactly one of each size for each possible value of the icons's `scale` property. | +|`tabs.customMobileRibbonGroups.controls.icons.url` | String | 2048 characters | Γ£ö∩╕Å | The full, absolute URL of the icon's image file. | +|`tabs.customMobileRibbonGroups.controls.icons.scale` | Number enum | | Γ£ö∩╕Å | Specifies the UIScreen.scale property for iOS devices. The possible values are 1, 2, and 3. There must be exactly one of each value for each possible value of the icons's `size` property. | ++To use `extensions.ribbons`, see [create add-in commands](/office/dev/add-ins/develop/create-addin-commands-unified-manifest), [configure the UI for the task pane command](/office/dev/add-ins/develop/create-addin-commands-unified-manifest#configure-the-ui-for-the-task-pane-command), and [configure the UI for the function command](/office/dev/add-ins/develop/create-addin-commands-unified-manifest#configure-the-ui-for-the-function-command). ++### extensions.autoRunEvents ++The `extensions.autoRunEvents` property defines event-based activation extension points. ++|Name| Type| Maximum size | Required | Description| +|||||| +|`events`| Array |20 | Γ£ö∩╕Å | Configures the event that cause actions in an Outlook Add-in to run automatically. For example, see [use smart alerts and the `OnMessageSend` and `OnAppointmentSend` events in your Outlook Add-ins](/office/dev/add-ins/outlook/smart-alerts-onmessagesend-walkthrough?tabs=jsonmanifest).| +|`events.type`| String | 64 characters | | Specifies the type of event. For supported types, see [supported events](/office/dev/add-ins/outlook/autolaunch?tabs=xmlmanifest#supported-events).| +|`events.actionId`| String | 64 characters | | Identifies the action that is taken when the event fires. The `actionId` must match with `runtime.actions.id`. | +|`events.options`| Object | | | Configures how Outlook responds to the event.| +|`events.options.sendMode`| String | | Γ£ö∩╕Å | Specifies the actions to take during a mail send action. <br>Supported values: `promptUser`, `softBlock`, `block`. For more information, see [available send mode options](/office/dev/add-ins/outlook/smart-alerts-onmessagesend-walkthrough?tabs=jsonmanifest#available-send-mode-options).| +|`requirements`| Object | | | Specifies the scopes, formFactors, and Office JavaScript Library requirement sets that must be supported on the Office client in order for the event handling code to run. For more information, see [Specify Office Add-in requirements in the unified manifest for Microsoft 365](/office/dev/add-ins/develop/requirements-property-unified-manifest).| +|`requirements.capabilities`| Array | | | Identifies the requirement sets. <br>Options: `name` (required), `minVersion`, `maxVersion`| +|`requirements.capabilities.name`| String | | Γ£ö∩╕Å | Identifies the name of the requirement set. | +|`requirements.capabilities.minVersion`| String | | | Identifies the minimum version for the requirement set. | +|`requirements.capabilities.maxVersion`| String | | | Identifies the maximum version for the requirement set. | +|`requirements.scopes`| Array of enums | 1 | | Identifies the scopes in which the add-in can run and defines the Microsoft 365 applications in which the extension can run. For example, `mail` (Outlook). <br>Supported value: `mail` | +|`requirements.formFactors`| Array of enums | | | Identifies the form factors that support the add-in. <br>Supported values: `mobile`, `desktop`| ++### extensions.alternates ++The `extensions.alternates` property is used to hide or prioritize specific in-market add-ins when you've published multiple add-ins with overlapping functionality. ++|Name| Type| Maximum size | Required | Description| +|||||| +|`prefer`| Object | | | Specifies the backward compatibility with an equivalent COM add-in, XLL add-in, or both.| +|`prefer.comAddin`| Object | | | Specifies a COM add-in that must be used in place of the Microsoft 365 Web Add-in for Windows.| +|`prefer.comAddin.progId`| String | 64 characters | Γ£ö∩╕Å | Identifies the application type in which the extension can run.| +|`hide`| Object | | | Configures how to hide another add-in that you've published whenever the add-in is installed, so users don't see both in the Microsoft 365 UI. For example, use this property when you've previously published an add-in that uses the old XML app manifest and you're replacing it with a version that uses the new JSON app manifest. | +|`hide.storeOfficeAddin`| Object | | | Specifies a Microsoft 365 Add-in available in Microsoft AppSource. | +|`hide.storeOfficeAddin.officeAddinId`| String | 64 characters | Γ£ö∩╕Å | Specifies the ID of the in-market add-in to hide. The GUID is taken from the app manifest `id` property if the in-market add-in uses the JSON app manifest. The GUID is taken from the `<Id>` element if the in-market add-in uses the XML app manifest. | +|`hide.storeOfficeAddin.assetId`| String | 64 characters | Γ£ö∩╕Å | Specifies the AppSource asset ID of the in-market add-in to hide.| +|`hide.customOfficeAddin`| Object | | | Configures how to hide an in-market add-in that isn't distributed through AppSource.| +|`hide.customOfficeAddin.officeAddinId`|String | 64 characters | Γ£ö∩╕Å | Specifies the ID of the in-market add-in to hide. The GUID is taken from the app manifest `id` property if the in-market add-in uses the JSON app manifest. The GUID is taken from the `<Id>` element if the in-market add-in uses the XML app manifest. | +|`requirements`| Object | | | Specifies the scopes, formFactors, and Office JavaScript Library requirement sets that must be supported on the Office client in order for the "hide", "prefer", or "alternateIcons" properties to take effect. For more information, see [Specify Office Add-in requirements in the unified manifest for Microsoft 365](/office/dev/add-ins/develop/requirements-property-unified-manifest).| +|`requirements.capabilities`| Array | | | Identifies the requirement sets. <br>Options: `name` (required), `minVersion`, `maxVersion`| +|`requirements.capabilities.name`| String | | Γ£ö∩╕Å | Identifies the name of the requirement set. | +|`requirements.capabilities.minVersion`| String | | | Identifies the minimum version for the requirement set. | +|`requirements.capabilities.maxVersion`| String | | | Identifies the maximum version for the requirement set. | +|`requirements.scopes`| Array of enums | 1 | | Identifies the scopes in which the add-in can run and defines the Microsoft 365 applications in which the extension can run. For example, `mail` (Outlook). <br>Supported value: `mail` | +|`requirements.formFactors`| Array of enums | | | Identifies the form factors that support the add-in. <br>Supported values: `mobile`, `desktop`| +|`alternateIcons`| Object | | | Specifies the main icons that are used to represent the add-in on older versions of Office. This property is **required** if the Office add-in is to be installable in Office on Mac, perpetual Office licenses, and Microsoft 365 subscription versions of Office on Windows earlier than 2304 (Build 16320.00000).| +|`alternateIcons.icon`| Object | | Γ£ö∩╕Å | Specifies properties of the image file used to represent the add-in. | +|`alternateIcons.icon.size`| Number enum | | Γ£ö∩╕Å | This property is reserved for future use. The value must be 64.| +|`alternateIcons.icon.url`| String | 2048 characters | Γ£ö∩╕Å | Specifies the full, absolute URL of the image file that is used to represent the add-in. Icon image must be 64 x 64 pixels and use one of the following file formats: GIF, JPG, PNG, EXIF, BMP, TIFF.| +|`alternateIcons.highResolutionIcon`| Object | | Γ£ö∩╕Å | Specifies properties of the image file used to represent the add-in on high DPI screens. | +|`alternateIcons.highResolutionIcon.size`| Number enum | | Γ£ö∩╕Å | This property is reserved for future use. The value must be 64 (not 128). | +|`alternateIcons.highResolutionIcon.url`| String | 2048 characters | Γ£ö∩╕Å | Specifies the full, absolute URL of the image file that is used to represent the add-in on high DPI screens. Icon image must be 128 x 128 pixels and use one of the following file formats: GIF, JPG, PNG, EXIF, BMP, TIFF.| ++## dashboardCards ++**Optional** – Array ++Defines a list of cards that can be pinned to a dashboard, such as Microsoft Viva Connections, to provide a summarized view of app information. To learn more about creating cards for Viva Connections Dashboard, see [Overview of Bot Powered Adaptive Card Extensions](/sharepoint/dev/spfx/viva/bot-powered/overview-bot-powered-aces). ++This item is an array of `dashboardCard` elements of type `object`. ++### dashboardCards.dashboardCard ++Defines a single dashboard card and its properties. ++|Name| Type| Maximum size | Required | Description| +|||||| +|`id`| String | | Γ£ö∩╕Å | A unique identifier for this dashboard card. ID must be a GUID. | +|`displayName`| String | 255 characters | Γ£ö∩╕Å | Display name of the card.| +|`description`| String | 255 characters | Γ£ö∩╕Å | Description of the card.| +|`pickerGroupId`| String | | Γ£ö∩╕Å | ID of the group in the card picker. ID must be a GUID.| +|`icon`| Object | | | Specifies icon for the card. | +|`contentSource`| Object | | Γ£ö∩╕Å | Specifies the source of the card's content | +|`defaultSize`| String | | Γ£ö∩╕Å | Rendering size for the dashboard card. Options: `medium` or `large`. | ++### dashboardCards.dashboardCard.icon ++Defines the icon properties of a given dashboard card. ++|Name| Type| Maximum size | Required | Description| +|||||| +|`iconUrl`| String | 2048 characters | | Location of the icon for the card, to be displayed in the toolbox and card bar. | +|`officeUIFabricIconName`| String | 255 characters | | Office UI Fabric or Fluent UI icon friendly name for the card. This value is used if *iconUrl* is not specified. | ++### dashboardCards.dashboardCard.contentSource ++Defines the content source of a given dashboard card. ++|Name| Type| Maximum size | Required | Description| +|||||| +|`sourceType`| String | | | Represents the source of a card's content. Options: `bot`.| +|`botConfiguration`| Object | | | The configuration for the bot source. Required if the *sourceType* is set to `bot`.| ++#### dashboardCards.dashboardCard.contentSource.botConfiguration ++|Name| Type| Maximum size | Required | Description| +|||||| +|`botId`| String | | | The unique Microsoft app ID for the bot as registered with the Bot Framework. ID must be a GUID.| + ## Create an app manifest file If your app doesn't have an app manifest file, you need to create it. |
platform | Cards Format | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/task-modules-and-cards/cards/cards-format.md | -# Format cards in Microsoft Teams +# Format cards in Teams Following are the two ways to add rich text formatting to your cards: On the desktop, Adaptive Card Markdown formatting appears as shown in the follow On iOS, Adaptive Card Markdown formatting appears as shown in the following image: On Android, Adaptive Card Markdown formatting appears as shown in the following image: For more information, see [text features in Adaptive Cards](/adaptive-cards/create/textfeatures). Adaptive Cards support emoji. The following code shows an example of Adaptive Ca > [!NOTE] > If you are using REST APIs, then set `charset=UTF-8` in your request headers to add emojis in Adaptive Cards. ### Mention support within Adaptive Cards Bots and message extensions can include mentions within the card content in [Tex > [!NOTE] >-> * [Media elements](https://adaptivecards.io/explorer/Media.html) are currently not supported in Adaptive Cards on Teams platform. +> * [Media elements](https://adaptivecards.io/explorer/Media.html) aren't supported in Adaptive Cards on Teams platform. > * Channel and team mentions aren't supported in bot messages. > * You can @mention multiple users in a single Adaptive Card message, however, ensure that the message size limit doesn't exceed 28 KB for [Incoming Webhooks](~/webhooks-and-connectors/how-to/add-incoming-webhook.md) and 40 KB for a [bot message](~/bots/how-to/format-your-bot-messages.md). > * Adaptive Cards sent from Incoming Webhooks only support user mentions and don't support bot mentions. Teams platform allows you to mention users with their Microsoft Entra Object ID The following table describes the newly supported user mention IDs: -|IDs | Supporting capabilities | Description | Example | +|IDs | Supporting capabilities | Description | Example | |-|--||| | Microsoft Entra Object ID | Bot, Connector | Microsoft Entra user’s Object ID | 49c4641c-ab91-4248-aebb-6a7de286397b | | UPN | Bot, Connector | Microsoft Entra user’s UPN | `john.smith@microsoft.com` | Example for user mention in bots with Adaptive Cards as follows: Following image illustrates the user mention with Adaptive Card in Bot: #### User mention in Incoming Webhook with Adaptive Cards Example for user mention in Incoming Webhook as follows: Following image illustrates user mention in Incoming Webhook: ### People icon in an Adaptive Card People icon helps users to view the images of users in an Adaptive Card. You can There are two types of people icons that are supported in an Adaptive Card: -* Persona: If you want to show a single user in an Adaptive Card, the Adaptive Card displays the people icon and the name of the user. +* Persona: If you want to show a single user in an Adaptive Card, it displays the people icon and the name of the user. - The following is a JSON example of a Persona card: + The following JSON code is an example of a Persona card: ```json { There are two types of people icons that are supported in an Adaptive Card: } ``` -* Persona Set: If you want to show multiple users in an Adaptive Card, the Adaptive Card displays only the people icon of the users. +* Persona Set: If you want to show multiple users in an Adaptive Card, it displays only the people icon of the users. - The following is a JSON example of a Persona Set: + The following JSON code is an example of a Persona Set: ```json { The following image is an example of the people icon in an Adaptive Card: The following table lists the query parameters: -|Property name |description | +| Property name | Description | |||-|`type` | `component` | -|`name` | `graph.microsoft.com/users`. Search all members across the organization. | -|`view` | `compact` | -|`properties`|Passed to the component template| -|`id` | User's MRI | -|`displayName` | Name of the user | -|`userPrincipalName`|The user's principal name of the account in Microsoft Entra ID| +| `type` | `component` | +| `name` | Use `graph.microsoft.com/users` to search all members across the organization | +| `view` | `compact` | +| `properties` | Passed to the component template | +| `id` | User's MRI | +| `displayName` | Name of the user | +| `userPrincipalName` | The user's principal name of the account in Microsoft Entra ID | -Adaptive Components are high-level components powered by [templating](/adaptive-cards/templating/) and native Adaptive Card elements. The type `component` can be used anywhere inside the card body and the component data is defined in the `properties` attribute. The component data under `properties` is passed directly to the component. The `properties` property defines the format for Persona and Persona Set and all other properties under `properties` is ignored by `component` type in the Adaptive Card schema. +Adaptive Components are high-level components powered by [templating](/adaptive-cards/templating/) and native Adaptive Card elements. The type `component` can be used anywhere inside the card body and the component data is defined in the `properties` attribute. The component data under `properties` is passed directly to the component. The `properties` property defines the format for Persona and Persona Set and all other properties under `properties` is ignored by `component` type in the Adaptive Card schema. -Your bot can query for the list of members and their basic user profiles, including Teams user IDs and Microsoft Entra information, such as `name`, `id` and `userPrincipalName`. For more information, see [Fetch the roster or user profile](../../bots/how-to/get-teams-context.md#fetch-the-roster-or-user-profile). +Your bot can query for the list of members and their basic user profiles, including Teams user IDs and Microsoft Entra information, such as `name`, `id`, and `userPrincipalName`. For more information, see [Fetch the roster or user profile](../../bots/how-to/get-teams-context.md#fetch-the-roster-or-user-profile). -The following is an example of the people icon in an Adaptive Card on Teams desktop and mobile clients: +The following images show the people icon in an Adaptive Card on Teams desktop and mobile clients: **Desktop client**: When a user hovers on a people icon, the people card of that user is displayed. :::image type="content" source="../../assets/images/adaptive-cards/people-icon-mobile-1.png" alt-text="Screenshot shows an example of people icon in a persona and persona set in Teams mobile client."::: :::column-end::: :::column:::- :::image type="content" source="../../assets/images/adaptive-cards/people-icon-mobile-2.png" alt-text="Screenshot shows an example of people icon in a persona and persona set in Teams mobile."::: + :::image type="content" source="../../assets/images/adaptive-cards/people-icon-mobile-2.png" alt-text="Screenshot shows another example of people icon in a persona and persona set in Teams mobile client."::: :::column-end::: :::row-end::: The following code shows an example of Adaptive Card with masking property: The following image is an example of masking information in Adaptive Cards: ### Full width Adaptive Card -You can use the `msteams` property to expand the width of an Adaptive Card and make use of additional canvas space. The next section provides information on how to use the property. +You can use the `msteams` property to expand the width of an Adaptive Card and make use of extra canvas space. The next section provides information on how to use the property. > [!NOTE]-> Test your full width Adaptive Card in narrow form factors such as mobile and meeting side panels to ensure that content is not truncated. +> Test your full width Adaptive Card in narrow form factors such as mobile and meeting side panels to ensure that content isn't truncated. #### Construct full width cards To make a full width Adaptive Card, your app must include the elements from the The following image shows a full width Adaptive Card: -The following image shows the default view of the Adaptive Card when you have not set the `width` property to **Full**: +The following image shows the default view of an Adaptive Card when you haven't set the `width` property to **Full**: ### Adaptive Card responsive layout The following are JSON samples for an Adaptive Card designed without using `targ * When the card's width is **wide**, the card looks good. - :::image type="content" source="../../assets/images/Cards/card-width-wide.png" alt-text="Screenshot shows how adaptive card with card width as wide renders when the card is designed without using targetWidth property."::: + :::image type="content" source="../../assets/images/Cards/card-width-wide.png" alt-text="Screenshot shows how an Adaptive Card with card width as wide renders when the card is designed without using targetWidth property."::: * When the card's width is **standard** or **narrow**, the role is squeezed. - :::image type="content" source="../../assets/images/Cards/card-width-standard-narrow.png" alt-text="Screenshot shows how adaptive card with card width as standard or narrow renders when the card is designed without using targetWidth property."::: + :::image type="content" source="../../assets/images/Cards/card-width-standard-narrow.png" alt-text="Screenshot shows how an Adaptive Card with card width as standard or narrow renders when the card is designed without using targetWidth property."::: * When the card's width is **very narrow**, the name and role are significantly squeezed. - :::image type="content" source="../../assets/images/Cards/card-width-very-narrow.png" alt-text="Screenshot shows how adaptive card with card width as very narrow renders when the card is designed without using targetWidth property."::: + :::image type="content" source="../../assets/images/Cards/card-width-very-narrow.png" alt-text="Screenshot shows how an Adaptive Card with card width as very narrow renders when the card is designed without using targetWidth property."::: * Adaptive Card updated to be responsive using `targetWidth`: The following are JSON samples for an Adaptive Card designed without using `targ * When the card's width is **wide**, the card still looks good. - :::image type="content" source="../../assets/images/Cards/target-width-wide.png" alt-text="Screenshot shows how adaptive card renders when the targetWidth property is wide."::: + :::image type="content" source="../../assets/images/Cards/target-width-wide.png" alt-text="Screenshot shows how an Adaptive Card renders when the targetWidth property is wide."::: * When the card's width is **standard** or **narrow**, the role is moved under the name as there's no horizontal space to show them side-by-side. - :::image type="content" source="../../assets/images/Cards/target-width-standard-narrow.png" alt-text="Screenshot shows how adaptive card renders when the targetWidth property is standard or narrow."::: + :::image type="content" source="../../assets/images/Cards/target-width-standard-narrow.png" alt-text="Screenshot shows how an Adaptive Card renders when the targetWidth property is standard or narrow."::: * When the card's width is **very narrow**, we can hide the image and only keep the most meaningful information. - :::image type="content" source="../../assets/images/Cards/target-width-very-narrow.png" alt-text="Screenshot shows how adaptive card renders when the targetWidth property is veryNarrow."::: + :::image type="content" source="../../assets/images/Cards/target-width-very-narrow.png" alt-text="Screenshot shows how an Adaptive Card renders when the targetWidth property is veryNarrow."::: -For more information on how to design an Adaptive Card, see [designing Adaptive Cards for your Microsoft Teams app](design-effective-cards.md). +For more information on how to design an Adaptive Card, see [designing Adaptive Cards for your Teams app](design-effective-cards.md). ### Typeahead support The following code shows an example of Adaptive Card with typeahead support: ### Stageview for images in Adaptive Cards -In an Adaptive Card, you can use the `msteams` property to add the ability to display images in Stageview selectively. When users hover over the images, they can see an expand icon, for which the `allowExpand` attribute is set to `true`. The following is an example of the `msteams` property: +In an Adaptive Card, you can use the `msteams` property to add the ability to display images in Stageview selectively. When users hover over the images, they can see an expand icon, for which the `allowExpand` attribute is set to `true`. The following code is an example of the `msteams` property: ``` json { In an Adaptive Card, you can use the `msteams` property to add the ability to di When users hover over the image, an expand icon appears at the upper-right corner as shown in the following image: The image appears in Stageview when the user selects the expand icon as shown in the following image: In connector cards, newlines are rendered for `\n\n`, but not for `\n` or `\r`. On the desktop, Markdown formatting for connector cards appears as shown in the following image: On iOS, Markdown formatting for connector cards appears as shown in the following image: Connector cards using Markdown for iOS include the following issues: Connector cards using Markdown for iOS include the following issues: On Android, Markdown formatting for connector cards appears as shown in the following image: ### Format example for Markdown connector cards The following code shows an example of formatting for Markdown connector cards: +## CodeBlock in Adaptive Cards ++The `CodeBlock` element enables you to share code snippets as richly formatted Adaptive Cards in Teams chats, channels, and meetings. Adaptive Cards with the `CodeBlock` element make the code snippet easy to read as the indentation, numbering, and syntax highlighting match the programming language. Additionally, you can add action buttons to view the code at its source or edit the code in integrated development environments (IDEs) such as Microsoft Visual Studio or Microsoft Visual Studio Code. ++The following screenshot shows an Adaptive Card with a code snippet: ++ :::image type="content" source="../../assets/images/adaptive-cards/code-block-adaptive-card.png" alt-text="Screenshot shows an Adaptive Card with a code snippet."::: ++The `CodeBlock` element supports the following languages: ++| Language | Supported | Language | Supported | +|:|::|:|::| +| Bash | ✔️ | JSON | ✔️ | +| C | ✔️ | Perl | ✔️ | +| C++ | ✔️ | PHP | ✔️ | +| C# | ✔️ | PowerShell | ✔️ | +| CSS | ✔️ | Python | ✔️ | +| DOS | ✔️ | SQL | ✔️ | +| Go | ✔️ | TypeScript | ✔️ | +| GraphQL | ✔️ | Visual Basic | ✔️ | +| HTML | ✔️ | Verilog | ✔️ | +| Java | ✔️ | VHDL | ✔️ | +| JavaScript | ✔️ | XML | ✔️ | ++> [!NOTE] +> The `CodeBlock` element recognizes plain text as a language if you set the enum value to `PlainText` in the `language` property of the schema. ++The following code is an example of an Adaptive Card displaying a code snippet: ++``` json +{ + "$schema": "https://adaptivecards.io/schemas/adaptive-card.json", + "type": "AdaptiveCard", + "version": "1.5", + "body": [ + { + "type": "TextBlock", + "text": "editor.js", + "style": "heading" + }, + { + "type": "TextBlock", + "text": "Lines 61 - 76" + }, + { + "type": "CodeBlock", + "codeSnippet": "/**\n* @author John Smith <john.smith@example.com>\n*/\npackage l2f.gameserver.model;\n\npublic abstract strictfp class L2Char extends L2Object {\n public static final Short ERROR = 0x0001;\n\n public void moveTo(int x, int y, int z) {\n _ai = null;\n log(\"Shouldn't be called\");\n if (1 > 5) { // what!?\n return;\n }\n }\n}", + "language": "java", + "startLineNumber": 61 + } + ], + "actions": [ + { + "type": "Action.OpenUrl", + "title": "View in Azure Repos", + "url": "https://azure.microsoft.com/en-us/products/devops/repos/" + }, + { + "type": "Action.OpenUrl", + "title": "Edit in vscode.dev", + "url": "https://vscode.dev/" + } + ] +} +``` ++The `CodeBlock` element supports the following properties: ++| Property | Type | Required | Description | +||||| +| `codeSnippet` | String | Yes | The code snippet to be displayed in an Adaptive Card. | +| `language` | Enum | Yes | The language of the code snippet to be displayed in an Adaptive Card. | +| `startLineNumber` | Number | No | The line number in the source where the code snippet begins. If left blank, defaults to 1. | ++> [!TIP] +> +> * Special characters have specific functions in the `codeSnippet` property. For example, the newline character `\n` triggers a line break. +> * To display the newline character `\n` as part of the code snippet in an Adaptive Card, ensure that you escape it as `\\n` in the `codeSnippet` property. Else, Teams renders the code after the `\n` in the next line of the card. ++### Limitations ++* An Adaptive Card with the `CodeBlock` element is supported only in Teams web and desktop clients. +* The code snippet in an Adaptive Card is read-only and not editable. +* An Adaptive Card only previews the first 10 lines of the code snippet. If there are more than 10 lines of code, the user must select **Expand** to see the rest of the code snippet. + ## Adaptive Cards overflow menu Adaptive Card in Teams supports overflow menu. You can populate an overflow menu for all the secondary actions in an Adaptive Card. An overflow menu in an Adaptive Card can be added to the following: Adaptive Card in Teams supports overflow menu. You can populate an overflow menu > [!NOTE] > An Adaptive Card supports up to six primary actions to be viewed on the card. Any additional primary action is viewed in the overflow menu. - :::image type="content" source="../../assets/images/Cards/overflow-menu-gif.gif" alt-text="GIF shows the overflow menu experience in an Adaptive Card."::: + :::image type="content" source="../../assets/images/Cards/overflow-menu-gif.gif" alt-text="The graphical representation shows the overflow menu experience in an Adaptive Card."::: ### Enable overflow menu To enable overflow menu, configure the `mode` property with the value as `primar ||||| |`mode`| Enum (Primary, Secondary) |No |Whether or not the action is a primary or secondary action. Secondary actions are collapsed into an overflow menu.| -The following is an example of the `mode` property in the `actions` type and the `ActionSet` element: +The following example shows the `mode` property in the `actions` type and the `ActionSet` element: **Actions** In the following example, there are two primary actions and one secondary action > [!NOTE] >-> * The overflow menu behaves differently on a bot sent card and a message extension card for the root level `actions` in an Adaptive Card. The overflow menu on a bot sent card appears as a pop-up context menu and on the message extension card it appears at the upper-right corner under the More options (**...**) icon. The behavior is not applicable to the `ActionSet` in an Adaptive Card. +> * The overflow menu behaves differently on a bot sent card and a message extension card for the root level `actions` in an Adaptive Card. The overflow menu on a bot sent card appears as a pop-up context menu and on the message extension card it appears at the upper-right corner under the More options (**...**) icon. The behavior isn't applicable to the `ActionSet` in an Adaptive Card. The following image is an example of overflow menu in a bot sent card and a message extension card: In the following example, all the actions are marked as secondary, therefore, a } ``` -The following is an example of the overflow menu experience in Teams desktop and mobile: +The following example shows the overflow menu experience in Teams desktop and mobile clients: # [Desktop](#tab/desktop) When a user selects the overflow menu on a desktop, the buttons that are set as secondary appear in the Adaptive Card. - :::image type="content" source="../../assets/images/Cards/desktop-overflow-image-1.png" alt-text="Screenshot shows an example of buttons in an Adaptive Card on Teams desktop."::: + :::image type="content" source="../../assets/images/Cards/desktop-overflow-image-1.png" alt-text="Screenshot shows an example of buttons in an Adaptive Card on Teams desktop client."::: - :::image type="content" source="../../assets/images/Cards/desktop-overflow-image-2.png" alt-text="Screenshot shows an example of an Adaptive Card with the list of actions in an overflow menu on Teams desktop."::: + :::image type="content" source="../../assets/images/Cards/desktop-overflow-image-2.png" alt-text="Screenshot shows an example of an Adaptive Card with the list of actions in an overflow menu on Teams desktop client."::: - :::image type="content" source="../../assets/images/Cards/desktop-overflow-menu-image-3.png" alt-text="Screenshot shows an example of an Adaptive Card with the buttons that are set as secondary as options in an overflow menu on Teams desktop."::: + :::image type="content" source="../../assets/images/Cards/desktop-overflow-menu-image-3.png" alt-text="Screenshot shows an example of an Adaptive Card with the buttons that are set as secondary as options in an overflow menu on Teams desktop client."::: # [Mobile](#tab/mobile) -When a user selects the overflow menu on mobile, the Adaptive Card displays the buttons that are defined. There's an integrated sheet that displays an overflow menu with card related tasks with a message option. A long press on any message displays a list of related messages. This option is available only for actions. +When a user selects the overflow menu on mobile, Adaptive Card displays the buttons that are defined. There's an integrated sheet that displays an overflow menu with card related tasks with a message option. A long press on any message displays a list of related messages. This option is available only for actions. - :::image type="content" source="../../assets/images/over-flow-menu-mob-1.png" alt-text="Screenshot shows an example of overflow menu on Teams mobile."::: + :::image type="content" source="../../assets/images/over-flow-menu-mob-1.png" alt-text="Screenshot shows an example of overflow menu on Teams mobile client."::: You can test formatting in your own cards by modifying this code. ## Code samples -|S.No.| Description|.NET|Node.js|Manifest| -|:--|:--|:--|--|--| -|1|This sample app shows different card formatting supported in Teams.|[View](https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/bot-formatting-cards/csharp)|[View](https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/bot-formatting-cards/nodejs)|[View](https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/bot-formatting-cards/csharp/demo-manifest/bot-formatting-cards.zip)| +| S.No. | Description |.NET | Node.js | Manifest | +|:--|:--|:--||| +| 1 | This sample app shows the various card formats supported in Teams. | [View](https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/bot-formatting-cards/csharp) | [View](https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/bot-formatting-cards/nodejs) | [View](https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/bot-formatting-cards/csharp/demo-manifest/bot-formatting-cards.zip) | ## See also |
platform | What Are Cards | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/task-modules-and-cards/what-are-cards.md | Last updated 01/08/2023 A card is a user interface (UI) container for short or related pieces of information. Cards can have multiple properties and attachments and can include buttons, which trigger [card actions](~/task-modules-and-cards/cards/cards-actions.md). Using cards, you can organize information into groups and give users the opportunity to interact with specific parts of the information. -The bots for Teams support the following types of cards: +The bots for Microsoft Teams support the following types of cards: - Adaptive Card - Hero card The bots for Teams support the following types of cards: - Card collections - Overflow menu on Adaptive Cards -You can add rich text formatting to your cards using either Markdown or HTML, depending on the card type. Cards used by bots and message extensions in Microsoft Teams, add and respond to these card actions, `openUrl`, `messageBack`, `imBack`, `invoke`, and `signin`. +You can add rich text formatting to your cards using either Markdown or HTML, depending on the card type. Cards used by bots and message extensions in Teams, add and respond to these card actions, `openUrl`, `messageBack`, `imBack`, `invoke`, and `signin`. Teams uses cards in three different places: In addition to Adaptive Cards, Teams supports two other types of cards: ### Typeahead search in Adaptive Cards -Typeahead search added as an input control in Adaptive Cards enable [dynamic search](~/task-modules-and-cards/cards/dynamic-search.md) experience from a dynamically loaded dataset. It also allows users to do a type-ahead static search within a list with limited number of choices. The mobile and desktop clients support type ahead dynamic search experience. +Typeahead search added as an input control in Adaptive Cards enable [dynamic search](~/task-modules-and-cards/cards/dynamic-search.md) experience from a dynamically loaded dataset. It also allows users to do a typeahead static search within a list with limited number of choices. The mobile and desktop clients support typeahead dynamic search experience. ### Media elements in Adaptive Cards Media elements in Adaptive Card provide enhanced media experience and increases Adaptive Cards with Incoming Webhooks enable you to use the rich and flexible capabilities of Adaptive Cards. It sends data using Incoming Webhooks in Teams from their web service. +### CodeBlock in Adaptive Cards ++Share code snippets as richly formatted Adaptive Cards in Teams chats, channels, and meetings with the `CodeBlock` element. Adaptive Cards with the `CodeBlock` element make the code snippet easy to read as the indentation, numbering, and syntax highlighting match the programming language. For more information, see [CodeBlock in Adaptive Cards](cards/cards-format.md#codeblock-in-adaptive-cards). + ### Adaptive Card responsive layout You must design your Adaptive Cards to look great on any device to provide an enhanced user experience across chat, channels, and meeting chat. Adaptive Card responsive layout helps you to design cards with different layouts that target different card widths. For more information, see [Adaptive Card responsive layout](cards/cards-format.md#adaptive-card-responsive-layout). |
platform | What Are Task Modules | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/task-modules-and-cards/what-are-task-modules.md | A dialog includes the following as shown in the previous image: ## See also +* [Adaptive Cards overflow menu](~/task-modules-and-cards/cards/cards-format.md#adaptive-cards-overflow-menu) +* [Bot configuration experience](../bots/how-to/bot-configuration-experience.md) * [Cards and dialogs](cards-and-task-modules.md) * [Cards](~/task-modules-and-cards/what-are-cards.md)-* [Adaptive Cards overflow menu](~/task-modules-and-cards/cards/cards-format.md#adaptive-cards-overflow-menu) * [Instrumenting for Teams app specific analytics](../concepts/design/overview-analytics.md#instrumenting-for-teams-app-specific-analytics) |
platform | Whats New | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/whats-new.md | Title: What is new and updated for developers in Teams -description: Learn about new Microsoft Teams developer features and updates to existing features, deprecation notes, and changes. Subscribe to the RSS feed for latest updates +description: Learn about new Microsoft Teams developer features and updates to existing features, deprecation notes, and changes. Subscribe to the RSS feed for latest updates. ms.localizationpriority: high zone_pivot_groups: What-new-features Teams platform features that are available to all app developers. **2024 April** +* ***April 12, 2024***: [Implement authentication in API-based search message extensions to provide secure and seamless access to your app.](messaging-extensions/build-api-based-message-extension.md#authentication) +* ***April 12, 2024***: [Introducing app manifest v1.17 with semanticDescription, samplePrompts, and dashboardCards](resources/schem). +* ***April 12, 2024***: [Outlook extensions specifies Outlook Add-ins within an app manifest and simplify the distribution and acquisition across the Microsoft 365 ecosystem](resources/schem#extensionsrequirements). +* ***April 12, 2024***: [Create Dashboardcards that can be pinned to a dashboard such as Microsoft Viva Connections to provide a summarized view of app information](resources/schem#dashboardcards). +* ***April 12, 2024***: [Share code snippets as richly formatted Adaptive Cards in Teams chats, channels, and meetings with the CodeBlock element.](task-modules-and-cards/cards/cards-format.md#codeblock-in-adaptive-cards) +* ***April 12, 2024***: [Introduced bot configuration experience that helps you to enable the bot settings for users to configure their bot during installation and reconfigure the bot.](bots/how-to/bot-configuration-experience.md) +* ***April 12, 2024***: [Use sample prompts to guide users on how to use the various plugins within Copilot.](messaging-extensions/high-quality-message-extension.md#sample-prompts) * ***April 10, 2024***: [Define and deploy Outlook Add-ins in version 1.17 and later of the app manifest schema.](m365-apps/overview.md#outlook-add-ins)+* ***April 04, 2024***: [Added support for python in Teams AI library.](bots/how-to/Teams%20conversational%20AI/teams-conversation-ai-overview.md) * ***April 04, 2024***: [Stageview API with the openmode property allows you to open your app content in different Stageview experience.](tabs/open-content-in-stageview.md) * ***April 03, 2024***: [Updated the common reasons for app validation failure to help your app pass the Teams Store submission process.](concepts/deploy-and-publish/appsource/common-reasons-for-app-validation-failure.md) Developer preview is a public program that provides early access to unreleased T |02/11/2023| Introduced Adaptive Card Previewer in public developer preview. | Tools > [Adaptive Card Previewer](concepts/build-and-test/adaptive-card-previewer.md)| |25/10/2023| Introduced the `extensions` property in public developer preview app manifest schema. | App manifest > [Public developer preview](resources/schem#extensions)| |25/10/2023| Build message extensions using API (API-based) to interact directly with third-party data, apps, and services. | Build message extensions > [Build message extensions using API](messaging-extensions/api-based-overview.md)|-|28/09/2023| Configure your bot during installation or after installation from the team or group chat where the bot is installed. | Build bots > [Bot configuration experience](bots/how-to/bot-configuration-experience.md)| |31/08/2023| The new Teams client supports light theme for apps in Teams meetings. | Build tabs > [Get context for your tab](tabs/how-to/access-teams-context.md#handle-theme-change)| |28/08/2023| Teams app manifest is now referred to as app manifest. | App manifest > [App manifest schema](resources/schem)| |21/08/2023| Introduced the new Microsoft Teams client to provide better experience for your apps and users | Resources > [Introducing the new Microsoft Teams client](resources/teams-updates.md)| Discover Microsoft Teams platform features that are deprecated. You can now get Teams platform features that aren't available. +* ***April 12, 2024***: The `packageName` property is deprecated as part of manifest v1.17. + * ***April 10, 2024***: [Location](concepts/device-capabilities/location-capability.md#location-apis) and [Media](concepts/device-capabilities/media-capabilities.md#media-capability-apis) APIs aren't supported in the new Teams client. We recommend using HTML5 Geolocation and Media. * ***April 10, 2024***: The `window.alert`, `window.confirm`, and `window.prompt` APIs used to display a dialog aren't supported in the [new Teams Client](resources/teams-updates.md#limitations). We recommended you to render a dialog within your own frame. |