Service | Microsoft Docs article | Related commit history on GitHub | Change details |
---|---|---|---|
platform | Authentication | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/concepts/authentication/authentication.md | Last updated 05/23/2022 Authentication is all about validating app users, and securing the app and app users against unwarranted access. You can use an authentication method suitable for your app to validate app users who want to use the Teams app. -Choose to add authentication for your app in one of the two ways: +Choose to add authentication for your app in one of the following ways: * **Enable single sign-on (SSO) in a Teams app**:- SSO within Teams is an authentication method that uses an app user's Teams identity to provide them access to your app. A user who has logged into Teams doesn't need to log 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. + SSO within Teams is an authentication method that uses an app user's Teams identity to provide them with access to your app. A user who has logged into Teams doesn't need to log 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. * **Enable authentication using third-party OAuth provider**:- You can use a third-party OAuth Identity Provider (IdP) to authenticate your app users. The app user is registered with the identity provider, which has a trust relationship with your app. When the user attempts to log in, the identity provider validates the app user and provides them access to your app. Microsoft Entra ID is one such third party OAuth provider. You can use other providers, such as Google, Facebook, GitHub, or any other provider. + You can use a third-party OAuth Identity Provider (IdP) to authenticate your app users. The app user is registered with the identity provider, which has a trust relationship with your app. When the user attempts to log in, the identity provider validates the app user and provides them with access to your app. Microsoft Entra ID is one such third party OAuth provider. You can use other providers, such as Google, Facebook, GitHub, or any other provider. * **Enable SSO for nested apps**: You can use nested app authentication (NAA) to utilize SSO for authentication of apps nested (embedded) inside the supported Microsoft apps. Compared with existing full-trust authentication models and the on-behalf-of (OBO) flow, NAA provides better security and flexibility in app architecture, enabling the creation of rich, client-driven apps. Choose to add authentication for your app in one of the two ways: > * NAA is available only in [public developer preview](../../resources/dev-preview/developer-preview-intro.md). > * NAA is supported in MSAL.js v3.15 and higher. For the latest updates, see [changelog entries](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/CHANGELOG.md). +* **Enable authentication for your API based message extensions**: ++ You can enable the following authentication methods for your API-based message extension: ++ * **API key authentication**: Implement API key authentication to use a key token known only to the app and the API service to authenticate requests. For more information, see [API key authentication](../../messaging-extensions/api-based-secret-service-auth.md) ++ * **SSO authentication**: Microsoft Entra is a comprehensive identity and access management solution that provides secure authentication for API-based message extensions. It ensures that only authenticated users can access your appΓÇÖs features within Microsoft Teams. For more information, see [enable SSO for API-based message extensions](../../messaging-extensions/api-based-microsoft-entra.md). ++ * **None**: Update `none` as a value for `authorization` in an API-based message extension when the API doesn't require any authentication for the user. When Teams service sends a request to the API, it doesn't supply any authentication information. ++ ```json + "authorization": { + "authType": "none" + } + ``` + ## Select authentication method Enable authentication with SSO or third party OAuth IdPs in your tab app, bot app, and messaging extension app. Select one of the two methods for adding authentication in your app: |
platform | Apps Package | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/concepts/build-and-test/apps-package.md | An app package is a file format that has the required resources to install and r * **[App manifest](#app-manifest)**: Describes how your app is configured, including its capabilities, required resources, and other important attributes. * **[App icons](#app-icons)**: Each package requires a color and outline icon for your app. -To distribute your Microsoft Teams app, you need to zip the files in the app package folder and provide a suitable name. +To publish your Microsoft Teams app, you need to zip the files in the app package folder and provide a suitable name. ## Teams doesn't host your app Here's how app icons appear in different Teams capabilities and contexts. ## Next step -Choose how you plan to distribute your app: +Choose how you plan to publish your app: > [!div class="nextstepaction"] > [Upload your custom app in Teams](~/concepts/deploy-and-publish/apps-upload.md) |
platform | Apps Publish Overview | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/concepts/deploy-and-publish/apps-publish-overview.md | Title: Overview - Distribute your app + Title: Overview - Publish your app description: Learn to publish app to Teams Store or to your org. Understand how app's endpoints comply with your Government Community Cloud (GCC) organization's requirements. ms.localizationpriority: high Last updated 02/22/2023 -# Distribute your Microsoft Teams app +# Publish your Microsoft Teams app You can provide your Microsoft Teams app to an individual, team, organization, or anyone who wants to use it. How you distribute depends on several factors including users' needs, business, technical requirements, and your goals for the app. You can allow customers to customize some aspects of your Microsoft Teams app in ## Create Teams app package -To distribute your Teams app, you must have a valid app package. An app package is a zip file that contains an **app manifest** and **app icons**. +To publish your Teams app, you must have a valid app package. An app package is a zip file that contains an **app manifest** and **app icons**. ## Upload your app in Teams |
platform | Common Reasons For App Validation Failure | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/concepts/deploy-and-publish/appsource/common-reasons-for-app-validation-failure.md | Title: Reasons for App Validation Failure description: Learn about inadequate app description, improper screenshots, Partner Center and app manifest mismatch, valid domains violation, or broken app functionality. --++ ms.localizationpriority: high Last updated 12/15/2022 For more information, see [Teams Store validation guidelines for apps with AI-ge ## See also -* [Distribute your Microsoft Teams app](../apps-publish-overview.md) +* [Publish your Microsoft Teams app](../apps-publish-overview.md) * [Publish your app to the Microsoft Teams Store](publish.md) * [Microsoft Teams Store validation guidelines](prepare/teams-store-validation-guidelines.md) * [Microsoft Trademark and Brand Guidelines](https://www.microsoft.com/legal/intellectualproperty/trademarks) |
platform | Submission Checklist | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/concepts/deploy-and-publish/appsource/prepare/submission-checklist.md | Depending on your app functionality, you're required to provide Teams tenant con * Ensure that test accounts are safe-listed or configured with license keys, if applicable. * If your app requires users to log in or connect to external services, provide the required credentials to complete the login or connection with the external service.- * Ensure that phone-based two-way authentication is disabled for test accounts. * If the app provides a collaborative experience, provide a non-admin account for each user persona. For example, if your app is used by teachers and students, provide credentials for both user personas. * Ensure that at least one account has access to premium or upgraded features, if applicable. * All accounts you provide must include pre-populated data to help in testing. For example, if your app helps to provide market insights based on the user profile, ensure that market data is pre-populated along with a few user profiles. During submission, you're asked to categorize your app. App category helps impro | Maps and feeds | | Other | -### Distribute your app to specific countries or regions +### Publish your app to specific countries or regions If you want to cater your app to a specific audience, you can select from the available list of countries or regions and communicate whatΓÇÖs great about your app in ways that are relevant to users. This is known as Geo-filtering. Geo-filtering is applicable only for apps listed in the Teams Store. For example, a Contoso US app, which sells gift cards that are valid within the US and Canada is only visible in the Teams Store for the users in the US and Canada. |
platform | Teams Store Validation Guidelines | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/concepts/deploy-and-publish/appsource/prepare/teams-store-validation-guidelines.md | App packages must be correctly formatted and include all required information an > * **Clearly describe limitations**, conditions, or exceptions to the functionality, features, and deliverables in the app long description and related materials. > * **Emphasis on any considerations** for testers while validating your app submission. > * **Prepopulate the test accounts with dummy data** to aid testing.-> * If you are providing your test accounts, ensure that you enable third-party integration. Also, disable two-factor or multi-factor authentication. +> * If you are providing your test accounts, ensure that you enable third-party integration. [Back to top](#teams-store-validation-guidelines) |
platform | Update Apple Store Team Connect Id | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/concepts/deploy-and-publish/appsource/prepare/update-apple-store-team-connect-id.md | description: Update your Apple Developer Program Team ID in the Microsoft Partne ms.localizationpriority: medium -+ Last updated 12/15/2022 You can also refer to Apple's official documentation to locate Apple Developer P ## See also -* [Distribute your Microsoft Teams app](../../apps-publish-overview.md) +* [Publish your Microsoft Teams app](../../apps-publish-overview.md) * [Resolve issues if your Microsoft Teams store submission fails](~/concepts/deploy-and-publish/appsource/resolve-submission-issues.md) |
platform | Publish | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/concepts/deploy-and-publish/appsource/publish.md | Last updated 12/15/2022 # Publish your app to the Teams Store -You can distribute your app directly to the Microsoft Teams Store inside Microsoft Teams and reach millions of users around the world. If your app is also featured in the Teams Store, you can instantly reach potential customers. +You can publish your app directly to the Microsoft Teams Store inside Microsoft Teams and reach millions of users around the world. If your app is also featured in the Teams Store, you can instantly reach potential customers. Apps published to the Teams Store also automatically list on [the Microsoft commercial marketplace](https://appsource.microsoft.com), which is the official marketplace for Microsoft 365 apps and solutions. Teams provides intelligent search experience by matching the user input to the f * [Upload your Teams app](~/concepts/deploy-and-publish/apps-upload.md) * [Publish your Teams app to your org](/microsoftteams/tenant-apps-catalog-teams?toc=/microsoftteams/platform/toc.json&bc=/microsoftteams/breadcrumb/toc.json) * [Plan onboarding experience for users](../../design/planning-checklist.md#plan-beyond-app-building)-* [Distribute tab apps on mobile](../../../tabs/design/tabs-mobile.md#distribution) +* [Publish tab apps on mobile](../../../tabs/design/tabs-mobile.md#publish-to-teams-store) * [Test preview for monetized apps](prepare/Test-preview-for-monetized-apps.md) * [Microsoft Teams Store ranking parameters](post-publish/teams-store-ranking-parameters.md) |
platform | Resolve Submission Issues | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/concepts/deploy-and-publish/appsource/resolve-submission-issues.md | Once your app is approved, publishing usually takes 1-2 business days depending ## See also -[Distribute your Microsoft Teams app](../apps-publish-overview.md) +[Publish your Microsoft Teams app](../apps-publish-overview.md) |
platform | Glossary | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/get-started/glossary.md | Common terms and definitions used in Microsoft Teams developer documentation. | Term | Definition | | | |-| [Geo-filtering](../concepts/deploy-and-publish/appsource/prepare/submission-checklist.md#distribute-your-app-to-specific-countries-or-regions) | A Teams feature where you can cater your app to a specific audience from the available list of countries or regions and communicate whatΓÇÖs great about your app in ways that are relevant to users. | +| [Geo-filtering](../concepts/deploy-and-publish/appsource/prepare/submission-checklist.md#publish-your-app-to-specific-countries-or-regions) | A Teams feature where you can cater your app to a specific audience from the available list of countries or regions and communicate whatΓÇÖs great about your app in ways that are relevant to users. | | [Government community cloud (GCC)](../concepts/app-fundamentals-overview.md#government-community-cloud)| GCC environment provides compliance with federal requirements for cloud services. It includes FedRAMP High, Defense Federal Acquisition Regulations Supplement (DFARS), and requirements for criminal justice and federal tax information systems (CJI and FTI data types).| | [Government community cloud (GCC) High](../concepts/app-fundamentals-overview.md#government-community-cloud)|GCC high environments deliver compliance with Department of Defense (DoD) Security Requirements Guidelines, Defense Federal Acquisition Regulations Supplement (DFARS), and International Traffic in Arms Regulations (ITAR).<br>**See also**: [Department of Defense (DoD)](#d)| | [Graph API](../graph-api/proactive-bots-and-messages/graph-proactive-bots-and-messages.md) | A RESTful web API for Microsoft Graph that enables you to access Microsoft Cloud service resources. <br>**See also**: [Microsoft Graph Explorer](#m) | |
platform | Api Based Microsoft Entra | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/messaging-extensions/api-based-microsoft-entra.md | + + Title: SSO for API-based message extensions ++description: Learn how to enable Microsoft Entra SSO authentication, register a new app, configure access token, API scopes, and authorize client application. +ms.localizationpriority: medium ++ Last updated : 07/16/2024+++# Enable SSO for API-based message extensions ++Single sign-on (SSO) authentication method for API based message extension 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. Microsoft Entra SSO enables the app to silently obtain a user token that is issued for its resource by Microsoft Entra. The app can then authenticate this token and retrieve the user profile information without the user's consent. ++## Prerequisites ++Before you start, ensure you have the following: ++* An Azure account with an active subscription. +* Basic familiarity with Microsoft Entra ID and Teams app development. ++The following image shows how SSO works when a Teams app user attempts to access API-based message extension app: +++* The user invokes the API-based message extension app within Teams and invokes 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. +* If the user consents, Microsoft Entra 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 and extracts the user information from the token, such as the name, email, and object ID. +* After successful authentication, user is granted access to the API-based message extension. ++To enable SSO authentication for API-based message extension, follow these steps: ++* [Register a new app in Microsoft Entra ID](#register-a-new-app-in-microsoft-entra-id). +* [Configure scope for access token](#configure-scope-for-access-token). +* [Authenticate token](#authenticate-token). +* [Update app manifest](#update-app-manifest). ++## Register a new app in Microsoft Entra ID ++1. Open the [Azure portal](https://ms.portal.azure.com/) on your web browser. ++1. Select the **App registrations** icon. ++ :::image type="content" source="../assets/images/authentication/teams-sso-tabs/azure-portal.png" alt-text="Screenshot shows the Microsoft Entra admin center page."::: ++ The **App registrations** page appears. ++1. Select **+ New registration** icon. ++ :::image type="content" source="../assets/images/authentication/teams-sso-tabs/app-registrations.png" alt-text="Screenshot shows you the new registration page on Microsoft Entra admin center."::: ++ The **Register an application** page appears. ++1. 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. ++ :::image type="content" source="../assets/images/authentication/teams-sso-tabs/register-app.png" alt-text="Screenshot shows you the app registration page on Microsoft Entra admin center."::: ++1. 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. ++ <details> + <summary><b>Options for supported account types</b></summary> ++ | 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. | ++ </details> ++ > [!NOTE] + > You don't need to enter **Redirect URI** for enabling SSO for an API-based message extension app. ++1. 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."::: ++ The page with app ID and other app details is displayed. ++ :::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. Note and save the app ID from **Application (client) ID** to update the app manifest later. ++ Your app is registered in Microsoft Entra ID. You now have the app ID for your API-based message extension app. ++## 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. ++To configure scope and authorize trusted client applications, you must: ++* [Add App ID URI](#app-id-uri): Configure scope (permission) options for your app. Expose a web API and configure the app 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 don't have the opportunity to decline consent. ++### App ID URI ++1. Select **Manage** > **Expose an API** from the left pane. ++ The **Expose an API** page appears. ++1. Select **Add** to generate app ID URI in the form of `api://{AppID}`. ++ :::image type="content" source="../assets/images/Copilot/api-based-me-entra-sso-expose-api.png" alt-text="Screenshot shows you how to set app ID URI."::: ++ The section for setting app ID URI appears. ++1. Enter the **Application ID URI** in the format explained here. ++ :::image type="content" source="../assets/images/Copilot/api-based-me-entra-sso-app-id-uri.png" alt-text="Screenshot shows you the App ID URI in Microsoft Entra ID."::: ++ * The **Application ID URI** is prefilled with app ID (GUID) in the format `api://{AppID}`. + * The app 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}. ++ > [!IMPORTANT] + > + > * If you're building a standalone bot, enter the app ID URI as api://botid-{YourBotId}. Here, {YourBotId} is your Microsoft Entra app ID. + > * If you're building an app with a bot, a message extension, and a tab, enter the app ID URI as api://fully-qualified-domain-name.com/botid-{YourClientId}, where {YourClientId} is your bot app ID. + > * If you're building an app with a message extension or tab capabilities without the bot, enter the app ID URI as api://fully-qualified-domain-name.com/{YourClientId}, where {YourClientId} is your Microsoft Entra app ID. + > * **Application ID URI for app with multiple capabilities**: If you're building an API-based message extension, enter the app ID URI as `api://fully-qualified-domain-name.com/{YourClientId}`, where {YourClientId} is your Microsoft Entra app ID. + > * **Format for domain name**: Use only lower-case letters for domain name. ++1. Select **Save**. ++ A message pops up on the browser stating that the app ID URI was updated. ++ :::image type="content" source="../assets/images/authentication/teams-sso-tabs/app-id-uri-msg.png" alt-text="Screenshot shows you the app ID URI message."::: ++ The app ID URI displays on the page. ++ :::image type="content" source="../assets/images/Copilot/api-based-me-entra-sso-app-id-uri-final.png" alt-text="Screenshot shows you the app ID URI updated."::: ++1. Note and save the app ID URI to update the app manifest later. ++### Configure API scope ++> [!NOTE] +> +> * API-based message extension supports only the **access_as_user** scope. +> * The API receives a Microsoft Entra access 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. ++1. Select **+ Add a scope** in the **Scopes defined by this API** section. ++ :::image type="content" source="../assets/images/authentication/teams-sso-tabs/select-scope.png" alt-text="Screenshot shows you the select scope option."::: ++ The **Add a scope** page appears. ++1. Enter the details for configuring scope. ++ :::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."::: ++ 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**. ++ A message pops up on the browser stating that the scope was added. ++ :::image type="content" source="../assets/images/authentication/teams-sso-tabs/scope-added-msg.png" alt-text="Screenshot shows you the scope added message."::: ++ The new scope you defined displays on the page. ++ :::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."::: ++### Configure authorized client application ++1. Move through the **Expose an API** page to the **Authorized client application** section and select **+ Add a client application**. ++ :::image type="content" source="../assets/images/authentication/teams-sso-tabs/auth-client-apps.png" alt-text="Screenshot shows you the authorized client application."::: ++ The **Add a client application** page appears. ++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-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"::: ++ > [!NOTE] + > + > The Microsoft 365 client IDs for mobile, desktop, and web apps for Teams are the actual IDs that you must add. ++ 1. Select one of the following client IDs: ++ | Use client ID | For authorizing... | + | | | + | 1fec8e78-bce4-4aaf-ab1b-5451cc387264 | Teams mobile or desktop app | + | 5e3ce6c0-2b1f-4285-8d4b-75ee78787346 | Teams web app | ++ 1. Select the app ID URI you created for your app in **Authorized scopes** to add the scope to the web API you exposed. ++ 1. Select **Add application**. ++ A message pops up on the browser stating that the authorized client app was added. ++ :::image type="content" source="../assets/images/authentication/teams-sso-tabs/update-app-auth-msg.png" alt-text="Screenshot shows you the client application added message."::: ++ The authorized app's client ID displays on the page. ++ :::image type="content" source="../assets/images/authentication/teams-sso-tabs/client-app-added.png" alt-text="Screenshot shows you the client app added."::: ++> [!NOTE] +> You can authorize more than one client application. Repeat the steps of this procedure for configuring another authorized client application. ++You've successfully configured app scope, permissions, and client applications. Ensure that you note and save the app ID URI. Next, you configure the access token version. ++## Authenticate token ++When the message extension calls the API during authentication, it receives a request with the userΓÇÖs access 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. For more claims, see [ID token claims](/entra/identity-platform/access-tokens#validate-tokens). ++ The following example shows the 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. For more information on claims reference with details on the claims included in access tokens, see [access token claims](/entra/identity-platform/access-token-claims-reference). ++## Update app manifest ++Update the following properties in the app manifest file: ++* `webApplicationInfo`: The `webApplicationInfo` property is used to enable SSO for your app to help app users access your API-based message extension app seamlessly. The app ID URI that you registered in Microsoft Entra ID is configured with the scope of the API you exposed. 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 SSO authentication for your app. Configure the `supportsSingleSignOn` property to `true` to support SSO and reduce the need for multiple authentications. If the property is set to `false` or is left empty, the user can't upload the app to Teams and the app fails validation. ++To configure app manifest: ++1. Open the API-based message extension app. +2. Open the app manifest folder. ++ > [!NOTE] + > + > * The app manifest folder should be at the root of your app folder. 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 into the `webApplicationInfo` section of your app manifest file: ++ ```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. + * `api://subdomain.example.com/{Microsoft Entra AppId}` is the app ID URI that you registered when creating scope in Microsoft Entra ID. ++1. Add the following code snippet into the `composeExtensions` section of your app manifest file: ++ ```json + "authorization": { + "authType": "microsoftEntra", + ΓÇ£microsoftEntraConfigurationΓÇ¥: { + ΓÇ£supportsSingleSignOnΓÇ¥: true + } + }, + ``` + +1. Save the app manifest file. ++Congratulations! You've enabled SSO for your API-based message extensions. ++## See also ++* [Create API-based message extension](create-api-message-extension.md) +* [API key authentication](api-based-secret-service-auth.md) +* [Authenticate users in Microsoft Teams](../concepts/authentication/authentication.md) |
platform | Api Based Overview | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/messaging-extensions/api-based-overview.md | -# Build message extensions using API +# API-based message extension > [!NOTE] > 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. 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: +Message extensions built using API (API-based) use a web service to manage user requests and responses and don't require a bot registration. 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. 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. --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. +* Retrieve knowledge-based information, for example, my teamΓÇÖs design files in Figma See the video to learn more about building an API-based message extension using Teams Toolkit: </br> See the video to learn more about building an API-based message extension using > [!VIDEO https://www.youtube.com/embed/jSYNHz6hz4Y?si=htmfWtlY9bYH_RT2] +<br> ++|Traditional bot-based message extensions |API-based message extensions | +||| +|Developers need to build, deploy, and maintain a service to handle invoke commands from the Teams client. | If the end-service's APIs can be described using the OpenAPI Specification, developers can eliminate the need for the middle-layer handling service. | +|This service processes the incoming query and makes a call to the developerΓÇÖs end-service. | Teams can directly use the [OpenAPI Specification](https://swagger.io/resources/open-api/) to build requests and communicate with the developer's end-service. | ++The following images show the flow of user queries through Traditional message extensions and API message extensions: ++*User query flow using Traditional Message Extensions. The developer must maintain a custom bot handler service, which handles the requests from a Teams bot. The handler service sends a request to the developerΓÇÖs service when a query is invoked.* ++<br> ++*User query flow using API Message Extensions. There's no need for a developer maintained handler service as long as the interaction is clearly outlined in the OpenAPI Specification in the App Package.* ++<br> +<br> ++Here's a high-level sequence of events that occur during a query command invocation: ++1. When a user invokes a query command, the parameters of the query command are received by the Teams Bot Service. ++1. The query command is defined inside the app manifest file. The command definition contains a reference to the `operationId` inside the OpenAPI Specification file along with the details of the parameters that the Teams client renders for that command. For reference, the `operationId` inside the OpenAPI Specification file is unique to a particular HTTP operation. ++1. The Teams Bot Service then uses the parameters supplied by the user along with the copy of the OpenAPI Specification for the associated `operationId` to build an HTTP request for the developerΓÇÖs endpoint. ++1. If authentication is required and is configured in the manifest. It's resolved to the appropriate token or key. This token or key is used as part of the outgoing request. *[Optionally]* ++1. The Teams bot service performs the HTTP request to the developerΓÇÖs service. ++1. The developerΓÇÖs service should respond in accordance with the schema outlined in the OpenAPI Specification. This is in JSON format. ++1. The Teams client must show the results back to the user. To convert the JSON results from the previous step to UI, the Teams bot service uses the response Rendering template to build an Adaptive Card for each result. ++1. The Adaptive Cards are sent to the client, which renders them in the UI. ++ ## Prerequisites -Before you get started, ensure that you adhere to the following requirements: +The app definition package includes various compelling artifacts that support the functionality of this feature. Before you get started, ensure that have a basic understanding of the following files: > [!div class="checklist"] >-> * [OpenAPI Description (OAD)](#openapi-description) -> * [Update app manifest](#update-app-manifest) +> * [OpenAPI Description (OAD)](#openapi-description-oad) +> * [App manifest](#app-manifest) +> * [Response rendering template](#response-rendering-template) ++### OpenAPI Description (OAD) ++OpenAPI description documenat is an adopted industry standard for describing APIs. It allows you to abstract your APIs from their implementation, providing language-agnostic definitions that are both human-readable and machine-readable. The OpenAPI description documenat outlines the interactions your extension supports, enabling Teams to build requests and communicate directly with your service without the need for a middle-layer handling service. ++An OpenAPI description document contains details to communicate with the developerΓÇÖs service. Ensure that you adhere to following guidelines for OpenAPI Description (OAD) document: ++* OpenAPI versions 2.0 and 3.0.x are supported. +* 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 POST and GET HTTP methods are supported. +* 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: ++<details><summary>Sample OpenAPI Description document</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. +``` ++</details> +<br> ++For more information on how to write OpenAPI definitions in YAML, see [OpenAPI structure.](https://swagger.io/docs/specification/basic-structure/) ++### App manifest ++App manifest is a blueprint for your Teams app, defining how and where the message extension is invoked within the Teams client. It includes the commands your extension supports and the locations from which they can be accessed, such as the compose message area, command bar, and message. The manifest links to the OpenAPI Specification and the Response Rendering Template to ensure proper functionality. ++App manifest contains query command definition. 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 document 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 document. +* 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 document. +* Ensure that the name of parameters for each command in the app manifest match exactly with the corresponding name of the parameter defined for the operation in the OpenAPI Description document. +* A response rendering template must be defined per command, which is used to convert responses from an API. +* The command and parameter descriptions must not exceed 128 characters. -### OpenAPI Description +The following is an app manifest example with definitions for API-based message extensions: -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. +<details><summary>App manifest example</summary> ++ ```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": [] + } + ``` ++</details> ++#### 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). ### 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. +> [!NOTE] +> +> Teams supports Adaptive Cards up to version 1.5. When using Adaptive Card designer, ensure that you change the target version to 1.5. ++Response rendering template is a predefined format that dictates how the results from your API are displayed within Teams. It uses templates to create Adaptive Cards or other UI elements from the APIΓÇÖs response, ensuring a seamless and integrated user experience within Teams. The template defines the layout and style of the information presented, which can include text, images, and interactive components. Ensure that you adhere to following guidelines for response rendering template: ++* Define the schema reference URL in the `$schema` property to establish the structure of your template to the [response rendering template schema](https://developer.microsoft.com/json-schemas/teams/v1.17/MicrosoftTeams.ResponseRenderingTemplate.schema.json). +* The supported values for `responseLayout` are `list` and `grid`, which determine how the response is visually presented. For more information on the layout, see [respond to user requests](how-to/search-commands/respond-to-search.md#respond-to-user-requests). +* A `jsonPath` is rerequired 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 Adaptive Card 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", + "$schema": "developer.microsoft.com/json-schemas/teams/v1.17/MicrosoftTeams.ResponseRenderingTemplate.schema.json", + "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}" + } + } + } + ``` ++ </details> ++ **Preview Card** ++A preview card template in the response rendering template schema is used to map JSON responses to a preview card that users see when they select a search result. The preview card then expands into an Adaptive Card in the message compose box. The preview card template is part of the response rendering template, which also includes an Adaptive Card template and metadata. ++ :::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 'test app' returns five cards showing 'Title', 'Description' (truncated) and 'AssignedTo' properties and values in each one."::: ++ **Expanded Adaptive Card** ++ :::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."::: -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). +#### Parameters -### Update app manifest +|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 | -Update app manifest (previously called Teams app manifest) with the `composeExtensions` property. The following code is an example of the app manifest with the `composeExtensions` property: +#### Json path ++The [JSON path](https://www.newtonsoft.com/json/help/html/QueryJsonSelectToken.htm) 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. This tool can be used. You can use the [JSON tool](https://jsonpath.com/) to validate if a JSON path is correct. 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. ++**Example** +Let's say you have the following JSON for a list of products and you want to create a card result for each entry. ```json {- "composeExtensions": [ - { - "composeExtensionType": "apiBased", - "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" - } + "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". ++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. Teams supports cards up to version 1.5 while the designer supports 1.6. ++## OpenAPI schema conversion ++> [!NOTE] +> We send an accept-language header in the HTTP request that is sent to the endpoint defined in the OpenAPI description document. The accept-language is based on the Teams client locale and can be used by the developer for returning back a localized response. ++The following data types in the OpenAPI description document are converted into elements within an Adaptive Card 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> ++</details> ## Next step |
platform | Api Based Secret Service Auth | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/messaging-extensions/api-based-secret-service-auth.md | + + Title: API secret service auth ++description: Learn how to enable API key authentication and register an API key for API_based message extensions. +ms.localizationpriority: medium ++ Last updated : 07/16/2024+++# API key authentication ++API key authentication is a method used to authenticate access to your message extension app using an API. It involves using a unique API key, which is passed with each API request to verify the identity of the user or the app that initiated the request. The API key must be registered in Microsoft Teams and when a user interacts with your message extension, Teams uses the secret to authenticate with your API. ++The following API key registration properties help you to secure your key and ensure it's limited to your application: ++* **Base URL**: Teams transmits the secret to URL endpoints that begin with the value in this field. +* **Target Tenant**: To limit API access to your Microsoft 365 tenant or any tenant. +* **App ID**: To limit the key access to a specific app or any app. +* **API key**: To authenticate access to your app. ++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 must contain the API key registration ID returned when you submitted the API key through the Developer Portal for Teams. ++> [!NOTE] +> You must ensure to secure the API key registration ID as it can be retrieved from the Teams app manifest. For more information on securing your API key, see [best practices](#best-practices). ++When an API request is initiated, the system retrieves the API key from an encrypted database and includes it in the authorization header, using the bearer token scheme. The system sends the authorization header with the API key to the endpoint defined in the app manifest. ++The following example shows the payload with the authorization header using the bearer token scheme: ++```https +GET https://example.com/search?myQuery=test +Accept-Language: en-US +Authorization: Bearer <MY_API_KEY> +``` ++## Register an API key ++To register an API key, follow these steps: ++1. Go to **Tools** > **API key registration**. ++ :::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, select **+ Add Secret**. The **Add an API key** dialog appears. ++1. Enter a value for the key and select **Save**. ++ > [!NOTE] + > You can maintain up to two API keys. If you need to replace one, you can do so without service interruption, as Teams uses the other configured key during the update process. ++ :::image type="content" source="../assets/images/Copilot/api-based-me-api-key-secret.png" alt-text="Screenshot shows Add an API key dialog to add API key for your app."::: ++1. Under **API key name**, add a meaningful name for the API Key. For example, API key for Contoso message extension. ++1. Under **Base URL**, specify a common base URL for all the API endpoints that must be called. This URL must start with https, include a fully qualified domain name, and optionally, a path. Teams transmits the key to URL endpoint that begins with the value in this field. For example, `https://api.yelp.com`. ++ Base URL ensures that the key remains secure and isn't leaked to random endpoints, even if another app illicitly acquires the API key registration ID and incorporates it into their own app. If the URL registered in the API key configuration isn't a prefix for the target endpoints defined in the OpenAPI spec, the call gets dropped. ++ :::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 **Target tenant**, select any of the following: ++ * **Home tenant**: The API key is only functional within the tenant where it's registered. + * **Any tenant**: The API key is usable in any tenant. ++ :::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 **Target Teams app**, select any of the following: ++ * **Existing Teams app**: The **Existing Teams app** option binds the API key registration ID to your specific Teams app. + * **Any Teams app**: The API key can be used with any Teams app. ++ <!-- Adding a domain ensures that the key isn't exposed to random endpoints. However, the API secret registration ID is publicly accessible and can be added to random apps, potentially allowing unwanted callers authorization to a developer's endpoint. To prevent this, you can bind the registration to a specific app and Teams rejects requests for any app other than the one specified in the secret registration. --> ++ :::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."::: ++ An **API key registration ID** is generated. ++ :::image type="content" source="../assets/images/Copilot/api-based-me-api-key-reg-id.png" alt-text="Screenshot shows the API key registration ID generated in Developer Portal for Teams."::: ++1. In Developer portal for Teams, select **Apps** and select an app where you want to add the API key. ++1. Go to **App features** > **Message extension**. ++1. Under **Authentication**, select **API key** and add the API key registration ID. ++ :::image type="content" source="../assets/images/Copilot/api-based-me-auth-add-key.png" alt-text="Screenshot shows an example of the Authentication section with none and API key options in Developer Portal for Teams."::: ++1. Select **Save**. ++The API key registration ID is updated as the value for the `apiSecretRegistrationId` property in app manifest. You can verify your API key registration ID in app manifest in the Developer Portal for Teams. ++## Update app manifest ++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) ++```json +"composeExtensions": [ + { + "composeExtensionType": "apiBased", + "authorization": { + "authType": "apiSecretServiceAuth", + "apiSecretServiceAuthConfiguration": { + "apiSecretRegistrationId": "9xxxxb0f-xxxx-40cc-xxxx-15xxxxxxxxx3" + } + }, +``` ++## Best practices ++* **API key**: + * The API key must have at least 10 characters and at most 128 characters. + * After you update the API key, it takes up to one hour for the key to reflect throughout the system. ++* **Base URL**: + * The base URL must begin with `https` to ensure secure communication. + * You must include the full host name to specify the exact domain. + * You can add an optional path to define a specific entry point for the API. ++ This structure is crucial for the security of your API key(s), as Teams sends API key to endpoints that start with the specified Base URL. ++* **Target tenant**: As you develop your app within your Microsoft 365 tenant, you'll initially test it as a custom app built for your org (LOB app) or custom app. During this stage, you must register the API key with your **Home tenant** as the target tenant to ensure that the key remains exclusive to your tenant. ++ After you've completed testing and are ready to submit your app manifest to the Partner Center for the Teams Store, you'll need to switch the target tenant setting to **Any tenant**. This change allows your API key registration ID to be used across various tenants once your app is available in the Teams Store. ++* **Teams app ID**: As you develop your app within your Microsoft 365 tenant and start to test it as a custom app built for your org (LOB) or custom app, you must set the API key registration ID with the Teams app ID as **Any Teams app**. This configuration allows the key to be used with any Teams app uploaded as a custom app and custom apps built for your org (LOB apps) to generate IDs after they're uploaded. You won't have the app's ID at this stage. ++ Your key's security is still maintained through the **Home Tenant** and **Base URL**. When you're ready to release your app to the world, you need to change the Teams app ID setting to **Existing Teams app** and enter your Teams app ID. Finally, submit your app manifest to the Partner Center for inclusion in the Teams Store. Your API key registration is now tied to your specific Teams app and can't be used with others. ++## See also ++* [Create API-based message extension](create-api-message-extension.md) +* [Configure your API based message extension in Microsoft Entra ID](api-based-microsoft-entra.md) +* [Authenticate users in Microsoft Teams](../concepts/authentication/authentication.md) |
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: API-based Message Extension Guidelines + Title: Authentication for API-based Message Extension description: Learn about the requirements and troubleshooting guidelines for an API-based message extension, authentication, register an API key, and schema mapping. ms.localizationpriority: medium-# Build API-based message extension +# Enable authentication for API-based message extensions -> [!NOTE] -> API-based message extensions only support search commands. +Authentication is a fundamental aspect of security and serves as the first line of defense that ensures access to systems, applications, and data is granted only to those with verified credentials. Authentication for API-based message extensions is crucial for the following reasons: -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. +* **Security**: Protects against unauthorized access and potential breaches, safeguarding both user data and the integrity of the system. +* **Data Privacy**: Ensures that personal and sensitive information is only accessible to users with the correct permissions. -Before you get started, ensure that you meet the following requirements: --</br> -<details><summary id="oad">1. OpenAPI Description (OAD) </summary> --Ensure that you adhere to following guidelines for OpenAPI Description (OAD) document: --* OpenAPI versions 2.0 and 3.0.x are supported. -* 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 POST and GET HTTP methods are supported. -* 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 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. 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. -- ```json - { - "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.17/MicrosoftTeams.schema.json", - + "manifestVersion": "1.17", - "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": "9xxxxxxx-7xxx-4xxx-bxxx-1xxxxxxxxxxx" - + } - + }, - + "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 id="response-template">3. Response rendering template</summary> --> [!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}" - } - } - } - ``` -- </details> -- **Preview Card** -- :::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."::: -- **Expanded Adaptive Card** -- :::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."::: --#### 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 | --#### Json path --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. --**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. --```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". --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 - ``` -- * **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> --</details> --## Authentication +* **User Trust**: Builds confidence among users that their interactions with the app are secure, which is essential for user adoption and engagement. 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: -<details><summary id="none">none</summary> -<br> --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. --```json - "authorization": { - "authType": "none" - } - }, -``` --</details> -<br/> --<details><summary id="secret-service-auth">Secret service auth</summary> --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. --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. --### Register an API key --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. --To register an API Key, follow these steps: --1. Go to **Tools** > **API key registration**. -- :::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] - > - > * 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. -- :::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."::: --An **API key registration ID** is generated. ---Copy and save the API key registration ID and update it as a value for the `apiSecretRegistrationId` property in the app manifest. --### Update app manifest --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) --```json -"composeExtensions": [ - { - "composeExtensionType": "apiBased", - "authorization": { - "authType": "apiSecretServiceAuth", - "apiSecretServiceAuthConfiguration": { - "apiSecretRegistrationId": "9xxxxb0f-xxxx-40cc-xxxx-15xxxxxxxxx3" - } - }, -``` --</details> -<br/> --<details><summary id="microsoft-entra">Microsoft Entra </summary> --`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. --### Prerequisites --Before you start, ensure you have the following: +* **API key authentication**: Implement API key authentication to use a key token known only to the app and the API service to authenticate requests. API key authentication involves using a unique key to verify the identity of users or apps accessing your API-based message extension app through an API. The key must be registered in Microsoft Teams. When users interact with your API-based message extension, Teams uses the API key to authenticate with your API. You can register through the Developer Portal for Teams and update the app manifest with the appropriate configuration. For more information, see [API key authentication](api-based-secret-service-auth.md). -* An Azure account with an active subscription. -* Basic familiarity with Microsoft Entra ID and Teams app development. +* **SSO authentication**: Microsoft Entra is a comprehensive identity and access management solution that provides secure authentication for API-based message extensions. It ensures that only authenticated users can access your appΓÇÖs features within Microsoft Teams. -The following image shows how SSO works when a Teams app user attempts to access API-bsed message extension app: + You can implement authentication in API-based message extension to provide secure and seamless access to app. If your message extension requires authentication, update your app manifest as follows: + * Add the `authorization` property under `composeExtensions`. + * Define the type of authentication for your app by setting the `authType` property under `authorization`. -* 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 returns the response to the user in Teams. + For more information, see [configure your app in Microsoft Entra ID](api-based-microsoft-entra.md). -To enable `microsoftEntra` authentication method for API-based message extension, follow these steps: --### Register a new app in Microsoft Entra ID --1. Open the [Azure portal](https://ms.portal.azure.com/) on your web browser. --2. Select the **App registrations** icon. -- :::image type="content" source="../assets/images/authentication/teams-sso-tabs/azure-portal.png" alt-text="Microsoft Entra admin center page."::: -- The **App registrations** page appears. --3. Select **+ New registration** icon. -- :::image type="content" source="../assets/images/authentication/teams-sso-tabs/app-registrations.png" alt-text="New registration page on Microsoft Entra admin center."::: -- The **Register an application** page appears. --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. -- :::image type="content" source="../assets/images/authentication/teams-sso-tabs/register-app.png" alt-text="App registration page on Microsoft Entra admin center."::: --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. -- <details> - <summary><b>Options for supported account types</b></summary> -- | 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. | -- </details> -- > [!NOTE] - > You don't need to enter **Redirect URI** for enabling SSO for an API-based message extension app. --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."::: -- The page with app ID and other configurations is displayed. -- :::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."::: --8. Note and save the app ID from **Application (client) ID** to update the app manifest later. -- Your app is registered in Microsoft Entra ID. You now have the app ID for your API-based message extension app. --### 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. --To configure scope and authorize trusted client applications, you need: --* [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 only let 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 don't have the opportunity to decline consent. --#### Application ID URI --1. Select **Manage** > **Expose an API** from the left pane. -- The **Expose an API** page appears. --1. Select **Add** to generate application ID URI in the form of `api://{AppID}`. -- :::image type="content" source="../assets/images/Copilot/api-based-me-entra-sso-expose-api.png" alt-text="Set app ID URI"::: -- The section for setting application ID URI appears. --1. Enter the **Application ID URI** in the format explained here. -- :::image type="content" source="../assets/images/Copilot/api-based-me-entra-sso-app-id-uri.png" alt-text="Application ID URI"::: -- * 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}. -- > [!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 on Android. | - > - > Use the lower-case option *demoapplication* as base resource name. --1. Select **Save**. -- A message pops up on the browser stating that the application ID URI was updated. -- :::image type="content" source="../assets/images/authentication/teams-sso-tabs/app-id-uri-msg.png" alt-text="Application ID URI message"::: -- The application ID URI displays on the page. -- :::image type="content" source="../assets/images/Copilot/api-based-me-entra-sso-app-id-uri-final.png" alt-text="Application ID URI updated"::: --1. Note and save the Application ID URI to update the app manifest later. --#### Configure API scope --> [!NOTE] -> API-based message extension support **access_as_user** scope only. --1. Select **+ Add a scope** in the **Scopes defined by this API** section. -- :::image type="content" source="../assets/images/authentication/teams-sso-tabs/select-scope.png" alt-text="Select scope"::: -- The **Add a scope** page appears. --1. Enter the details for configuring scope. -- :::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."::: -- 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**. -- A message pops up on the browser stating that the scope was added. -- :::image type="content" source="../assets/images/authentication/teams-sso-tabs/scope-added-msg.png" alt-text="Scope added message"::: -- The new scope you defined displays on the page. -- :::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."::: --#### Configure authorized client application --1. Move through the **Expose an API** page to the **Authorized client application** section, and select **+ Add a client application**. -- :::image type="content" source="../assets/images/authentication/teams-sso-tabs/auth-client-apps.png" alt-text="Authorized client application"::: -- The **Add a client application** page appears. --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-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"::: -- > [!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. -- 1. Select one of the following client IDs: -- | Use client ID | For authorizing... | - | | | - | 1fec8e78-bce4-4aaf-ab1b-5451cc387264 | Teams mobile or desktop application | - | 5e3ce6c0-2b1f-4285-8d4b-75ee78787346 | Teams web application | -- 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. Select **Add application**. -- A message pops up on the browser stating that the authorized client app was added. -- :::image type="content" source="../assets/images/authentication/teams-sso-tabs/update-app-auth-msg.png" alt-text="Client application added message"::: -- The authorized app's client ID displays on the page. -- :::image type="content" source="../assets/images/authentication/teams-sso-tabs/client-app-added.png" alt-text="Client app added and displayed"::: --> [!NOTE] -> You can authorize more than one client application. Repeat the steps of this procedure for configuring another authorized client application. --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. --### Update app manifest --> [!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."::: --* `authorization.microsoftEntraConfiguration`: Enables single sign-on (SSO) authentication for your message extension. Configure the `supportsSingleSignOn` property to `true` to support SSO and reduce the need for multiple authentications. For more information, see [composeExtensions](../resources/schem#composeextensions). --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** +* **None**: Update `none` as a value for `authorization` in an API-based message extension when the API doesn't require any authentication for the user. When Teams service sends a request to the API, it doesn't supply any authentication information. ```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 - } - }, + "authorization": { + "authType": "none" + } ``` -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 a 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. --For more information on how to validate an access token, see [validate tokens](/azure/active-directory/develop/access-tokens#validate-tokens). --There are several libraries to validate JSON Web Tokens (JWT). For basic validation, ensure that you check the following: --* The token is well-formed. -* The token was issued by the intended authority. -* The token is targeted to the web API. --When validating the token, ensure the following: --* Valid SSO tokens are issued by Microsoft Entra ID. The `iss` claim in the token must start with this value. -* The `aud1` parameter in the token must match the app ID from Microsoft Entra app registration. -* The token's `scp` parameter is set to `access_as_user`. --</details> -<br/> --### Troubleshooting --* 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."::: --* If you encounter any issues while running your app in Teams, use the following troubleshooting steps to identify and resolve your issue: -- * **Network**: Select the **Network** tab in Developer tools to inspect network activity -- 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. 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. -- :::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."::: -- **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, due to a server-side issue. --* **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. +## See also -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. +* [Create API-based message extension](create-api-message-extension.md) +* [Authenticate users in Microsoft Teams](../concepts/authentication/authentication.md) |
platform | Create Api Message Extension | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/messaging-extensions/create-api-message-extension.md | Last updated 09/16/2024 # Create an API-based message extension +> [!NOTE] +> API-based message extensions only support search commands. ++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 id="oad">1. OpenAPI Description (OAD) </summary> ++Ensure that you adhere to following guidelines for OpenAPI Description (OAD) document: ++* OpenAPI versions 2.0 and 3.0.x are supported. +* 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 POST and GET HTTP methods are supported. +* 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 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. 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. ++ ```json + { + "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.17/MicrosoftTeams.schema.json", + + "manifestVersion": "1.17", + "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": "9xxxxxxx-7xxx-4xxx-bxxx-1xxxxxxxxxxx" + + } + + }, + + "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 id="response-template">3. Response rendering template</summary> ++> [!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}" + } + } + } + ``` ++ </details> ++ **Preview Card** ++ :::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."::: ++ **Expanded Adaptive Card** ++ :::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."::: ++#### 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 | ++#### Json path ++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. ++**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. ++```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". ++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 + ``` ++ * **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> ++</details> + 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, follo 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. Enter a name of the app and select the **Manifest version** as **Public developer preview (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."::: You can add commands and parameters to your message extension, to add commands: 1. Select **Save**. +1. Under **Authentication**, select any of the following options: ++ * **No Authentication** + * **API key** + An API-based message extension is created. :::image type="content" source="../assets/images/Copilot/api-based-me-tdp-plugin-copilot.png" alt-text="Screenshot shows the plugin for Microsoft 365 Copilot created in the app features page in Teams Developer Portal."::: To build an API-based message extension using Teams Toolkit for Visual Studio Co npm run keygen ``` - The API key is generated as **Generated a new API Key: xxx...**. The generated API key is registered and recorded in the [API key registration tool](https://dev.teams.microsoft.com/api-key-registration) in Developer portal for Teams. For more information on API key registration, see [Register an API key](build-api-based-message-extension.md#register-an-api-key). + The API key is generated as **Generated a new API Key: xxx...**. The generated API key is registered and recorded in the [API key registration tool](https://dev.teams.microsoft.com/api-key-registration) in Developer portal for Teams. For more information on API key registration, see [Register an API key](api-based-secret-service-auth.md#register-an-api-key). 4. Enter the generated API key into your `env/.env.*.user` file. Replace `<your-api-key>` with the actual key: To build an API-based message extension, follow these step-by-step guides: * [For beginners](../sbs-api-msg-ext-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.++## See also ++[Authentication for API-based message extensions](build-api-based-message-extension.md) |
platform | Troubleshoot | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/resources/troubleshoot.md | If you're attempting to upload an updated package with the same ID again, choose If you're not re-uploading an updated package, ensure that the ID is unique. +### Error while uploading app in Teams ++* 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](../messaging-extensions/api-based-overview.md#app-manifest) and the [OpenAPI Description (OAD)](../messaging-extensions/api-based-overview.md#openapi-description-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."::: ++* If you encounter any issues while running your app in Teams, use the following troubleshooting steps to identify and resolve your issue: ++ * **Network**: Select the **Network** tab in Developer tools to inspect network activity ++ 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. 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. ++ :::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."::: ++ **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, due to a server-side issue. ++* **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. ++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. + ## See also * [Build tabs for meeting](../apps-in-teams-meetings/build-tabs-for-meeting.md) |
platform | Tabs Mobile | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/tabs/design/tabs-mobile.md | Mobile clients function with low bandwidth and intermittent connections. Your ap You must validate that your tab functions properly on mobile devices of various sizes and qualities. For Android devices, you can use [DevTools](~/tabs/how-to/developer-tools.md) to debug your tab while it's running. It's recommended that you test on both high and low-performance devices, including a tablet. -## Distribution +## Publish to Teams Store Apps listed on the Teams Store must be approved for mobile use to function properly in the Teams mobile client. Tab availability and behavior depends on whether your app is approved. |
platform | Teamsfx Preview And Customize App Manifest | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/toolkit/TeamsFx-preview-and-customize-app-manifest.md | For example, you can put your manifest.json file in `test/test.json`, and update 1. You can define your own environment variables. The default manifest.json contains some placeholders with format of ${{xx_xx}}. You can define your own environment variables and add placeholders in the manifest.json file. For example, you can customize app description by defining a new environment variable in env/.env.xx file, and update manifest.json with corresponding placeholder. -`.env.dev` + `.env.dev` -```text - TEAMS_APP_DESCRIPTION=This is an amazing app -``` + ```text + TEAMS_APP_DESCRIPTION=This is an amazing app + ``` + `manifest.json` -`manifest.json` --```json + ```json {- "$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.16/MicrosoftTeams.schema.json", - "manifestVersion": "1.16", + "$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.17/MicrosoftTeams.schema.json", + "manifestVersion": "1.17", "description": { "short": "${{TEAMS_APP_DESCRIPTION}}", "full": "Full description of tab0418" }, }-``` + ``` ++1. Starting with Teams Toolkit 5.10, using the `file` function you can store the value of a field, such as a lengthy or multiline app description, in a separate text file. For example, create a `description.txt` file in the parent folder of `manifest.json` to store your app's complete description. Then, set the value of `description.full` in `manifest.json` as `$[file('description.txt')]`. Teams Toolkit reads the content from the text file and uses it as full description when building an app package. ++ `description.txt` ++ ```text + This is the full description. + ``` ++ `manifest.json` ++ ```json + { + "$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.17/MicrosoftTeams.schema.json", + "manifestVersion": "1.17", + "description": { + "short": "Short description of tab", + "full": "$[file('./description.txt')]" + }, + } + ``` ++ You can also add the file path in `env/.env.xx`. Then, modify the parameter of `file()` to a placeholder in the `${{xx_xx}}` format. +++ `.env.dev` ++ ```text + DESCRIPTION_PATH=./description.txt + ``` ++ `manifest.json` ++ ```json + { + "$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.17/MicrosoftTeams.schema.json", + "manifestVersion": "1.17", + "description": { + "short": "Short description of tab", + "full": "$[file(${{DESCRIPTION_PATH}})]" + }, + } + ``` ++ ## Validate your app |
platform | Debug Apps In Teams Desktop Client | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/toolkit/debug-apps-in-Teams-desktop-client.md | + + Title: Debug your apps in Teams Desktop Client ++description: Learn how to debug your bot, Copilot plugin, custom engine agent, message extension apps in Teams desktop client using Teams Toolkit. ++ms.localizationpriority: high + Last updated : 10/22/2024+++# Debug in Teams desktop client ++Microsoft Teams Toolkit helps you to debug and preview your Microsoft Teams app in desktop client. During the debug process, Teams Toolkit automatically starts app services, opens debuggers, and uploads Teams app. You can preview your Teams app in Teams desktop client after debugging. ++The following are the advantages of Teams desktop client: ++* Improves performance. +* Reduces time-to-F5. +* Improves coverage of debug targets. ++## Capabilities of Teams desktop client ++Teams desktop client incorporates debugging capabilities in the following app templates scaffolded by the Teams Toolkit: ++* Bot. +* Copilot plugin. +* Custom engine agent. +* Message extension. ++## Prerequisites ++Ensure you install the following tools for building and deploying your app in Teams desktop client: ++| | Install | For using... | +| | | | +| | [Teams Toolkit](install-Teams-Toolkit.md) | A Microsoft Visual Studio Code extension that creates a project scaffolding for your app. Use the latest prerelease version. | +| | [Node.js](https://nodejs.org/en/download/) | Back-end JavaScript runtime environment. For more information, see [node.js version compatibility table for project type](~/toolkit/build-environments.md#nodejs-version-compatibility-table-for-project-type). | +| | [Visual Studio Code](https://code.visualstudio.com/download) | JavaScript, TypeScript, or SharePoint Framework (SPFx) build environments. Use the latest version. | +| | [Microsoft 365 developer account](../concepts/build-and-test/prepare-your-o365-tenant.md)| Access to Teams account with the appropriate permissions to install an app. | ++## Debug in Teams desktop client ++**To debug your custom engine agent app in Teams desktop client** ++1. Open Visual Studio Code (VS Code) and log into your Microsoft 365 account through Teams Toolkit. ++1. Select the Teams Toolkit :::image type="icon" source="../assets/images/teams-toolkit-v2/teams-toolkit-sidebar-icon.PNG" border="false"::: icon in the VS Code **Activity Bar** and then select **Create a New App**. ++ :::image type="content" source="../assets/images/teams-toolkit-v2/debug-apps-in-teams-desktop-client/create-project.png" alt-text="Screenshot shows the location of the Create New Project link in the Teams Toolkit sidebar."::: ++1. Select **Custom Engine Agent**. ++ :::image type="content" source="../assets/images/teams-toolkit-v2/debug-apps-in-teams-desktop-client/custom-engine-copilot.png" alt-text="Screenshot shows the Teams Toolkit app templates."::: ++1. Select **Basic AI Chatbot**. ++ :::image type="content" source="../assets/images/teams-toolkit-v2/debug-apps-in-teams-desktop-client/app-feature.png" alt-text="Screenshot shows the app capabilities to add to your new app."::: ++1. Select **JavaScript**. ++ :::image type="content" source="../assets/images/teams-toolkit-v2/first-bot/select-language-tab.png" alt-text="Screenshot shows the option to select the programming language."::: ++1. Select **OpenAI**. ++ :::image type="content" source="../assets/images/teams-toolkit-v2/debug-apps-in-teams-desktop-client/service-for-large-language-model.png" alt-text="Screenshot shows LLM in Visual Studio Code."::: ++1. Enter the OpenAI service key. ++ :::image type="content" source="../assets/images/teams-toolkit-v2/debug-apps-in-teams-desktop-client/openai-key.png" alt-text="Screenshot shows to enter openai service key in Visual Studio Code."::: ++1. Select **Default folder**. ++ :::image type="content" source="../assets/images/teams-toolkit-v2/first-bot/select-default-location.png" alt-text="Screenshot shows the selection of default location."::: ++ To change the default location, follow these steps: ++ 1. Select **Browse**. ++ :::image type="content" source="../assets/images/teams-toolkit-v2/first-bot/select-browse.png" alt-text="Screenshot shows the option to browse and select the location."::: ++ 1. Select the location for the project workspace. + 1. Select **Select Folder**. ++ :::image type="content" source="../assets/images/teams-toolkit-v2/select-folder.png" alt-text="Screenshot shows the folder to select."::: ++1. Enter a suitable name for your app and then select the **Enter** key. ++ :::image type="content" source="../assets/images/teams-toolkit-v2/first-bot/hello-bot.png" alt-text="Screenshot shows where to enter the app name."::: ++1. From the left pane, select **Run and Debug** (`Ctrl+Shift+D`) and select **Debug in Teams (Desktop)** from the dropdown list. ++ :::image type="content" source="../assets/images/teams-toolkit-v2/debug-apps-in-teams-desktop-client/debug-in-teams-desktop.png" alt-text="Screenshot shows the option to select debug in Teams (Desktop)."::: ++1. Ensure your Teams desktop login matches your Microsoft 365 account used in Teams Toolkit and then select **Continue**. ++ :::image type="content" source="../assets/images/teams-toolkit-v2/debug-apps-in-teams-desktop-client/desktop-login-matches.png" alt-text="Screenshot shows the desktop login."::: ++ Teams desktop client requests to add your app. ++1. Select **Add**. ++ :::image type="content" source="../assets/images/teams-toolkit-v2/debug-apps-in-teams-desktop-client/add-app.png" alt-text="Screenshot shows the add button to add the app to Teams desktop client."::: ++ A chat window opens. ++1. From the message compose area, send a message to invoke the bot. ++ :::image type="content" source="../assets/images/teams-toolkit-v2/debug-apps-in-teams-desktop-client/desktop-client.png" alt-text="Screenshot shows the app added to Teams desktop client."::: ++ > [!NOTE] + > + > The system level notification for account matching appears only once per project. In subsequent debug sessions, Teams Toolkit sends reminders about the account through VS Code notifications. + > + > :::image type="content" source="../assets/images/teams-toolkit-v2/debug-apps-in-teams-desktop-client/subsequent-desktop-login.png" alt-text="Screenshot shows the subsequent desktop login notification in vs code."::: ++1. You can add breakpoints and [hot reload](debug-overview.md#hot-reload) your changes. In the following example, the breakpoint is highlighted with the red dot next to the row number. ++ :::image type="content" source="../assets/images/teams-toolkit-v2/debug-apps-in-teams-desktop-client/hot-reload.png" alt-text="Screenshot shows an example of the breakpoints in app."::: ++ :::image type="content" source="../assets/images/teams-toolkit-v2/debug-apps-in-teams-desktop-client/after-hot-reload.png" alt-text="Screenshot shows an example after hot reload of an app."::: ++You can continue to debug your custom engine agent app in Teams desktop client. ++## See also ++* [Teams Toolkit Overview](teams-toolkit-fundamentals.md) +* [Debug for mobile](debug-mobile.md) |
platform | Debug Overview | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/toolkit/debug-overview.md | Teams Toolkit supports the following debug features: * [Hot reload](#hot-reload) * [Stop debugging](#stop-debugging) * [Teams App Test Tool](#teams-app-test-tool)+* [Debug apps in Teams desktop client](#debug-apps-in-teams-desktop-client) Teams Toolkit performs background functions during debug process, which include verifying the prerequisites required for debug. You can see the progress of the verification process in the output channel of Teams Toolkit. In the setup process you can register and configure your Teams app. When you complete local debug, you can select **Stop (Shift+F5)** or **[Alt] Dis The Teams App Test Tool makes debugging your bot-based apps effortless. You can chat with your bot and see its messages and adaptive cards as they appear in Teams. You donΓÇÖt need a Microsoft 365 developer account, tunneling, or Teams app and bot registration to use the Test Tool. For more information, see [Teams App Test Tool](debug-your-Teams-app-test-tool.md). +### Debug apps in Teams desktop client ++Microsoft Teams Toolkit helps you to debug and preview your Microsoft Teams app in desktop client. For more information, see [debug apps in Teams desktop client](debug-apps-in-Teams-desktop-client.md). + ## Prepare for debug The following steps help you to prepare for debug: |
platform | Update Bot Me App To Use Certificate Or Msi For Authentication | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/toolkit/update-bot-me-app-to-use-certificate-or-msi-for-authentication.md | + + Title: Use Certificate or MSI Authentication for Bots ++description: Learn how to use certificate or MSI-based authentication for your bot app, which resolves compliance concerns with Microsoft Entra ID and bot secret. ++ms.localizationpriority: high + Last updated : 10/22/2024+++# Use certificate or MSI for app authentication ++You can use certificate- or MSI-based authentication to validate your bot app instead of bot ID and secret. This authentication resolves the compliance concerns related to the use of Microsoft Entra ID and bot secret. ++## Prerequisites ++Ensure that you have a Teams bot app deployed to Azure with the following resources: ++* An Azure bot. +* An Entra ID with a secret used for bot authentication. +* A resource that hosts your bot app, such as Azure App Service, Azure Functions. ++# [Update to certificate-based Authentication](#tab/certificate) ++To update your bot app to use certificate-based authentication: ++1. [Create and upload certificate in Azure AD](#create-and-upload-certificate-in-azure-ad) +1. [Update the bot app code](#update-the-bot-app-code) +1. [Delete bot secret](#delete-bot-secret) ++## Create and upload certificate in Azure AD ++To use a certificate for bot authentication: ++1. Prepare a certificate and private key. ++1. Go to [Azure portal](https://ms.portal.azure.com). ++1. Select **App registrations**. ++ :::image type="content" source="../assets/images/include-files/azure-app-registration.png" alt-text="Screenshot shows the Azure services to select App registrations."::: ++1. Select your registered app. ++1. In the left pane, under **Manage**, select **Certificates & secrets**. ++1. Under **Certificates**, select **Upload certificate**. ++ :::image type="content" source="../assets/images/teams-toolkit-v2/certificates-secrets.png" alt-text="Screenshot shows the certificates and secrets option."::: ++ The **Upload a certificate** window appears. ++ > [!NOTE] + > Upload a certificate (public key) with one of the following file types: .cer, .pem, .crt. ++1. Upload the certificate you prepared. ++1. Enter **Description**. ++1. Select **Add**. ++ :::image type="content" source="../assets/images/teams-toolkit-v2/upload-certificate.png" alt-text="Screenshot shows the upload certificate option."::: ++## Update the bot app code ++Follow the steps to update the bot app code: ++1. Open your bot app project in Visual Studio or Visual Studio Code. +1. Update your code. ++ # [JavaScript](#tab/js1) ++ ```javascript + const credentialsFactory = new ConfigurationServiceClientCredentialFactory({ + MicrosoftAppId: config.botId, + CertificatePrivateKey: '{your private key}', + CertificateThumbprint: '{your cert thumbprint}', + MicrosoftAppType: "MultiTenant", + }); + + const botFrameworkAuthentication = new ConfigurationBotFrameworkAuthentication( + {}, + credentialsFactory + ); + + const adapter = new CloudAdapter(botFrameworkAuthentication); + ``` ++ # [C#](#tab/cs1) ++ ```csharp + builder.Services.AddSingleton<ServiceClientCredentialsFactory>((e) => new CertificateServiceClientCredentialsFactory("{your certificate}", "{your entra id}")); + ``` ++ ++1. Ensure you test your bot to confirm the operation aligns with the updated authentication. ++## Delete bot secret ++Ensure that your bot app uses the certificate for authentication before you delete the bot secret. ++To delete the bot secret: ++1. Go to [Azure portal](https://ms.portal.azure.com). +1. Select **App registrations**. ++ :::image type="content" source="../assets/images/include-files/azure-app-registration.png" alt-text="Screenshot shows the Azure services to select App registrations."::: ++1. Select your registered app. ++1. In the left pane, under **Manage**, select **Certificates & secrets**. +1. Delete the secrets from Entra. ++ :::image type="content" source="../assets/images/teams-toolkit-v2/delete-client-secret-value.png" alt-text="Screenshot shows the delete client secret value."::: ++Your bot app now uses the certificate for authentication. ++# [Update to MSI-based authentication](#tab/msi) ++To update your bot app to use MSI-based authentication: ++1. [Create bot service with MSI type in Azure AD](#create-bot-service-with-msi-type-in-azure-ad) +1. [Update your bot app code for MSI](#update-your-bot-app-code-for-msi) +1. [Delete bot secret](#delete-bot-secret-1) ++> [!NOTE] +> The **Azure Bot** service ID and type can't be modified after creation. ++## Create bot service with MSI type in Azure AD ++To create a new **Azure Bot** service with MSI type, follow these steps: ++1. Go to [Azure portal](https://ms.portal.azure.com). +1. Go to **Home**. +1. Select **+ Create a resource**. +1. In the search box, enter **Azure Bot**. +1. Select the **Enter** key. +1. Select **Azure Bot**. +1. Select **Create**. ++ :::image type="content" source="../assets/images/include-files/azure-bot.png" alt-text="Screenshot shows the creation of Azure bot."::: ++1. Enter the bot name in **Bot handle**. +1. Select your **Subscription** from the dropdown list. +1. Select your **Resource group** from the dropdown list. ++ :::image type="content" source="../assets/images/include-files/create-azure-bot.png" alt-text="Screenshot shows the option resource group and subscription in the Azure portal."::: ++ If you don't have an existing resource group, you can create a new resource group. To create a new Azure bot service and managed identity, follow these steps: ++ 1. Select **Create new**. + 1. Enter the resource name and select **OK**. + 1. Select a location from **New resource group location** dropdown list. ++ :::image type="content" source="../assets/images/include-files/new-resource-location.png" alt-text="Screenshot shows the new resource group option in Azure portal."::: ++1. Under **Microsoft App ID**, select **Type of App** as **User-Assigned Managed Identity**. ++1. From the **Creation type**, select **Create new Microsoft App ID**. ++ :::image type="content" source="../assets/images/teams-toolkit-v2/microsoft-app-id.png" alt-text="Screenshot shows the microsoft app ID option."::: ++ OR ++ You can manually create a managed identity first, then create the **Azure Bot** using the **Use existing app registration**. ++1. Update the new **Azure Bot** messaging endpoint and channels to match those of the old service. ++1. Go to your apps hosting resource. ++1. Select **Settings > Identity > User assigned**. ++1. Add the managed identity that you've created. ++## Update your bot app code for MSI ++To update the bot app code for MSI, follow these steps: ++1. Open your bot app project in Visual Studio or Visual Studio Code. +1. Update your code. ++ # [JavaScript](#tab/js2) ++ ```javascript + const credentialsFactory = new ConfigurationServiceClientCredentialFactory({ + MicrosoftAppType: 'UserAssignedMsi', + MicrosoftAppId: '{your MSIΓÇÖs client ID}', + MicrosoftAppTenantId: '{your MSIΓÇÖs tenant ID}', + }); + + const botFrameworkAuthentication = new ConfigurationBotFrameworkAuthentication( + {}, + credentialsFactory + ); + + const adapter = new CloudAdapter(botFrameworkAuthentication); + ``` ++ # [C#](#tab/cs2) ++ ```csharp + builder.Configuration["MicrosoftAppType"] = "UserAssignedMsi"; + builder.Configuration["MicrosoftAppId"] = "{your MSIΓÇÖs client ID}"; + builder.Configuration["MicrosoftAppPassword"] = "{your MSIΓÇÖs tenant ID}"; + builder.Services.AddSingleton<BotFrameworkAuthentication, ConfigurationBotFrameworkAuthentication>(); + ``` ++ ++1. Update the `BOT_ID` in your `.env` file. ++1. Ensure you test your bot to confirm its operation aligns with the updated authentication. ++## Delete bot secret ++Ensure that your bot app uses the certificate for authentication before you delete the bot secret. ++To delete the bot secret: ++1. Go to [Azure portal](https://ms.portal.azure.com). +1. Select **App registrations**. ++ :::image type="content" source="../assets/images/include-files/azure-app-registration.png" alt-text="Screenshot shows the Azure services to select App registrations."::: ++1. Select your registered app. ++1. In the left pane, under **Manage**, select **Certificates & secrets**. +1. Delete the secrets from Entra. ++ :::image type="content" source="../assets/images/teams-toolkit-v2/delete-client-secret-value.png" alt-text="Screenshot shows the delete client secret value."::: ++Your bot app now uses MSI for authentication. ++++## See Also ++* [Build bots for Teams](../bots/what-are-bots.md) +* [Build message extensions](../messaging-extensions/what-are-messaging-extensions.md) +* [Authenticate users in Microsoft Teams](../concepts/authentication/authentication.md) |
platform | Use CICD Template | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/toolkit/use-CICD-template.md | You can use [Teams Toolkit command line interface (CLI)](Teams-Toolkit-CLI.md) t | | | | Set up required resources for your Teams app, such as Teams app ID, bot ID, and so on. | ΓÇó Manually extract the resources from the `manifest.json` file under the `appPackage` folder. <br> ΓÇó Automatically generate to run the `Provision` command in Teams Toolkit. | | Configure Azure resources |ΓÇó Manually prepare the resources by examining the bicep files under the `infra` folder. <br> ΓÇó Automatically prepare the resources using the `Provision` command in Teams Toolkit.|-| Ensure that you've a service principal and its access policies on resources are properly configured. Set up a service principal as follows:| ΓÇó [Create service principal using Entra portal](/entra/identity-platform/howto-create-service-principal-portal). <br> ΓÇó [Create service principal using Azure CLI](/cli/azure/azure-cli-sp-tutorial-1?tabs=bash). <br> ΓÇó The `Teamsapp` command-line interface (CLI) supports Azure login with a service principal secret. [Create a secret](/entra/identity-platform/howto-create-service-principal-portal) and save the client ID, client secret, and tenant ID of the service principal. <br> :::image type="content" source="../assets/images/teams-toolkit-v2/service-principal.png" alt-text="Screenshot shows the service principal secret.":::| +| Ensure you've a properly configured service principal with appropriate access policies on resources. | The `Teamsapp` command-line interface (CLI) supports Azure login through certificate-based authentication or password-based authentication (application secret). You can either [create a service principal with certificate-based authentication](/cli/azure/azure-cli-sp-tutorial-3) and save the generated certificate, `appId` (client ID) and `tenant` (tenant ID) or [create a secret](/entra/identity-platform/howto-create-service-principal-portal) and save the client ID, client secret, and tenant ID of the service principal. <br> :::image type="content" source="../assets/images/teams-toolkit-v2/service-principal.png" alt-text="Screenshot shows the service principal secret."::: <br> For more information about service principal, see: <br> ΓÇó [Create service principal using Entra portal](/entra/identity-platform/howto-create-service-principal-portal). <br> ΓÇó [Create service principal using Azure CLI](/cli/azure/azure-cli-sp-tutorial-1?tabs=bash). | After you've completed the prerequisites, let's set up a pipeline: To set up the pipeline with GitHub, follow these steps: 1. Open Visual Studio Code. 1. Create a `cd.yml` file in your project under `.github/workflows` folder and add the following code in the file:+ # [Certificate-based authentication](#tab/certificate) + ```yaml + on: + push: + branches: + - main + jobs: + build: + runs-on: ubuntu-latest + env: + TEAMSAPP_CLI_VERSION: "3.0.4" + # Add extra environment variables here so that teamsapp cli can use them. + + steps: + - name: "Checkout GitHub Action" + uses: actions/checkout@v4 + + - name: Setup Node 20.x + uses: actions/setup-node@v1 + with: + node-version: "20.x" + + - name: install cli + run: | + npm install @microsoft/teamsapp-cli@${{env.TEAMSAPP_CLI_VERSION}} + - name: Retrieve the secret and decode it to a file + env: + CERTIFICATE_BASE64: ${{ secrets.AZURE_SERVICE_PRINCIPAL_CERTIFICATE_BASE64 }} + run: | + echo $CERTIFICATE_BASE64 | base64 --decode > cert.pem + + - name: Login Azure by service principal + run: | + npx teamsapp auth login azure --username ${{vars.AZURE_SERVICE_PRINCIPAL_CLIENT_ID}} \ + --service-principal true \ + --tenant ${{vars.AZURE_TENANT_ID}} \ + --password cert.pem \ + --interactive false + + - name: Deploy to hosting environment + run: | + npx teamsapp deploy --ignore-env-file true \ + --interactive false + + - name: Package app + run: | + npx teamsapp package + + - name: upload appPackage + uses: actions/upload-artifact@v4 + with: + name: artifact + path: appPackage/build/appPackage.zip + ``` + # [Password-based authentication](#tab/secret) ```yaml on: push: To set up the pipeline with GitHub, follow these steps: build: runs-on: ubuntu-latest env:- TEAMSAPP_CLI_VERSION: "3.0.0" + TEAMSAPP_CLI_VERSION: "3.0.4" # Add extra environment variables here so that teamsapp cli can use them. steps: To set up the pipeline with GitHub, follow these steps: name: artifact path: appPackage/build/appPackage.zip ```-+ > [!NOTE] > The default pipeline triggers when push events occur on the main branch. You've the option to modify it to suit your specific requirements. To set up the pipeline with GitHub, follow these steps: 1. Update the following variables and secrets you created during the prerequisites: - * `AZURE_SERVICE_PRINCIPAL_CLIENT_ID`, `AZURE_TENANT_ID`, and `AZURE_SERVICE_PRINCIPAL_CLIENT_SECRET` + * # [Certificate-based authentication](#tab/certificate) + `AZURE_SERVICE_PRINCIPAL_CLIENT_ID`, `AZURE_TENANT_ID`, and `AZURE_SERVICE_PRINCIPAL_CERTIFICATE_BASE64`. `AZURE_SERVICE_PRINCIPAL_CERTIFICATE_BASE64` is the Base64 string encoded content of the certificate that you've generated. ++ :::image type="content" source="../assets/images/teams-toolkit-v2/repo-settings.png" alt-text="Screenshot shows the repo settings."::: ++ > [!NOTE] + > The `AZURE_SERVICE_PRINCIPAL_CERTIFICATE_BASE64` variable must be set as secret. + > Use the [GitHub environment](https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment#environment-variables) for different variable sets. ++ # [Password-based authentication](#tab/secret) + `AZURE_SERVICE_PRINCIPAL_CLIENT_ID`, `AZURE_TENANT_ID`, and `AZURE_SERVICE_PRINCIPAL_CLIENT_SECRET` :::image type="content" source="../assets/images/teams-toolkit-v2/repo-settings.png" alt-text="Screenshot shows the repo settings."::: To set up the pipeline with GitHub, follow these steps: * `AZURE_SERVICE_PRINCIPAL_CLIENT_ID` * `AZURE_TENANT_ID`- * `AZURE_SERVICE_PRINCIPAL_CLIENT_SECRET` + * `AZURE_SERVICE_PRINCIPAL_CLIENT_SECRET` or `AZURE_SERVICE_PRINCIPAL_CERTIFICATE_BASE64` * `BOT_AZURE_APP_SERVICE_RESOURCE_ID` * `TEAMS_APP_ID` To set up the pipeline with GitHub, follow these steps: * `AZURE_SERVICE_PRINCIPAL_CLIENT_ID` * `AZURE_TENANT_ID`- * `AZURE_SERVICE_PRINCIPAL_CLIENT_SECRET` + * `AZURE_SERVICE_PRINCIPAL_CLIENT_SECRET` or `AZURE_SERVICE_PRINCIPAL_CERTIFICATE_BASE64` :::image type="content" source="../assets/images/teams-toolkit-v2/modification.png" alt-text="Screenshot shows the modified pipeline yml."::: To set up the pipeline with Azure DevOps, follow these steps: 1. Create a `cd.yml` file in your project and add the following code in the file: + # [Certificate-based authentication](#tab/certificate) ```yaml trigger: - main To set up the pipeline with Azure DevOps, follow these steps: vmImage: ubuntu-latest variables:- TEAMSAPP_CLI_VERSION: 3.0.0 + TEAMSAPP_CLI_VERSION: 3.0.4 + + steps: + - task: NodeTool@0 + inputs: + versionSpec: "20" + checkLatest: true + + - script: | + npm install @microsoft/teamsapp-cli@$(TEAMSAPP_CLI_VERSION) + displayName: "Install CLI" ++ - task: DownloadSecureFile@1 + name: certFile + displayName: 'Download Certificate File' + inputs: + secureFile: 'azure_sp_cert.pem' + + - script: | + npx teamsapp auth login azure --username $(AZURE_SERVICE_PRINCIPAL_CLIENT_ID) --service-principal true --tenant $(AZURE_TENANT_ID) --password $(certFile.secureFilePath) --interactive false + displayName: "Login Azure by service principal" + + - script: | + npx teamsapp deploy --ignore-env-file true --interactive false + displayName: "Deploy to Azure" + workingDirectory: $(System.DefaultWorkingDirectory) + + - script: | + npx teamsapp package + displayName: "Package app" + workingDirectory: $(System.DefaultWorkingDirectory) + + - publish: $(System.DefaultWorkingDirectory)/appPackage/build/appPackage.zip + artifact: artifact + ``` ++ # [password-based authentication](#tab/secret) + ```yaml + trigger: + - main + + pool: + vmImage: ubuntu-latest + + variables: + TEAMSAPP_CLI_VERSION: 3.0.4 steps: - task: NodeTool@0 To set up the pipeline with Azure DevOps, follow these steps: After you push your code to the repo, navigate to **Pipelines** and select **New pipeline**. Select your repo and the existing yml file to configure your pipeline. -1. Update the following variables and secrets you created during the prerequisites: +1. # [Certificate-based authentication](#tab/certificate) + Update the following variables and set the certificate that you've created during the prerequisites: + * `AZURE_SERVICE_PRINCIPAL_CLIENT_ID`, `AZURE_TENANT_ID` ++ * Go to the `teamsapp.yml` file. In the `deploy` stage, the values enclosed in `${{}}` are the required variable keys. If you've used the `provision` command from Teams Toolkit, you can locate the values in the environment files in the `.env` folder. ++ Set the `BOT_AZURE_APP_SERVICE_RESOURCE_ID` as a repository variable: ++ :::image type="content" source="../assets/images/teams-toolkit-v2/teamsappyml.png" alt-text="Screenshot shows the bot Azure app service resource ID in teamsapp.yml file."::: ++ * Go to the `appPackage/manifest.json` file. The values enclosed in `${{}}` are the required variable keys. If you've used the `provision` command from Teams Toolkit, you can locate the values in the environment files in the `.env` folder. ++ Set the `TEAMS_APP_ID` as a repository variable: ++ :::image type="content" source="../assets/images/teams-toolkit-v2/manifest.png" alt-text="Screenshot shows the Teams app ID in manifest file."::: ++ You need to set the following key name variables in the repo: ++ * `AZURE_SERVICE_PRINCIPAL_CLIENT_ID` + * `AZURE_TENANT_ID` + * `BOT_AZURE_APP_SERVICE_RESOURCE_ID` + * `TEAMS_APP_ID` ++ To set variables in your pipeline, go to your pipeline and select **Edit** > **Variables**. ++ In your Azure DevOps project, navigate to **Pipelines** > **Library** and add a new secure file. Upload the certificate (.pem) file and name the file as `azure_sp_cert.pem`. + # [Password-based authentication](#tab/secret) + Update the following variables and secrets that you've created during the prerequisites: * `AZURE_SERVICE_PRINCIPAL_CLIENT_ID`, `AZURE_TENANT_ID`, and `AZURE_SERVICE_PRINCIPAL_CLIENT_SECRET` * Go to the `teamsapp.yml` file. In the `deploy` stage, the values enclosed in `${{}}` are the required variable keys. If you've used the `provision` command from Teams Toolkit, you can locate the values in the environment files in the `.env` folder. |
platform | Use Existing Aad App | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/toolkit/use-existing-aad-app.md | -# Use existing Microsoft Entra app in TeamsFx project +# Use existing Entra app in TeamsFx This section provides information for using existing Microsoft Entra app or manually creates Microsoft Entra app for TeamsFx project. Follow the instruction and make sure all required info is properly set in your TeamsFx project. |
platform | Whats New | https://github.com/MicrosoftDocs/msteams-docs/commits/main/msteams-platform/whats-new.md | Teams platform features that are available to all app developers. **2024 October** +* ***October 28, 2024***: [Enable API key and SSO authentication for your API-based message extension](messaging-extensions/build-api-based-message-extension.md). +* ***October 28, 2024***: [Update bot or message extension app to use certificate or MSI for authentication.](toolkit/update-bot-me-app-to-use-certificate-or-msi-for-authentication.md) +* ***October 28, 2024***: [Debug apps in Teams desktop client to improve debugging performance and efficency](toolkit/debug-apps-in-Teams-desktop-client.md). * ***October 25, 2024***: [Introduced prompt suggestions for bots to create an engaging and insightful bot experience.](bots/how-to/conversations/prompt-suggestions.md) * ***October 17, 2024***: [Introducing app manifest v1.19](./resources/schem) with copilotAgents, declarativeAgents, and defaultLanguageFile. * ***October 17, 2024***: [Localize your Copilot agents](/microsoft-365-copilot/extensibility/agents-are-apps#localizing-your-agent). Teams platform features that are available to all app developers. | 13/09/2024 | Use app analytics in Developer Portal to analyze your app usage metrics to gain valuable insights into how users interact with your app. | Tools and SDKs > Tools > Developer Portal for Teams > [Analyze your apps usage in Developer Portal](concepts/build-and-test/analyze-your-apps-usage-in-developer-portal.md) | | 26/08/2024 | Enhanced user experience for Teams app susbscriptions purchased from Teams Store. | Monetize your app > Purchase and manage app subscriptions and licenses > [Subscription purchase experience](concepts/deploy-and-publish/appsource/prepare/end-user-purchase-experience.md#subscription-purchase-experience) | | 22/08/2024 | Dev Tools for Teams tabs are available in the new Microsoft Teams client. | Test your app > Tabs > [Dev Tools for Microsoft Teams Tab](tabs/how-to/developer-tools.md) |-| 21/08/2024 | Use sample prompts to guide the users for using various plugins within Microsoft 365 Copilot. | Distribute your app > Publish to the Teams Store > Review Copilot validation guidelines > [Sample prompts](concepts/deploy-and-publish/appsource/prepare/review-copilot-validation-guidelines.md#sample-prompts) | +| 21/08/2024 | Use sample prompts to guide the users for using various plugins within Microsoft 365 Copilot. | Publish your app > Publish to the Teams Store > Review Copilot validation guidelines > [Sample prompts](concepts/deploy-and-publish/appsource/prepare/review-copilot-validation-guidelines.md#sample-prompts) | | 31/07/2024 | Use app validation tool to validate your Teams app in Developer Portal for Teams. | Tools and SDKs > Tools > Developer Portal for Teams > [Publish](concepts/build-and-test/manage-your-apps-in-developer-portal.md#publish) | | 03/07/2024 | share content to the meeting Stage simplifies app content sharing during meetings and provides a seamless multi-player viewing experience. | Build apps for Teams meetings and calls > Enable and configure apps for Teams meetings > [Share to stage](apps-in-teams-meetings/build-apps-for-teams-meeting-stage.md#screen-share-content-to-meetings) | | 02/07/2024 | Extend bot-based message extension plugins to Teams meetings. | Build message extensions > Build message extensions using Bot Framework > Search Commands > [Enable message extension as a plugin for Copilot for meetings](messaging-extensions/build-bot-based-plugin.md#enable-message-extension-as-a-plugin-for-copilot-for-meetings) | Teams platform features that are available to all app developers. | 21/05/2024 | Introduced a step-by-step guide to build a custom engine agent to chat with your data using the Teams AI library and Teams Toolkit. | Build bots > Teams AI library > Build custom engine agent > [Build custom engine agent using Teams Toolkit](teams-ai-library-tutorial.yml)| | 21/05/2024 | Use Live Share sessions to enable seamless collaboration in Teams meetings, chats, and channels. | Build apps for Teams meetings and calls > Enhanced collaboration with Live Share > [Live Share collaborative contexts](apps-in-teams-meetings/teams-live-share-overview.md#live-share-collaborative-contexts)| |17/05/2024|Deploy Teams app to container service.|Tools and SDKs > Teams Toolkit for Visual Studio Code > Host your app on Azure > [Deploy Teams app to container service](toolkit/deploy-Teams-app-to-container-service.md)|-|12/04/2024|Implement authentication in API-based search message extensions to provide secure and seamless access to your app.|Build message extensions > Build message extensions using API > [Authentication](messaging-extensions/build-api-based-message-extension.md#authentication)| +|12/04/2024|Implement authentication in API-based search message extensions to provide secure and seamless access to your app.|Build message extensions > Build message extensions using API > [Authentication](messaging-extensions/build-api-based-message-extension.md)| |12/04/2024|Introducing app manifest v1.17 with semanticDescription, samplePrompts, and dashboardCards.|[App manifest](resources/schem)| |12/04/2024|Outlook extensions specifies Outlook Add-ins within an app manifest and simplify the distribution and acquisition across the Microsoft 365 ecosystem.|App manifest > [extensions.requirements](resources/schem#extensionsrequirements)| |12/04/2024|Create Dashboardcards that can be pinned to a dashboard such as Microsoft Viva Connections to provide a summarized view of app information|App manifest > [dashboardCards](resources/schem#dashboardcards)| Teams platform features that are available to all app developers. |10/04/2024|Define and deploy Outlook Add-ins in version 1.17 and later of the app manifest schema.|Extend your app across Microsoft 365 > [Outlook Add-ins](m365-apps/overview.md#outlook-add-ins)| |04/04/2024|Added support for python in Teams AI library.|Build bots > Teams AI library > [Teams AI library](bots/how-to/teams-conversational-ai/teams-conversation-ai-overview.md)| |04/04/2024|Stageview API with the openmode property allows you to open your app content in different Stageview experience.|Build tabs > [Open content in Stageview](tabs/open-content-in-stageview.md)|-|03/04/2024|Updated the common reasons for app validation failure to help your app pass the Teams Store submission process.|Distribute your app > Publish to the Teams Store > [Common reasons for app validation failure](concepts/deploy-and-publish/appsource/common-reasons-for-app-validation-failure.md)| +|03/04/2024|Updated the common reasons for app validation failure to help your app pass the Teams Store submission process.|Publish your app > Publish to the Teams Store > [Common reasons for app validation failure](concepts/deploy-and-publish/appsource/common-reasons-for-app-validation-failure.md)| |27/03/2024|Configure Teams deep links using the msteams:// and https:// protocol handlers.|Integrate with Teams > Create deep links > Overview > [Protocol handlers in deep links](concepts/build-and-test/deep-links.md#protocol-handlers-in-deep-links)| |26/03/2024|Adaptive Cards responsive layout helps you to design cards to look great on any device in order to provide an enhanced user experience across chat, channels, and meeting chat.|Build cards and dialogs > Build cards > Format cards in Microsoft Teams > [Adaptive Card responsive layout](task-modules-and-cards/cards/cards-format.md#adaptive-card-responsive-layout)| |07/03/2024|Introduced Adaptive Card Previewer to view the realtime changes for Visual Studio 2022.|Tools and SDKs > Tools > [Adaptive Card Previewer for Visual Studio](concepts/build-and-test/adaptive-card-previewer-vs.md)| Teams platform features that are available to all app developers. |25/10/2023|Configure your bot to receive meeting participant events. | Build apps for Teams meetings and calls > Enable and configure apps for Teams meetings > [Meeting apps APIs](apps-in-teams-meetings/meeting-apps-apis.md#receive-meeting-participant-events)| |11/10/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)| |05/10/2023|Use callTranscript API to fetch meeting transcript from all meetings.|Build apps for Teams meetings and calls > [Get meeting transcripts and recordings using Graph APIs](graph-api/meeting-transcripts/overview-transcripts.md)|-|05/10/2023|You can rate apps on Microsoft Teams Store and offer feedback on your usage experience.|Distribute your app > Publish to the Teams Store > [Maintain your published app](concepts/deploy-and-publish/appsource/post-publish/overview.md#ratings-and-review-for-teams-apps)| +|05/10/2023|You can rate apps on Microsoft Teams Store and offer feedback on your usage experience.|Publish your app > Publish to the Teams Store > [Maintain your published app](concepts/deploy-and-publish/appsource/post-publish/overview.md#ratings-and-review-for-teams-apps)| |26/09/2023|Configure your bot with read receipt events to identify if the recipient has read the message sent by the bot.|Build bots > Messages in bot conversations > [Read receipts](bots/how-to/conversations/conversation-messages.md#receive-a-read-receipt)| |26/09/2023|Use media elements such as audio or video clips to your Adaptive Card for enhanced media experience and user engagement.|Build cards and task modules > Build cards > [Media elements in Adaptive Card](task-modules-and-cards/cards/media-elements-in-adaptive-cards.md)| | 06/09/2023|Generate a deep link to share content to stage in meetings.|Build apps for Teams meetings and calls > Enable and configure apps for Teams meeting > [Share in meeting](concepts/build-and-test/share-in-meeting.md)|-| 29/08/2023 | Use Microsoft Teams Store with intelligent search experience to display apps that are closest match to the user's specified characters.|Distribute your app > [Publish to the Teams Store](concepts/deploy-and-publish/appsource/publish.md#teams-store-search-experience) | +| 29/08/2023 | Use Microsoft Teams Store with intelligent search experience to display apps that are closest match to the user's specified characters.|Publish your app > [Publish to the Teams Store](concepts/deploy-and-publish/appsource/publish.md#teams-store-search-experience) | | 28/08/2023 | Teams app manifest is now referred to as app manifest.|App manifest > [Overview](resources/schem)| | 16/08/2023 | Use Teams Toolkit Visual Studio v17.7 extension with many new app development features to get started with app development for Teams.|Tools and SDKs > Tools > [Teams Toolkit for Visual Studio](toolkit/toolkit-v4/teams-toolkit-fundamentals-vs.md) | | 10/08/2023 | Send a proactive message using Microsoft Entra ID.|Build bots > Bot conversations > [Proactive messages](bots/how-to/conversations/send-proactive-messages.md)| Teams platform features that are available to all app developers. | 25/07/2023 | Use people icon in an Adaptive Card to view the images of users.|Build cards and task modules > Build cards > Review Teams Store validation guidelines > [Build cards](task-modules-and-cards/cards/cards-format.md#people-icon-in-an-adaptive-card) | | 20/07/2023 | App caching for iOS personal tray | Build tabs > [App caching for iOS personal tray](tabs/how-to/app-caching.md) | | 06/07/2023 | Use app icon badging to identify any app activity during a meeting | Build apps for Teams meetings and calls > Build in-meeting notification and app icon badging > [Use app icon badging to identify any app activity during a meeting](apps-in-teams-meetings/app-icon-badging-for-your-app.md) |-| 14/06/2023 | Added validation guidelines for Teams app powered by Artificial Intelligence (AI). | Distribute your app > Publish to the Teams Store > Review Teams Store validation guidelines > [Apps powered by Artificial Intelligence](concepts/deploy-and-publish/appsource/prepare/teams-store-validation-guidelines.md#apps-powered-by-artificial-intelligence) | +| 14/06/2023 | Added validation guidelines for Teams app powered by Artificial Intelligence (AI). | Publish your app > Publish to the Teams Store > Review Teams Store validation guidelines > [Apps powered by Artificial Intelligence](concepts/deploy-and-publish/appsource/prepare/teams-store-validation-guidelines.md#apps-powered-by-artificial-intelligence) | | 02/06/2023 | Get real-time meeting events for channel meetings. | Build apps for Teams meetings and calls > Enable and configure apps for Teams meeting > Meeting apps APIs > [Get real-time Teams meeting events API](apps-in-teams-meetings/meeting-apps-apis.md#receive-real-time-teams-meeting-events) | | 25/05/2023 | Use a deep link to open a tab app in meeting side panel in Teams mobile client. | Build apps for Teams meetings and calls > Enable and configure apps for Teams meeting > [Build tabs for meeting](apps-in-teams-meetings/build-tabs-for-meeting.md#deep-link-to-meeting-side-panel) | |23/05/2023 | Live Share SDK is now generally available. Use Live Share to transform Teams apps into collaborative multi-user experiences without writing any dedicated back-end code. | Build apps for Teams meetings and calls > Enhanced collaboration with Live Share > [Live Share SDK](apps-in-teams-meetings/teams-live-share-overview.md)| |23/05/2023 | Use Teams app design guidelines to help you make quick and right decisions to design your app. | Design your app > [Overview](concepts/design/design-teams-app-overview.md)|-|17/05/2023 | Cater your app to a specific audience from the available list of countries or regions. | Distribute your app > Publish to the Teams Store > Prepare your Teams Store submission > [Distribute your app to specific countries or regions](concepts/deploy-and-publish/appsource/prepare/submission-checklist.md#distribute-your-app-to-specific-countries-or-regions)| +|17/05/2023 | Cater your app to a specific audience from the available list of countries or regions. | Publish your app > Publish to the Teams Store > Prepare your Teams Store submission > [Publish your app to specific countries or regions](concepts/deploy-and-publish/appsource/prepare/submission-checklist.md#publish-your-app-to-specific-countries-or-regions)| | 17/05/2023 | Use the Teams Toolkit v5 extension with many new app development features to get started with app development for Teams using Visual Studio Code. | Tools and SDKs > Teams Toolkit > [Teams Toolkit Overview](toolkit/teams-toolkit-fundamentals.md)| | 17/05/2023 | Updated Get started module with GitHub Codespaces and step-by-step guides aligned with Teams Toolkit v5. It also includes details for extending Teams app over Microsoft 365 and Outlook. | [Get started](get-started/get-started-overview.md)| | 24/04/2023 | Develop your apps with a seamless transition between Teams Developer Portal and Teams Toolkit. | Tools and SDKs > Developer Portal for Teams > [Develop your apps with Teams Toolkit](concepts/build-and-test/develop-your-apps-with-teams-toolkit.md) |-| 14/04/2023 | App update in any one context where the app is installed automatically updates the app in all the related contexts (chats, channels, and meetings). | Distribute your app > [Upload your app in Teams](concepts/deploy-and-publish/apps-upload.md#update-your-app) | +| 14/04/2023 | App update in any one context where the app is installed automatically updates the app in all the related contexts (chats, channels, and meetings). | Publish your app > [Upload your app in Teams](concepts/deploy-and-publish/apps-upload.md#update-your-app) | | 06/04/2023 | Set up Microsoft license management for third-party SaaS apps in Partner Center as part of the offer publishing that allows easy management and tracking of licenses for third-party app subscriptions within Teams. | Monetize your app > [Set up Microsoft license management](~/concepts/deploy-and-publish/appsource/prepare/manage-third-party-apps-license.md) | | 04/04/2023 | Tab apps in shared channels are available in Department of Defense (DOD) environment. | Build tabs > [Build apps for shared channels](~/concepts/build-and-test/shared-channels.md) | | 23/03/2023 | Use apps in Teams meetings scheduled through public channels. | Build apps for Teams meetings and calls > [Overview](apps-in-teams-meetings/teams-apps-in-meetings.md) | | 20/03/2023 | Bots are available in Department of Defense (DOD) environment. | Build bots > [Overview](bots/what-are-bots.md)| | 20/03/2023 | Message extensions are available in Department of Defense (DOD) environment. | Build message extensions > [Overview](messaging-extensions/what-are-messaging-extensions.md)|-| 28/02/2023 | Use the resources and best practices to support the rollout of your Teams app in your customersΓÇÖ organizations and facilitate adoption of your app. | Distribute your app > adoption > [Drive customer adoption of your app](promote-app-adoption.md) | +| 28/02/2023 | Use the resources and best practices to support the rollout of your Teams app in your customersΓÇÖ organizations and facilitate adoption of your app. | Publish your app > adoption > [Drive customer adoption of your app](promote-app-adoption.md) | | 27/02/2023 | Use Changelog to view the latest updates on Developer Portal about features, recent changes in APIs, and important bug fixes. | Tools and SDKs > Developer Portal for Teams > [Overview](concepts/build-and-test/teams-developer-portal.md#changelog-for-developer-portal) | | 23/02/2023 | Enable single sign-on (SSO) authentication to access Adaptive Cards Universal Actions in a bot. | Add authentication > Enable SSO for your Teams app > Enable SSO for Adaptive Cards Universal Actions in your bot > [Overview](task-modules-and-cards/cards/Universal-actions-for-adaptive-cards/enable-sso-for-your-adaptive-cards-universal-action.md) | |23/02/2023| Enable third party authentication to add user-specific views in instances where an Adaptive Card with Universal Action is shared. | Add authentication > Use third party IdP authentication > [Third party authentication for Adaptive Cards Universal Actions](task-modules-and-cards/cards/Universal-actions-for-adaptive-cards/authentication-flow-in-universal-action-for-adaptive-cards.md) | Teams platform features that are available to all app developers. |04/26/2022|Uninstall behavior for personal app with bot | Build bots > Bot conversations > [Uninstall behavior updates in personal apps with bots](bots/how-to/conversations/subscribe-to-conversation-events.md#uninstall-behavior-for-personal-app-with-bot)| | 04/22/2022 | Test preview for monetized apps | Monetize your app > [Test preview for monetized apps](concepts/deploy-and-publish/appsource/prepare/test-preview-for-monetized-apps.md) | 04/22/2022 | In-app purchase flow for monetization of apps | Monetize your app > [In-app purchases](concepts/deploy-and-publish/appsource/prepare/in-app-purchase-flow.md)-| 04/28/2022 | Common reasons for app validation failure | Distribute your app > Publish to the Teams Store > [Common reasons for app validation failure](concepts/deploy-and-publish/appsource/common-reasons-for-app-validation-failure.md)| +| 04/28/2022 | Common reasons for app validation failure | Publish your app > Publish to the Teams Store > [Common reasons for app validation failure](concepts/deploy-and-publish/appsource/common-reasons-for-app-validation-failure.md)| | 04/20/2022 | Set up CI/CD pipelines | Tools and SDKs > Teams Toolkit for Visual Studio Code > [Set up CI/CD pipelines](toolkit/use-CICD-template.md)|-| 04/19/2022 | Upload your app in Microsoft Teams | Distribute your app > [Upload your app](concepts/deploy-and-publish/apps-upload.md)| +| 04/19/2022 | Upload your app in Microsoft Teams | Publish your app > [Upload your app](concepts/deploy-and-publish/apps-upload.md)| | 04/01/2022 | Introduced step-by-step guide to create Teams conversational bot| Build bots > Bot conversations > Channel and group conversations > [Step-by-step guide to create Teams conversational bot](sbs-teams-conversation-bot.yml) | | 03/30/2022 | Updated the Get started module with Blazor app using tabs and bots| Get started > [Build your first app using Blazor](sbs-gs-blazorupdate.yml)| | 03/30/2022 | Device permissions for the browser | Integrate device capabilities > [Device permissions for the browser](concepts/device-capabilities/browser-device-permissions.md) | Teams platform features that are available to all app developers. | 02/24/2022| Introduced step-by-step guide to build action based message extension | Build Message Extensions > Action commands > Define action commands > [Build action based message extension](sbs-meetingextension-action.yml)| | 02/24/2022 | Introduced step-by-step guide to build search based message extension | Build message extensions > Search commands > Define search commands > [Build search based message extension](sbs-messagingextension-searchcommand.yml)| | 02/24/2022 | Introduced step-by-step guide to create Outgoing Webhooks | Build webhooks and connectors > Create Outgoing Webhooks > [Create Outgoing Webhooks](sbs-outgoing-webhooks.yml)|-| 02/23/2022 | Microsoft Teams Store ranking parameters| Distribute your app > Publish to the Teams Store > [Microsoft Teams Store ranking parameters](concepts/deploy-and-publish/appsource/post-publish/teams-store-ranking-parameters.md)| +| 02/23/2022 | Microsoft Teams Store ranking parameters| Publish your app > Publish to the Teams Store > [Microsoft Teams Store ranking parameters](concepts/deploy-and-publish/appsource/post-publish/teams-store-ranking-parameters.md)| | 02/18/2022 | Introduced extensive Glossary for the Microsoft Teams Developer Documentation to help you find the definition about a term quickly | [Glossary](~/get-started/glossary.md) | | 02/18/2022 | Updated the Overview module for mapping Teams app to organizational goals, user story, and exploring Teams app features | Overview > [Teams app that fits](overview.md) | | 02/18/2022 | Updated the App fundamentals module to Plan your app to include mapping use cases to Teams features, and app planning checklist | Plan your app > [Overview](~/concepts/app-fundamentals-overview.md) |-| 02/17/2022 | What to expect after you submit your app?| Distribute your app > Publish to the Teams Store > [Overview](concepts/deploy-and-publish/appsource/publish.md) | +| 02/17/2022 | What to expect after you submit your app?| Publish your app > Publish to the Teams Store > [Overview](concepts/deploy-and-publish/appsource/publish.md) | | 02/15/2022 | Introduced step-by-step guide how to upload files to Teams from a bot | Build bots > Send and receive files > [Step-by-step guide how to upload files to Teams from a bot](sbs-file-handling-in-bot.yml) | | 02/11/2022 | Shared meeting stage| ΓÇó Build apps for Teams meetings > [Shared meeting stage](apps-in-teams-meetings/build-tabs-for-meeting.md) </br> ΓÇó Build apps for Teams meetings > [Build apps for Teams meetings](apps-in-teams-meetings/build-apps-for-teams-meeting-stage.md) </br> ΓÇó App manifest > Public developer preview > [Developer preview manifest schema](resources/schem)| | 02/08/2022 | Introduced step-by-step guide to create Calling and Meeting bot| Build bots > Calls and meetings bots > Register calls and meetings bot > [Step-by-step guide to create Calling and Meeting bot](sbs-calling-and-meeting.yml) | Explore updates from the previous GA releases listed here. |12/20/2021| Introduced step-by-step guide for tabs and message extensions with Single sign-on (SSO) | Add authentication > Tabs > Use SSO authentication > [Step-by-step guide with SSO for tabs and message extensions](sbs-tabs-and-messaging-extensions-with-SSO.yml)| |12/20/2021| Introduced step-by-step guide to create meeting content bubble | Build apps for Teams meetings > Enable and configure apps for meetings > [Step-by-step guide to create meeting content bubble](sbs-meeting-content-bubble.yml) | |12/09/2021| Introduced step-by-step guide to meeting Stageview | Build apps for Teams meetings > Enable and configure apps for meetings > [Step-by-step guide to create meetings Stageview](sbs-meetings-stage-view.yml)|-|12/13/2021 | Introduced guidelines for app linked to SaaS offer | Distribute your app > Publish to the Teams Store > Review Teams Store validation guidelines > [Guidelines for apps linked to SaaS offer](concepts/deploy-and-publish/appsource/prepare/teams-store-validation-guidelines.md#apps-linked-to-saas-offer)| +|12/13/2021 | Introduced guidelines for app linked to SaaS offer | Publish your app > Publish to the Teams Store > Review Teams Store validation guidelines > [Guidelines for apps linked to SaaS offer](concepts/deploy-and-publish/appsource/prepare/teams-store-validation-guidelines.md#apps-linked-to-saas-offer)| |12/09/2021| Introduced step-by-step guide to create meeting side panel | Build apps for Teams meetings > Enable and configure apps for meetings > [Step-by-step guide to create meeting side panel in Teams](sbs-meetings-sidepanel.yml)| |12/01/2021 | Introduced new Teams Store icon | ΓÇó Design your app > App capabilities > [Designing your personal app for Microsoft Teams](concepts/design/personal-apps.md)</br> ΓÇó Design your app > UI components > [Designing your Microsoft Teams app with advanced UI components](concepts/design/design-teams-app-advanced-ui-components.md) | |11/24/2021| Introduced step-by-step guide to generate meeting token | Build apps for Teams meetings > Enable and configure apps for meetings > [Step-by-step guide to create meeting token in Teams](sbs-meeting-token-generator.yml)| |11/17/2021| Updated Teams Store validation guidelines|[Teams Store validation guidelines](~/concepts/deploy-and-publish/appsource/prepare/teams-store-validation-guidelines.md)| |11/17/2021| Static and dynamic typeahead search for desktop and mobile users | ΓÇó Build cards and task modules > Build cards > [Typeahead search in Adaptive Cards](task-modules-and-cards/cards/dynamic-search.md) </br> ΓÇó Build cards and task modules > Build cards > Overview > [Typeahead search in Adaptive Cards](task-modules-and-cards/what-are-cards.md#typeahead search-in-adaptive-cards) </br> ΓÇó Build cards and task modules > Overview > [Cards and task modules](task-modules-and-cards/cards-and-task-modules.md)| |11/13/2021| Bots can be enabled to receive all channel messages using resource-specific consent (RSC) | ΓÇó Build bots > Bot conversations > Messages in bot conversations > [Receive all channel messages with RSC](~/bots/how-to/conversations/channel-messages-with-rsc.md) </br> ΓÇó Build bots > Bot conversations > [Bot conversation overview](~/bots/how-to/conversations/conversation-basics.md) </br> ΓÇó Build bots > Bot conversations > [Channel and group conversations](~/bots/how-to/conversations/channel-and-group-conversations.md) |-|10/28/2021| Monetize your Teams app with a transactable SaaS offer | Distribute your app > Publish to the Teams Store > [Include a SaaS offer with your Teams app](~/concepts/deploy-and-publish/appsource/prepare/include-saas-offer.md) | +|10/28/2021| Monetize your Teams app with a transactable SaaS offer | Publish your app > Publish to the Teams Store > [Include a SaaS offer with your Teams app](~/concepts/deploy-and-publish/appsource/prepare/include-saas-offer.md) | |10/25/2021| Updated Get started module for Microsoft Teams Developer Documentation with new structure and procedures in a step-by-step guide | Get started > [Get started with your first Teams app](get-started/get-started-overview.md) | |10/20/2021| Meeting stage is now available in GA | Build apps for Teams meetings > [Enable and configure your apps for Teams meetings](apps-in-teams-meetings/build-tabs-for-meeting.md) | |10/20/2021| Meeting Details API and real-time Teams meeting events | Build apps for Teams meetings > [Get meeting details API](apps-in-teams-meetings/meeting-apps-apis.md) | Explore updates from the previous GA releases listed here. |04/29/2021 | Up to date cards | Build cards and task module > Build cards > Universal actions for Adaptive Cards > [Up to date cards](task-modules-and-cards/cards/universal-actions-for-adaptive-cards/Up-To-Date-Views.md) | |04/08/2021| App customization feature | ΓÇó Design your apps > [Design teams app overview](concepts/design/enable-app-customization.md)</br> ΓÇó Tools and SDKs > [Developer Portal](concepts/build-and-test/teams-developer-portal.md) </br> ΓÇó App manifest > Public developer preview > [Manifest schema](resources/schem) | |03/18/2021| Notice: Update to version 4.10 or above of the Bot Framework SDK, as we've started with the deprecation process for `TeamsInfo.getMembers` and `TeamsInfo.GetMembersAsync`. | Build bots > [Bot API Changes for Team/Chat Members](resources/team-chat-member-api-changes.md) |-|03/05/2021|Default install scope and group capability | Distribute your app > [Default install scope and group capability](concepts/deploy-and-publish/add-default-install-scope.md) | +|03/05/2021|Default install scope and group capability | Publish your app > [Default install scope and group capability](concepts/deploy-and-publish/add-default-install-scope.md) | |03/05/2021|Reorder personal app tabs | Build tabs > [Reorder the chat tab in personal apps](tabs/how-to/create-personal-tab.md#reorder-static-personal-tabs) | |03/04/2021|Information masking in Adaptive cards | Build cards and task modules > Build cards > [Information masking in Adaptive cards](task-modules-and-cards/cards/cards-format.md#information-masking-in-adaptive-cards) | |02/19/2021|Added location capabilities. | ΓÇó App fundamentals > Device capabilities > [Overview](concepts/device-capabilities/device-capabilities-overview.md) </br> ΓÇó App fundamentals > Device capabilities > [Request device permissions](concepts/device-capabilities/native-device-permissions.md) </br> ΓÇó App fundamentals > Device capabilities > [Integrate media capabilities](concepts/device-capabilities/media-capabilities.md) </br> ΓÇó App fundamentals > Device capabilities > [Integrate QR or barcode scanner capability](concepts/device-capabilities/qr-barcode-scanner-capability.md) </br> ΓÇó App fundamentals > Device capabilities > [Integrate location capabilities](concepts/device-capabilities/location-capability.md) | Developer preview is a public program that provides early access to unreleased T | 23/05/2024 | Leverage AI label, citations, feedback buttons, and sensitivity labels in your bot's messages. | Build bots > Bot conversations > [Format AI bot messages](bots/how-to/format-ai-bot-messages.md) | | 23/05/2024 | Enhance your Copilot message extension plugin to hand off a conversation to your custom engine agent.| Build message extensions > Build message extensions using Bot Framework > Search commands > [Copilot handoff](bots/how-to/conversations/bot-copilot-handoff.md)| | 14/05/2024 | Introduced a new manifest property to let potential customers contact you with queries before they can confidently adopt your app.| App manifest > [Public developer preview](resources/schem#developercontactinfo)|-| 07/05/2024 | You can specify a 32x32 color icon with a transparent background to ensure a consistent appearance when your app runs in Outlook and Microsoft 365.| Distribute your app > [32x32 color icon](concepts/build-and-test/apps-package.md#outline-icon)| +| 07/05/2024 | You can specify a 32x32 color icon with a transparent background to ensure a consistent appearance when your app runs in Outlook and Microsoft 365.| Publish your app > [32x32 color icon](concepts/build-and-test/apps-package.md#outline-icon)| | 15/03/2024 | Extend static tabs to channels with a customizable experience. | [Build tabs for Teams](tabs/what-are-tabs.md) | | 12/02/2024 | Build API-based message extension using Developer Portal for Teams. | Build message extension > [Build API-based message extension](messaging-extensions/build-api-based-message-extension.md) | | 06/02/2024 | Introduced `systemDefault` reserved activity type for send activity feed notifications| Build tabs > [Send activity feed notifications](tabs/send-activity-feed-notification.md#requirements-to-use-the-activity-feed-notification-apis)| |