From 66ce1a1549b428ea96fa60e2a6a8560b6a90f50d Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Wed, 13 Aug 2025 13:21:55 +0530 Subject: [PATCH 01/44] Create App Developer Guidance for Shared and Private Channel.md --- ...Guidance for Shared and Private Channel.md | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 msteams-platform/concepts/build-and-test/App Developer Guidance for Shared and Private Channel.md diff --git a/msteams-platform/concepts/build-and-test/App Developer Guidance for Shared and Private Channel.md b/msteams-platform/concepts/build-and-test/App Developer Guidance for Shared and Private Channel.md new file mode 100644 index 00000000000..3d5d163aa49 --- /dev/null +++ b/msteams-platform/concepts/build-and-test/App Developer Guidance for Shared and Private Channel.md @@ -0,0 +1,45 @@ +--- +title: Teams Connect Shared Channels +author: surbhigupta +description: Learn about Teams Connect shared channels to securely collaborate with internal and external users in a shared space without switching tenants. +ms.author: surbhigupta +ms.localizationpriority: high +ms.topic: conceptual +ms.date: 04/09/2025 +--- +# Adapting Microsoft Teams App for Private and Shared Channels: A Developer's Guide + +As Microsoft Teams evolves, shared and private channels introduce new collaboration patterns that differ significantly from Standard channels. To function reliably and securely across all channel types, apps must become context-aware—specifically in terms of: + +- Membership structure +- Storage architecture +- Privacy boundaries + +## Updating Your App Ensures the following: + +- Visible and usable everywhere: Your app can be added to private and shared channels, not just standard ones. +- Works as expected: Your app handles channel-specific members and file storage correctly. +- Safe and secure: Your app respects privacy rules and avoids data leaks between channels. +- Future Readiness: Your app follows Microsoft’s direction to support private and shared channels. + +This guide helps you understand the updates needed to make your Teams app work seamlessly across Standard, private, and Shared channels. It covers what’s changed, key concepts such as membership, access control, installation flow, and storage, along with implementation steps, testing tips, and best practices to get your app channel-ready. + +## Channel Models in Microsoft Teams + +**Standard Channels** + +- Visible to the entire team +- All team members have access by default + +**Private Channels** + +- Access limited to invited team members only +- Files are stored in the channel’s dedicated SharePoint site + +**Shared Channels** + +- Can include members outside the host team +- Shareable with individuals or teams across the same or different organizations +- Files are stored in the channel’s own SharePoint site + + From e978febb258d12dfb80257063f1da73f47edd31a Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Wed, 13 Aug 2025 13:59:24 +0530 Subject: [PATCH 02/44] Update App Developer Guidance for Shared and Private Channel.md --- ...Guidance for Shared and Private Channel.md | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/msteams-platform/concepts/build-and-test/App Developer Guidance for Shared and Private Channel.md b/msteams-platform/concepts/build-and-test/App Developer Guidance for Shared and Private Channel.md index 3d5d163aa49..941508967d2 100644 --- a/msteams-platform/concepts/build-and-test/App Developer Guidance for Shared and Private Channel.md +++ b/msteams-platform/concepts/build-and-test/App Developer Guidance for Shared and Private Channel.md @@ -1,7 +1,7 @@ --- title: Teams Connect Shared Channels author: surbhigupta -description: Learn about Teams Connect shared channels to securely collaborate with internal and external users in a shared space without switching tenants. +description: Explore Teams Connect shared channels to collaborate securely with both internal and external users in one shared space. ms.author: surbhigupta ms.localizationpriority: high ms.topic: conceptual @@ -15,21 +15,28 @@ As Microsoft Teams evolves, shared and private channels introduce new collaborat - Storage architecture - Privacy boundaries -## Updating Your App Ensures the following: +## Updating Your App Ensures - Visible and usable everywhere: Your app can be added to private and shared channels, not just standard ones. - Works as expected: Your app handles channel-specific members and file storage correctly. - Safe and secure: Your app respects privacy rules and avoids data leaks between channels. - Future Readiness: Your app follows Microsoft’s direction to support private and shared channels. -This guide helps you understand the updates needed to make your Teams app work seamlessly across Standard, private, and Shared channels. It covers what’s changed, key concepts such as membership, access control, installation flow, and storage, along with implementation steps, testing tips, and best practices to get your app channel-ready. +This guide helps you understand the updates needed to make your Teams app work seamlessly across Standard, private, and Shared channels. + +What This Guide Covers + +- key concepts (membership, access, installation, storage) +- Implementation steps +- testing guidance +- Best practices ## Channel Models in Microsoft Teams **Standard Channels** - Visible to the entire team -- All team members have access by default +- All team members have access to the channel by default **Private Channels** @@ -38,8 +45,6 @@ This guide helps you understand the updates needed to make your Teams app work s **Shared Channels** -- Can include members outside the host team -- Shareable with individuals or teams across the same or different organizations -- Files are stored in the channel’s own SharePoint site - - +- Including external and nonhost team members +- Sharing with individuals or teams across organizations +- Storing files in the channel’s dedicated SharePoint sit From 95fabf56d3880dbe07f544b4c12adb50da95928d Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Wed, 13 Aug 2025 14:07:18 +0530 Subject: [PATCH 03/44] Update App Developer Guidance for Shared and Private Channel.md --- .../App Developer Guidance for Shared and Private Channel.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msteams-platform/concepts/build-and-test/App Developer Guidance for Shared and Private Channel.md b/msteams-platform/concepts/build-and-test/App Developer Guidance for Shared and Private Channel.md index 941508967d2..bff784888e1 100644 --- a/msteams-platform/concepts/build-and-test/App Developer Guidance for Shared and Private Channel.md +++ b/msteams-platform/concepts/build-and-test/App Developer Guidance for Shared and Private Channel.md @@ -1,5 +1,5 @@ --- -title: Teams Connect Shared Channels +title: Teams Connect Shared and Private Channels author: surbhigupta description: Explore Teams Connect shared channels to collaborate securely with both internal and external users in one shared space. ms.author: surbhigupta From 77adb58323cc0b14a338c47d4523777b3facd1ce Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Wed, 13 Aug 2025 14:30:25 +0530 Subject: [PATCH 04/44] Update App Developer Guidance for Shared and Private Channel.md --- ... Guidance for Shared and Private Channel.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/msteams-platform/concepts/build-and-test/App Developer Guidance for Shared and Private Channel.md b/msteams-platform/concepts/build-and-test/App Developer Guidance for Shared and Private Channel.md index bff784888e1..aaf82dd18bf 100644 --- a/msteams-platform/concepts/build-and-test/App Developer Guidance for Shared and Private Channel.md +++ b/msteams-platform/concepts/build-and-test/App Developer Guidance for Shared and Private Channel.md @@ -48,3 +48,21 @@ What This Guide Covers - Including external and nonhost team members - Sharing with individuals or teams across organizations - Storing files in the channel’s dedicated SharePoint sit + +## Shared Channel Capabilities + +## Teams Channel Models – Capabilities Comparison + +| **Category** | **Capability** | **Standard Channel** | **Private Channel** | **Shared Channel** | +|--------------|----------------------------------------------------------------------------------|----------------------|---------------------|---------------------| +| **Membership** | Can add people to the channel without adding to the host team | No | No | Yes | +| | Channel membership can be limited to a subset of the host team | No | Yes | Yes | +| | Channel can be shared with other teams to inherit members from the team | No | No | Yes | +| | Channel can be shared directly with its parent team to inherit members | N/A | No | Yes | +| | Guests (B2B Guests) can participate in the channel | Yes | Yes | No | +| | External participants (B2B Direct Connect) can participate in the channel | No | No | Yes | +| | Channel is hosted under a host team | Yes | Yes | Yes | +| **Storage** | Each channel has a dedicated SharePoint site | No (inherits team site) | Yes | Yes | +| **App Model** | App must be installed in the host team | Yes | Yes | Yes | +| | App installed to host team automatically available in channel | Yes | No | No | +| | App must be added to each channel | No | Yes | Yes | From 90ed453c935eafc936f218ca30edf7d08c1b8966 Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Wed, 13 Aug 2025 17:12:06 +0530 Subject: [PATCH 05/44] Update App Developer Guidance for Shared and Private Channel.md --- ... Developer Guidance for Shared and Private Channel.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/msteams-platform/concepts/build-and-test/App Developer Guidance for Shared and Private Channel.md b/msteams-platform/concepts/build-and-test/App Developer Guidance for Shared and Private Channel.md index aaf82dd18bf..1f1d924308b 100644 --- a/msteams-platform/concepts/build-and-test/App Developer Guidance for Shared and Private Channel.md +++ b/msteams-platform/concepts/build-and-test/App Developer Guidance for Shared and Private Channel.md @@ -24,7 +24,7 @@ As Microsoft Teams evolves, shared and private channels introduce new collaborat This guide helps you understand the updates needed to make your Teams app work seamlessly across Standard, private, and Shared channels. -What This Guide Covers +What This Guide Covers? - key concepts (membership, access, installation, storage) - Implementation steps @@ -66,3 +66,10 @@ What This Guide Covers | **App Model** | App must be installed in the host team | Yes | Yes | Yes | | | App installed to host team automatically available in channel | Yes | No | No | | | App must be added to each channel | No | Yes | Yes | + +> **Note:** + +> - Currently, only apps that include tabs are supported in private and shared channels in Microsoft Teams. +> - Tab apps in shared channels are available in [Government Community Cloud (GCC), GCC High, Department of Defense (DoD)](../cloud-overview.md#teams-app-capabilities), and [Teams operated by 21Vianet](../sovereign-cloud.md) environments. +> - SharePoint and the SharePoint pages apps aren't supported for shared channels in GCC, GCC High, DoD, and Teams operated by 21Vianet environments. +> - Bots and message extensions are not supported in shared channels. From 7be884dd72cef426eedaca4a5f96db31a8db55c9 Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Wed, 13 Aug 2025 18:19:17 +0530 Subject: [PATCH 06/44] Create App-Developer-Guidance-for-Shared-and-Private-Channel.md --- ...Guidance-for-Shared-and-Private-Channel.md | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 msteams-platform/concepts/build-and-test/App-Developer-Guidance-for-Shared-and-Private-Channel.md diff --git a/msteams-platform/concepts/build-and-test/App-Developer-Guidance-for-Shared-and-Private-Channel.md b/msteams-platform/concepts/build-and-test/App-Developer-Guidance-for-Shared-and-Private-Channel.md new file mode 100644 index 00000000000..1f1d924308b --- /dev/null +++ b/msteams-platform/concepts/build-and-test/App-Developer-Guidance-for-Shared-and-Private-Channel.md @@ -0,0 +1,75 @@ +--- +title: Teams Connect Shared and Private Channels +author: surbhigupta +description: Explore Teams Connect shared channels to collaborate securely with both internal and external users in one shared space. +ms.author: surbhigupta +ms.localizationpriority: high +ms.topic: conceptual +ms.date: 04/09/2025 +--- +# Adapting Microsoft Teams App for Private and Shared Channels: A Developer's Guide + +As Microsoft Teams evolves, shared and private channels introduce new collaboration patterns that differ significantly from Standard channels. To function reliably and securely across all channel types, apps must become context-aware—specifically in terms of: + +- Membership structure +- Storage architecture +- Privacy boundaries + +## Updating Your App Ensures + +- Visible and usable everywhere: Your app can be added to private and shared channels, not just standard ones. +- Works as expected: Your app handles channel-specific members and file storage correctly. +- Safe and secure: Your app respects privacy rules and avoids data leaks between channels. +- Future Readiness: Your app follows Microsoft’s direction to support private and shared channels. + +This guide helps you understand the updates needed to make your Teams app work seamlessly across Standard, private, and Shared channels. + +What This Guide Covers? + +- key concepts (membership, access, installation, storage) +- Implementation steps +- testing guidance +- Best practices + +## Channel Models in Microsoft Teams + +**Standard Channels** + +- Visible to the entire team +- All team members have access to the channel by default + +**Private Channels** + +- Access limited to invited team members only +- Files are stored in the channel’s dedicated SharePoint site + +**Shared Channels** + +- Including external and nonhost team members +- Sharing with individuals or teams across organizations +- Storing files in the channel’s dedicated SharePoint sit + +## Shared Channel Capabilities + +## Teams Channel Models – Capabilities Comparison + +| **Category** | **Capability** | **Standard Channel** | **Private Channel** | **Shared Channel** | +|--------------|----------------------------------------------------------------------------------|----------------------|---------------------|---------------------| +| **Membership** | Can add people to the channel without adding to the host team | No | No | Yes | +| | Channel membership can be limited to a subset of the host team | No | Yes | Yes | +| | Channel can be shared with other teams to inherit members from the team | No | No | Yes | +| | Channel can be shared directly with its parent team to inherit members | N/A | No | Yes | +| | Guests (B2B Guests) can participate in the channel | Yes | Yes | No | +| | External participants (B2B Direct Connect) can participate in the channel | No | No | Yes | +| | Channel is hosted under a host team | Yes | Yes | Yes | +| **Storage** | Each channel has a dedicated SharePoint site | No (inherits team site) | Yes | Yes | +| **App Model** | App must be installed in the host team | Yes | Yes | Yes | +| | App installed to host team automatically available in channel | Yes | No | No | +| | App must be added to each channel | No | Yes | Yes | + +> **Note:** + +> - Currently, only apps that include tabs are supported in private and shared channels in Microsoft Teams. +> - Tab apps in shared channels are available in [Government Community Cloud (GCC), GCC High, Department of Defense (DoD)](../cloud-overview.md#teams-app-capabilities), and [Teams operated by 21Vianet](../sovereign-cloud.md) environments. +> - SharePoint and the SharePoint pages apps aren't supported for shared channels in GCC, GCC High, DoD, and Teams operated by 21Vianet environments. +> - Bots and message extensions are not supported in shared channels. From 813c413039ff3f4b894b7843862c0afe6b7f9a67 Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Wed, 13 Aug 2025 18:23:25 +0530 Subject: [PATCH 07/44] Update App-Developer-Guidance-for-Shared-and-Private-Channel.md --- .../App-Developer-Guidance-for-Shared-and-Private-Channel.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msteams-platform/concepts/build-and-test/App-Developer-Guidance-for-Shared-and-Private-Channel.md b/msteams-platform/concepts/build-and-test/App-Developer-Guidance-for-Shared-and-Private-Channel.md index 1f1d924308b..2cce9b4516a 100644 --- a/msteams-platform/concepts/build-and-test/App-Developer-Guidance-for-Shared-and-Private-Channel.md +++ b/msteams-platform/concepts/build-and-test/App-Developer-Guidance-for-Shared-and-Private-Channel.md @@ -51,7 +51,7 @@ What This Guide Covers? ## Shared Channel Capabilities -## Teams Channel Models – Capabilities Comparison +### Teams Channel Models – Capabilities Comparison | **Category** | **Capability** | **Standard Channel** | **Private Channel** | **Shared Channel** | |--------------|----------------------------------------------------------------------------------|----------------------|---------------------|---------------------| From 40b6a35469de5df61f87360d11cb0b9a5e1ff29e Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Wed, 13 Aug 2025 18:53:23 +0530 Subject: [PATCH 08/44] Delete msteams-platform/concepts/build-and-test/App Developer Guidance for Shared and Private Channel.md --- ...Guidance for Shared and Private Channel.md | 75 ------------------- 1 file changed, 75 deletions(-) delete mode 100644 msteams-platform/concepts/build-and-test/App Developer Guidance for Shared and Private Channel.md diff --git a/msteams-platform/concepts/build-and-test/App Developer Guidance for Shared and Private Channel.md b/msteams-platform/concepts/build-and-test/App Developer Guidance for Shared and Private Channel.md deleted file mode 100644 index 1f1d924308b..00000000000 --- a/msteams-platform/concepts/build-and-test/App Developer Guidance for Shared and Private Channel.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -title: Teams Connect Shared and Private Channels -author: surbhigupta -description: Explore Teams Connect shared channels to collaborate securely with both internal and external users in one shared space. -ms.author: surbhigupta -ms.localizationpriority: high -ms.topic: conceptual -ms.date: 04/09/2025 ---- -# Adapting Microsoft Teams App for Private and Shared Channels: A Developer's Guide - -As Microsoft Teams evolves, shared and private channels introduce new collaboration patterns that differ significantly from Standard channels. To function reliably and securely across all channel types, apps must become context-aware—specifically in terms of: - -- Membership structure -- Storage architecture -- Privacy boundaries - -## Updating Your App Ensures - -- Visible and usable everywhere: Your app can be added to private and shared channels, not just standard ones. -- Works as expected: Your app handles channel-specific members and file storage correctly. -- Safe and secure: Your app respects privacy rules and avoids data leaks between channels. -- Future Readiness: Your app follows Microsoft’s direction to support private and shared channels. - -This guide helps you understand the updates needed to make your Teams app work seamlessly across Standard, private, and Shared channels. - -What This Guide Covers? - -- key concepts (membership, access, installation, storage) -- Implementation steps -- testing guidance -- Best practices - -## Channel Models in Microsoft Teams - -**Standard Channels** - -- Visible to the entire team -- All team members have access to the channel by default - -**Private Channels** - -- Access limited to invited team members only -- Files are stored in the channel’s dedicated SharePoint site - -**Shared Channels** - -- Including external and nonhost team members -- Sharing with individuals or teams across organizations -- Storing files in the channel’s dedicated SharePoint sit - -## Shared Channel Capabilities - -## Teams Channel Models – Capabilities Comparison - -| **Category** | **Capability** | **Standard Channel** | **Private Channel** | **Shared Channel** | -|--------------|----------------------------------------------------------------------------------|----------------------|---------------------|---------------------| -| **Membership** | Can add people to the channel without adding to the host team | No | No | Yes | -| | Channel membership can be limited to a subset of the host team | No | Yes | Yes | -| | Channel can be shared with other teams to inherit members from the team | No | No | Yes | -| | Channel can be shared directly with its parent team to inherit members | N/A | No | Yes | -| | Guests (B2B Guests) can participate in the channel | Yes | Yes | No | -| | External participants (B2B Direct Connect) can participate in the channel | No | No | Yes | -| | Channel is hosted under a host team | Yes | Yes | Yes | -| **Storage** | Each channel has a dedicated SharePoint site | No (inherits team site) | Yes | Yes | -| **App Model** | App must be installed in the host team | Yes | Yes | Yes | -| | App installed to host team automatically available in channel | Yes | No | No | -| | App must be added to each channel | No | Yes | Yes | - -> **Note:** - -> - Currently, only apps that include tabs are supported in private and shared channels in Microsoft Teams. -> - Tab apps in shared channels are available in [Government Community Cloud (GCC), GCC High, Department of Defense (DoD)](../cloud-overview.md#teams-app-capabilities), and [Teams operated by 21Vianet](../sovereign-cloud.md) environments. -> - SharePoint and the SharePoint pages apps aren't supported for shared channels in GCC, GCC High, DoD, and Teams operated by 21Vianet environments. -> - Bots and message extensions are not supported in shared channels. From 72a38df6eb6d8e3078d30aff0b15e3cb44848362 Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Thu, 14 Aug 2025 12:04:43 +0530 Subject: [PATCH 09/44] Update App-Developer-Guidance-for-Shared-and-Private-Channel.md --- ...Guidance-for-Shared-and-Private-Channel.md | 41 +++++++++++++++++-- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/msteams-platform/concepts/build-and-test/App-Developer-Guidance-for-Shared-and-Private-Channel.md b/msteams-platform/concepts/build-and-test/App-Developer-Guidance-for-Shared-and-Private-Channel.md index 2cce9b4516a..d0d6aa21afe 100644 --- a/msteams-platform/concepts/build-and-test/App-Developer-Guidance-for-Shared-and-Private-Channel.md +++ b/msteams-platform/concepts/build-and-test/App-Developer-Guidance-for-Shared-and-Private-Channel.md @@ -33,17 +33,17 @@ What This Guide Covers? ## Channel Models in Microsoft Teams -**Standard Channels** +### Standard Channels - Visible to the entire team - All team members have access to the channel by default -**Private Channels** +### Private Channels - Access limited to invited team members only - Files are stored in the channel’s dedicated SharePoint site -**Shared Channels** +### Shared Channels - Including external and nonhost team members - Sharing with individuals or teams across organizations @@ -73,3 +73,38 @@ What This Guide Covers? > - Tab apps in shared channels are available in [Government Community Cloud (GCC), GCC High, Department of Defense (DoD)](../cloud-overview.md#teams-app-capabilities), and [Teams operated by 21Vianet](../sovereign-cloud.md) environments. > - SharePoint and the SharePoint pages apps aren't supported for shared channels in GCC, GCC High, DoD, and Teams operated by 21Vianet environments. > - Bots and message extensions are not supported in shared channels. + +## Understanding How Your Teams App Works in Private and Shared Channels + +Microsoft Teams supports different types of channels—Standard, Private, and Shared. Each has unique rules for membership, storage, and access. To ensure your app works reliably and securely, it’s important to understand these differences. + +### Channel Membership Considerations + +- Private and Shared channels include only selected members; team membership isn't automatic. +- Private and Shared channels deliver app messages or notifications exclusively to users who are members of that specific channel. +- Private and Shared channels require the use of channel-designated tools to view or manage membership accurately. + +### External and Guest Users + +- Shared channels might include users from outside your organization or tenant. +- These users might have limited permissions depending on their role. +- Tip: Always check user roles before assigning tasks or granting access through the app. + +### File Storage Behaviours in Private and Shared Channels + +- Private and Shared channels use dedicated SharePoint sites for storing files. +- Private and Shared channels require apps to access or save documents using the correct site linked to the channel. +- Private and Shared channels work best when your app is configured to locate and use the associated SharePoint site. + +### Data Privacy and Scope + +- Apps that collect or display data (like analytics or reports) should only show information from the current channel. +- Aggregating data across channels can expose private content to unintended users. +- Tip: Keep data scoped to the channel unless broader sharing is explicitly allowed. + +### Implementation Guidelines for Developers + +- Confirm your app is installed in the correct channel type. +- Check membership lists before sending messages or assigning tasks. +- Use approved SharePoint sites for file access. +- Be cautious when sharing or aggregating data across channels. From f2dca7b4a291691decdec3b33752864ca389b21c Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Thu, 14 Aug 2025 13:02:01 +0530 Subject: [PATCH 10/44] Update App-Developer-Guidance-for-Shared-and-Private-Channel.md --- ...Guidance-for-Shared-and-Private-Channel.md | 47 ++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/msteams-platform/concepts/build-and-test/App-Developer-Guidance-for-Shared-and-Private-Channel.md b/msteams-platform/concepts/build-and-test/App-Developer-Guidance-for-Shared-and-Private-Channel.md index d0d6aa21afe..d806352ca78 100644 --- a/msteams-platform/concepts/build-and-test/App-Developer-Guidance-for-Shared-and-Private-Channel.md +++ b/msteams-platform/concepts/build-and-test/App-Developer-Guidance-for-Shared-and-Private-Channel.md @@ -90,7 +90,7 @@ Microsoft Teams supports different types of channels—Standard, Private, and Sh - These users might have limited permissions depending on their role. - Tip: Always check user roles before assigning tasks or granting access through the app. -### File Storage Behaviours in Private and Shared Channels +### File Storage Behavior in Private and Shared Channels - Private and Shared channels use dedicated SharePoint sites for storing files. - Private and Shared channels require apps to access or save documents using the correct site linked to the channel. @@ -108,3 +108,48 @@ Microsoft Teams supports different types of channels—Standard, Private, and Sh - Check membership lists before sending messages or assigning tasks. - Use approved SharePoint sites for file access. - Be cautious when sharing or aggregating data across channels. + +## Core Implementation Concepts for Shared and Private Channels + +![This diagram shows how membership works in shared channels across organizations.](../../assets/images/membership-types-shared-channels.png) + +![This diagram shows how direct membership works in a private channel.](../../assets/images/membership-types-private-channels.png) + +## Channel Membership Basics + +Every channel—whether Standard, Private, or Shared—lives inside a host team. Understanding how users are added to these channels helps you build apps that behave correctly for different member types. + +### Direct vs. Indirect Membership + +Private Channels + +- Only members of the host team can be added directly. + +Shared Channels + +- Can include direct members from: + - The host team + - Other users within the same organization + - Users from external organizations (via B2B Direct Connect) + +Indirect Members (Shared Channels Only) + +- A shared channel can be linked to other teams (inside or outside your org). +- Members of those teams get indirect access to the channel. + +### Types of Users in Channels + +Understanding user types helps you tailor app behavior: + +| **User Type** | **Description** | **Channel Access** | +|----------------------|----------------------------------------------------------------------|-------------------------------------------| +| Host Team Users | Members of the team where the channel was created | Standard, Private, Shared | +| In-Tenant Users | Users from your organization, not necessarily in the host team | Shared channels only | +| Guest Users | External users added as B2B guests in your organization | Standard and Private channels only | +| External Users | Users from other organizations via B2B Direct Connect | Shared channels only | + +### Developer Tips + +- Always fetch channel members, not team members—channel membership is what matters. +- Use user roles to adjust app behavior: + For example, limit actions for external users to protect sensitive features. From f242351e24c8fee757ddd9316b93e7be598227d5 Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Thu, 14 Aug 2025 13:15:48 +0530 Subject: [PATCH 11/44] Update App-Developer-Guidance-for-Shared-and-Private-Channel.md --- ...Guidance-for-Shared-and-Private-Channel.md | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/msteams-platform/concepts/build-and-test/App-Developer-Guidance-for-Shared-and-Private-Channel.md b/msteams-platform/concepts/build-and-test/App-Developer-Guidance-for-Shared-and-Private-Channel.md index d806352ca78..2e7217a19c8 100644 --- a/msteams-platform/concepts/build-and-test/App-Developer-Guidance-for-Shared-and-Private-Channel.md +++ b/msteams-platform/concepts/build-and-test/App-Developer-Guidance-for-Shared-and-Private-Channel.md @@ -153,3 +153,28 @@ Understanding user types helps you tailor app behavior: - Always fetch channel members, not team members—channel membership is what matters. - Use user roles to adjust app behavior: For example, limit actions for external users to protect sensitive features. + +## SharePoint Storage for Private and Shared Channels + +Each Private or Shared channel has its own SharePoint site, separate from the host team's site. This site includes: + +- A dedicated document library +- Channel-specific folders, lists, and pages + +### Key Considerations + +- When your app uploads or retrieves files, or interacts with SharePoint lists/pages, make sure you're targeting the channel’s site, not the team’s root site. +- To share files or links: +- Use “people with existing access” links to respect channel permissions. +- Or use the Microsoft Graph invite API to explicitly grant access—especially important for external users in shared channels. + +## App Installation in Private and Shared Channels + +To make your app available in Private or Shared channels, you need to explicitly declare support in the app manifest. Unlike Standard channels, where installing the app at the team level is sufficient, Private and Shared channels require an additional step. + +### Installation Workflow + +- Install the app at the team level. +- Add the app to the specific channel. A channel owner or member must add the app to each Private or Shared channel where it’s needed. + + Note: Without this step, your app won’t appear or function in those channels—even if it’s installed at the team level. From e6ec293427737acc025af161473808c20dea4068 Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Thu, 14 Aug 2025 13:28:06 +0530 Subject: [PATCH 12/44] Update App-Developer-Guidance-for-Shared-and-Private-Channel.md --- ...per-Guidance-for-Shared-and-Private-Channel.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/msteams-platform/concepts/build-and-test/App-Developer-Guidance-for-Shared-and-Private-Channel.md b/msteams-platform/concepts/build-and-test/App-Developer-Guidance-for-Shared-and-Private-Channel.md index 2e7217a19c8..d64b40bddd6 100644 --- a/msteams-platform/concepts/build-and-test/App-Developer-Guidance-for-Shared-and-Private-Channel.md +++ b/msteams-platform/concepts/build-and-test/App-Developer-Guidance-for-Shared-and-Private-Channel.md @@ -163,18 +163,19 @@ Each Private or Shared channel has its own SharePoint site, separate from the ho ### Key Considerations -- When your app uploads or retrieves files, or interacts with SharePoint lists/pages, make sure you're targeting the channel’s site, not the team’s root site. -- To share files or links: -- Use “people with existing access” links to respect channel permissions. -- Or use the Microsoft Graph invite API to explicitly grant access—especially important for external users in shared channels. +- Ensure you're targeting the channel’s site—not the team’s root site—when uploading or retrieving files, or interacting with SharePoint lists/pages. +- Use 'people with existing access' links to respect channel-level permissions when sharing files or links. +- Call the Microsoft Graph invite API to explicitly grant access, especially for external users in shared channels. ## App Installation in Private and Shared Channels -To make your app available in Private or Shared channels, you need to explicitly declare support in the app manifest. Unlike Standard channels, where installing the app at the team level is sufficient, Private and Shared channels require an additional step. +To make your app available in Private or Shared channels, you need to explicitly declare support in the app manifest. Unlike Standard channels, where installing the app at the team level is sufficient, Private and Shared channels require an extra step. ### Installation Workflow - Install the app at the team level. -- Add the app to the specific channel. A channel owner or member must add the app to each Private or Shared channel where it’s needed. +- Add the app to the specific channel. A channel owner or member adds the app to each Private or Shared channel as needed. - Note: Without this step, your app won’t appear or function in those channels—even if it’s installed at the team level. + Note: Without this step, your app doesn’t appear or function in those channels—even if it's installed at the team level. + +Now that we understand the concepts, let’s look at how to make the required changes in your app. From 96e2a7a58bbec5c25979e93d32f7f27dc0d44a2c Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Thu, 14 Aug 2025 14:15:24 +0530 Subject: [PATCH 13/44] Create app-developer-guidance-shared-private-channel.md --- ...veloper-guidance-shared-private-channel.md | 181 ++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md diff --git a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md new file mode 100644 index 00000000000..914a0fd0329 --- /dev/null +++ b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md @@ -0,0 +1,181 @@ +--- +title: Teams Connect Shared and Private Channels +author: surbhigupta +description: Explore Teams Connect shared channels to collaborate securely with both internal and external users in one shared space. +ms.author: surbhigupta +ms.localizationpriority: high +ms.topic: conceptual +ms.date: 04/09/2025 +--- +# Adapting Microsoft Teams App for Private and Shared Channels: A Developer's Guide + +As Microsoft Teams evolves, shared and private channels introduce new collaboration patterns that differ significantly from Standard channels. To function reliably and securely across all channel types, apps must become context-aware—specifically in terms of: + +- Membership structure +- Storage architecture +- Privacy boundaries + +This guide helps you understand the updates, best practices, and testing steps needed to adapt your app for priavte and shared channels. + +## Updating Your App Ensures + +- Visible and usable everywhere: Your app can be added to private and shared channels, not just standard ones. +- Works as expected: Your app handles channel-specific members and file storage correctly. +- Safe and secure: Your app respects privacy rules and avoids data leaks between channels. +- Future Readiness: Your app follows Microsoft’s direction to support private and shared channels. + +What This Guide Covers? + +- key concepts (membership, access, installation, storage) +- Implementation steps +- testing guidance +- Best practices + +## Channel Models in Microsoft Teams + +### Standard Channels + +- Visible to the entire team +- All team members have access to the channel by default + +### Private Channels + +- Access limited to invited team members only +- Files are stored in the channel’s dedicated SharePoint site + +### Shared Channels + +- Including external and nonhost team members +- Sharing with individuals or teams across organizations +- Storing files in the channel’s dedicated SharePoint sit + +## Shared Channel Capabilities + +### Teams Channel Models – Capabilities Comparison + +| **Category** | **Capability** | **Standard Channel** | **Private Channel** | **Shared Channel** | +|--------------|----------------------------------------------------------------------------------|----------------------|---------------------|---------------------| +| **Membership** | Can add people to the channel without adding to the host team | No | No | Yes | +| | Channel membership can be limited to a subset of the host team | No | Yes | Yes | +| | Channel can be shared with other teams to inherit members from the team | No | No | Yes | +| | Channel can be shared directly with its parent team to inherit members | N/A | No | Yes | +| | Guests (B2B Guests) can participate in the channel | Yes | Yes | No | +| | External participants (B2B Direct Connect) can participate in the channel | No | No | Yes | +| | Channel is hosted under a host team | Yes | Yes | Yes | +| **Storage** | Each channel has a dedicated SharePoint site | No (inherits team site) | Yes | Yes | +| **App Model** | App must be installed in the host team | Yes | Yes | Yes | +| | App installed to host team automatically available in channel | Yes | No | No | +| | App must be added to each channel | No | Yes | Yes | + +> **Note:** + +> - Currently, only apps that include tabs are supported in private and shared channels in Microsoft Teams. +> - Tab apps in shared channels are available in [Government Community Cloud (GCC), GCC High, Department of Defense (DoD)](../cloud-overview.md#teams-app-capabilities), and [Teams operated by 21Vianet](../sovereign-cloud.md) environments. +> - SharePoint and the SharePoint pages apps aren't supported for shared channels in GCC, GCC High, DoD, and Teams operated by 21Vianet environments. +> - Bots and message extensions are not supported in shared channels. + +## Understanding How Your Teams App Works in Private and Shared Channels + +Microsoft Teams supports different types of channels—Standard, Private, and Shared. Each has unique rules for membership, storage, and access. To ensure your app works reliably and securely, it’s important to understand these differences. + +### Channel Membership Considerations + +- Private and Shared channels include only selected members; team membership isn't automatic. +- Private and Shared channels deliver app messages or notifications exclusively to users who are members of that specific channel. +- Private and Shared channels require the use of channel-designated tools to view or manage membership accurately. + +### External and Guest Users + +- Shared channels might include users from outside your organization or tenant. +- These users might have limited permissions depending on their role. +- Tip: Always check user roles before assigning tasks or granting access through the app. + +### File Storage Behavior in Private and Shared Channels + +- Private and Shared channels use dedicated SharePoint sites for storing files. +- Private and Shared channels require apps to access or save documents using the correct site linked to the channel. +- Private and Shared channels work best when your app is configured to locate and use the associated SharePoint site. + +### Data Privacy and Scope + +- Apps that collect or display data (like analytics or reports) should only show information from the current channel. +- Aggregating data across channels can expose private content to unintended users. +- Tip: Keep data scoped to the channel unless broader sharing is explicitly allowed. + +### Implementation Guidelines for Developers + +- Confirm your app is installed in the correct channel type. +- Check membership lists before sending messages or assigning tasks. +- Use approved SharePoint sites for file access. +- Be cautious when sharing or aggregating data across channels. + +## Core Implementation Concepts for Shared and Private Channels + +![This diagram shows how membership works in shared channels across organizations.](../../assets/images/membership-types-shared-channels.png) + +![This diagram shows how direct membership works in a private channel.](../../assets/images/membership-types-private-channels.png) + +## Channel Membership Basics + +Every channel—whether Standard, Private, or Shared—lives inside a host team. Understanding how users are added to these channels helps you build apps that behave correctly for different member types. + +### Direct vs. Indirect Membership + +Private Channels + +- Only members of the host team can be added directly. + +Shared Channels + +- Can include direct members from: + - The host team + - Other users within the same organization + - Users from external organizations (via B2B Direct Connect) + +Indirect Members (Shared Channels Only) + +- A shared channel can be linked to other teams (inside or outside your org). +- Members of those teams get indirect access to the channel. + +### Types of Users in Channels + +Understanding user types helps you tailor app behavior: + +| **User Type** | **Description** | **Channel Access** | +|----------------------|----------------------------------------------------------------------|-------------------------------------------| +| Host Team Users | Members of the team where the channel was created | Standard, Private, Shared | +| In-Tenant Users | Users from your organization, not necessarily in the host team | Shared channels only | +| Guest Users | External users added as B2B guests in your organization | Standard and Private channels only | +| External Users | Users from other organizations via B2B Direct Connect | Shared channels only | + +### Developer Tips + +- Always fetch channel members, not team members—channel membership is what matters. +- Use user roles to adjust app behavior: + For example, limit actions for external users to protect sensitive features. + +## SharePoint Storage for Private and Shared Channels + +Each Private or Shared channel has its own SharePoint site, separate from the host team's site. This site includes: + +- A dedicated document library +- Channel-specific folders, lists, and pages + +### Key Considerations + +- Ensure you're targeting the channel’s site—not the team’s root site—when uploading or retrieving files, or interacting with SharePoint lists/pages. +- Use 'people with existing access' links to respect channel-level permissions when sharing files or links. +- Call the Microsoft Graph invite API to explicitly grant access, especially for external users in shared channels. + +## App Installation in Private and Shared Channels + +To make your app available in Private or Shared channels, you need to explicitly declare support in the app manifest. Unlike Standard channels, where installing the app at the team level is sufficient, Private and Shared channels require an extra step. + +### Installation Workflow + +- Install the app at the team level. +- Add the app to the specific channel. A channel owner or member adds the app to each Private or Shared channel as needed. + + Note: Without this step, your app doesn’t appear or function in those channels—even if it's installed at the team level. + +Now that we understand the concepts, let’s look at how to make the required changes in your app. From 4635a126a5f1537fd448ce7da0fefece7dfdc03d Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Thu, 14 Aug 2025 18:18:25 +0530 Subject: [PATCH 14/44] Update app-developer-guidance-shared-private-channel.md --- ...veloper-guidance-shared-private-channel.md | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md index 914a0fd0329..cdae7ffae46 100644 --- a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md +++ b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md @@ -15,7 +15,7 @@ As Microsoft Teams evolves, shared and private channels introduce new collaborat - Storage architecture - Privacy boundaries -This guide helps you understand the updates, best practices, and testing steps needed to adapt your app for priavte and shared channels. +This guide helps you understand the updates, best practices, and testing steps needed to adapt your app for private and shared channels. ## Updating Your App Ensures @@ -179,3 +179,30 @@ To make your app available in Private or Shared channels, you need to explicitly Note: Without this step, your app doesn’t appear or function in those channels—even if it's installed at the team level. Now that we understand the concepts, let’s look at how to make the required changes in your app. + +## Step-by-step Guide for Updating Your App + +### Design Principle + +Don’t rely on the channel type (Standard, Private, Shared) to decide how your app behaves. Instead, base behavior on: + +- Channel membership +- User permissions +- App installation status in the channel + +This approach makes your app work reliably across all channel types. + +### Preliminary Configuration Requirements + +1. Update Your App Manifest + +- Add "supportsChannelFeatures": "tier1" to your manifest. This step lets your app be added to Shared and Private channels. [More details here] + +2. Install the App Properly + +- Install the app to the team. +- Ensure users add the app to each channel (Shared or Private) where they want to use it +- If the app isn’t added to a channel, most RSC-based APIs will fail with a 403 error like: +'Caller is not enabled for requesting the lwg channel of Shared channel type…' + +- There is no direct way to check app presence in a channel. You won’t get a clear API response saying 'app not added'. But if you see a 403 error or partial API results, it usually means the app hasn’t been added to that channel by users From 5442a48b2be1ceb7576cc6569f6954cdca53be02 Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Thu, 14 Aug 2025 19:24:36 +0530 Subject: [PATCH 15/44] Update app-developer-guidance-shared-private-channel.md --- .../app-developer-guidance-shared-private-channel.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md index cdae7ffae46..0730c750831 100644 --- a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md +++ b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md @@ -184,7 +184,7 @@ Now that we understand the concepts, let’s look at how to make the required ch ### Design Principle -Don’t rely on the channel type (Standard, Private, Shared) to decide how your app behaves. Instead, base behavior on: +Avoid using the channel type (Standard, Private, Shared) as the basis for determining your app’s behavior. Instead, base behavior on: - Channel membership - User permissions @@ -200,9 +200,7 @@ This approach makes your app work reliably across all channel types. 2. Install the App Properly -- Install the app to the team. -- Ensure users add the app to each channel (Shared or Private) where they want to use it -- If the app isn’t added to a channel, most RSC-based APIs will fail with a 403 error like: -'Caller is not enabled for requesting the lwg channel of Shared channel type…' - -- There is no direct way to check app presence in a channel. You won’t get a clear API response saying 'app not added'. But if you see a 403 error or partial API results, it usually means the app hasn’t been added to that channel by users +- Install the app at the team level. +- Add the app manually in each Shared or Private channel where it's required. +if the app isn't added to the channel, most APIs that depend on RSC will fail with a 403 error message 'Caller isn't enabled for requesting the lwg channel of Shared channel type…' +- When a 403 error with the specified message occurs or API responses return incomplete data,assume the app is not added to the channel. This typically means channel members have not added it. From ffae97a8781da9d9190f81cbc584ed0a57eb36b5 Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Thu, 14 Aug 2025 19:49:23 +0530 Subject: [PATCH 16/44] Update app-developer-guidance-shared-private-channel.md --- .../app-developer-guidance-shared-private-channel.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md index 0730c750831..3b870d61bcb 100644 --- a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md +++ b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md @@ -202,5 +202,5 @@ This approach makes your app work reliably across all channel types. - Install the app at the team level. - Add the app manually in each Shared or Private channel where it's required. -if the app isn't added to the channel, most APIs that depend on RSC will fail with a 403 error message 'Caller isn't enabled for requesting the lwg channel of Shared channel type…' +if the app isn't added to the channel, most APIs that rely on resource-specific consent fails with a 403 error message 'Caller isn't enabled for requesting the lwg channel of Shared channel type…' - When a 403 error with the specified message occurs or API responses return incomplete data,assume the app is not added to the channel. This typically means channel members have not added it. From 55f8a740195d50431542f343e83585f2a904b097 Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Fri, 15 Aug 2025 12:25:51 +0530 Subject: [PATCH 17/44] Update app-developer-guidance-shared-private-channel.md --- ...veloper-guidance-shared-private-channel.md | 51 ++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md index 3b870d61bcb..b5c18e5482d 100644 --- a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md +++ b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md @@ -203,4 +203,53 @@ This approach makes your app work reliably across all channel types. - Install the app at the team level. - Add the app manually in each Shared or Private channel where it's required. if the app isn't added to the channel, most APIs that rely on resource-specific consent fails with a 403 error message 'Caller isn't enabled for requesting the lwg channel of Shared channel type…' -- When a 403 error with the specified message occurs or API responses return incomplete data,assume the app is not added to the channel. This typically means channel members have not added it. +- When a 403 error with the specified message occurs or API responses return incomplete data, assume the app isn't added to the channel. This error typically means channel members didn't add the app to the channel. + +## Getting Accurate Channel Membership in Microsoft Teams + +### Why It Matters + +When sending messages, assigning tasks, or managing permissions, check who is in the channel, not just who is in the team. Shared channels and cross-tenant access often cause team and channel member lists to differ. + +### Use Microsoft Graph to Get Channel Members + +Get Full Roster for Any Channel Type + +- Endpoint GET /teams/{team-id}/members returns only team membership, applicable to standard channels. +- Endpoint GET /teams/{team-id}/channels/{channel-id}/allMembers provides accurate channel membership for Standard, Shared, and Private channels. +- Response from this endpoint includes only eligible members. +- Support for Resource-Specific Consent (RSC) isn't available on these endpoints yet. + +### Understand Indirect Membership in Shared Channels + +Use these endpoints to identify which teams provide access and which users from those teams can access the shared channel: + +- Get contributing teams: +GET /teams/{team-id}/channels/{channel-id}/sharedWithTeams + +Returns each team’s ID, displayName, and isHostTeam. + +Get allowed members from a contributing team: +GET /teams/{team-id}/channels/{channel-id}/sharedWithTeams/{id}/allowedMembers + +- Returns only eligible members. +- These endpoints don't support RSC yet. + +### Identify Direct vs Indirect Members + +- Property @microsoft.graph.originalSourceMembershipUrl on allMembers (beta) indicates indirect membership. +- Property absence signifies that the member is direct. +- Property usage is recommended only as a hint—avoid parsing it directly and prefer supported endpoints instead. + +### Check User Access Before Sensitive Actions + +Use: doesUserHaveAccess(userId, tenantId, upn) + +- Function result returns a Boolean. +- Function purpose is to determine whether to show sensitive actions or target users outside the host tenant. +- Function scope is limited to shared channels only. +- Function roadmap includes broader support, but it's not available yet. + + + + From 39ad87f7ba149b557775c7a202acd1a8b851f712 Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Fri, 15 Aug 2025 12:43:36 +0530 Subject: [PATCH 18/44] Update app-developer-guidance-shared-private-channel.md --- ...veloper-guidance-shared-private-channel.md | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md index b5c18e5482d..d82f2061a48 100644 --- a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md +++ b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md @@ -250,6 +250,26 @@ Use: doesUserHaveAccess(userId, tenantId, upn) - Function scope is limited to shared channels only. - Function roadmap includes broader support, but it's not available yet. +## Retrieving Full Channel Roster Using Bot Framework SDK +When working with the Bot Framework SDK (C#, JavaScript, etc.), you can retrieve the full roster from any channel as follows: +- Use paginated access: Call TeamsInfo.GetPagedMembersAsync(turnContext, pageSize, continuationToken) and continue paging until all members are retrieved. + +- Set required permissions: Make sure your app manifest includes the RSC permission ChannelMember.Read.Group. Without this permission, roster access fails within channels. + +## Handling Known Failure Patterns + +Be aware of the following common issues when accessing channel rosters: + +- Error 403 on Graph calls under RSC + + Cause: The app isn't added to the channel. + + Resolution: Prompt the user to add the app to the channel and retry the request. +- Partial results (owners only) in Shared channels + + Cause: App is disabled or not added to the channel. + + Resolution: Treat the response as a partial roster. Instruct the user to add the app to the channel, then refetch the roster after successful addition. From ec9c374acf7b03dae5973dd892476bb1d20457de Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Fri, 15 Aug 2025 13:20:45 +0530 Subject: [PATCH 19/44] Update app-developer-guidance-shared-private-channel.md --- ...veloper-guidance-shared-private-channel.md | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md index d82f2061a48..71a396c22e2 100644 --- a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md +++ b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md @@ -273,3 +273,25 @@ Be aware of the following common issues when accessing channel rosters: Cause: App is disabled or not added to the channel. Resolution: Treat the response as a partial roster. Instruct the user to add the app to the channel, then refetch the roster after successful addition. + +## Handling Channel Membership Changes + +Channel membership is fluid—users might join or leave, and channels can be shared or unshared with other teams. Your integration should be designed to respond to these changes dynamically. + +### Using Microsoft Graph + +To track membership updates: + +- Subscribe to changes +Set up a Microsoft Graph subscription on: +/teams/{team-id}/channels/getAllMembers +This notifies your app whenever there are changes to channel membership. + +- Respond to notifications +When you receive a membership, share, or unshare notification: +- Refresh the allMembers list to get the current state of channel members. If the channel is shared: + - call sharedWithTeams to identify which teams have access to the shared channel. + - Call allowedMembers to efficiently retrieve indirect members added through shared teams. + + + From f40a6ca9a173db0e194d970605763ce0881cd5af Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Fri, 15 Aug 2025 13:30:28 +0530 Subject: [PATCH 20/44] Update app-developer-guidance-shared-private-channel.md --- ...veloper-guidance-shared-private-channel.md | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md index 71a396c22e2..98e44203408 100644 --- a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md +++ b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md @@ -293,5 +293,26 @@ When you receive a membership, share, or unshare notification: - call sharedWithTeams to identify which teams have access to the shared channel. - Call allowedMembers to efficiently retrieve indirect members added through shared teams. +### Handling Membership Changes in Bot Framework (Bot SDK) + +In the Bot Framework SDK, monitor the conversationUpdate activity to track channel membership changes. + +Key Events to Handle + +- channelShared / channelUnshared +Triggered when a channel is shared or unshared with a team. + - Expect changes in indirect membership. + - Refresh your channel topology and member roster. + - To update your member list, use the member APIs described earlier. +- channelMemberAdded / channelMemberRemoved +Triggered when a user is added or removed from the channel. + - Also fires when the app itself is added or removed. + - Update your member list accordingly when this event occurs. + +Required Permissions + +- Manifest requirement: To receive and process these membership events, include the RSC permission ChannelMember.Read.Group in your app manifest. + + From f8ee056bc82dbe4936633d2504591313057caca6 Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Fri, 15 Aug 2025 13:48:51 +0530 Subject: [PATCH 21/44] Update app-developer-guidance-shared-private-channel.md --- ...veloper-guidance-shared-private-channel.md | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md index 98e44203408..0aa8964ceb2 100644 --- a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md +++ b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md @@ -313,6 +313,26 @@ Required Permissions - Manifest requirement: To receive and process these membership events, include the RSC permission ChannelMember.Read.Group in your app manifest. +## Detecting If Your App Is Added to a Channel + +As you build your app, consider the following: + +- No direct API exists to check whether your app is installed in a specific channel. + +- Bot installation is confirmed when your bot receives a channelMemberAdded event in the conversationUpdate activity for itself. + - This event signals the start of your channel-specific logic—such as sending a welcome message, fetching the roster, configuring tabs, or scheduling background jobs. + - Bot events begin flowing only after the app is added to the channel + +- Channel API access is blocked with a 403 error and the message: +'Caller isn't enabled for requesting the lwg channel of Shared channel type.' To access channel data app has to be enabled in the requesting channel. if the app isn't yet added to the channel. Wait until installation is complete before accessing channel data via Graph or the Bot SDK. + +Note: You can list apps installed at the team level using GET /teams/{team-id}/installedApps, but there's no equivalent API for channel-level installations. +Don't assume that a team-level install means the app is present in all its channels. + + + + + From 6fdeee06ce07f47a694130d321e78f746834d63b Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Fri, 15 Aug 2025 20:32:21 +0530 Subject: [PATCH 22/44] Update app-developer-guidance-shared-private-channel.md --- ...veloper-guidance-shared-private-channel.md | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md index 0aa8964ceb2..5beddd15a81 100644 --- a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md +++ b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md @@ -201,7 +201,7 @@ This approach makes your app work reliably across all channel types. 2. Install the App Properly - Install the app at the team level. -- Add the app manually in each Shared or Private channel where it's required. +- Manually add the app to each Shared or Private channel where it is required. if the app isn't added to the channel, most APIs that rely on resource-specific consent fails with a 403 error message 'Caller isn't enabled for requesting the lwg channel of Shared channel type…' - When a 403 error with the specified message occurs or API responses return incomplete data, assume the app isn't added to the channel. This error typically means channel members didn't add the app to the channel. @@ -315,7 +315,7 @@ Required Permissions ## Detecting If Your App Is Added to a Channel -As you build your app, consider the following: +As you build your app, consider the following guidelines: - No direct API exists to check whether your app is installed in a specific channel. @@ -329,10 +329,41 @@ As you build your app, consider the following: Note: You can list apps installed at the team level using GET /teams/{team-id}/installedApps, but there's no equivalent API for channel-level installations. Don't assume that a team-level install means the app is present in all its channels. +## Identifying External Users and Guests in Channel +As a developer, it's important to differentiate between internal users, guests, and external (cross-tenant) users in channels to: +- Limit sensitive actions to internal users only +- Show or hide certain features based on user type +- Set up the right sign-in process for external users in tabs or bots +### Detecting User Type at Runtime (Tabs & Bots) +For Tabs (using Teams JS SDK): +- Call microsoftTeams.getContext() when the tab loads. +- Check context.user.userRole or context.team.userRole: if it's 'guest,' the user is a guest. +- Compare context.user.tenant.id with context.channel.ownerTenantId (or context.team.groupTenantId): if they differ, the user is external (via B2B Direct Connect). +For Bots: +- To detect guests: +Use TeamsInfo.getMemberAsync or TeamsInfo.getPagedMembersAsync and check if userRole === 'guest.' +- To detect external users: +Each incoming activity includes conversation.tenantId and from.aadObjectId. + +Compare the member’s tenantId with the channel’s host tenant (from Graph channel metadata). (Note: This part might need further clarification.) + +### Detecting User Type from Roster (Graph API or Bot SDK) + +Using Microsoft Graph: + +- Call GET /teams/{team-id}/channels/{channel-id}/allMembers to retrieve the channel roster. +- Check the roles field: if it includes "guest," the user is a guest. +- Compare member.tenantId with channel.hostTenantId: if they’re different, the user is external. + +Using Bot SDK: + +- Use TeamsInfo.GetPagedMembersAsync to get channel members. +- Check TeamsChannelAccount.UserRole: "guest" indicates a guest user. +- Compare TeamsChannelAccount.TenantId with the channel’s host tenant ID (which can be fetched via Graph if needed). (Note: Host tenant ID retrieval might need clarification.) From e8660fe2fddc9a646f504faff4a6495491fdbba7 Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Sat, 16 Aug 2025 08:41:05 +0530 Subject: [PATCH 23/44] Update app-developer-guidance-shared-private-channel.md --- ...veloper-guidance-shared-private-channel.md | 100 +++++++++++++++++- 1 file changed, 97 insertions(+), 3 deletions(-) diff --git a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md index 5beddd15a81..d06a604a896 100644 --- a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md +++ b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md @@ -1,5 +1,5 @@ --- -title: Teams Connect Shared and Private Channels +title: Teams Connects Shared and Private Channels author: surbhigupta description: Explore Teams Connect shared channels to collaborate securely with both internal and external users in one shared space. ms.author: surbhigupta @@ -201,7 +201,7 @@ This approach makes your app work reliably across all channel types. 2. Install the App Properly - Install the app at the team level. -- Manually add the app to each Shared or Private channel where it is required. +- Manually add the app in each Shared or Private channel where required. if the app isn't added to the channel, most APIs that rely on resource-specific consent fails with a 403 error message 'Caller isn't enabled for requesting the lwg channel of Shared channel type…' - When a 403 error with the specified message occurs or API responses return incomplete data, assume the app isn't added to the channel. This error typically means channel members didn't add the app to the channel. @@ -324,7 +324,7 @@ As you build your app, consider the following guidelines: - Bot events begin flowing only after the app is added to the channel - Channel API access is blocked with a 403 error and the message: -'Caller isn't enabled for requesting the lwg channel of Shared channel type.' To access channel data app has to be enabled in the requesting channel. if the app isn't yet added to the channel. Wait until installation is complete before accessing channel data via Graph or the Bot SDK. +'Caller isn't enabled for requesting the lwg channel of Shared channel type.' To access channel data, app has to be enabled in the requesting channel. if the app isn't yet added to the channel. Wait until installation is complete before accessing channel data via Graph or the Bot SDK. Note: You can list apps installed at the team level using GET /teams/{team-id}/installedApps, but there's no equivalent API for channel-level installations. Don't assume that a team-level install means the app is present in all its channels. @@ -367,3 +367,97 @@ Using Bot SDK: - Use TeamsInfo.GetPagedMembersAsync to get channel members. - Check TeamsChannelAccount.UserRole: "guest" indicates a guest user. - Compare TeamsChannelAccount.TenantId with the channel’s host tenant ID (which can be fetched via Graph if needed). (Note: Host tenant ID retrieval might need clarification.) + +## Working with Files Across Channel Types + +When handling files in channels—whether it's file tabs, document libraries, or uploading and retrieving files, you need to account for the distinct SharePoint sites that support private and shared channels, along with their respective storage locations. Relying on the Team’s main site to access channel files or folders doesn’t work. + +### Resolving Storage Correctly + +- Call GET /teams/{teamId}/channels/{channelId}/filesFolder +→ Returns a DriveItem representing the root folder for the channel’s files. +- Use the following details from the response for all subsequent file operations: + - parentReference.driveId: the SharePoint drive linked to the channel’s site + - ID: the folder ID +- Standard channels + - The driveId typically points to the team’s main SharePoint site. +- Private and shared channels + - Expect a different driveId, as these channels have their own dedicated SharePoint sites. + +Best practice + +- Store and reuse the exact driveId and itemId from the filesFolder API. +- Avoid hardcoding library names or URLs assuming the team site applies to all channels. + +Note: This API works consistently across all channel types. + +### File Access Management for External and Guest Users + +External Users (Cross-Tenant) + +- Ensure external users remain in their home tenant while accessing the host channel’s SharePoint site. +- Ensure cross-tenant access is properly configured on both the source and target tenants. +- Ensure your app is multitenant, with consent granted in the host tenant for correct functionality. + +Guest Users (Within Tenant) + +- The channel’s SharePoint site automatically grants channel members access, including guest users from the same tenant. + +### You can take the following actions + +Avoid relying on “Org-wide” sharing links. + +- Use sharing methods that typically exclude users from outside the organization. +- Use specific-people sharing or membership-based direct permissions instead of broad access links. +- Use tenant or site policies to determine whether anonymous or org-wide links are permitted. + +Use the Invite API for precise access control. + +- POST /drives/{driveId}/items/{itemId}/invite +- This method is the most reliable way, to programmatically grant access to specific users or groups. + +### Authenticating External Users in Tabs or Task Modules + +When creating a tab or task module that needs to access SharePoint files from the channel’s tenant, ensure external users are authenticated correctly—especially in private or shared channels. + +- Use getContext() when the content page loads for retrieving the full channel context in which the tab is running. +- Use user.tenant.id and compare it with channel.ownerTenantId or hostTenantId for identifying if the user is external. +- Use getAuthToken with user.tenant.id (or tid) for ensuring the token is issued from the user’s home tenant instead of the host. + +## Messaging in Channels + +### Microsoft Graph + +- Use GET /teams/{team-id}/channels/{channel-id}/messages and .../messages/delta only when the app is added in Shared or Private channels; otherwise, a 403 error occurs with an "app not added to channel" message. +- Use change notifications on /channels/{id}/messages for Shared or Private channels only if RSC permissions are set up correctly. If not, the request fails with a 403 error. +- Use on-demand message reads after the app is added to the channel for reliable access. + +### Bots SDK + +- Use normal v3 conversation routes to send, edit, or delete messages; refer to the documentation for details. +- Use the channel roster to fetch recipients—never rely on team membership. + +## Update the App Manifest to Declare Support for Shared and Private Channels + +Declare support for shared and private channels by adding a new property in your app manifest. This change is mandatory. + +"supportsChannelFeatures": { + "type": "string," + "enum": [ + "tier1," + "tier2," + null + ] + "description": "A property in the app manifest that declares support for all channel features, categorized by tiers." +} + +To support shared and private channels, set supportsChannelFeatures = tier1. + +Benefits of Declaring Tier1 Support: + +- Enable your app to appear in shared and private channels. +- Enable support for the membership model used in shared and private channels. +- Enable access to channel-based SharePoint storage, if your app interacts with files. +- Enable identification of external users in shared channels and guest users in private channels. + +As Microsoft Teams evolves, other channel capabilities might be introduced. To take advantage of future features, further updates to your app might be required. From 988990cca3438fb08ba2b701f644989997b612fa Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Sat, 16 Aug 2025 08:56:32 +0530 Subject: [PATCH 24/44] Update app-developer-guidance-shared-private-channel.md --- ...veloper-guidance-shared-private-channel.md | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md index d06a604a896..d7ac6de300c 100644 --- a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md +++ b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md @@ -461,3 +461,37 @@ Benefits of Declaring Tier1 Support: - Enable identification of external users in shared channels and guest users in private channels. As Microsoft Teams evolves, other channel capabilities might be introduced. To take advantage of future features, further updates to your app might be required. + +## Test Your App Thoroughly Before Shipping + +Make sure to test your app in real scenarios before releasing changes. Here's how to validate it across different channel types. + +### In a standard channel + +- Check that everything still works after your changes. + +### In a private channel (for example, Channel P in Team A) + +- Add the app to Team A, then to private channel P. +- Check if your tab loads properly. +- Check if your bot responds when a member sends a message—test with both in-tenant and guest users. +- Check any feature that lists members or assigns tasks—make sure it only uses channel members. +- Add a new member to the private channel—see if your bot gets an event or if your membership API shows the new member. + +### In a shared channel within the same tenant (for example, Channel X in Team A shared with Team B) + +- Add the app to Team A, then to Channel X. +- Test with a Team B member—make sure they can see the tab and interact with the bot. +- Unshare the channel from Team B—check if your bot receives a channelUnshared event. + +### In a shared channel with an external tenant (for example, using Teams Connect) + +- Send a message from an external user to the bot—check if the bot receives it. +- Trigger a tab or task module from the external user—check if authentication works. If using single sign-On (SSO), you might need to handle it with getAuthToken using the user’s home tenant ID. +- Avoid sending direct messages from your bot to external users—direct messaging functionality doesn't work unless they’re in the same tenant. But bot messages inside the shared channel should work fine. + +Final Step + +- To make sure all required changes are complete, review your test results and check the full documentation. + + From 80cf0c4a45cc8f60f9ecc44d67b90cd6344437cc Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Sat, 16 Aug 2025 09:13:06 +0530 Subject: [PATCH 25/44] Update app-developer-guidance-shared-private-channel.md --- ...p-developer-guidance-shared-private-channel.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md index d7ac6de300c..4c00ab58a1a 100644 --- a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md +++ b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md @@ -494,4 +494,19 @@ Final Step - To make sure all required changes are complete, review your test results and check the full documentation. +## Best Practices for Supporting All Channel Types + +To make sure your app works smoothly in shared, private, and standard channels, follow these best practices: + +- Fetch the latest member list and roles before doing anything. For example, when sending a message or assigning a task, use the actual channel members—not the full team list. +- Adjust features based on user roles. For example, allow sensitive actions only for owners or internal users, and show limited options to guests or external users. +- Protect user data and respect privacy. For example, don’t include private channel data in public reports unless you have clear permission. +- Authenticate users based on their type (internal, guest, external). For example, make sure external users are authenticated in their own tenant, especially when accessing files. +- Update your help guides and tooltips with explanations of how your app behaves in different channels, including any limits for guests or external users. +- Improve performance by caching large member lists. For example, update the cache only when you get a membership change event, instead of calling the API too often. +- Test your app with all kinds of users—owners, members, guests, and external users—across every channel type and confirm everything works as expected. +- Watch for updates in Microsoft Teams documentation and changelogs. For example, keep your app updated when APIs, permissions, or channel features change. + + + From 7264d857bff6b29da1a587c782451e8855113d41 Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Sat, 16 Aug 2025 12:27:50 +0530 Subject: [PATCH 26/44] Update app-developer-guidance-shared-private-channel.md --- ...p-developer-guidance-shared-private-channel.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md index 4c00ab58a1a..cd38c5a1b2f 100644 --- a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md +++ b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md @@ -507,6 +507,21 @@ To make sure your app works smoothly in shared, private, and standard channels, - Test your app with all kinds of users—owners, members, guests, and external users—across every channel type and confirm everything works as expected. - Watch for updates in Microsoft Teams documentation and changelogs. For example, keep your app updated when APIs, permissions, or channel features change. +## Appendix: Developer Guidance with Examples for Updating Teams Apps in Shared & Private Channels +### Mandatory Updates for Teams Apps in Shared & Private Channels +| Change Type | What to Do | Why It Matters | Example | +|-------------|------------|----------------|---------| +| **Mandatory** | Use the Channel Members API | Shared/Private channels have different members than the team. Using the wrong API can miss users or cause data leaks. | **Task app**: Assign tasks only to channel members, not all team members. | +| **Mandatory** | Access the Channel's SharePoint Site | Each channel has its own SharePoint. Using the team site can break file access or expose data. | **Document app**: Store and retrieve files from the channel’s SharePoint site. | +| **Mandatory** | Respect Channel Boundaries | Don’t access or post across channels unless the user allows it. | **Summary app**: Only summarize messages from channels the user opts into. | +| **Mandatory** | Update the App Manifest | Declare support for Shared/Private channels so your app shows up there. | **Any app**: Add `"supportsChannelFeatures": "level2"` to your manifest. | +### Optional UX Improvements for Shared & Private Channels + +| Area | What to Do | Why It Helps | Example | +|------|------------|--------------|---------| +| **Privacy & Access Controls** | Add logic to limit features for guests/external users | Keeps sensitive data safe and follows company policies | **Poll app**: Guests can vote, but only members can create polls or see results | +| **Collaboration Features** | Adjust tools based on channel roles and members | Prevents confusion and accidental changes by guests | **Whiteboard app**: Guests can draw, but not erase others’ work | +| **Smart Notifications** | Customize alerts by channel type and user role | Cuts down noise and makes alerts more useful | **Helpdesk app**: IT gets all alerts. vendors only see their tickets | From 6d8c6fdfa11e479c1685e4a39d43166b65357dcc Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Sat, 16 Aug 2025 14:24:25 +0530 Subject: [PATCH 27/44] Update app-developer-guidance-shared-private-channel.md --- ...veloper-guidance-shared-private-channel.md | 48 +++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md index cd38c5a1b2f..8cecf44fc64 100644 --- a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md +++ b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md @@ -196,9 +196,9 @@ This approach makes your app work reliably across all channel types. 1. Update Your App Manifest -- Add "supportsChannelFeatures": "tier1" to your manifest. This step lets your app be added to Shared and Private channels. [More details here] +- Add "supportsChannelFeatures": "tier1" to your manifest. This step makes your app available in Shared and Private channels.[More details here] -2. Install the App Properly +1. Install the App Properly - Install the app at the team level. - Manually add the app in each Shared or Private channel where required. @@ -211,7 +211,7 @@ if the app isn't added to the channel, most APIs that rely on resource-specific When sending messages, assigning tasks, or managing permissions, check who is in the channel, not just who is in the team. Shared channels and cross-tenant access often cause team and channel member lists to differ. -### Use Microsoft Graph to Get Channel Members +### To Get Channel Members Use Microsoft Graph Get Full Roster for Any Channel Type @@ -525,3 +525,45 @@ To make sure your app works smoothly in shared, private, and standard channels, | **Privacy & Access Controls** | Add logic to limit features for guests/external users | Keeps sensitive data safe and follows company policies | **Poll app**: Guests can vote, but only members can create polls or see results | | **Collaboration Features** | Adjust tools based on channel roles and members | Prevents confusion and accidental changes by guests | **Whiteboard app**: Guests can draw, but not erase others’ work | | **Smart Notifications** | Customize alerts by channel type and user role | Cuts down noise and makes alerts more useful | **Helpdesk app**: IT gets all alerts. vendors only see their tickets | + +### Context & Event Payloads + +- Use teamId for the host team and channelId for the shared channel in context and event payloads. +- Apply hostTeamId and hostTenantId when handling cross-tenant scenarios. +- Detect external users by comparing a user’s tenantId with hostTenantId. +- Listen for events like channelShared, channelUnshared, channelMemberAdded, and channelMemberRemoved to track changes in shared channels. +- Ensure your app is present in the channel so it receives these events. + +### API Changes + +- Review the API Change Table in the Appendix for updates to Graph and Activity Payload Extensions (APX) APIs. +- Switch to the latest APIs that support shared and private channels. + +### Handling External Users + +- Identify B2B Guests using role = guest in Graph or user role = guest in APX. +- Detect B2B Native users by comparing their tenantId with the hostTenantId from getContext(). +- Fetch members using /teams/{teamId}/channels/{channelId}/allmembers for tabs. +- Use channelMemberAdded and /v3/conversations/{conversationId}/pagedMembers to get members in bots. +- Classify users as external if their tenantId doesn’t match the host tenant. + +### Manifest and Permissions + +- Include supportsChannelFeatures = "tier1" in your app manifest so it supports shared and private channels. +- Omit this setting, and your app doesn't appear in shared or private channels. +- Remove this setting later, and your app stops showing up in those channels. +- Update your manifest with Resource Specific Consent (RSC) permissions, as many APIs now require them for shared/private channel functionality. +- Check the API documentation and confirm the RSC permissions required for your app. + +### Privacy, Access & Security + +- Use channel-specific APIs—don’t assume team members are also channel members. +- Access storage through channel-specific APIs and avoid cross-posting unless allowed. +- Respect privacy boundaries, and avoid leaking data between channels or user types. +- Handle internal users, B2B Guests, and B2B Direct Connect users correctly. +- Test all scenarios, including edge cases—not just the happy path. + + + + + From 29fd8f7bb0b6387c54050268da1caab456cb9867 Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Mon, 18 Aug 2025 13:42:45 +0530 Subject: [PATCH 28/44] Update app-developer-guidance-shared-private-channel.md --- ...veloper-guidance-shared-private-channel.md | 62 +++++++++++++++++-- 1 file changed, 58 insertions(+), 4 deletions(-) diff --git a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md index 8cecf44fc64..e744711fc82 100644 --- a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md +++ b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md @@ -194,11 +194,11 @@ This approach makes your app work reliably across all channel types. ### Preliminary Configuration Requirements -1. Update Your App Manifest +Update Your App Manifest - Add "supportsChannelFeatures": "tier1" to your manifest. This step makes your app available in Shared and Private channels.[More details here] -1. Install the App Properly +Install the App Properly - Install the app at the team level. - Manually add the app in each Shared or Private channel where required. @@ -507,7 +507,7 @@ To make sure your app works smoothly in shared, private, and standard channels, - Test your app with all kinds of users—owners, members, guests, and external users—across every channel type and confirm everything works as expected. - Watch for updates in Microsoft Teams documentation and changelogs. For example, keep your app updated when APIs, permissions, or channel features change. -## Appendix: Developer Guidance with Examples for Updating Teams Apps in Shared & Private Channels +## Technical Appendix: Teams App Update Guide for Shared & Private Channel Support ### Mandatory Updates for Teams Apps in Shared & Private Channels @@ -561,7 +561,61 @@ To make sure your app works smoothly in shared, private, and standard channels, - Access storage through channel-specific APIs and avoid cross-posting unless allowed. - Respect privacy boundaries, and avoid leaking data between channels or user types. - Handle internal users, B2B Guests, and B2B Direct Connect users correctly. -- Test all scenarios, including edge cases—not just the happy path. +- Test all scenarios, including edge cases. + +## FAQ Highlights + +General Questions + +Q1: Can I be part of a shared channel without being in the parent team? +A: Yes, shared channels let people outside the team join, as long as they’re invited and have the right permissions. + +Q2: Who has the ability to create shared or private channels? +A: Typically, only team owners or users with specific permissions can create these channels. However, admins might restrict this capability through policy settings. + +Access & Permissions + +Q1: Why can’t I see a private channel I was added to? +A: To view a private channel, you must be a member of both the parent team and the private channel. If you're removed from the team, you lose access to its private channels. + +Q2: Can guests or external users access shared channels? +A: Yes. To allow access, both organizations must enable external access, and the user must be explicitly invited to the shared channel to gain access. + +Q3: How do I know if a channel is private or shared? +A: Check the icon next to the channel name. + +- A lock icon indicates private channel +- A link icon indicates shared channel + +Functionality & Limitations + +Q1: Can I add apps or tabs to a private channel? +A: Yes, you can add apps and tabs to a private channel. However, some apps might not be supported due to permission limitations or compatibility issues. Always check app compatibility before adding it to the private channel. + +Q2: Are files in private channels stored differently? +A: Yes, in platforms like Microsoft Teams, files shared in a Private Channel files are stored in a separate SharePoint site with restricted access. The site is accessible exclusively to Private Channel members, ensuring secure and controlled data sharing. + +Q3: Can I convert a private channel to a shared channel (or vice versa)? +A: No, channel types are permanent once created. If you want to change the type, you need to create a new channel with the preferred settings and migrate content manually. + +Q4: Why am I seeing an 'Access Denied' error when trying to join a shared channel? +A: This issue can happen due to several reasons: + +- You might not be invited correctly +- External access might be disabled for your organization +- You could be signed in with wrong account or tenant + +Q5: What should I do if files or tabs aren’t loading in a channel? +A: Try refreshing the app or browser. If that doesn't help, clear your cache, or try accessing the channel from another device. Also verify that you have the necessary permissions. + +Q6: How do I report issues with shared or private Channels? +A: Contact your IT admin or support team with: + +- Channel name +- Type (shared or private) +- Error message or screenshot + + From c2c0043ccebeac3bfc04bd29647a17f9e8788dfc Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Tue, 19 Aug 2025 11:56:11 +0530 Subject: [PATCH 29/44] Delete msteams-platform/concepts/build-and-test/App-Developer-Guidance-for-Shared-and-Private-Channel.md --- ...Guidance-for-Shared-and-Private-Channel.md | 181 ------------------ 1 file changed, 181 deletions(-) delete mode 100644 msteams-platform/concepts/build-and-test/App-Developer-Guidance-for-Shared-and-Private-Channel.md diff --git a/msteams-platform/concepts/build-and-test/App-Developer-Guidance-for-Shared-and-Private-Channel.md b/msteams-platform/concepts/build-and-test/App-Developer-Guidance-for-Shared-and-Private-Channel.md deleted file mode 100644 index d64b40bddd6..00000000000 --- a/msteams-platform/concepts/build-and-test/App-Developer-Guidance-for-Shared-and-Private-Channel.md +++ /dev/null @@ -1,181 +0,0 @@ ---- -title: Teams Connect Shared and Private Channels -author: surbhigupta -description: Explore Teams Connect shared channels to collaborate securely with both internal and external users in one shared space. -ms.author: surbhigupta -ms.localizationpriority: high -ms.topic: conceptual -ms.date: 04/09/2025 ---- -# Adapting Microsoft Teams App for Private and Shared Channels: A Developer's Guide - -As Microsoft Teams evolves, shared and private channels introduce new collaboration patterns that differ significantly from Standard channels. To function reliably and securely across all channel types, apps must become context-aware—specifically in terms of: - -- Membership structure -- Storage architecture -- Privacy boundaries - -## Updating Your App Ensures - -- Visible and usable everywhere: Your app can be added to private and shared channels, not just standard ones. -- Works as expected: Your app handles channel-specific members and file storage correctly. -- Safe and secure: Your app respects privacy rules and avoids data leaks between channels. -- Future Readiness: Your app follows Microsoft’s direction to support private and shared channels. - -This guide helps you understand the updates needed to make your Teams app work seamlessly across Standard, private, and Shared channels. - -What This Guide Covers? - -- key concepts (membership, access, installation, storage) -- Implementation steps -- testing guidance -- Best practices - -## Channel Models in Microsoft Teams - -### Standard Channels - -- Visible to the entire team -- All team members have access to the channel by default - -### Private Channels - -- Access limited to invited team members only -- Files are stored in the channel’s dedicated SharePoint site - -### Shared Channels - -- Including external and nonhost team members -- Sharing with individuals or teams across organizations -- Storing files in the channel’s dedicated SharePoint sit - -## Shared Channel Capabilities - -### Teams Channel Models – Capabilities Comparison - -| **Category** | **Capability** | **Standard Channel** | **Private Channel** | **Shared Channel** | -|--------------|----------------------------------------------------------------------------------|----------------------|---------------------|---------------------| -| **Membership** | Can add people to the channel without adding to the host team | No | No | Yes | -| | Channel membership can be limited to a subset of the host team | No | Yes | Yes | -| | Channel can be shared with other teams to inherit members from the team | No | No | Yes | -| | Channel can be shared directly with its parent team to inherit members | N/A | No | Yes | -| | Guests (B2B Guests) can participate in the channel | Yes | Yes | No | -| | External participants (B2B Direct Connect) can participate in the channel | No | No | Yes | -| | Channel is hosted under a host team | Yes | Yes | Yes | -| **Storage** | Each channel has a dedicated SharePoint site | No (inherits team site) | Yes | Yes | -| **App Model** | App must be installed in the host team | Yes | Yes | Yes | -| | App installed to host team automatically available in channel | Yes | No | No | -| | App must be added to each channel | No | Yes | Yes | - -> **Note:** - -> - Currently, only apps that include tabs are supported in private and shared channels in Microsoft Teams. -> - Tab apps in shared channels are available in [Government Community Cloud (GCC), GCC High, Department of Defense (DoD)](../cloud-overview.md#teams-app-capabilities), and [Teams operated by 21Vianet](../sovereign-cloud.md) environments. -> - SharePoint and the SharePoint pages apps aren't supported for shared channels in GCC, GCC High, DoD, and Teams operated by 21Vianet environments. -> - Bots and message extensions are not supported in shared channels. - -## Understanding How Your Teams App Works in Private and Shared Channels - -Microsoft Teams supports different types of channels—Standard, Private, and Shared. Each has unique rules for membership, storage, and access. To ensure your app works reliably and securely, it’s important to understand these differences. - -### Channel Membership Considerations - -- Private and Shared channels include only selected members; team membership isn't automatic. -- Private and Shared channels deliver app messages or notifications exclusively to users who are members of that specific channel. -- Private and Shared channels require the use of channel-designated tools to view or manage membership accurately. - -### External and Guest Users - -- Shared channels might include users from outside your organization or tenant. -- These users might have limited permissions depending on their role. -- Tip: Always check user roles before assigning tasks or granting access through the app. - -### File Storage Behavior in Private and Shared Channels - -- Private and Shared channels use dedicated SharePoint sites for storing files. -- Private and Shared channels require apps to access or save documents using the correct site linked to the channel. -- Private and Shared channels work best when your app is configured to locate and use the associated SharePoint site. - -### Data Privacy and Scope - -- Apps that collect or display data (like analytics or reports) should only show information from the current channel. -- Aggregating data across channels can expose private content to unintended users. -- Tip: Keep data scoped to the channel unless broader sharing is explicitly allowed. - -### Implementation Guidelines for Developers - -- Confirm your app is installed in the correct channel type. -- Check membership lists before sending messages or assigning tasks. -- Use approved SharePoint sites for file access. -- Be cautious when sharing or aggregating data across channels. - -## Core Implementation Concepts for Shared and Private Channels - -![This diagram shows how membership works in shared channels across organizations.](../../assets/images/membership-types-shared-channels.png) - -![This diagram shows how direct membership works in a private channel.](../../assets/images/membership-types-private-channels.png) - -## Channel Membership Basics - -Every channel—whether Standard, Private, or Shared—lives inside a host team. Understanding how users are added to these channels helps you build apps that behave correctly for different member types. - -### Direct vs. Indirect Membership - -Private Channels - -- Only members of the host team can be added directly. - -Shared Channels - -- Can include direct members from: - - The host team - - Other users within the same organization - - Users from external organizations (via B2B Direct Connect) - -Indirect Members (Shared Channels Only) - -- A shared channel can be linked to other teams (inside or outside your org). -- Members of those teams get indirect access to the channel. - -### Types of Users in Channels - -Understanding user types helps you tailor app behavior: - -| **User Type** | **Description** | **Channel Access** | -|----------------------|----------------------------------------------------------------------|-------------------------------------------| -| Host Team Users | Members of the team where the channel was created | Standard, Private, Shared | -| In-Tenant Users | Users from your organization, not necessarily in the host team | Shared channels only | -| Guest Users | External users added as B2B guests in your organization | Standard and Private channels only | -| External Users | Users from other organizations via B2B Direct Connect | Shared channels only | - -### Developer Tips - -- Always fetch channel members, not team members—channel membership is what matters. -- Use user roles to adjust app behavior: - For example, limit actions for external users to protect sensitive features. - -## SharePoint Storage for Private and Shared Channels - -Each Private or Shared channel has its own SharePoint site, separate from the host team's site. This site includes: - -- A dedicated document library -- Channel-specific folders, lists, and pages - -### Key Considerations - -- Ensure you're targeting the channel’s site—not the team’s root site—when uploading or retrieving files, or interacting with SharePoint lists/pages. -- Use 'people with existing access' links to respect channel-level permissions when sharing files or links. -- Call the Microsoft Graph invite API to explicitly grant access, especially for external users in shared channels. - -## App Installation in Private and Shared Channels - -To make your app available in Private or Shared channels, you need to explicitly declare support in the app manifest. Unlike Standard channels, where installing the app at the team level is sufficient, Private and Shared channels require an extra step. - -### Installation Workflow - -- Install the app at the team level. -- Add the app to the specific channel. A channel owner or member adds the app to each Private or Shared channel as needed. - - Note: Without this step, your app doesn’t appear or function in those channels—even if it's installed at the team level. - -Now that we understand the concepts, let’s look at how to make the required changes in your app. From 86f2c2294bf4389b2a70dd232afd712701f7ef19 Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Tue, 19 Aug 2025 11:59:20 +0530 Subject: [PATCH 30/44] Update app-developer-guidance-shared-private-channel.md --- ...veloper-guidance-shared-private-channel.md | 109 +++++++++++------- 1 file changed, 67 insertions(+), 42 deletions(-) diff --git a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md index e744711fc82..b4b54e56e0f 100644 --- a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md +++ b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md @@ -145,7 +145,7 @@ Understanding user types helps you tailor app behavior: |----------------------|----------------------------------------------------------------------|-------------------------------------------| | Host Team Users | Members of the team where the channel was created | Standard, Private, Shared | | In-Tenant Users | Users from your organization, not necessarily in the host team | Shared channels only | -| Guest Users | External users added as B2B guests in your organization | Standard and Private channels only | +| Guest Users | External users added as [B2B]() guests in your organization | Standard and Private channels only | | External Users | Users from other organizations via B2B Direct Connect | Shared channels only | ### Developer Tips @@ -352,7 +352,7 @@ Use TeamsInfo.getMemberAsync or TeamsInfo.getPagedMembersAsync and check if user - To detect external users: Each incoming activity includes conversation.tenantId and from.aadObjectId. -Compare the member’s tenantId with the channel’s host tenant (from Graph channel metadata). (Note: This part might need further clarification.) +Compare the member’s tenant ID with the channel’s host tenant (from Graph channel metadata). (Note: This part might need further clarification.) ### Detecting User Type from Roster (Graph API or Bot SDK) @@ -380,13 +380,13 @@ When handling files in channels—whether it's file tabs, document libraries, or - parentReference.driveId: the SharePoint drive linked to the channel’s site - ID: the folder ID - Standard channels - - The driveId typically points to the team’s main SharePoint site. + - The drive ID typically points to the team’s main SharePoint site. - Private and shared channels - - Expect a different driveId, as these channels have their own dedicated SharePoint sites. + - Expect a different drive ID, as these channels have their own dedicated SharePoint sites. Best practice -- Store and reuse the exact driveId and itemId from the filesFolder API. +- Store and reuse the exact drive ID and item ID from the filesFolder API. - Avoid hardcoding library names or URLs assuming the team site applies to all channels. Note: This API works consistently across all channel types. @@ -562,62 +562,87 @@ To make sure your app works smoothly in shared, private, and standard channels, - Respect privacy boundaries, and avoid leaking data between channels or user types. - Handle internal users, B2B Guests, and B2B Direct Connect users correctly. - Test all scenarios, including edge cases. - -## FAQ Highlights - -General Questions - -Q1: Can I be part of a shared channel without being in the parent team? -A: Yes, shared channels let people outside the team join, as long as they’re invited and have the right permissions. -Q2: Who has the ability to create shared or private channels? -A: Typically, only team owners or users with specific permissions can create these channels. However, admins might restrict this capability through policy settings. +## Troubleshooting Guide -Access & Permissions +### App Installation Issues -Q1: Why can’t I see a private channel I was added to? -A: To view a private channel, you must be a member of both the parent team and the private channel. If you're removed from the team, you lose access to its private channels. +| Problem | Cause | Resolution | +|--------|-------|------------| +| App doesn't appear in shared or private channels | `supportsChannelFeatures` not set in manifest | Add `'supportsChannelFeatures': 'tier 1'` in the app manifest. Reinstall the app. | +| 403 error - Caller isn't enabled for requesting the [xyz] channel of shared channel type | App installed at team level but not added to the channel | Install the app both at the team level and the specific channel. | -Q2: Can guests or external users access shared channels? -A: Yes. To allow access, both organizations must enable external access, and the user must be explicitly invited to the shared channel to gain access. +### Membership & Identity Issues -Q3: How do I know if a channel is private or shared? -A: Check the icon next to the channel name. +| Problem | Cause | Resolution | +|--------|-------|------------| +| App shows wrong members (for example, includes team members not in channel) | Using team membership APIs instead of channel APIs | Use `GET /teams/{team-id}/channels/{channel-id}/allMembers` | +| can't distinguish external users from internal | `tenantId` not being compared | Compare `member.tenantId` with `hostTenantId`; if different → external user (B2B) | +| Guest vs External not differentiated | Only checking `role = guest` | Detect B2B Native by comparing tenant ID | -- A lock icon indicates private channel -- A link icon indicates shared channel +### File Access Issues -Functionality & Limitations +| Problem | Cause | Resolution | +|--------|-------|------------| +| App fails to access files in private/shared channels | Using team SharePoint site instead of channel-specific site | Use `GET /teams/{teamId}/channels/{channelId}/filesFolder` | +| External users can't access files | Org-wide links not supported cross-tenant | Use specific-people sharing or `POST /drives/{driveId}/items/{itemId}/invite` | +| Token errors for external users | Auth tokens issued for host tenant instead of user's home tenant | Call `getAuthToken` with the user's `tenantId`. Always request token in user's home tenant. | -Q1: Can I add apps or tabs to a private channel? -A: Yes, you can add apps and tabs to a private channel. However, some apps might not be supported due to permission limitations or compatibility issues. Always check app compatibility before adding it to the private channel. +### Messaging Issues -Q2: Are files in private channels stored differently? -A: Yes, in platforms like Microsoft Teams, files shared in a Private Channel files are stored in a separate SharePoint site with restricted access. The site is accessible exclusively to Private Channel members, ensuring secure and controlled data sharing. +| Problem | Cause | Resolution | +|--------|-------|------------| +| Can't read messages in shared/private channels | App not added to channel | Add app explicitly to the channel. Retry after install. | +| Subscriptions to channel messages fail | RSC restriction | Use on-demand message reads instead of subscriptions. | +| Bot fails to send/receive messages for external users | Bot fetching recipients from team roster instead of channel roster | Always fetch from channel roster. | -Q3: Can I convert a private channel to a shared channel (or vice versa)? -A: No, channel types are permanent once created. If you want to change the type, you need to create a new channel with the preferred settings and migrate content manually. +### Event Handling Issues -Q4: Why am I seeing an 'Access Denied' error when trying to join a shared channel? -A: This issue can happen due to several reasons: +| Problem | Cause | Resolution | +|--------|-------|------------| +| Can't read messages in shared/private channels | App not added to channel | Add app explicitly to the channel. Retry after install. | +| Shared channel changes not detected | Not handling APX events | Handle `channelShared` and `channelUnshared` events from Activity Payload Extension. | +| Membership list out of sync | Relying on old cached data | Refresh membership list on every `conversationUpdate` or Graph notification. | -- You might not be invited correctly -- External access might be disabled for your organization -- You could be signed in with wrong account or tenant +### Privacy & Security Issues -Q5: What should I do if files or tabs aren’t loading in a channel? -A: Try refreshing the app or browser. If that doesn't help, clear your cache, or try accessing the channel from another device. Also verify that you have the necessary permissions. +| Problem | Cause | Resolution | +|--------|-------|------------| +| Private channel data leaks into reports | Using aggregated team-level analytics | Scope analytics to channel-level data | +| External/guest access not properly restricted | App not checking role/tenant before action | Implement role and tenant-based access checks before performing sensitive actions | -Q6: How do I report issues with shared or private Channels? -A: Contact your IT admin or support team with: +### Testing Gaps -- Channel name -- Type (shared or private) -- Error message or screenshot +| Problem | Cause | Resolution | +|--------|-------|------------| +| Features work in standard but fail in shared/private channels | App only tested in standard channels | Test all scenarios: standard, private, shared (same-tenant + cross-tenant) | +| Bots don't respond for guests/external users | Microsoft Edge cases not tested | Validate all user types: internal, guest, external (B2B Direct) | +| API returns inconsistent results | Using cached lists or partial roster | Validate against full roster APIs and refresh after membership changes | +## FAQ Summary +### General Questions +| Question | Answer | +|----------|--------| +| Can I be part of a shared channel without being in the parent team? | Yes, shared channels allow external users to join if invited and granted permissions. | +| Who can create shared or private channels? | Typically, team owners or users with specific permissions. Admins might restrict this capability via policy settings. | +### Access & Permissions +| Question | Answer | +|----------|--------| +| Why can’t I see a private channel I was added to? | You must be a member of both the parent team and the private channel. Removal from the team revokes access. | +| Can guests or external users access shared channels? | Yes, if both organizations enable external access and the user is explicitly invited. | +| How do I know if a channel is private or shared? | A lock icon indicates private channel. A link icon indicates shared channel = shared channel. | +| Why am I seeing an 'Access Denied' error when joining a shared channel? | Possible causes: incorrect invitation, disabled external access, or wrong account/tenant. | +### Functionality & Limitations +| Question | Answer | +|----------|--------| +| Can I add apps or tabs to a private channel? | Yes, but some apps might not be supported due to permissions or compatibility. Check before adding. | +| Are files in private channels stored differently? | Yes, they’re stored in a separate SharePoint site accessible only to channel members. | +| Can I convert a private channel to a shared channel (or vice versa)? | No, channel types are permanent. Create a new channel and migrate content manually. | +| What should I do if files or tabs aren’t loading in a channel? | Refresh the app/browser, clear cache, try another device, and verify permissions. | +| How do I report issues with shared or private channels? | Contact your IT admin or support team with: channel name, type, and error message or screenshot. | From ea9217cfe17a88133f40946bc5674019909893d1 Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Wed, 20 Aug 2025 01:00:34 +0530 Subject: [PATCH 31/44] Update app-developer-guidance-shared-private-channel.md --- ...veloper-guidance-shared-private-channel.md | 369 +++++++++++++++++- 1 file changed, 366 insertions(+), 3 deletions(-) diff --git a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md index b4b54e56e0f..fa7752bdf8b 100644 --- a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md +++ b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md @@ -145,8 +145,8 @@ Understanding user types helps you tailor app behavior: |----------------------|----------------------------------------------------------------------|-------------------------------------------| | Host Team Users | Members of the team where the channel was created | Standard, Private, Shared | | In-Tenant Users | Users from your organization, not necessarily in the host team | Shared channels only | -| Guest Users | External users added as [B2B]() guests in your organization | Standard and Private channels only | -| External Users | Users from other organizations via B2B Direct Connect | Shared channels only | +| Guest Users | External users added as [B2B](/entra/external-id/what-is-b2b) guests in your organization | Standard and Private channels only | +| External Users | Users from other organizations via [B2B Direct Connect](/entra/external-id/b2b-direct-connect-overview) | Shared channels only | ### Developer Tips @@ -205,6 +205,367 @@ Install the App Properly if the app isn't added to the channel, most APIs that rely on resource-specific consent fails with a 403 error message 'Caller isn't enabled for requesting the lwg channel of Shared channel type…' - When a 403 error with the specified message occurs or API responses return incomplete data, assume the app isn't added to the channel. This error typically means channel members didn't add the app to the channel. +## Bot Lifecycle Events + +### Handling Shared and Private Channel Events in Microsoft Teams Bots + +Microsoft Teams sends specific event payloads to bots when shared or private channels are created, updated, or removed. These events are delivered as conversationUpdate activities and can be used to trigger custom logic in your app. + +Key Event Types + +- channelSharedWithTeam +- channelUnsharedFromTeam +- channelMemberRemoved + +Developer Action Points + +- Detect the event: To capture this payload, use OnConversationUpdateAsync in your bot logic. +- Parse the context: To determine if the channel was shared or unshared, check conversationType, tenantId, and channelData.eventType. +- Respond accordingly: You might log the event, notify users, or update your app’s internal state. + +Best Practices + +- Private channels: Only members added to the channel can access it. Use this framework to scope bot responses and permissions. +- Shared channels: These collaboration spaces allow cross-team or cross-org collaboration. Ensure your bot respects access boundaries and doesn’t expose sensitive data. + +### Handling Bot Addition to Shared and Private Channel + +Microsoft Teams sends a conversationUpdate activity when your bot is added to a shared or private channel. This event is crucial for initializing bot logic specific to that channel. + +Event Summary + +The payload includes: + +- type: "conversationUpdate" +- channelData.eventType: "channelMemberAdded" +- channelData.channel.type: "shared" or "private" +- channelData.channel.name: Name of the channel +- channelData.channel.id: Unique identifier of the channel +- membersAdded: Array of added members, typically including the bot: +- - ID: Bot ID +- recipient: Metadata about the bot receiving the event: +- - ID: Bot ID +- - name: Bot display name + +Developer Action Points + +- Detect the event: Use OnConversationUpdateAsync to capture when your bot is added to a channel. +- Check channelData.channel.type: "This category indicates the channel classification type, either 'shared' or 'private.' +- Use channelData.eventType: "channelMemberAdded" indicates your bot was added. +- Initialize logic: Set up channel-specific state, permissions, or welcome messages. + +Best Practices + +- Avoid assuming team-level installation means channel-level availability. +- Use this event to verify your bot is active in the channel before performing actions. +- Log or audit bot additions for cross-tenant shared channels to ensure. + +### Bot Removal from Shared or Private Channel + +When your bot is removed from a shared or private channel, Microsoft Teams sends a conversationUpdate activity with the channelMemberRemoved event type. This event allows your app to clean up resources, revoke access, or log the removal for auditing. + +Event Summary + +When your bot is added to a channel, the activity includes: + +- type: "conversationUpdate" +- channelData.eventType: "channelMemberAdded" +- channelData.channel.type: "shared" or "private" +- membersAdded: Contains the bot's ID +- recipient: Identifies your bot + +Developer Action Points + +- Detect the event: Use OnConversationUpdateAsync to capture when your bot is removed. +- Check channelData.channel.type: "shared" or "private" indicates the channel type. +- Use channelData.eventType: "channelMemberRemoved" confirms bot removal. + +Best Practices + +- Graceful exit: Avoid errors or retries after removal—respect the channel’s updated access boundaries. +- Audit trail: Log bot removals to monitor usage and detect unexpected removals. +- User experience: If your app has a dashboard or admin panel, reflect the removal status clearly. + +### Detecting Channel Rename Events in Shared and Private Channels + +When a channel is renamed—whether it's a shared or private channel—Microsoft Teams sends a conversationUpdate activity with the eventType: "channelRenamed". Bots can use this mechanism to update internal records, logs, or user-facing labels. + +Event Summary + +The payload includes: + +- type: "conversationUpdate" +- channelData.eventType: "channelRenamed" +- channelData.channel.name: The updated channel name +- channelData.channel.type: "shared" or "private" +- recipient: Identifies the bot receiving the even + +Developer Action Points + +- Detect the event: Use OnConversationUpdateAsync to capture the rename. +- Check channelData.eventType: Look for "channelRenamed." +- Update internal records: Sync the new channel name in your app’s database or UI. +- Log the change: Optionally log the rename for audit or analytics. +- Notify users: If your bot displays channel names, consider sending a message or updating the interface. + +Best Practices + +- Avoid using hardcoded channel names: Always retrieve the latest name dynamically from the API. +- Avoid notifying unauthorized users: Ensure notifications are sent only to users with access to the renamed channel. +- Avoid overlooking cross-tenant scenarios: In shared channels, make sure your bot handles renames across both host and member teams. + +### Handling Channel Deletion Events in Shared and Private Channels + +When a shared or private channel is deleted, Microsoft Teams sends a conversationUpdate activity with eventType: "channelDeleted". Bots should use this event to clean up resources, revoke access, and update internal records. + +Event Summary + +The payload includes: + +- type: "conversationUpdate" +- channelData.eventType: "channelDeleted" +- channelData.channel.type: "shared" or "private" +- channelData.channel.name: The name of the deleted channel +- channelData.team.id: The team associated with the channel +- channelData.tenant.id: The tenant where the event occurred +- recipient: Identifies the bot receiving the even + +Developer Action Points + +- Detect the event: Use OnConversationUpdateAsync to capture channelDeleted. +- Check channelData.channel.type: "shared" or "private" indicates the channel type. +- Use channelData.eventType: "channelDeleted" confirms the deletion. + +Best Practices + +- Avoid retries or proactive messaging after deletion. +- Log deletions to monitor usage and detect unexpected removals. +- Respect tenant boundaries in shared channels—ensure cleanup spans all contributing teams. + +### Handling Channel Restoration Events in Shared and Private Channels + +When a shared or private channel is restored in Microsoft Teams, bots receive a conversationUpdate activity with eventType: "channelRestored." This event signals that a previously deleted channel is reactivated and is available for use again. Bots should respond by reinitializing resources, re-enabling access, and updating internal records accordingly. + +Event Summary + +The payload includes: + +- type: "conversationUpdate" +- channelData.eventType: "channelRestored" +- channelData.channel.type: "shared" or "private" +- channelData.channel.name: The restored channel’s name +- channelData.team.id: The associated team +- channelData.tenant.id: The tenant where the event occurred +- recipient: Identifies the bot receiving the even + +Developer Action Points + +- Detect the event: Use OnConversationUpdateAsync to capture channelRestored. +- Identify channel type: Check channelData.channel.type for "shared" or "private." +- Confirm restoration: Ensure channelData.eventType is "channelRestored." + +Best Practices + +- Reinitialize bot state for the restored channel if needed. +- Resume any suspended workflows or subscriptions tied to the channel. +- Audit restoration events to track lifecycle changes and ensure compliance. +- Respect tenant boundaries in shared channels—restoration might affect multiple teams. + +### Handling Member Additions in Shared Channels + +When a member is added to a shared channel in Microsoft Teams, bots receive a conversationUpdate activity with eventType: "channelMemberAdded". This event allows bots to track membership changes and respond accordingly—such as onboarding users, updating access controls, or syncing internal records. + +Event Summary + +The payload includes: + +- type: "conversationUpdate" +- channelData.eventType: "channelMemberAdded" +- channelData.channel.type: "shared" +- channelData.channel.name: The name of the shared channel +- membersAdded: An array of newly added members, including their ID and membershipSource details +- membershipSource: Indicates how the user was added (for example, transitive membership via team) +- channelData.tenant.id: The tenant where the event occurred +- recipient: Identifies the bot receiving the event + + Developer Action Points + +- Detect the event: Use OnConversationUpdateAsync to capture channelMemberAdded. +- Identify channel type: Confirm channelData.channel.type is "shared" to apply shared channel logic. +- Inspect membersAdded array: Each entry contains user identity and membershipSource, which indicates how the user was added (for example, transitive membership via team). +- Respect tenant boundaries: Use membershipSource.tenantId to determine cross-tenant relationships. + +Best Practices + +- Welcome new members: Send onboarding messages or resources if appropriate. +- Sync permissions: Update internal systems to reflect new access rights. +- Audit membership changes: Log additions for compliance and traceability. +- Handle transitive membership: Recognize that users might be added via team-level membership and not directly to the channel. + +### Handling Member Removal in Shared Channels + +When a member is removed from a shared channel in Microsoft Teams, bots receive a conversationUpdate activity with eventType: "channelMemberRemoved". This event allows bots to update internal records, revoke access, and maintain accurate membership tracking across tenants and teams. + +Event Summary + +The payload includes: + +type:"conversationUpdate" +channelData.eventType:"channelMemberRemoved" +channelData.channel.type:"Shared" +channelData.channel.name: The name of the shared channel +channelData.channel.id: The unique ID of the shared channel +channelData.team.id: The ID of the team associated with the shared channel +channelData.tenant.id: The tenant where the event occurred +membersRemoved: +ID: The Teams user ID of the removed member +aadObjectId: The Azure AD object ID of the removed member +membershipSource: Details about how the user was removed, including: +sourceType: The source of membership (for example, team) +ID: The source ID +membershipType: Indicates if the membership was direct or indirect +tenantId: The tenant ID of the source +recipient: Identifies the bot receiving the event, including bot ID and name + +Developer Action Points + +- Detect the event: To capture channelMemberRemoved, use OnConversationUpdateAsync. +- Identify channel type: To apply shared channel logic, Confirm channelData.channel.type is "shared." +- Inspect membersRemoved array: Each entry contains user identity and membershipSource, which indicates how the user was removed (for example, indirect removal via team membership). +- Respect tenant boundaries: To determine cross-tenant implications, use membershipSource.tenantId. + +Best Practices + +- Revoke access: Ensure the removed member no longer has access to bot features or data tied to the channel. +- Update internal records: To maintain accuracy, reflect membership changes in your system. +- Audit removals: Log removal events for compliance and traceability. +- Handle indirect membership: Recognize that users might be removed due to changes at the team level, not directly from the channel. + +### Retrieving Member Details in Shared Channels + +When a bot or app queries a member in a shared channel, the API response includes detailed identity and membership metadata. This information helps the bot or app understand how the user is associated with the channel—either directly or transitively through a team. + +Event Summary: Member Added to Shared Channel + +The payload includes: + +- type: "conversationUpdate" +- channelData.eventType: "channelMemberAdded" +- channelData.channel.type: "shared" +- channelData.channel.name: Name of the shared channel +- channelData.channel.id: Unique ID of the shared channel +- channelData.tenant.id: Tenant where the event occurred +- membersAdded: Array of added members with: +- ID: Teams user ID +- aadObjectId: Azure AD object ID +- membershipSource: Details on how the user was added: +- - sourceType: for example, "team" +- - membershipType: "direct" or "transitive" +- - tenantId: Source tenant ID +- recipient: Bot ID and name receiving the event + +Developer Action Points + +- Support multiple membership paths: A user might appear in both direct and transitive contexts. +- Respect tenant boundaries: Use tenantId to determine cross-tenant relationships. +- Audit membership types: Use membershipType to distinguish between explicit and inherited access. +- Handle nulls gracefully: teamAadGroupId might be null for direct channel membership. + +Best Practices + +- Avoid duplicate processing: When both direct and transitive memberships exist, ensure logic doesn’t double-count. +- Use aadObjectId for identity resolution: This identifier framework is consistent across tenants and contexts. +- Log membership sources: Useful for debugging access issues or validating permissions. + +### Get Member in Shared Channel + +The Get Member API retrieves detailed information about a specific user in a shared channel. This user-channel linkage includes identity attributes and a breakdown of how the user is connected to the channel—either directly or transitively via a team. + +Event Summary + +The payload includes: + +- name: Full name of the user +- givenName: First name +- surname: Family name +- email: Primary email address +- userPrincipalName: User's sign-in name +- userRole: Role in the channel (for example, "user") +- ID: Teams user ID +- aadObjectId: Microsoft Entra object ID +- objectId: Legacy object ID (might match aadObjectId) +- tenantId: Tenant where the user belongs +- membershipSource: Array showing how the user is linked to the channel: +- - conversationId: ID of the conversation (channel or team thread) +- - conversationType: "channel" or "team" +- - membershipType: "direct" or "transitive" +- - teamAadGroupId: Group ID for team membership (might be null) +- - tenantId: Source tenant ID + +Developer Action Points + +- Use this API to audit individual user access to shared channels. +- Check membershipSource to determine if the user was added directly or inherited access via a team. +- Use tenantId to identify cross-tenant relationships in shared channels. +- Handle multiple membership paths gracefully—users might have both direct and transitive links. + +Best Practices + +- Avoid duplicate logic when both membership types exist. +- Log membership paths for compliance and access reviews. +- Use aadObjectId for consistent identity resolution across tenants. +- Respect tenant boundaries when managing access or sending messages. + +### Get Members in Shared Channel + +The Get Members API retrieves a list of all users in a shared channel, including identity details and optional membership metadata. This response is useful for bulk operations such as syncing, auditing, or broadcasting messages. + +Event Summary + +The payload includes: + +- members: Array of user objects, each containing: +- name: Full name of the user +- givenName: First name +- surname: Family name (if available) +- email: Primary email address +- userPrincipalName: Sign-in name +- userRole: Role in the channel (for example, "user") +- ID: Teams user ID +- aadObjectId: Microsoft Entra object ID +- objectId: Legacy object ID (might match aadObjectId) +- tenantId: Tenant where the user belongs +- membershipSource (optional): Array showing how the user is linked to the channel: +- - conversationId: ID of the conversation +- - conversationType: "channel" or "team" +- - membershipType: "direct" or "transitive" +- - teamAadGroupId: Group ID for team membership (might be null) +- - tenantId: Source tenant ID + +Developer Action Points + +- Avoid redundant processing by deduplicating users based on aadObjectId or ID. +- Avoid fragmented data by merging membershipSource arrays when the same user appears more than once. +- Avoid incomplete insights by using the Get Member API when membershipSource is missing or partial. +- Avoid misinterpreting access by respecting tenant boundaries in cross-tenant scenarios. + +Best Practices + +- Normalize data before applying business logic or access controls. +- Log membership types for audit and compliance tracking. +- Use aadObjectId for consistent identity resolution across tenants and contexts. + +### Developer Action Points + +- Detect the event: To capture this payload, use OnConversationUpdateAsync in your bot logic. +- Parse the context: To determine if the channel was shared or unshared, check conversationType, tenantId, and channelData.eventType. +- Respond accordingly: You might log the event, notify users, or update your app’s internal state. + +### Best Practices + +- Private channels: Only members added to the channel can access it. Use this framework to scope bot responses and permissions. +- Shared channels: These collaboration environments allow cross-team or cross-org collaboration. Ensure your bot respects access boundaries and doesn’t expose sensitive data. + ## Getting Accurate Channel Membership in Microsoft Teams ### Why It Matters @@ -384,7 +745,9 @@ When handling files in channels—whether it's file tabs, document libraries, or - Private and shared channels - Expect a different drive ID, as these channels have their own dedicated SharePoint sites. -Best practice +You can find detailed guidance on this article on [Microsoft Learn](/graph/api/channel-get-filesfolder). + +Best Practice - Store and reuse the exact drive ID and item ID from the filesFolder API. - Avoid hardcoding library names or URLs assuming the team site applies to all channels. From 697d35f6bec6e92ceb1db5fea09ccc19a4bbe92e Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Wed, 20 Aug 2025 01:03:32 +0530 Subject: [PATCH 32/44] Update app-developer-guidance-shared-private-channel.md --- .../app-developer-guidance-shared-private-channel.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md index fa7752bdf8b..990ebd0f201 100644 --- a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md +++ b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md @@ -410,7 +410,7 @@ Event Summary The payload includes: -type:"conversationUpdate" +Type:"conversationUpdate" channelData.eventType:"channelMemberRemoved" channelData.channel.type:"Shared" channelData.channel.name: The name of the shared channel @@ -419,7 +419,7 @@ channelData.team.id: The ID of the team associated with the shared channel channelData.tenant.id: The tenant where the event occurred membersRemoved: ID: The Teams user ID of the removed member -aadObjectId: The Azure AD object ID of the removed member +aadObjectId: The Microsoft Entra ID object ID of the removed member membershipSource: Details about how the user was removed, including: sourceType: The source of membership (for example, team) ID: The source ID @@ -457,7 +457,7 @@ The payload includes: - channelData.tenant.id: Tenant where the event occurred - membersAdded: Array of added members with: - ID: Teams user ID -- aadObjectId: Azure AD object ID +- aadObjectId: Microsoft Entra ID object ID - membershipSource: Details on how the user was added: - - sourceType: for example, "team" - - membershipType: "direct" or "transitive" From c50a160dafb878c34cdf87bb11a45af861d57843 Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Wed, 20 Aug 2025 11:31:24 +0530 Subject: [PATCH 33/44] Update app-developer-guidance-shared-private-channel.md --- ...veloper-guidance-shared-private-channel.md | 123 +++++++++++------- 1 file changed, 78 insertions(+), 45 deletions(-) diff --git a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md index 990ebd0f201..9dad17fedf8 100644 --- a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md +++ b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md @@ -17,20 +17,22 @@ As Microsoft Teams evolves, shared and private channels introduce new collaborat This guide helps you understand the updates, best practices, and testing steps needed to adapt your app for private and shared channels. -## Updating Your App Ensures +## Why App updates Matter - Visible and usable everywhere: Your app can be added to private and shared channels, not just standard ones. - Works as expected: Your app handles channel-specific members and file storage correctly. - Safe and secure: Your app respects privacy rules and avoids data leaks between channels. - Future Readiness: Your app follows Microsoft’s direction to support private and shared channels. -What This Guide Covers? +### What This Guide Covers? - key concepts (membership, access, installation, storage) - Implementation steps - testing guidance - Best practices +Before diving into implementation, learn about the different channel models available in Microsoft Teams. + ## Channel Models in Microsoft Teams ### Standard Channels @@ -49,7 +51,7 @@ What This Guide Covers? - Sharing with individuals or teams across organizations - Storing files in the channel’s dedicated SharePoint sit -## Shared Channel Capabilities +### Shared Channel Capabilities ### Teams Channel Models – Capabilities Comparison @@ -74,7 +76,9 @@ What This Guide Covers? > - SharePoint and the SharePoint pages apps aren't supported for shared channels in GCC, GCC High, DoD, and Teams operated by 21Vianet environments. > - Bots and message extensions are not supported in shared channels. -## Understanding How Your Teams App Works in Private and Shared Channels +In addition to channel models and capabilities, understand how your team app behaves in these environments. + +### Understanding How Your Teams App Works in Private and Shared Channels Microsoft Teams supports different types of channels—Standard, Private, and Shared. Each has unique rules for membership, storage, and access. To ensure your app works reliably and securely, it’s important to understand these differences. @@ -88,7 +92,8 @@ Microsoft Teams supports different types of channels—Standard, Private, and Sh - Shared channels might include users from outside your organization or tenant. - These users might have limited permissions depending on their role. -- Tip: Always check user roles before assigning tasks or granting access through the app. + +**Tip: Always check user roles before assigning tasks or granting access through the app.** ### File Storage Behavior in Private and Shared Channels @@ -109,17 +114,17 @@ Microsoft Teams supports different types of channels—Standard, Private, and Sh - Use approved SharePoint sites for file access. - Be cautious when sharing or aggregating data across channels. -## Core Implementation Concepts for Shared and Private Channels +### Core Implementation Concepts for Shared and Private Channels ![This diagram shows how membership works in shared channels across organizations.](../../assets/images/membership-types-shared-channels.png) ![This diagram shows how direct membership works in a private channel.](../../assets/images/membership-types-private-channels.png) -## Channel Membership Basics +### Channel Membership Basics Every channel—whether Standard, Private, or Shared—lives inside a host team. Understanding how users are added to these channels helps you build apps that behave correctly for different member types. -### Direct vs. Indirect Membership +#### Direct vs. Indirect Membership Private Channels @@ -137,7 +142,7 @@ Indirect Members (Shared Channels Only) - A shared channel can be linked to other teams (inside or outside your org). - Members of those teams get indirect access to the channel. -### Types of Users in Channels +#### Types of Users in Channels Understanding user types helps you tailor app behavior: @@ -148,30 +153,30 @@ Understanding user types helps you tailor app behavior: | Guest Users | External users added as [B2B](/entra/external-id/what-is-b2b) guests in your organization | Standard and Private channels only | | External Users | Users from other organizations via [B2B Direct Connect](/entra/external-id/b2b-direct-connect-overview) | Shared channels only | -### Developer Tips +#### Developer Best Practices - Always fetch channel members, not team members—channel membership is what matters. - Use user roles to adjust app behavior: For example, limit actions for external users to protect sensitive features. -## SharePoint Storage for Private and Shared Channels +### SharePoint Storage for Private and Shared Channels Each Private or Shared channel has its own SharePoint site, separate from the host team's site. This site includes: - A dedicated document library - Channel-specific folders, lists, and pages -### Key Considerations +#### Key Considerations - Ensure you're targeting the channel’s site—not the team’s root site—when uploading or retrieving files, or interacting with SharePoint lists/pages. - Use 'people with existing access' links to respect channel-level permissions when sharing files or links. - Call the Microsoft Graph invite API to explicitly grant access, especially for external users in shared channels. -## App Installation in Private and Shared Channels +### App Installation in Private and Shared Channels To make your app available in Private or Shared channels, you need to explicitly declare support in the app manifest. Unlike Standard channels, where installing the app at the team level is sufficient, Private and Shared channels require an extra step. -### Installation Workflow +#### Installation Workflow - Install the app at the team level. - Add the app to the specific channel. A channel owner or member adds the app to each Private or Shared channel as needed. @@ -180,9 +185,9 @@ To make your app available in Private or Shared channels, you need to explicitly Now that we understand the concepts, let’s look at how to make the required changes in your app. -## Step-by-step Guide for Updating Your App +### Step-by-step Guide for Updating Your App -### Design Principle +#### Design Principle Avoid using the channel type (Standard, Private, Shared) as the basis for determining your app’s behavior. Instead, base behavior on: @@ -192,7 +197,7 @@ Avoid using the channel type (Standard, Private, Shared) as the basis for determ This approach makes your app work reliably across all channel types. -### Preliminary Configuration Requirements +#### Preliminary Configuration Requirements Update Your App Manifest @@ -228,7 +233,7 @@ Best Practices - Private channels: Only members added to the channel can access it. Use this framework to scope bot responses and permissions. - Shared channels: These collaboration spaces allow cross-team or cross-org collaboration. Ensure your bot respects access boundaries and doesn’t expose sensitive data. -### Handling Bot Addition to Shared and Private Channel +### Handling Bot Addition to Shared and Private Channels Microsoft Teams sends a conversationUpdate activity when your bot is added to a shared or private channel. This event is crucial for initializing bot logic specific to that channel. @@ -247,7 +252,7 @@ The payload includes: - - ID: Bot ID - - name: Bot display name -Developer Action Points + Developer Action Points - Detect the event: Use OnConversationUpdateAsync to capture when your bot is added to a channel. - Check channelData.channel.type: "This category indicates the channel classification type, either 'shared' or 'private.' @@ -260,7 +265,7 @@ Best Practices - Use this event to verify your bot is active in the channel before performing actions. - Log or audit bot additions for cross-tenant shared channels to ensure. -### Bot Removal from Shared or Private Channel +### Bot Removal from Shared or Private Channels When your bot is removed from a shared or private channel, Microsoft Teams sends a conversationUpdate activity with the channelMemberRemoved event type. This event allows your app to clean up resources, revoke access, or log the removal for auditing. @@ -371,7 +376,7 @@ Best Practices - Audit restoration events to track lifecycle changes and ensure compliance. - Respect tenant boundaries in shared channels—restoration might affect multiple teams. -### Handling Member Additions in Shared Channels +### Handling Member Additions to Shared Channels When a member is added to a shared channel in Microsoft Teams, bots receive a conversationUpdate activity with eventType: "channelMemberAdded". This event allows bots to track membership changes and respond accordingly—such as onboarding users, updating access controls, or syncing internal records. @@ -566,22 +571,22 @@ Best Practices - Private channels: Only members added to the channel can access it. Use this framework to scope bot responses and permissions. - Shared channels: These collaboration environments allow cross-team or cross-org collaboration. Ensure your bot respects access boundaries and doesn’t expose sensitive data. -## Getting Accurate Channel Membership in Microsoft Teams +### Getting Accurate Channel Membership in Microsoft Teams -### Why It Matters +#### Why It Matters When sending messages, assigning tasks, or managing permissions, check who is in the channel, not just who is in the team. Shared channels and cross-tenant access often cause team and channel member lists to differ. -### To Get Channel Members Use Microsoft Graph +#### To Get Channel Members Use Microsoft Graph -Get Full Roster for Any Channel Type +Get Full Membership for Any Channel Type - Endpoint GET /teams/{team-id}/members returns only team membership, applicable to standard channels. - Endpoint GET /teams/{team-id}/channels/{channel-id}/allMembers provides accurate channel membership for Standard, Shared, and Private channels. - Response from this endpoint includes only eligible members. - Support for Resource-Specific Consent (RSC) isn't available on these endpoints yet. -### Understand Indirect Membership in Shared Channels +#### Understand Indirect Membership in Shared Channels Use these endpoints to identify which teams provide access and which users from those teams can access the shared channel: @@ -596,13 +601,13 @@ GET /teams/{team-id}/channels/{channel-id}/sharedWithTeams/{id}/allowedMembers - Returns only eligible members. - These endpoints don't support RSC yet. -### Identify Direct vs Indirect Members +#### Identify Direct vs Indirect Members - Property @microsoft.graph.originalSourceMembershipUrl on allMembers (beta) indicates indirect membership. - Property absence signifies that the member is direct. - Property usage is recommended only as a hint—avoid parsing it directly and prefer supported endpoints instead. -### Check User Access Before Sensitive Actions +#### Check User Access Before Sensitive Actions Use: doesUserHaveAccess(userId, tenantId, upn) @@ -611,7 +616,7 @@ Use: doesUserHaveAccess(userId, tenantId, upn) - Function scope is limited to shared channels only. - Function roadmap includes broader support, but it's not available yet. -## Retrieving Full Channel Roster Using Bot Framework SDK +#### Retrieving Full Channel Roster Using Bot Framework SDK When working with the Bot Framework SDK (C#, JavaScript, etc.), you can retrieve the full roster from any channel as follows: @@ -619,7 +624,7 @@ When working with the Bot Framework SDK (C#, JavaScript, etc.), you can retrieve - Set required permissions: Make sure your app manifest includes the RSC permission ChannelMember.Read.Group. Without this permission, roster access fails within channels. -## Handling Known Failure Patterns +#### Handling Known Failure Patterns Be aware of the following common issues when accessing channel rosters: @@ -635,11 +640,11 @@ Be aware of the following common issues when accessing channel rosters: Resolution: Treat the response as a partial roster. Instruct the user to add the app to the channel, then refetch the roster after successful addition. -## Handling Channel Membership Changes +### Handling Channel Membership Changes Channel membership is fluid—users might join or leave, and channels can be shared or unshared with other teams. Your integration should be designed to respond to these changes dynamically. -### Using Microsoft Graph +#### Using Microsoft Graph To track membership updates: @@ -650,7 +655,7 @@ This notifies your app whenever there are changes to channel membership. - Respond to notifications When you receive a membership, share, or unshare notification: -- Refresh the allMembers list to get the current state of channel members. If the channel is shared: + - Refresh the allMembers list to get the current state of channel members. If the channel is shared: - call sharedWithTeams to identify which teams have access to the shared channel. - Call allowedMembers to efficiently retrieve indirect members added through shared teams. @@ -670,11 +675,11 @@ Triggered when a user is added or removed from the channel. - Also fires when the app itself is added or removed. - Update your member list accordingly when this event occurs. -Required Permissions +### Required Permissions - Manifest requirement: To receive and process these membership events, include the RSC permission ChannelMember.Read.Group in your app manifest. -## Detecting If Your App Is Added to a Channel +### Detecting If Your App Is Added to a Channel As you build your app, consider the following guidelines: @@ -690,7 +695,7 @@ As you build your app, consider the following guidelines: Note: You can list apps installed at the team level using GET /teams/{team-id}/installedApps, but there's no equivalent API for channel-level installations. Don't assume that a team-level install means the app is present in all its channels. -## Identifying External Users and Guests in Channel +## Identifying External Users and Guests in Channels As a developer, it's important to differentiate between internal users, guests, and external (cross-tenant) users in channels to: @@ -729,11 +734,11 @@ Using Bot SDK: - Check TeamsChannelAccount.UserRole: "guest" indicates a guest user. - Compare TeamsChannelAccount.TenantId with the channel’s host tenant ID (which can be fetched via Graph if needed). (Note: Host tenant ID retrieval might need clarification.) -## Working with Files Across Channel Types +## Working with Files Across Channels When handling files in channels—whether it's file tabs, document libraries, or uploading and retrieving files, you need to account for the distinct SharePoint sites that support private and shared channels, along with their respective storage locations. Relying on the Team’s main site to access channel files or folders doesn’t work. -### Resolving Storage Correctly +### Resolving Channel File Storage - Call GET /teams/{teamId}/channels/{channelId}/filesFolder → Returns a DriveItem representing the root folder for the channel’s files. @@ -766,7 +771,7 @@ Guest Users (Within Tenant) - The channel’s SharePoint site automatically grants channel members access, including guest users from the same tenant. -### You can take the following actions +### Best Practices for File Access Avoid relying on “Org-wide” sharing links. @@ -800,7 +805,7 @@ When creating a tab or task module that needs to access SharePoint files from th - Use normal v3 conversation routes to send, edit, or delete messages; refer to the documentation for details. - Use the channel roster to fetch recipients—never rely on team membership. -## Update the App Manifest to Declare Support for Shared and Private Channels +## Update the App Manifest for Shared and Private Channels Declare support for shared and private channels by adding a new property in your app manifest. This change is mandatory. @@ -829,11 +834,11 @@ As Microsoft Teams evolves, other channel capabilities might be introduced. To t Make sure to test your app in real scenarios before releasing changes. Here's how to validate it across different channel types. -### In a standard channel +### Testing in a Standard Channel - Check that everything still works after your changes. -### In a private channel (for example, Channel P in Team A) +### Testing in a Private Channel - Add the app to Team A, then to private channel P. - Check if your tab loads properly. @@ -841,13 +846,13 @@ Make sure to test your app in real scenarios before releasing changes. Here's ho - Check any feature that lists members or assigns tasks—make sure it only uses channel members. - Add a new member to the private channel—see if your bot gets an event or if your membership API shows the new member. -### In a shared channel within the same tenant (for example, Channel X in Team A shared with Team B) +### Testing in a Shared Channel (Same Tenant) - Add the app to Team A, then to Channel X. - Test with a Team B member—make sure they can see the tab and interact with the bot. - Unshare the channel from Team B—check if your bot receives a channelUnshared event. -### In a shared channel with an external tenant (for example, using Teams Connect) +### Testing in a Shared Channel (External Tenant) - Send a message from an external user to the bot—check if the bot receives it. - Trigger a tab or task module from the external user—check if authentication works. If using single sign-On (SSO), you might need to handle it with getAuthToken using the user’s home tenant ID. @@ -874,6 +879,8 @@ To make sure your app works smoothly in shared, private, and standard channels, ### Mandatory Updates for Teams Apps in Shared & Private Channels +To ensure proper functionality in shared and private channels, all apps must include these updates. + | Change Type | What to Do | Why It Matters | Example | |-------------|------------|----------------|---------| | **Mandatory** | Use the Channel Members API | Shared/Private channels have different members than the team. Using the wrong API can miss users or cause data leaks. | **Task app**: Assign tasks only to channel members, not all team members. | @@ -883,6 +890,8 @@ To make sure your app works smoothly in shared, private, and standard channels, ### Optional UX Improvements for Shared & Private Channels +These improvements enhance user experience and app reliability, but they're optional. + | Area | What to Do | Why It Helps | Example | |------|------------|--------------|---------| | **Privacy & Access Controls** | Add logic to limit features for guests/external users | Keeps sensitive data safe and follows company policies | **Poll app**: Guests can vote, but only members can create polls or see results | @@ -891,6 +900,8 @@ To make sure your app works smoothly in shared, private, and standard channels, ### Context & Event Payloads +Follow these guidelines to process events and payloads correctly in shared and private channels. + - Use teamId for the host team and channelId for the shared channel in context and event payloads. - Apply hostTeamId and hostTenantId when handling cross-tenant scenarios. - Detect external users by comparing a user’s tenantId with hostTenantId. @@ -899,11 +910,15 @@ To make sure your app works smoothly in shared, private, and standard channels, ### API Changes +Use the latest APIs to support shared and private channels. Earlier versions may have limited support. + - Review the API Change Table in the Appendix for updates to Graph and Activity Payload Extensions (APX) APIs. - Switch to the latest APIs that support shared and private channels. ### Handling External Users +Follow these steps to identify and manage external or guest users when your app is used across tenants. + - Identify B2B Guests using role = guest in Graph or user role = guest in APX. - Detect B2B Native users by comparing their tenantId with the hostTenantId from getContext(). - Fetch members using /teams/{teamId}/channels/{channelId}/allmembers for tabs. @@ -912,13 +927,17 @@ To make sure your app works smoothly in shared, private, and standard channels, ### Manifest and Permissions +Update your app manifest and permissions to support shared and private channels and enable required capabilities. + - Include supportsChannelFeatures = "tier1" in your app manifest so it supports shared and private channels. - Omit this setting, and your app doesn't appear in shared or private channels. - Remove this setting later, and your app stops showing up in those channels. - Update your manifest with Resource Specific Consent (RSC) permissions, as many APIs now require them for shared/private channel functionality. - Check the API documentation and confirm the RSC permissions required for your app. -### Privacy, Access & Security +### Privacy & Security + +Follow these best practices to protect user data, respect privacy, and manage access in shared and private channels." - Use channel-specific APIs—don’t assume team members are also channel members. - Access storage through channel-specific APIs and avoid cross-posting unless allowed. @@ -930,6 +949,8 @@ To make sure your app works smoothly in shared, private, and standard channels, ### App Installation Issues +If you're having trouble installing the app in shared or private channels, check for the following common issues and resolutions. + | Problem | Cause | Resolution | |--------|-------|------------| | App doesn't appear in shared or private channels | `supportsChannelFeatures` not set in manifest | Add `'supportsChannelFeatures': 'tier 1'` in the app manifest. Reinstall the app. | @@ -937,6 +958,8 @@ To make sure your app works smoothly in shared, private, and standard channels, ### Membership & Identity Issues +If your app is showing incorrect member information or failing to identify user types accurately, review the following common causes and solutions. + | Problem | Cause | Resolution | |--------|-------|------------| | App shows wrong members (for example, includes team members not in channel) | Using team membership APIs instead of channel APIs | Use `GET /teams/{team-id}/channels/{channel-id}/allMembers` | @@ -945,6 +968,8 @@ To make sure your app works smoothly in shared, private, and standard channels, ### File Access Issues +If your app is having trouble accessing or sharing files in private or shared channels, review these common issues and recommended fixes. + | Problem | Cause | Resolution | |--------|-------|------------| | App fails to access files in private/shared channels | Using team SharePoint site instead of channel-specific site | Use `GET /teams/{teamId}/channels/{channelId}/filesFolder` | @@ -953,6 +978,8 @@ To make sure your app works smoothly in shared, private, and standard channels, ### Messaging Issues +If your app or bot is having trouble sending, receiving, or reading messages in shared or private channels, check these common messaging issues and how to resolve them. + | Problem | Cause | Resolution | |--------|-------|------------| | Can't read messages in shared/private channels | App not added to channel | Add app explicitly to the channel. Retry after install. | @@ -961,6 +988,8 @@ To make sure your app works smoothly in shared, private, and standard channels, ### Event Handling Issues +If your app isn't responding correctly to channel events or membership updates, review these common event handling issues and how to fix them. + | Problem | Cause | Resolution | |--------|-------|------------| | Can't read messages in shared/private channels | App not added to channel | Add app explicitly to the channel. Retry after install. | @@ -969,6 +998,8 @@ To make sure your app works smoothly in shared, private, and standard channels, ### Privacy & Security Issues +To avoid exposing sensitive data or allowing unauthorized access, review these common privacy and security issues and how to address them. + | Problem | Cause | Resolution | |--------|-------|------------| | Private channel data leaks into reports | Using aggregated team-level analytics | Scope analytics to channel-level data | @@ -976,6 +1007,8 @@ To make sure your app works smoothly in shared, private, and standard channels, ### Testing Gaps +To ensure consistent behavior across all channel types and user scenarios, review these common testing gaps and how to address them. + | Problem | Cause | Resolution | |--------|-------|------------| | Features work in standard but fail in shared/private channels | App only tested in standard channels | Test all scenarios: standard, private, shared (same-tenant + cross-tenant) | From 685c8a3e4744c4c52419a361ce985e7480cda453 Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Wed, 20 Aug 2025 12:08:46 +0530 Subject: [PATCH 34/44] Update app-developer-guidance-shared-private-channel.md --- ...veloper-guidance-shared-private-channel.md | 367 +----------------- 1 file changed, 4 insertions(+), 363 deletions(-) diff --git a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md index 9dad17fedf8..080787b6d6f 100644 --- a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md +++ b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md @@ -210,367 +210,6 @@ Install the App Properly if the app isn't added to the channel, most APIs that rely on resource-specific consent fails with a 403 error message 'Caller isn't enabled for requesting the lwg channel of Shared channel type…' - When a 403 error with the specified message occurs or API responses return incomplete data, assume the app isn't added to the channel. This error typically means channel members didn't add the app to the channel. -## Bot Lifecycle Events - -### Handling Shared and Private Channel Events in Microsoft Teams Bots - -Microsoft Teams sends specific event payloads to bots when shared or private channels are created, updated, or removed. These events are delivered as conversationUpdate activities and can be used to trigger custom logic in your app. - -Key Event Types - -- channelSharedWithTeam -- channelUnsharedFromTeam -- channelMemberRemoved - -Developer Action Points - -- Detect the event: To capture this payload, use OnConversationUpdateAsync in your bot logic. -- Parse the context: To determine if the channel was shared or unshared, check conversationType, tenantId, and channelData.eventType. -- Respond accordingly: You might log the event, notify users, or update your app’s internal state. - -Best Practices - -- Private channels: Only members added to the channel can access it. Use this framework to scope bot responses and permissions. -- Shared channels: These collaboration spaces allow cross-team or cross-org collaboration. Ensure your bot respects access boundaries and doesn’t expose sensitive data. - -### Handling Bot Addition to Shared and Private Channels - -Microsoft Teams sends a conversationUpdate activity when your bot is added to a shared or private channel. This event is crucial for initializing bot logic specific to that channel. - -Event Summary - -The payload includes: - -- type: "conversationUpdate" -- channelData.eventType: "channelMemberAdded" -- channelData.channel.type: "shared" or "private" -- channelData.channel.name: Name of the channel -- channelData.channel.id: Unique identifier of the channel -- membersAdded: Array of added members, typically including the bot: -- - ID: Bot ID -- recipient: Metadata about the bot receiving the event: -- - ID: Bot ID -- - name: Bot display name - - Developer Action Points - -- Detect the event: Use OnConversationUpdateAsync to capture when your bot is added to a channel. -- Check channelData.channel.type: "This category indicates the channel classification type, either 'shared' or 'private.' -- Use channelData.eventType: "channelMemberAdded" indicates your bot was added. -- Initialize logic: Set up channel-specific state, permissions, or welcome messages. - -Best Practices - -- Avoid assuming team-level installation means channel-level availability. -- Use this event to verify your bot is active in the channel before performing actions. -- Log or audit bot additions for cross-tenant shared channels to ensure. - -### Bot Removal from Shared or Private Channels - -When your bot is removed from a shared or private channel, Microsoft Teams sends a conversationUpdate activity with the channelMemberRemoved event type. This event allows your app to clean up resources, revoke access, or log the removal for auditing. - -Event Summary - -When your bot is added to a channel, the activity includes: - -- type: "conversationUpdate" -- channelData.eventType: "channelMemberAdded" -- channelData.channel.type: "shared" or "private" -- membersAdded: Contains the bot's ID -- recipient: Identifies your bot - -Developer Action Points - -- Detect the event: Use OnConversationUpdateAsync to capture when your bot is removed. -- Check channelData.channel.type: "shared" or "private" indicates the channel type. -- Use channelData.eventType: "channelMemberRemoved" confirms bot removal. - -Best Practices - -- Graceful exit: Avoid errors or retries after removal—respect the channel’s updated access boundaries. -- Audit trail: Log bot removals to monitor usage and detect unexpected removals. -- User experience: If your app has a dashboard or admin panel, reflect the removal status clearly. - -### Detecting Channel Rename Events in Shared and Private Channels - -When a channel is renamed—whether it's a shared or private channel—Microsoft Teams sends a conversationUpdate activity with the eventType: "channelRenamed". Bots can use this mechanism to update internal records, logs, or user-facing labels. - -Event Summary - -The payload includes: - -- type: "conversationUpdate" -- channelData.eventType: "channelRenamed" -- channelData.channel.name: The updated channel name -- channelData.channel.type: "shared" or "private" -- recipient: Identifies the bot receiving the even - -Developer Action Points - -- Detect the event: Use OnConversationUpdateAsync to capture the rename. -- Check channelData.eventType: Look for "channelRenamed." -- Update internal records: Sync the new channel name in your app’s database or UI. -- Log the change: Optionally log the rename for audit or analytics. -- Notify users: If your bot displays channel names, consider sending a message or updating the interface. - -Best Practices - -- Avoid using hardcoded channel names: Always retrieve the latest name dynamically from the API. -- Avoid notifying unauthorized users: Ensure notifications are sent only to users with access to the renamed channel. -- Avoid overlooking cross-tenant scenarios: In shared channels, make sure your bot handles renames across both host and member teams. - -### Handling Channel Deletion Events in Shared and Private Channels - -When a shared or private channel is deleted, Microsoft Teams sends a conversationUpdate activity with eventType: "channelDeleted". Bots should use this event to clean up resources, revoke access, and update internal records. - -Event Summary - -The payload includes: - -- type: "conversationUpdate" -- channelData.eventType: "channelDeleted" -- channelData.channel.type: "shared" or "private" -- channelData.channel.name: The name of the deleted channel -- channelData.team.id: The team associated with the channel -- channelData.tenant.id: The tenant where the event occurred -- recipient: Identifies the bot receiving the even - -Developer Action Points - -- Detect the event: Use OnConversationUpdateAsync to capture channelDeleted. -- Check channelData.channel.type: "shared" or "private" indicates the channel type. -- Use channelData.eventType: "channelDeleted" confirms the deletion. - -Best Practices - -- Avoid retries or proactive messaging after deletion. -- Log deletions to monitor usage and detect unexpected removals. -- Respect tenant boundaries in shared channels—ensure cleanup spans all contributing teams. - -### Handling Channel Restoration Events in Shared and Private Channels - -When a shared or private channel is restored in Microsoft Teams, bots receive a conversationUpdate activity with eventType: "channelRestored." This event signals that a previously deleted channel is reactivated and is available for use again. Bots should respond by reinitializing resources, re-enabling access, and updating internal records accordingly. - -Event Summary - -The payload includes: - -- type: "conversationUpdate" -- channelData.eventType: "channelRestored" -- channelData.channel.type: "shared" or "private" -- channelData.channel.name: The restored channel’s name -- channelData.team.id: The associated team -- channelData.tenant.id: The tenant where the event occurred -- recipient: Identifies the bot receiving the even - -Developer Action Points - -- Detect the event: Use OnConversationUpdateAsync to capture channelRestored. -- Identify channel type: Check channelData.channel.type for "shared" or "private." -- Confirm restoration: Ensure channelData.eventType is "channelRestored." - -Best Practices - -- Reinitialize bot state for the restored channel if needed. -- Resume any suspended workflows or subscriptions tied to the channel. -- Audit restoration events to track lifecycle changes and ensure compliance. -- Respect tenant boundaries in shared channels—restoration might affect multiple teams. - -### Handling Member Additions to Shared Channels - -When a member is added to a shared channel in Microsoft Teams, bots receive a conversationUpdate activity with eventType: "channelMemberAdded". This event allows bots to track membership changes and respond accordingly—such as onboarding users, updating access controls, or syncing internal records. - -Event Summary - -The payload includes: - -- type: "conversationUpdate" -- channelData.eventType: "channelMemberAdded" -- channelData.channel.type: "shared" -- channelData.channel.name: The name of the shared channel -- membersAdded: An array of newly added members, including their ID and membershipSource details -- membershipSource: Indicates how the user was added (for example, transitive membership via team) -- channelData.tenant.id: The tenant where the event occurred -- recipient: Identifies the bot receiving the event - - Developer Action Points - -- Detect the event: Use OnConversationUpdateAsync to capture channelMemberAdded. -- Identify channel type: Confirm channelData.channel.type is "shared" to apply shared channel logic. -- Inspect membersAdded array: Each entry contains user identity and membershipSource, which indicates how the user was added (for example, transitive membership via team). -- Respect tenant boundaries: Use membershipSource.tenantId to determine cross-tenant relationships. - -Best Practices - -- Welcome new members: Send onboarding messages or resources if appropriate. -- Sync permissions: Update internal systems to reflect new access rights. -- Audit membership changes: Log additions for compliance and traceability. -- Handle transitive membership: Recognize that users might be added via team-level membership and not directly to the channel. - -### Handling Member Removal in Shared Channels - -When a member is removed from a shared channel in Microsoft Teams, bots receive a conversationUpdate activity with eventType: "channelMemberRemoved". This event allows bots to update internal records, revoke access, and maintain accurate membership tracking across tenants and teams. - -Event Summary - -The payload includes: - -Type:"conversationUpdate" -channelData.eventType:"channelMemberRemoved" -channelData.channel.type:"Shared" -channelData.channel.name: The name of the shared channel -channelData.channel.id: The unique ID of the shared channel -channelData.team.id: The ID of the team associated with the shared channel -channelData.tenant.id: The tenant where the event occurred -membersRemoved: -ID: The Teams user ID of the removed member -aadObjectId: The Microsoft Entra ID object ID of the removed member -membershipSource: Details about how the user was removed, including: -sourceType: The source of membership (for example, team) -ID: The source ID -membershipType: Indicates if the membership was direct or indirect -tenantId: The tenant ID of the source -recipient: Identifies the bot receiving the event, including bot ID and name - -Developer Action Points - -- Detect the event: To capture channelMemberRemoved, use OnConversationUpdateAsync. -- Identify channel type: To apply shared channel logic, Confirm channelData.channel.type is "shared." -- Inspect membersRemoved array: Each entry contains user identity and membershipSource, which indicates how the user was removed (for example, indirect removal via team membership). -- Respect tenant boundaries: To determine cross-tenant implications, use membershipSource.tenantId. - -Best Practices - -- Revoke access: Ensure the removed member no longer has access to bot features or data tied to the channel. -- Update internal records: To maintain accuracy, reflect membership changes in your system. -- Audit removals: Log removal events for compliance and traceability. -- Handle indirect membership: Recognize that users might be removed due to changes at the team level, not directly from the channel. - -### Retrieving Member Details in Shared Channels - -When a bot or app queries a member in a shared channel, the API response includes detailed identity and membership metadata. This information helps the bot or app understand how the user is associated with the channel—either directly or transitively through a team. - -Event Summary: Member Added to Shared Channel - -The payload includes: - -- type: "conversationUpdate" -- channelData.eventType: "channelMemberAdded" -- channelData.channel.type: "shared" -- channelData.channel.name: Name of the shared channel -- channelData.channel.id: Unique ID of the shared channel -- channelData.tenant.id: Tenant where the event occurred -- membersAdded: Array of added members with: -- ID: Teams user ID -- aadObjectId: Microsoft Entra ID object ID -- membershipSource: Details on how the user was added: -- - sourceType: for example, "team" -- - membershipType: "direct" or "transitive" -- - tenantId: Source tenant ID -- recipient: Bot ID and name receiving the event - -Developer Action Points - -- Support multiple membership paths: A user might appear in both direct and transitive contexts. -- Respect tenant boundaries: Use tenantId to determine cross-tenant relationships. -- Audit membership types: Use membershipType to distinguish between explicit and inherited access. -- Handle nulls gracefully: teamAadGroupId might be null for direct channel membership. - -Best Practices - -- Avoid duplicate processing: When both direct and transitive memberships exist, ensure logic doesn’t double-count. -- Use aadObjectId for identity resolution: This identifier framework is consistent across tenants and contexts. -- Log membership sources: Useful for debugging access issues or validating permissions. - -### Get Member in Shared Channel - -The Get Member API retrieves detailed information about a specific user in a shared channel. This user-channel linkage includes identity attributes and a breakdown of how the user is connected to the channel—either directly or transitively via a team. - -Event Summary - -The payload includes: - -- name: Full name of the user -- givenName: First name -- surname: Family name -- email: Primary email address -- userPrincipalName: User's sign-in name -- userRole: Role in the channel (for example, "user") -- ID: Teams user ID -- aadObjectId: Microsoft Entra object ID -- objectId: Legacy object ID (might match aadObjectId) -- tenantId: Tenant where the user belongs -- membershipSource: Array showing how the user is linked to the channel: -- - conversationId: ID of the conversation (channel or team thread) -- - conversationType: "channel" or "team" -- - membershipType: "direct" or "transitive" -- - teamAadGroupId: Group ID for team membership (might be null) -- - tenantId: Source tenant ID - -Developer Action Points - -- Use this API to audit individual user access to shared channels. -- Check membershipSource to determine if the user was added directly or inherited access via a team. -- Use tenantId to identify cross-tenant relationships in shared channels. -- Handle multiple membership paths gracefully—users might have both direct and transitive links. - -Best Practices - -- Avoid duplicate logic when both membership types exist. -- Log membership paths for compliance and access reviews. -- Use aadObjectId for consistent identity resolution across tenants. -- Respect tenant boundaries when managing access or sending messages. - -### Get Members in Shared Channel - -The Get Members API retrieves a list of all users in a shared channel, including identity details and optional membership metadata. This response is useful for bulk operations such as syncing, auditing, or broadcasting messages. - -Event Summary - -The payload includes: - -- members: Array of user objects, each containing: -- name: Full name of the user -- givenName: First name -- surname: Family name (if available) -- email: Primary email address -- userPrincipalName: Sign-in name -- userRole: Role in the channel (for example, "user") -- ID: Teams user ID -- aadObjectId: Microsoft Entra object ID -- objectId: Legacy object ID (might match aadObjectId) -- tenantId: Tenant where the user belongs -- membershipSource (optional): Array showing how the user is linked to the channel: -- - conversationId: ID of the conversation -- - conversationType: "channel" or "team" -- - membershipType: "direct" or "transitive" -- - teamAadGroupId: Group ID for team membership (might be null) -- - tenantId: Source tenant ID - -Developer Action Points - -- Avoid redundant processing by deduplicating users based on aadObjectId or ID. -- Avoid fragmented data by merging membershipSource arrays when the same user appears more than once. -- Avoid incomplete insights by using the Get Member API when membershipSource is missing or partial. -- Avoid misinterpreting access by respecting tenant boundaries in cross-tenant scenarios. - -Best Practices - -- Normalize data before applying business logic or access controls. -- Log membership types for audit and compliance tracking. -- Use aadObjectId for consistent identity resolution across tenants and contexts. - -### Developer Action Points - -- Detect the event: To capture this payload, use OnConversationUpdateAsync in your bot logic. -- Parse the context: To determine if the channel was shared or unshared, check conversationType, tenantId, and channelData.eventType. -- Respond accordingly: You might log the event, notify users, or update your app’s internal state. - -### Best Practices - -- Private channels: Only members added to the channel can access it. Use this framework to scope bot responses and permissions. -- Shared channels: These collaboration environments allow cross-team or cross-org collaboration. Ensure your bot respects access boundaries and doesn’t expose sensitive data. - ### Getting Accurate Channel Membership in Microsoft Teams #### Why It Matters @@ -766,7 +405,7 @@ External Users (Cross-Tenant) - Ensure external users remain in their home tenant while accessing the host channel’s SharePoint site. - Ensure cross-tenant access is properly configured on both the source and target tenants. - Ensure your app is multitenant, with consent granted in the host tenant for correct functionality. - + Guest Users (Within Tenant) - The channel’s SharePoint site automatically grants channel members access, including guest users from the same tenant. @@ -910,7 +549,7 @@ Follow these guidelines to process events and payloads correctly in shared and p ### API Changes -Use the latest APIs to support shared and private channels. Earlier versions may have limited support. +Use the latest APIs to support shared and private channels. Earlier versions might have limited support. - Review the API Change Table in the Appendix for updates to Graph and Activity Payload Extensions (APX) APIs. - Switch to the latest APIs that support shared and private channels. @@ -1017,6 +656,8 @@ To ensure consistent behavior across all channel types and user scenarios, revie ## FAQ Summary +If you have questions about shared or private channels, permissions, or functionality, this FAQ provides quick answers to common scenarios. + ### General Questions | Question | Answer | From ee1f9a63c0d12aa89ae857873b879be877ef2d6a Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Wed, 20 Aug 2025 13:07:00 +0530 Subject: [PATCH 35/44] Update app-developer-guidance-shared-private-channel.md --- .../app-developer-guidance-shared-private-channel.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md index 080787b6d6f..d8e11380430 100644 --- a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md +++ b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md @@ -69,12 +69,12 @@ Before diving into implementation, learn about the different channel models avai | | App installed to host team automatically available in channel | Yes | No | No | | | App must be added to each channel | No | Yes | Yes | -> **Note:** - -> - Currently, only apps that include tabs are supported in private and shared channels in Microsoft Teams. -> - Tab apps in shared channels are available in [Government Community Cloud (GCC), GCC High, Department of Defense (DoD)](../cloud-overview.md#teams-app-capabilities), and [Teams operated by 21Vianet](../sovereign-cloud.md) environments. -> - SharePoint and the SharePoint pages apps aren't supported for shared channels in GCC, GCC High, DoD, and Teams operated by 21Vianet environments. -> - Bots and message extensions are not supported in shared channels. +> [!NOTE] +> +> * Currently, only apps that include tabs are supported in private and shared channels in Microsoft Teams. +> * Tab apps in shared channels are available in [Government Community Cloud (GCC), GCC High, Department of Defense (DoD)](../cloud-overview.md#teams-app-capabilities), and [Teams operated by 21Vianet](../sovereign-cloud.md) environments. +> * SharePoint and the SharePoint pages apps aren't supported for shared channels in GCC, GCC High, DoD, and Teams operated by 21Vianet environments. +> * Bots and message extensions are not supported in shared channels. In addition to channel models and capabilities, understand how your team app behaves in these environments. From 298b9d56c68cff292a2d1f91463d7500eb7e72d1 Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Wed, 20 Aug 2025 13:13:11 +0530 Subject: [PATCH 36/44] Update app-developer-guidance-shared-private-channel.md --- .../app-developer-guidance-shared-private-channel.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md index d8e11380430..3dcbe08c316 100644 --- a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md +++ b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md @@ -74,7 +74,7 @@ Before diving into implementation, learn about the different channel models avai > * Currently, only apps that include tabs are supported in private and shared channels in Microsoft Teams. > * Tab apps in shared channels are available in [Government Community Cloud (GCC), GCC High, Department of Defense (DoD)](../cloud-overview.md#teams-app-capabilities), and [Teams operated by 21Vianet](../sovereign-cloud.md) environments. > * SharePoint and the SharePoint pages apps aren't supported for shared channels in GCC, GCC High, DoD, and Teams operated by 21Vianet environments. -> * Bots and message extensions are not supported in shared channels. +> * Bots and message extensions aren't supported in shared channels. In addition to channel models and capabilities, understand how your team app behaves in these environments. From 6bd1450d64e0fa2a7a21334c60bc169d67cb9cb9 Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Wed, 20 Aug 2025 13:50:56 +0530 Subject: [PATCH 37/44] Update app-developer-guidance-shared-private-channel.md --- .../app-developer-guidance-shared-private-channel.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md index 3dcbe08c316..7dff626cd9a 100644 --- a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md +++ b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md @@ -116,9 +116,9 @@ Microsoft Teams supports different types of channels—Standard, Private, and Sh ### Core Implementation Concepts for Shared and Private Channels -![This diagram shows how membership works in shared channels across organizations.](../../assets/images/membership-types-shared-channels.png) +:::image type="content" source="~/assets/images/membership-types-shared-channels.png" alt-text="This diagram shows how membership works in shared channels across organizations."::: -![This diagram shows how direct membership works in a private channel.](../../assets/images/membership-types-private-channels.png) +:::image type="content" source="~/assets/images/membership-types-private-channels.png" alt-text="This diagram shows how direct membership works in a private channel."::: ### Channel Membership Basics From 7dd3e7fd68dd80b2918b4a11b4c3bdaf2a2ac738 Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Wed, 20 Aug 2025 14:28:46 +0530 Subject: [PATCH 38/44] Update app-developer-guidance-shared-private-channel.md --- .../app-developer-guidance-shared-private-channel.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md index 7dff626cd9a..b639ea1c9da 100644 --- a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md +++ b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md @@ -116,9 +116,9 @@ Microsoft Teams supports different types of channels—Standard, Private, and Sh ### Core Implementation Concepts for Shared and Private Channels -:::image type="content" source="~/assets/images/membership-types-shared-channels.png" alt-text="This diagram shows how membership works in shared channels across organizations."::: +:::image type="content" source="../../assets/images/membership-types-shared-channels.png" alt-text=""This diagram shows how membership works in shared channels across organizations."::: -:::image type="content" source="~/assets/images/membership-types-private-channels.png" alt-text="This diagram shows how direct membership works in a private channel."::: +:::image type="content" source="../../assets/images/membership-types-private-channels.png" alt-text="This diagram shows how direct membership works in a private channel."::: ### Channel Membership Basics From 7f86a868f5fb7ab6b83a13995bbc70b31351b4dc Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Wed, 20 Aug 2025 16:15:31 +0530 Subject: [PATCH 39/44] Update app-developer-guidance-shared-private-channel.md --- .../app-developer-guidance-shared-private-channel.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md index b639ea1c9da..e7493c523d5 100644 --- a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md +++ b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md @@ -116,9 +116,9 @@ Microsoft Teams supports different types of channels—Standard, Private, and Sh ### Core Implementation Concepts for Shared and Private Channels -:::image type="content" source="../../assets/images/membership-types-shared-channels.png" alt-text=""This diagram shows how membership works in shared channels across organizations."::: - -:::image type="content" source="../../assets/images/membership-types-private-channels.png" alt-text="This diagram shows how direct membership works in a private channel."::: +![This diagram shows how membership works in shared channels across organizations.](../../assets/images/membership-types-shared-channels.png) + +![This diagram shows how direct membership works in a private channel.](../../assets/images/membership-types-private-channels.png) ### Channel Membership Basics From b5f5210700c3f09e048f6142bbdca4722edbb126 Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Thu, 21 Aug 2025 10:55:31 +0530 Subject: [PATCH 40/44] Update app-developer-guidance-shared-private-channel.md --- .../app-developer-guidance-shared-private-channel.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md index e7493c523d5..03573975616 100644 --- a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md +++ b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md @@ -117,7 +117,7 @@ Microsoft Teams supports different types of channels—Standard, Private, and Sh ### Core Implementation Concepts for Shared and Private Channels ![This diagram shows how membership works in shared channels across organizations.](../../assets/images/membership-types-shared-channels.png) - + ![This diagram shows how direct membership works in a private channel.](../../assets/images/membership-types-private-channels.png) ### Channel Membership Basics @@ -525,7 +525,7 @@ To ensure proper functionality in shared and private channels, all apps must inc | **Mandatory** | Use the Channel Members API | Shared/Private channels have different members than the team. Using the wrong API can miss users or cause data leaks. | **Task app**: Assign tasks only to channel members, not all team members. | | **Mandatory** | Access the Channel's SharePoint Site | Each channel has its own SharePoint. Using the team site can break file access or expose data. | **Document app**: Store and retrieve files from the channel’s SharePoint site. | | **Mandatory** | Respect Channel Boundaries | Don’t access or post across channels unless the user allows it. | **Summary app**: Only summarize messages from channels the user opts into. | -| **Mandatory** | Update the App Manifest | Declare support for Shared/Private channels so your app shows up there. | **Any app**: Add `"supportsChannelFeatures": "level2"` to your manifest. | +| **Mandatory** | Update the App Manifest | Declare support for Shared/Private channels so your app shows up there. | **Any app**: Add `"supportsChannelFeatures": "tier1"` to your manifest. | ### Optional UX Improvements for Shared & Private Channels From defc0ff4ab0decdb959006c1012ef4ae3e7dc693 Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Thu, 21 Aug 2025 12:24:39 +0530 Subject: [PATCH 41/44] Updated the link --- .../membership-types-private-channels.png | Bin 0 -> 44687 bytes .../membership-types-shared-channels.png | Bin 0 -> 79652 bytes ...veloper-guidance-shared-private-channel.md | 31 +++++++++++------- 3 files changed, 20 insertions(+), 11 deletions(-) create mode 100644 msteams-platform/assets/images/membership-types-private-channels.png create mode 100644 msteams-platform/assets/images/membership-types-shared-channels.png diff --git a/msteams-platform/assets/images/membership-types-private-channels.png b/msteams-platform/assets/images/membership-types-private-channels.png new file mode 100644 index 0000000000000000000000000000000000000000..98e510d41eb2d8379487214618d98b6106327d5f GIT binary patch literal 44687 zcmbrmbyQVtzcz}G1qPy&l41Z#BPFRQB1(uzhl+x9NVf_~2`DHjji4YP(yam_B2v;F z5+WVaeAj&5cYpuvGsZb%oIM8nd4;vsob!&~@2Y$GUQ?9azlUxQ2?@!5xyu)?laOr7 z#1AX!F8rqDC-Xu4XPeD+S!t4t9}MI8$BujF70#28WCiVAzr7RxCbPP%X+uInUP1h9 ztG0Y|mxLtagxtmRHyri;^w`-_wRL@*o&IBCFKlswg`AA#VL$h4>7AX@5BE_0p4w>9 zeM_5axl`+O&SmZHEB?i%@4ZN^9dx7DHlN?U5_;_ot+UkVaL#ud2YdWqOd-F+3n5{p z?zD3UPRIqH7~gmFR_r0$`HRZyE%OJ7E`ku01)V3LWPZEFcQ)J~K{`>TJNEqH= z`{jAfRlG=a=<6`?_h{?8bNFZQ4-tMR;?4IMB1-Vjq%(o?diZD45!wIGZ{OIKntJ`l zjf_6uYFL5MVlcGuL5SZ=^0t_Wb#Wreja_bG2%I{9u)khz<@u)W%C9 zP5Q02w&vTn&nCG=PwE|2RaNiay?aepcal!@ZDb@}AU?*x;I--4yXz_{7Yq$q@q&za zj~5jKN2R1<*VkQNDW;e%?{HcAbC$zB^B#Xh$tFo!%QxDauAfT(_SV|9=~fq54;>b^ zU>K?n8ZBF!y0f}4{vs@_xa^&3tm_<^`b{@M?L0H<{Ts%w6xr;H8C6wvFL-DuD<8b+ zwn+WA&qIomRsPnW_N?yvwOrzhKULo8l@`fprZm?CpSF1lI^n+W z!!;pq)6#6*#>p-{J^U#|Nm9<$wZwExX~0%gv+(}O%(B(f)q#vQ`?pwjlQZZF)EqiD?H?&8UYZ?=vTS;NmA0)RRywmS+ilIh*JEo#Dz_%Nq~sN5_W5+#S|CO@ zjM;tp;dJ>{3?A3-@m^Z~J74xCBqlm-u8e9HSh1w0CbUgh+t^f8RBSKRn=blxCMGJ1 zUNoBA^HV>aNlTI41UozXt)Fj{3yO=g4QfN1O^QS*kL=qeE-r3mV?#U@mCPqIp*#E$ ziWA`sXAHmJTy=S=s4(3z^eBvp*)3+`{b|@`eE$6Ty#}XztYkEn zduOhxcLIB-bF?DcnR`F(Vh$_6e9;$*%F;@Ir_da`(5hG(*M;9C%Trlv2{>_^= zw|=}j%c-6BG*LEaaAM->xpU|I|0=7##542V`@s;(srh+nvg_^Jw=A5T`w|=9yfp0% z;^X7Pew*)c=*zlWb10DE?4!&~o`(+~YIXeiV`li{m2Ye;vot9Ux6aoRr}_3m8#d?C z7#|`yu5A+Mdk8q=UW*3`u0-CzQbT)vMax8Li>zy z(}||0CdY~Nd=aaD64^k8fu^fGRkgLXxo?uo%3@aLM{S0`9u&3z^EH%9dwIZ{StHwU zKRy!mN?(9ZPC>z7=}*V{@=#DxQc^>*0{!~>x{i8vo_SZego{vZ7|&?`C(pwHm!vOT z$Sp`s{T?M8R2L;2^6c5i&5gB{sp4skToY;;8JUZ+vUddNuy6XkncZ)7d@wk{#y0fp zmrRt9dCuaWzVg^ukIjgI3UA7T2R}VMaz-P^=%6<_Xn3Jl0R7V zi2C{Yksdfu-P5DX5fT+u`#s{!?9x(lUS6ov{K)gj$Sba{;uxvn;k#IX)sJ@WCC13k z&JMfGq*~F=PH-;`=f}Fb0FKO(V62H*V*H&KP4?{FOGZZaskvFjrJPuRn36}Hp0j`d z?!GlUSoKajKM++WkV)cOexG|Swj?_zr}%A`*HVT}3HvF~XjnER1qB85D}4?gJ8|M7 zgQRP_Ag5Zo)=3iUKDWPQEMCh?U6wnKUJ7F3$|xAzv&{!PTZfdTlF^}?g(S;%{QC2- zFt*NoOPiRIsWtmkMadUS09ELKb+6N?uVS>Q z@A9(aY{$J=GF4TXD_8u+y7DuzmJeE3SR7+zy@XYuUh=osMOwfu5H0>tHgo>?gI_-ha{0^1)k`i1#Pt<*A7L$0w-WMNvAaXVk>Jgh}p}#xasOfhl|>!jy1jZAN%<>L}Y7y zUZyQWSH{*h$8olbRz^((Qxu~wYG{OCqmt2a9C&<8P*9bl zSifq|ZT^T#v?{hQ0rYInf2X*x%pQNbMN#U!c!)#oUBkCMER|($Yn5N0AD5Are>&Dv zoKIZT$KRh4H*M)ZZ9F$zL)=@C)Mf#81J(;ik;63immp>y6BCol`Fbgyf3|P0!qV6A z&%1Wx#);Lx(>&7B(v_$T+&|8aGCY6w>?q2ES8Qyou*;V(Q(%!%qh?X5rKys#c=cG& zj>foTppa5JbX$8D{P|FO5!LK*W@hHh{5)ll_?%C;plN8qpdZJ@FmBz8R#xwM5AV}o z7;EGzs~vAn+3Vrq!Ds(R!@6R>un+c_|Bq;~y*xZTe2z2yl!1xcca!^A4}I|^XB73Z z=qd7Ll5qC1pX~G{qh$4Y`gC7$f=N=iz>Vyku)YB2Hn1xuZ#GIn;kXjGmBV+sBj zb#z`G7O{#OYfX>x2?(H8l3Yo8^X?s$H0kr`XfE!;;X{puHuq+~9uM+4@41UufCB>q zEb^=&m^s>u_@E_sY?5MaTgRqF6BE-fqo)_6 zrnY+Lkwpyq-MQ86ks<16$J*=9B1`ete<l4jL<(1 z4nF2ZF^DF9$S_-zQ@7{_Hq^%7KA!J}*&2oS4gBrgQP5CB)HyZYpTpnYX=d*@I#n=4 zo@Lo5sjQ`Sx;0&!ZFO;i4PAn5Zf=g4oSK@N!OgX4+E1T8>5qJmI3^*X`yw=S4~rK{ z(({?We`(eAoL;vV*`)#BP^GD7(s=GZK$De~rH@DA%8S=DG)x|AP6;B$ZTA5t+x@XG zT1=>UN*96~CKeM^QWW(ED}D9rA_es~Ru>0RA8DLR^-5MoqO?|8($xQ*$Xg#tvW%Nq zmDSW((KFaC1<;)=DJiL3UzyMSK&)eui^M(x!m6y7+TzT!=sC^gwxAr}Hc?ePUB+Q1 z6h)!HRuUI?bYOIp&7yq6KFe`dKg(&}aJEsFnJl}5lc+&hsu)xB5k9ka-h)g`++|yv zF3+DoXF*4+%&wQ@Sl`&Fy2?|UWL{w@r-$37-nMNUF&@&SEcSoeS&kh)US(4+k#aJy z6{F*a!o3%rdDj6ZPRXrxn=FG`nk;m1K0FGsG=4~Jxz3{P_~x3n`7KVg`O{mLD3c6g zs@hu5I85m@qOVxDsH*#NY3KResSf=2bu1U2_@G2(-Ki#L@uDF2zMx}WMJ=sN)d-X} zTf-LX14QZbt2WGk+xA_g=ZHcljyj`{_NQO*WdFab;!>h=$?EU4&b7K%XH`(w8q3^V z{;i?Jb&ksh`T%=g-mz4gyid zlai8B9FSUnA9^j%tmD|{iV7KG^K7n8RH0*4qNK_=ITaojGlp z{JWlZd7hV#5>g;#xu~cZNbLF@M~PwKGx$c8WjCRg<+^g;da7{L@7c3wH04!W8`B=Z zMM~?aC!HTAGKv+$@{P5>{yoJG{=n7e#%x9TtOqYnItFhZ2F8yAR^q!q zeEA>+#Zj#O-B~VwEwW78xU0zw>X?bWc-Ge}CREjAoKFO3{eGVQc_G~U)C8myryJ+l~vW`x-zFVyO>RSwpk+Ms; zh;;%nXn-Isp)Egu`Vez$JJqd;-ep?*n1WdEpZof5%D-w~I_nDnW;)4JX)UK? zT&B(rOipr1F86!VWa$>$6I$;g7)q5bQ}s0&N0Bmy&SGeyLkz`*vn_ z*4TQ`QpkPXkyxRV`u(;cVHE=ucfLG5*x1;3?9?eapXA7f!qFIxBKt{a>GU;6Adtb& zdwHl19z3YO_`8KmALzOab-7bUB^zTP=ji0*yPMhdnosiISl-)@(Dj%|7B&g0_ZV#m1}Hf>HR$C)@{fvM|QKVH&xU7O7R ze2dqoc&g~CSVok@`b@=VGa-Ml4bsM(()jrJ!CzrFEtC~WSuBbtg$^D$atbKzxEF=~ z{7Bs~PEL89`!y%I-1p+P6HMDOj&XAhkwVvitT2+`2{mCfD-nv%b5~W(D+5Bj18in$)~Kv&W)(!0M>i zN5gF6X%!Ia`}g@%Q$JV@NGHojdgY&@uo%zu5aK89;` z&!V#gYlv@AkthSXx0+gJ+Zm&VIGT+kLQ(tCg|YHl!$LwlQ&RzrdF_7RAnxPmTa^e= zyVF3tcMS}zXZp{ZGo}p93{(IRhR+UFH|LtFlgP7Df;-0*6ojJ&6_i~(?sbmzyphou z*@nr~)Rd!(ODyl9A3Z&cH*elF7tqzzJhF4=PEwX|F$W9(`dqM%-@kv0xGwVo)3W3S zsMVA0uY}C$piB%84?l~IJ)lq>kifo=PT-A<$J?+l+MzE2$JyAtvC|?6f+^!qqkQvb zJve4HnCgCowdQf#rVL#%=f&TzOJkDHvkC-UUKdnM33>2<1Q1D^^8hJn+y!rPDjJ%Y zmx-oZr}&*V&eutO0UWWam-uTnUHW&f{Z0^3)n=+_Z(3DRs~42*DDIgm8rvZ$Df!Bw z*GX%)qypn-s2fiY^GRQIXJTS<-P-uuZQHCMA1UAqcKZR{W^(hbN`PZ_hgtiiJ!BKj z_qVnInHoTg;MDx!g<1(lat?$-OW_(m7Q6L%NQlihmpcG~AaCbL<4;nns=m$4v{cSG zYs?ty*xlVtth)n}%SU<2mXCq!>DPvGL4bh(p(H}~j|OKb&6b7YMd#A8sv_gl6Okm* ziYfNeN#ik+X)RZ-U%&3}2B@oVCPWWFX2xeVY)cTBg#}w7v-XeC4!t$z`8{8VAMlf$ z=?c58g8L#2Y_D!aD~^)Uo~o-=Rc%>PH#g_9FDBF=wG5q(K^yb-_YVQ~C@CqM2aDBJ z7rorNUcJ)s4i}!bX`4rt|QDi9nB5i*=Jz^tU_JJG9*`8d&D=4$L@9Z5o^O2htX5*%gwnFx zUKXI-vBlLsai@p2_fs~7l5YO85}8?A8p*0=8uDd}=_h`O{|$be0<4fx*A5`5G& zv-Ar-=6j_tr4yhxL1DwCJR}KVpC;7}2HFIe2o7;ZB>F?Xe&E+8s3jzC>9Q(I1Ighbq6pqlzvo@cS8e(pAy?%pgC$uM%?^!>Kx#V~C2VPkMPSzP;W2=dtE($8=E=v8A7}7vG>6w2 zdQpH}Jx+;nPOTbs-dJpl06+fQ&&O!{r9sLWD7IWR`lPj z49czAymGu0>`p18d`VnyDv4sgRS6!m+(B~I9% zeGAbWbTZ12kkVV({r&xwsbuIAn5n5Br=+lCDO>=7-w!*%!X z-*+5~_trr9fP8Xqd1gQyowsCbb1lcX`3V|5nftHB^2Z76KY#vw^=yohe7BR6lcTe9 z%v>ww_(Jr0+sTa~RQE8Q`(&ucs83|x6`wEtJ8Nvk`>c)9N4)u-PfnTGW#WvvG#SC-nTy;*-pdH zWiMa3(ggV{0P-AxXwh6hL52(fvuho-6%CZKX71wz+U8DHh2VZ8`qZO%D}W$7^2f5 zZLybGGo`*-I^;^ME|Hoc)Q^p?X>mSqD#H6y`Sxo=}@ z5+VxG%dqdyIL+PVE?u~uero=1tUBq#9*efs{gB%TvTzyeG}1I<00S{X{P!`f-p8Jv z=>GnG8oBh9`MkW|k_$%emY~hG$|@ZN1i!7Kn>BW?m<)`_BW`*{KxGF)_(_#Hd!9O*S@?Rjz>g9#PZsj z&C0K^p^1qJt)#~&uqY3NKB9Oy>m_iXV#*LWtvO$|XL-4lfq?-e@2Rpi3pgB!g0hgy zfr(@s9YrAeqAa4+)+-42RN^+@W@L=4&)2h^KE3Aw*qEs8*g0T4AjTXFv|g$6!1#C# zUgqoPcT7wy>fJj|FA9Roh|hmN(^)fo7te5n|1K$}w#rB#I4bI@lhawK#{a$qHq28x z!7E)BEMBc)HfWl8;i~a)DNup=j2e#a+E3@Dm&pc+9rDn#urN4J+n`YYBGx6?O;UXP z!x#ydCJ=0+NaIh2+17Y^)7YqFjv3qq)(CN3zz0xFsHI259eI6yeLI%~Ju;z_?_-u^ z$nJQmm~xzjdxD zUXW{v3Ws&wZo(Y*=~lxo9$T0uEfH!TK71hEyLSlt#h9-`7JUr37nLKYYTxO)*nFi} z$%Tow10+gHO6F@Q5U|iLk$!@r=m;P{h>xx7uVP{pZ{0c?rsr(zuPF+2_%=0l@X=oG zqtHjS^={r&QdA@-S_gi0PMONj-``q8u87X#QV~G z4PeIU=*Zu=K?TW<6ox^xnoVkYddrd>}RdT-_3kwSYpdqsIMb&9=(%>^l z_w5tE?S{qqv!x}PSNG64IXN=81CEZ46iiIL$LvKT``QMqUfDXIV%dS;yIGNXdWi0aaC?yD#Imhv?{>rTbo1>Bql+Pr>3PBwr$kwvR4Mfw$|k zy91v6`t@ta?%lBqxdNq1SS8?mom3a=u#-=oJozT|3Y1v?F&J%a zloS**X|x^y=m3LwDYhWnp928@*4A0}oH?!EH6h3w8^3MMw0C_3a1Y9L%7!7Q4M5)C=@bTI+1$6WfqT@@(4Z1SpVY^?9IF1WAH8}8 zbuAEjI~=26$|>rQO`T8qCCAnXZ+df|eQ~Lb)Z2x&V8Y5CSDJy`12i@#-?Yh zQ`-J%e=g~^nlsk-VpH`0x3~TOW{oeTTvw$o?s5N|`17?#Olm4Dgq5Dl_jX2(pm&}oHH>wjmj(% ztq2d4RaiLe)hmX!Dvu*rC+zG;IXG$slRAiZyRV$==;+8``H!I=9h{n4vOMTdhydO0 zYm?p9)r{S6nY*FpyDoLyyP>XbY5-pz6-ew&db)X5pj0yoVSAo=)P#N=#KFs3n;V+B zCNE8WP%f<-WoTzBDV1{Cr=+@|a(x1J7%p1oQBhZ~CWtYmlK22!)9|lfgba#(t$X1= z@d8mU7(^(Ouc$fH-os%5G`j>);fNv|Az*w6WsL+n;u9#0&tNr?aQVJXy`rF?;Ggn6 z^yN#ir}&L7RT-I`=ro<>k14SBXV7B#;P2rY#zsa)vveS#-aQugTHk5@tM-@+(L=Um zfeIO3H$rI=01gewEw}v=%MKdc~Cs;t56mFb11O@1g64;wwk00~dj=}C3fCrNTDo|Nj z`5t))I5C%OZ3RG@T*2nBX+97(Yes$iu0Vo5k3Eh-fh=ky+EE`X z6$>Ox3^<@CK?-mQ0&7Q{xd$@-s7n7+ZLPnLj}J|k81!aHw-BGsr!*7(7k0GG$oJb= zedza;jEr?VX>}fWd+(<4e+*eD8`c~o_A6RibWq)(&D_cF!cFYwP|rAloCWa;_YG(4 zf4_wHkfLaK^uA-|knY(736k^yX8Ia7JB(aHji~aY#!7?38SnN37VpT9Xu?Qr$9l!g z5C$pl;Wuba&{`7EHZi8YA3pHIx9`X`rA2AD1K0xO6W=_J2l;4`pAAhP3-$?IV<@(U zkR=5K1SlveJ@qp0;b{oLVP?h(41-WZ@Yrx%y^)wOiRBO%*SY#Ac)?NtZ9{WDSTUAj z(91m`Eu&};h%h|PJ?EgUNv+R#wh9PB7VCALSAZZF)I6R9LJZ+x9+qMMuV0UWfIvEk zzyt}p#pd+ZW)R$wo!%7>^)g4{pb-K=Vp$o}fddCnVfiBDmseL!eES_yGyx{9>jc|~ zF(YRZzl{0~;lKb)6Md7hxF;}yo#gwgvmv1v2*U?fUl4#90c zfWQgd2Lic9KyVbZ|3i4YV5>8&+Lpi|B)m~|f4U1pAY9$f)j~AnU-<#7vf;*Yw_h*S zHS)}kV6C8_=sAy{B-SWoM*XZA$g6Weo6iv_NMKJ&Ng)6t8_GGOHcO6wP8Q6$%HmPeBXuNQvaty#no;7Jf7Yyn_=6_O}k6w(Xh&9dE) z!9VL~!B1?@z85sso|OoRB^Uezzw~*llH!N)CG)R3M#%io;i@1@=Kh5^`nUk*<3%`b zaDQZ(oGx~|&ev&mw*W6yf(;;lbGlNnP3JgaD9u6;@*_li2!lR^NHd5LMbD;ANKL)6 z0E|Nj5`-^|DIpBwgY@(q#O089sYLGP6n8=YKgud9geVPCn*b4T5Jaz~cOJG6EgTG5 zc&2cZnB13d6VD3sDgI^Qcyd(bOLe_dscC6d$Prb>o%gJS=f(a`Ee#Jh_*|ChAg!Kb zJRlVf+Ij-y+d=QRq!iRyOMB}m6e}UNRy^CpSl#ta0<*zQdwI& ztu*t*M%RuWapkX(VGG_^H-t32{gAYgAYJ5YtnkRv+ST3wit$&HbneD zbVYel(bH2@Q=^e4C9EHFMkuO$1la|ACJ|u>q%?Vu0lebw?k+y_aXTSgLS?ar-*E^f zBS4x;ngE>O$eNm(V2!l$(V{QyCRz#e3>`pOm0DO>xD$$BSXkIn(b$*~h(%m!ERsD! zQ3?~nA3Drn{5Qb?OP7b_#D3}&pwu(SGuKsBt6;B3Km}Gwmj9%m71uVA)nTR;t6A>8 zp;h9JJxN?CCDuJMvwSmhFHgy{%F2tlPlPN$U!a4L@M34Lt>ur=i)|JwQ#~d`N(P2~ z3Vo{B2!MNGo}x(}66pEO$?SVXb!#t-5EAr@7eJ8Y3T*c3tYwLG*cz-kCP zhxhHmDAZzEC>GmK=6py^HHke>8gG6tdnBpn6@wQA#6T`ZmHPmj6}NcdCqO3PkARnh zR)TE64yg|p+VVC_ofTd7m*8DmxhbznRbz4 z%(Qj6<+fN;B)4B~vL;JhNn-T^``r$W@A=oSm(!p0M;_J@JTQz<$8Lz)Y(O5u*oxd$ zRaH=<8zG@Xa$bg1l-oum<{LN0UJ42OAh57u8dZ|QE)@PJ70JK zTJ$_N?0TIixQMa~`S581J8sJtPG=x`Hev#qL;;`0uDgEi+5^a1d4b?!@CggmrvIkC zeQV5@)2#}D9FPio5R0&2C{T<@4Jk=&2uzpElS5@YVcPnx@kvozTO0UJVrlPy6H-xjV7=A(8td(hvoG zBLaw%i%eBb%|wuw1dUC|qWg{cXp&qAn9|*bxbvVIy1KglleVJK1gyL;#YF>MO|?^q zF5nV6-B-ATapsB5IN=H^aLN`m>J2x-y@uyh=87PTLS z*#kpE7qAzhxF-Vw5xOlsy}x1#RxdH1CZ?tx#ST0WA_+xZmf4L8y2{f_$D!-UDpPSu zTJ@isD&KMksoO^2h5@T*FJ8d(6M&*8X>pZ)+Vl6%x0E3A=|ViMpf&XLSMx1;p!g$L zNsU|yIfKYKfFB5q;&We*S5{TA5Dpw1M>*UjG}Vclzk7;>fy5eKELJ29@H6PRmMKtz8m^P1;UYJ z2M!P(1YEuSaK8w({|Px`r@n_=Q+ZvI4E;62y!0z~?iFN}YtsBaZhL>ePMGr0q0b18 z>Q;(K zl<~@mQr7(M;BboVSOW`OL1_fD^4KZ5cN$w~=P zxt8goPs?{B?^RotS^k!97FXH8dLE|xPw=?u)a&HrIj}k+>S$6+*!wX~BS#SLgPF_) zokFw3G0XnUOzbZd>tjHB$P)C4PgG`};^HzuCc=ZAg?Y5-(ZZ>3L$KXISA|)2WkeY%1E?R}nH6Iy(iR`n9%}5WG%8J|g^5=n@1B z$4Y{u<_Z!6QP>-Q2nh|nWNdtjz|?R{AhCHqd9q6_Q%?cP0dOi2)I(wjjTnX|x6SB} zlN=oWfU(y#G`^zKe}zU2K_cW~r z&V95nfe5(=JBr_B$qdd^vO>#?n3x|h4G0$zNCgrjkyRvI9eiZY=wtJ~vS=cqi?K0p zrHoAerUf$zYBv%u3(gy4_2)y9&OCOF3A5GWq}jWD*FK0VQd5tyu$*_vP{YK4DgWs$rH3e?ps*hx18PtxD9N+P$ZzP; za#yYp0P60&dxZCm%}69aVL-o0{f6Kc`Z(kckbzVQ!FD`5T0J%dYLFr1dl=pz8Wq1= z($3x=CXE)g`)njI2jqM0+O>}eCCOv{5s4yjH)iP&BclQu0O3cfH6!kf+HfaJ0|BXD z5VOpBOCpfQA>x+MOCPtG7y#%4Z)d|sg8T#pj}lZ3T?zTy@%F6a=w%O+YwQyf5{%k1 z7_F_Xv5!7j4_$in=n=wMqkvk+p$ZUJJ$UfEwDdm^782gP@d4cm<<`9dKme-@s0v|| zfZ}2?O!&_jeFc@tLWrbnv95b!otOr z<}6TBuu4J{LOn*q_>cUfW7{aB<1(3xU@{8R$K~0fLTC1}{)KjTj`Wj3nC=$>U=eEE3gh2D z9TfGT(F!yyOP5y9Gc|8L10CkhaiLQi6o{Z@5Md#AiKMw2fmf=vq)UP`;HZbt8dAt&V3|wJSuC`k0 zttRQin!Bh7vR9EvikFGioey~dwFSweJA^&K%8D4>XVfAq5e6>SuGhvHGC;TZ3?l(_ zsS6N&4x>#nirFU>6-A;?Hv^RuIgOy816P`dj3e_iowj_EWzz+uT%IPoMTLZ1KtlA0 zfDr}i$C+K850QLh$fpjrHN>G6(UV}ya8v)Q-9r#I5*pdvRTSwP4V za4G)HB3w2yVh5KwE+j+)aD`%!>;4M43@-}k;DA#}6775^PI#fFqObupAH|b_O(4YJ zlfVx1jSyv!5=u_SIUui3w~oSF$Fei-dKn!22%HDh7k>k`Pm|zsM1ThyCxLwr)~-VCm*9CflOfIu?Psf zz|^9&H;mg7#lO8>10IQ-q9Sq30<^>^RS-Tmp<3gzsI&0}1&3L7AmoPLhAwdhawCG| zkidyYX)!qo#S7dI&>2DgH~=}6a+T}Xr8P7T!xn-L4j_Z_maR4~ucTCMkzad6DCx}g z8LrI#9;(tDen*_DYC0nKzfVuCDxlFJp+iVtI7AT~8#}Ev>;UtOC}|#!oyQ>bU`HW# zZ$94xs|v*7 zBFHufbdsVkqPP~&H0IbRNV-F)r`}7;eUTKWRJJuID~L^cHFg#m)3t69M*|Q9qp8jQ z@PWt#ppkce2uVltd4y!p1Jpb74(K+-5eKl$TE(SR!|LiN?SHZ-hN(5xVaQCAl)!aqgI2xQBbrY!%GhhVbJjvu_ zdJnG)PH7NA^WE(CeKF5j&C?ws#|8erbZ?yQ9 zL+8;4uTedQjfZ@NG^Q0{7FLv0ATf}>3t)^OqKG#&q^a|OOc6&Wh~pP#LNGt~e#Ci$ z4!|hr@x*oUuc66FqNNiud!NUa1ez6&Ple#%6EN1PQ>R#Xd9M}!^-GRan*XT`Cm+XC ztbl~URI<7z|MV2oqJQBkC=>T!mT9G*IePQ~BroDf8}xk~%xXw>{e~5W>PXZbc$`>a zkQ=b&2w&R5f*U3dcs>q&$$gUnDMdBTn;RmVG#U%OyY+h5VADRkPHqEYT$g8KwZKt4vC=_e66XujTJ?R{&)}q zwqr8uFi2R}1MnOBfmag2`5<`^F&gv$X{p~@&-(jxkr1}8Dk*v?P( z(_g|6FuTrd1Ew?UDSC?2h4 z@89Ls-f5hNriWVj$s+&Et&b0e%H-rk#lHGFy>9-1NDwsV2;STO5GTKY(BO+h1%N|A z@J1Z(LI3xLO)Mz*5_veVmb12F6fpA$z3XXJR{t8%!-WBJs zU88^sPwWf46&~5y>5`k=83^~*JY%_l^*uPK55twfvEU?xhfCFU)R(`-6bbP1(X!L zt!~IDyW_IF{4f!I077~Vn2Izl)NOpMj!m85J_eCzNl7PQXmkMNVe=6QO_=sL>*-v& zspQ7+6iOta!~{dK#!dya0f4xac#vg>Xtbi(`PJoRio=I}C?26mWR$I%5D7R|#aBcx zgHsDN2$9@}si~dvG=2#AWI0^ceaoH5&&w!7bZcfE zvvY8$#)Nu)imS707oU6y;E6~XVg=^+b)}@FChKqU-pbO**{nc|0`^D+m*Z>PALRPS9KQUk38skhoLcy?YAdA@TzLyE)t zCulODAK`p};P?avvWkd=V^hI|TZY_)EPf)yI^s|x!Eix?ke}3Y6@spZvJI+AR9YCP zC~QRj5Y9ew68j^A)h=Hq#p%A=*u8{eh1g<#xC`bKumEQykw5{y@b9rmLA6O~ep{N^ zJpS{WkW%G@ttgaZRaK11MHv}FX@d0whvRNzf(+0GBvsh>DH0@?fR;YgUlo0gj)8|m zsQfi_1mf^5251lgNvtYtDUg`Si;>~sU#EJCiI#y#eLPMCKsJK=(t(4ps5^v(jpHfE z!FS;JFSJLTiF}H!hv3WwxFg_bh;GDutghZ2c?igrw%B3%k}?%h8}Hsdfl-wO1G`A1ce>B!3 z8AXRk$|8<)OMnhdfd!rLR_i14QP#}GxD>LRh17mE$ds=v11CXD*lx%CFBkce`)IHu2aceJ$j{iJ{zC~r=$p1o=dM! zr`Jr#R4!-bZeIx#NGnb4{$1Nagt_uwCL5kRa3F|=xZNko_iP!N6ODE2YPNl>s7P$7 ztg>F4Sib1Ip2rk>EmBI!=7U*pY;~AjPqk=R(p{k_ZL_GRpHgg;VYYdQNvyUJlL5z_ z7aJ34f#4GaR206Su6jB6MB%?VivNeN1V|@;=^(0lf6ty%?A%oYws8$20&QkOjVz+U zB;{XxHc2>iqd8- z;@$MJvM<%uLLws`w-}l-D4ax-4ar~>yTvQ8^wUu(pvCa`$>aX1zazi2 zky3{=US9iZ^=SKck~fy`pM}0ukWp1=E>q@WHlZkwrZmGk zd8dQJnP{;}qqR&t>F~lGuBF(Nl-)gt26+V*8S#kLB9n)u->|czNc^+DF-F%HKdy4& zw%n;xM>NN5_w4y5_xGl~-uWR?k&kahjcJ)K-PK?h)g8KA@ZzbwU+uTtHg@)lkG&5a zqNlxxjk`TaTJ(dHU3lkzwdk1fwF` zZI(}!mt^AFg!R}AM@B-TZ(bg{O68S$s8=X_%!hZf_)7hc*Kq|m#9FDTFbPJ?M*th;GJZNIq&4L&vE1JmYgbnWlrIxit%n2MFtes+6QcdojLszn(psg z{oD~S8J3=NNh8D4+<*4=wH>DbM~JD4i1OJ zz6|!-`b(=SaLG3DzZavcXCqGuA(3JpywiExgf2@{M@>=7Fwj0RPsQ#K!{KxCH%_qL z86s`zest`^{9bF3=zz6r=dQ&`Wi>wUv=n74fA;5*^o>!TwM>Nv%(HxxIeq#T=lL|9 zRsz<7zGzEIdp^p!qpPYqS!~iReAMg8nvd17ATjl%yLW?c-gp%CsUe5P$C6pWD(Xug zLgx(Pk%|U(f_@2}$#-&8%v{!8>Fb}XMFn`uHowiZH0t&+8L||YOlFkS3s@^i&WORH z(%@7x?^||sI@rd&ho}CFa_KMCmLvniJ6T$}^I5T(!i))tIW{uZnrEx;&uP8laCIw@ z^D+0%GN!UpHa;@0Ss0LAC9rvPW_~gGD#T->wnu~4ub;`jM#XrgIg5&}`^j>+y+G|Z zj-$uL@~aB--0q4r4g`dlZD)`Om2p@0ZLQ|=y5c>?F6~Lr)-4&)udVkGvAaF$ExEaa zo3yspAIq)!B z>vVhi%Z?J4*fFV9=K-2F*=2h%Sx0-Oqr3E+5=DaTP{TvWsH zB>ADyz+#0PH&jgxXfia8|Kl9PR&r?fp1usv$J#o~d~-{?a|U1uw#^bBa!R;>owGl`u=w07_=p^?MdUP+y1U3?Gd!!<`ZkaL zA@@d1V3)tDj$M6Xz$`vrc68e@{eIrry7iNtqF5bO2Kn7=;$jDkx`oL$WW48P{W`9O zni`O&82Std_oPkI|5eYGAW4!>NDY}HxyzGM3so%i-xjFM(nK1`@K7^-}p zvoHPoNYC2E?w#tSf4w$8r(gs-oZ=4KwkRZgD7wUv?Yc3Nydiv z(mt6ZoQEu|-Mp0AJ_W4t6h%3X{i6IE%blE}_Ju1WKYaPqjmBG9CI%KBzYPXnid8Ui3Rgj~L(WGS{Z}R$iS} zXlzx!uE#Rvw4^%OK6izI9gBx!({j};U0%j6w_tPN-i}EZQetkVxjiou@A*tUk;DI* z`sLu@#I%WyQnO|D#pAZJmrI7POuCw3*FWjA%@hgVtSz)(3XZ*q zT_F@|yejG4=Nik-d8*~xcZ~vhuchL#Ft=AC*PfP4p2v67;CXO7v~2lyynUJRrbPGB z@YPOHoNdnyN;Y0gUimxoZOg4U;d@VgSt_GPUG% zUWR|Xx>daUPIJqB&#G@9^>npg6dGB1JhiYW5Kiwh$>u9i3ZgN{pc8uG6+T9Dym!_9 z>iVx3Pp zyoNhQ7bbn9K0Q!T1$;WTR8UXd#QLo3OMqd!lP7P{5en)4>7fhs9vYa(_9+PNeV|Mmt>pdY>lgpd=z8eNcZc`}R=aUa z-Q=+-G^C=9ZZ4nwtw9Z8#w7PN=yTBf?)-J#TNXLG0S zyz=`_Gg~v}bT`%qQ_-Sx-ER59dXvI96_ab@zt;JKxq&vMasTUacW&vaIixQI)qx;9Y3Yb*;2X3=+4u?4% z-oD{lIQ=B+#*LPQF*?)5^V{5aEDN-9k|ccYn)_UomT%yQ%94{JV028W=oeo2Xj3EOrC z@)yZ2y@&L>5-nFZe%m=eS(tq5rrw~j^1I`tp0@X=xX}cgUHtPN}*V;jPHSDjStnpfJ-7yDRsE^pn>z=4?U zTgAUbQ%z0jOQtPLO&+@(qtl@)5geZTz+Q1epdBmSid@r81=5EV17`24Vx-e* zu4W?1LEWLx>xGw}*nrWX;`G3Lip5#ElOT;m$l8}e{R;et9QHjYG-kh!3e&0tifcCKT5vawuM^U zrEl_o9{EIy0k2&v!$+Hb76cGc#)izEtkh3lB5B-vID^@zKem*rlbF|7qYT&XntCahqvVZ&d zwTGhKaX(nzlbvrqvzSy4SEyk8qe^DK@ipF8t7k3n$y=hprhnQ!p2d5v9&8#3+x?{o zUsw0CHAEde@~`+B-C7{Sul{-)?MlVhP2B8RsTwyPD(p-VNso|Bl9Jw5`p>1E^3IRX zB?g{LOprLChH)~x-{h^_^wZjqe{*hmPQ`i;`};R{Tg6W0ll^84sHHlW^0mBt;lQ<> z0wVEEtY6JUm;X9IPfim8{2%icH6LVAiv1Dka*2e$}zzn^K}bo{Ia-ZDbX5*PuyCdbh}q z7wxY;tXzW`FRgf+rMAsH;oXOCg0_#;<^vQ{8id~LZyZR8>1a#XW5Rga@16AqhoDHD zo*}-~?+3}QQl{*h<-g)`9m$VmUT$b_shuXyI@lUgNE>;iG?~oZ7m5BOVe4hrWncJ2 zv7hQ6Z+X2fE$IgegfI1j#4iC3N)Sz0S5KaT0Gl-KKANDof=;vsx?khrN& zP8(~yZgUq!9gL>wM9*W-k)D@P-G9=6`hS+!#mBk7=Hf>WjZKgK`+~jaGTUzRj_Lkq z*-A|%)$HwHU?&z(03F+i`9~)@%E7$Ik_Ax-vaCrI_-s>RV+U^@lFI1%S|!|FS5|Q< zBc3uRvZTAtkg32)d|G_X=YL*6@xIDm&2p7crG z&`VQ*q{@_{ohLTMV9IVgw7b(IXOBy#h&kTrd||8)FZni z#{fR-JAfQT}oPGS{NmKScrEbNc z>P=G|FNC~y7YE5Y`C;4=>L83Tq@~VuOxhENRWr&rosk(HrwiS@vukncQ#EBQYnfXP zhS0g5iMC{6d2C*bGpECxQ@8XXnBr8~R3r_b`l90bLWT8s+4%79yQpNmfAfns8JW1P zST>6He63m6`eS+goF(rq{s|IB#nD*d#;kuF>8RGbH+RO)??X1?8zM#uSFY^A*URt` z**9p0#GytwlEhaaz$+%)enb~w9OK&tV5h|+LXRXKPPm`7|8p36EQ|{xXap%6ia)*x zEgHTDyiRsRO>Xf*)!(L&8;>)bR5JfP`=_j@7x;f@I`4Qc_xF!CsT4{fLiR|q_o#$q zCuC=2W$&#avP0P`WRL7kcCuIY-r0NeyWXAO_m9rwoD-jM-}if6uh;8&fiehEE|?`C zKL~EW>h|^k;97u<1z3LwMFHXu*jONU0UB9a8j>0U10hCs3+z(GB_(o@Z2{O6A~S*z z1!?X{U`;@%4*VCOD=SL)Ls|m9M_^F;!(qhtKLQ?*&kxR`_=r7(!>J8&=AO47*dRF6qMx}+fCN^5=Yig}u!QkC~c zd-Sjk#>dhKq7Bx(hjMFc8xK>GO*aKd07Jn7b?F%tQb6fZ&|m6bF~g__XAGh=Ayo}& zZ>4`3pf+0vwcsYm27teg1$?Z?I)XCP;B<;YQX{x_k<(?hr-<%EO zG9!ftj~{YR$XQ8#0m}9k_i4oMORD65+tw34qi`$PCZV4U!YLgKTjkcPnHd_~nB-5U zSSv`=dus@SHC~V8)`M?TI$1cI>(vhP_==%HMka~Un=WECZSVI3!ZLhmc0a*JSMArri;Fw~lci%Ij!&Q_d+DvMf|YHF{LVq7)#Xm}ex zuE+k0{Wf#NHG6vwQ;6o)w)XFt<$0bRu~_7dDf5hx5<2}Qprlsk?I6V7`_ok>H{`?^ zE)?>eK%A?@19Zk@(B%NyqLuR!=1LUm01O~ABok0B6^t?sz*KMmX%BH7K(dGMEr>uL zaNh$h>U?k$0>d@J^dtic1{&Dl071h>O|1oD3;-OO0O+dD(cU^TN`l$r95``M>KF6~ zaE&1UUC0B?HXvPi`S>710Juj$?EigwJa%ePeUSh;4mDi&U*q3bsRP+x7-H#WIlaNxujh)Q;)B0q`d_;y1H{+uXwiaeuMSkky)Hs z(Gw=YV5PTY)VhEFeB)m*>)o(S=Q$z)t(H zBIaOFCCGM3Z|LuKBANK3WN>9Gw*`!~j{7uauWv>vPwVSX%_hZl)3f*V=IR_93A!!5 z4rw`xXz6(Yij(&_L(iarLPr5i+m&h~2q|#Ua4KBt!cP9-vMg$AHY#c(LhV>V+B*?< zm(R1j#h4ZT=5?=QR{*=MAi?x>uEPv3_VQ>z<^mh3Om?4~>T61BLmUXk>L$?yJ28@R z=`4Cl9~{CH3Wj2^dfDwZD4tbJPC@w@WHbcpB8-lXY)v7sT7y3` z4idg#fPq*9fIbNggZL=+Tg`F zZ1M}>aQON2Aqc=Qw81j528sOh;}8aibPhL|-H>drmvud%(Ci9Z67WT2K2VhVg5UH6{*ie$ z3!ZXK=k<&5D^n1hqvYl$d<%vxAn~Co2YGE^VVVIi%3vYvc5o*XkDEdL1=~DWrt-0v zgPQ=@a0evdYNGoShF}vRv$!E_1s`>TnJ*5o*ks@?3DAI7|Nj!~7 ziy(U5#g@wF*O>=9a{sdU!)E%p`I|c?LoHp(Y|8voeE98qF|YHgsD)_r*3+IV43xOu z_tAH*zlOvAn^?0oQMKxwGt2%pOaIrO!!6xK#$22BDMdG{qreo+_4(_jTbx9!hHu4` zYw0#wi;h`EKKux!5-Jx-7U|zPUhCG@E=(g6nz%heZfA;Vf-B?u>O$G z9fgEo(ni3RBmnw=`4=oRz$-IY7N4WJUoNsnY4*fSeo=mwo%J6yw2;1itiX)J09V zw#o4BCO+G%BFV{>g&q~ET%A@OxTRYQ0cLLr&Oa!3U$bQ~J~E^~TTT9?z9Gk{R>k#b zh3`Ej#chY<`-!2^`jY<7+KSPB* zG$X%Zzu-!4-jAV-t0WG$$hEF7jpoPX3m>vXNWM_`0-;Is-8J2xBDM2ux|d8SDHi^i z-DSD#b(PHN+I6|=I=e-27ZVbgrUwaNZJ^zKc~;p_?6Q|{%~)S>zkAy>sRS+c0<-9* z(8>1E-1gEyFcwqsTjb4y1nB3lUq!%81*w1ufUi)3cM;M>*#2ej_Vm8XXrTpn z6LNgRF{c}xwXki53IFCzlv;!sIf`7s(TL2Bu~e&Q2zJ2lu7_$SunCQirvS#c3yoAn9nd|SA!mf_MTkNTX5*{} zfhUMnf}g&fc>he}o9!ioBEFXehJ1OUM@vKp-IqJ<-)cJT9+$JdIlJmo6}Id4vL?~Y zHLme(HQn1qD>mokT?L zj!Lf4QTC$K>BcX^vptGRowAx@%39<+w^OG{o5zQnv+mMVve`!Z4gO{L!x-K^NR8EB z<$`r>ds|AW{7PJ${LMQ%4bi5ok#bOQt610i{8&NG`kBwYD|xqr3e9GJRgUN;e`npU z2x#JuklZ*CNTgbxq9Um78lwY41WH}OF<}$(xX5JuFB~@M^8gX-kk1Hkyx3A4*YgI3 zCu8n`MF`zD_?0GrYVE-iiuP>CKm|i12`sBE5ga~{GYLbf89)ys54jc};dEbfa6OcW4pq-FlZpWji(rvVn`!Z89wknKEFnpHi zVAHEXD53LHnJ4W^OiZy;sm{(;9f~%3M|QfqJ-i#9N2RzM!um zBD0;kF|MZqN%u8H$E+T_S|NxHid1+noh_DfF1U3_kCLZbKVXI=Q$3^tBE2_=9Mf=`>Af6;^XzXwVh3~gLl#WiB`F@ zL3+Fu{s)f4n6{?12CUsoS?9lt?C)V-9G_Vfd)B4#+xyKlTkpw5u$Jw^EwzVu73_d1 z;iiMjk`;(w;MmUoigoSU4B&y{AdPnhA;thE1rXcTG==n+xw@Cpst9pi$iGCwS#1rT zkS=h+!(o+aQ4|nn4Y8pUl#BKy;lqz?6?JhDfRG&O zhA`-~y*w0(W}*K$ID~w*jKMTgT?f4YMk|3_E8qdT{tN(S#}qKe4MXY?ke){-#>}G8 z!FV^^yL5D)hD^)+z~c3LdYi1L$cbRodE*i9lLFT__3QuRyqM+uNXqiZ)Nl??oPM#x zc$_8DqL3;@ovA3|_Lt^29-Q=ViZtFD(JtNy;VU_LC)P_PYaO>s#wu z9Ulqg6xDtoWed$!&S_RZVE$A@S{3Wl==)t=?T(>m0JHv}82`>JrZt&4Hkp(&K8_3y zsjCg^8LK3hn!h5Od&UFcf1MZ#NLpVOTiuxPmfAbm*I~c6H2C9d0IgsxwUS0N3C@T} z^fi88X171*D)-GSCAaJ){;5_=>H0bT3YQ$^`-xp#LdU0l@mp4h{51C`0M#WM@-&=JL+nQ^@W%dlOOEdIXpMZosUz}=qTA4 zB2ut(xR<(LjD|R@$jh|e+t4T^Fe`1;= zyDY}xtBcrk?s9EcpRjbH=bJ_}?glp2UJuzv(uV9$Ln9-xBYWS~>NQTAiY6=lP$ik) z;@vXky`zZ9nSLwSlMh2!M>$#}Kw9nxr(YT?;jqEdgb~qzc85;U0L(n|*Bm8jxL(|1 zymn1Wp0k95n(tktT)_8gjK@$xnD~+2C^gd)^(sQp(_ql`dyY^>&fH=#_Z8{hcha5T zxaQ@er7Sx86Ja1kVuZ{GsP39kzR@@(Z9Pw>7TE;leGx+uYM%X%)&>M0i}a`14KpvJ zg8N}P$e3!5C$CJ)Efe8@YmxgckXIyIYKZE^E%++&-CFFCvH-PdJ^QSi{Xh|O-a2e} zggKZuU9JUFiXyAWvzL_$3Kz_ki zbt;AF1B&P4kw5HvG4tX}15JmXw=|Eb=(SG5K9bmn7cg9=GKf_s<5`MQp>&dM_IGa2 z#Y^JA&hSnz170ZAafFFeu)V<~)pIstvzk*5*uDpM{<@|ky4EvNRP1qbqqV8}D=sY) zfzg!O$E;@61{K>a@1)2FsxDGiEw8zA2lKP0g2jAh9_RN9S`1fk4_2xFaX6}yDa;7x zZrXVU;~?`{^SuG9wM!fYnKD<*%i;9@Pw*IlLmW-;dOnQ-_y43IbaLLoj7c;u7zo>( zdWK8||5HcG`2`FKZu^%l^c>g1M~ob4tGV?ijQ35}|7zFg9c^bu=18ft)W7_9x;(@6 z;p`NdbAB;;x9BX;;h2bq$=o!_K$!w@;^y}me&>H>ZL?0JjT`5P7&-s`l{uEYg`}SY zwl80le%xEY?X9v)DId_CoJ|+oSUN5$^FS}Q@F2&;>;_KN0k&Z{&ws^qUsDW^SgtVQ z24D04X;1m_K_i&h@-9KNp=6)|Y^&1IxxIR>v5=i~hSx+;1Zf!$K4=7Zmfb!cvk1=B zFg)VhzK>Lkv)yFj93UP+w;K1Ko$U1csZgya%1{)HX7SXgIgW*|M-%{4c3+ZUmPbJtgR-%D9WeS;QB{*$?ug{ypP zji%2lXCmbOX^Y>2yUv~!CCQ0#d@RM=QreL2_MN^Yn%=GWXjgK-oBq`w`U|&h>Kqp@ zb1qEZzY6zSj&o(W7W}hRJjY>hv7U9b;)$#)wU;rOIkK)j2q-zd|Kcns`HytJQ@5lJ z`p?SGn@WWjqGAapjDL{r{2{YGT8(Gd;4h}XVk(8SEOGsa>^UZ|W{qhNgq}7!96ObH zZ~!u^%dr)UD6-8}W^%Gvb~Wc{Y_4~7m6>|TD>!0d{LVGCX~}swb9;DysTFt zsRkdd1cok6!VsBLP%ez}3G-4W!Nmbs3bqxO+D=FHVPqW8as(9Yjd0QTsWM6)81wE{ zu7S=aR2|oMyrPnfWSGOfefw@6rrBK_u#iTB3G-Fs$%m|Oc`+m3;)B~+gW)xX)VWiH z#!knEti2Y;|LI0Pvx3>DWDj;efyD(v16&=qpvW^ISoF5xu;=0n8c2 z&7SKWCVeIU8zZ)h(lke_hS=Ye%Kj5iOG{X+WreazwzT^?l-pCiHIp)t_Ibi->lyub zkoQiqMf&sfrp2n33FA8^DW^Etih<~Q(0jkvNaoAz9EEWYfVkd*FN!ZfVfr@^|A|af zyJLyNuL?E>mK^v`R~q3`j4mv(qrY$O1Bq{LXVEV}~B3)6DL z<>9__+T`U>peOvVwbw}jD7)VA<8zC`vT;z^%$SoU79&0(coPj5?KH7v*ctz%+@os) zD7#1;r%4FR301H8z$F9YbK4!4F1J?}4f`UCInov9S%n}rR(Kl&4u_K4SFbMg`N$E( zf=alUD%I-YEvX4F>2{C&0(S2J`_6b@K}7jU^OE$t_s&$_aD&FAf$Hg?6CeVv}S(8u+rh~i8V`&pTP)-XryuPMTbC-{GlL2{Hniku$)+Ptt$>XX2uH5p1S8R4R zx^mWO^RgWUrTXxZuGQWPcS^fJkGkVO-aY|fF0%o7#mHV81a_{7VPkXB!H<@J?j11eF zv*uv(;r2Uuj2;@9L?FyWujHp;!vlw)a7_C$qlp<;$QRYoZ9D_M6Y#-e&!xux@7i(b zU&lLLW$Wv3gYs>%oXJ;oh51ML>NjBx#U&yA`)>#~PnetErT&^(wp-@W=7{Z?XW@GP zzsE+g;s)P(%?G9FGwdlsswyD;&3<) z<#~~8j6T@`Ci`fjvtvSqs+7j#OW?quqXP#<^!AGahxaM+tNi~4A`tYkJvVpz%KzTS zA3fB@z$xDf`QOq#!fP{~!)HdpkdgWSPg$BJBW(cqlF^r`O^uhgrn9W`u*LwKA<)cF z)~cl?@y8EYC(>9*qd*NcvUT==6}s~+5Ro+|6pcNcUX{{#)~zEq+)DFrs!5}JHg)6? zWSvC!-~q~@jYHT+A91}wz(6c(U^&PuDmFk17oc5Rx(pcJgMMFeapOW(tNL&*S**T~RO!E7coK^4b>)Ql`5Nv#> zh{@!kDC;ifIZKqkY(JnuJ9~~U;q7U1o)@w`$fYwIspP6 zy+$*D)Ivu_=)r?~)j5hO^iLMH@Bsev2_>dh-i z9qQ^HajED)at_4vZy6a^flm+l5CC65QsoSY@K0rAAYUZ87z=cd8OY$HFOoN~2a+J9 z_bNlK0@~glocw4VMb-)r@ z^eK87f0w-)c3Opj_25>;Q9k=KZ#>0R;*Ql2PYD57*gz+P2VygMz#~MrLsF6o z$`+9QN|K4ieh9CCuzQeQnjNqHa7V!L3uM`l;{Zw&PoT^L+9NccK`@t~kdOvo*#P8? z6RtYSeZheX;!5czo1i#Cy$nPKNEW^6(=@d?s5(6q0{B!b`~pC?=)7y-n?YYE#1R0s z;R{5~cJ=`oL0zj1no+_x6c|f-520p&6 zO2S3eyw~lnqcH~@7M*ez4h~B_I3QPRP%%5B#koEo&9$*!m#ikNFQDH|DL1|3(G@Ow z>6?1>d7uTrq5zK;2-0vD=m07!C>VqKJOEt+-8^GsMyPE;`ZpAyWr0yqEg+i%z-qV_ zo?WQ8V?j@^Nhkr$0*Dwm35E7!d4ag+AoT{BPY8`cC?5qJ)6xLHe-WB*m=;f902>=H z=<)w4Z-C#2FdAH4TmT0_0T!;x1;DL_fr8Q|u&V}CcDNi+S-AuOLlh#0at%~(0o4Fe zd&C1UQi7&8#&__WyG}c*02em-htTE?^8mbB7CpM?fG35oRbqqDmDAhp3Mwbo7Jg4}oI< z)_1&8cky$~*Je8j*Q6g?p(aA%u#!MZmVzp*f4(7_NxUokk)4|6Bj{fT9u1V%LU|}4 z2Ouy#Jn5k1!+#)TF=%^6w9D|d0h8ecz^CSBEQni!igX$J^sJNW--7})Fhv0Dp$iap zgu#Pr3!rphzJb^P(Ou}K*I-(NM@rgujcfR!q~uj#Pfo#2f(#^TGN_W)X;25618X?Q z^_w@{%bavJ?XB1VH>?FQXHfM1X=VTnDlabwa31-C2dnwg zjQYGHaxe&0HjvV$2~!cIh_!$$36ds@NQgaz=M;cPri z1}KjV4>Bs@C%&?^L3k4a$Faof9cIM$}i z+6ib5P`2U1!^{mZj8ER)$gl$hg}d&r;DJ^VLK8cba}lTzNXk&;1!@l!V5PwTb_OUy zaJL}3*$whH%n2ayqY(f%2ak*_ph-90Y^)N6wxP))l%zqqZ5SGgM63=eKY$#-jD2n# zx_kbYO9x#r7|l1gZ+pRbf_H>p0#6gnDk!-P30J`RAle8D0=u1_K)e>U%>!7|8ngpI zC>~bUAeb1>qp&_0za(LT0IeRDRQSly$&d?@?g$FYP6Qw0WJJmnGaxBPuUWdmk8me_ z*AWVEXQ}6Bz2f)M=Tt8kLHCn`%+o1z72b6HlcJa;=VQzDLd>4oHA9q7f@dO#OdfQ7K|YXw*#s5zI0ftlxSlB!`9YT9VoLjSu~l{gnh5G znrdv6t;YJ+)!+kJNU^sztI>N~)@%fu%q?WB7R^U=1U8yhd8Kp&_W@O6D|*Xu#BhYp zwlIh9g*9}AI(Z1^j}t|3e)h$N>8e_FElrzqTX4G`st>|OyvqxAGq8)w^7%g1zhs+c zWMmQ5aFrbP^3m}L>Q4xxC$-gtPcJ98?FVg*L8Khizh2RD@hTY@1JENixv=mLhxM~$ zzH_URMLJ`TVw^W!y7GwhS@$_I{W;m^x3}h_e%8-j{W;W~AhKkCWe1UiucZqOL3cF(Ly1D?6o`X^OAu|~L`5+$KAc6~5KBw6_5-Q}X0=Xm z8NuJc?gbii`hwqYc^i_;2$=<-9eDiVr(oTNe*t9F5|=@|a!ASdJ$ zU`CxSEz$S08M0e%%Qw62(7FG_GuHWM1Mu`zWYD2`!t|t_n&~YWC+)X5=6IR+0MELe zP-3eK1dP_!k4f0ukZ=FbU1&Z$>;T)GL4!KT+QU8tcrHB{cwjetRiLuIwUwBk{{^P< z2^eIskE96}C*FcSjn9D2#K{Uz8SrJGT%Q1^23T55LNM|MoExI-fep704LDF2UYM?- z*W(#bZ_#uJuMhJ41W0v=s{-4ONAfk10E$C;E9|p?<^7HB3Mlfluq^y8_(NJBY3S0A?a`--3+*cCr)zBLd$UFq_c20~Q3>(!nGq1E@Cy zi-tdFA%fWwOt5g0nS~V`cKvXmsRc(GT7zM00!rih17fLN{oeqD`{-7(v_|HR z15cDR_IJG>E@O}2{3mmZ!PJq2cc1^k!qqN*9@u+KBR(1A=7Dfv1#%sztS>8_d4RR6 z3w?TF=EYS|Kt4@)<`Gm0e3@Xz%xtwo?W44FUc!d4X2JS7JX44T0%k6BHDR-ky1}6% z7;J-q)X}uHa5^^X;@K!Sf<<=P)`Fj@Sh34AkZY{Ga!p>x=o0P<^*bu}jaeFUuHk$x zhi%T?xfio5Qx2!^R8@r~5jX##5Gpjyvm9 z$E}5Vd2?L)vtRUY6A?{ z<4-&cIyyQffZKutlQvu_aJX)NvU51eVYnhEjp@y*XT9AcVjr0gEyX;nl9uQE7R3JfMkO#le}f=DkfyN&}}_;3C0Z z22SJgz`p=c3&LD{`g9lf5;JtT0e1`xXHq!-T)lb~9k~t;4-qLs5L(Z5ci2P&;0AhI z%fQJUh6BFI0I9H1&mhUjL?;KT(T^IroVuNy!>xB zLqkq}Rzwc&HEZK&i5e3+!2ZAMv8lE7HT>t^v8x&r0aGYea<@2q8uvePs?egWG>Z+| z%77=jX6&!SYi;rCyQ2=o$_uFz-*kK(20O^s^6Y0+B8K?(1_@3!Q~LK;zHfi+XS~uU zO(K@49>saH?V5{=3z|PRHY{NbAsG48Ix_(0!OQ90K8IY;(9&J0>OcXIT!_yF{awIe z7n%8woB1Da3usZafRq5t7NYFHp~7U5^11J+s8Faesz=}F&-gpJehulGuzOYmnZ zuZ9LuWcY)D4lO%%e}AEeUD(H}<2-3VlmPu7PA))NXAxTF7NdtVxporIB==czPq8=?*U zw0oW*jPyfC zemFm)+Xb9MMC~>(G@JkpT^m6AProS(0tg(|v-wi#H*fBtZtkQ3o~UgZcx+`IXsD^l zn_1z=1Sddvo?vq~s}Dy;-L6D&AdA6b1l5h%BM-P>v#Ir+ihc7O4KUrqliYI9tCxqm z4;EAcBBHG`{V~1DH8D%RmL`rU;AEIoJSnjg0t>n9>5(>*T~0R$I=S!$DE<_%zeawR z-fmRLcEi%Cg8yWx`Hqq441jCb<#IN|(+r2##;vFtxgDnc7oUFOWovr#lteGKEQUrC z>wGo&dq-UH#O%Bne}9GCpjUph4=8+sKJmxjlH&&I<;>{1GY`1+h#QH%M>tIxz_&M_@@FI}AuIqG<1PT#g@*|;lwARZ8S?&snE zo^f`MJ9$3E;3YLycf#)yZd=a4jfF9@3lq*;Tj^#Sez5{SyOK}qzUL)<^pt9hR?rBd z($!)tk?@e_P9biR&J$ zD|eHEl0w?(`5vAbc@(E$tBhD2aqO%}V4ac$Q{Gd24+R2}6ObkEUZQOx#L>T6!X3!+ zrsW~?FAtKh)O{&Z->2Fz(V`DmUlG@+O5_6=O~X0*ET z+V0u>eDXMEX<#OXnT<;Pv4R2sJzJ1teYv1-eqrIVTYqEx zBJWUnEM_6KN5@tO5DD8BquGnLsJsiA!s^gY3p z%vMf1h&sa-t4mxm+fr0q?7>G@&d*c}?p_+aO$iSlad*KE1}$QMADuw?2E?;M{|;3$ z8cNFZMMJH?_>>v2R@TTy$NF5@#aOF18WqITdGjPR@~xKFeiPO|-R{3Ea&dUGUiH^A zzI928#>@#_WkFh+4*sv~Qo`NrjNZ;W8HtSIPZOX-BD#?)(*OCs)|j8}i+o`c;f%xX zXBeu7GGX%#@Fl%l-}h=A7LgrlQ9btBWz?ohT5}S*+jJwBf-=?w^IVN`W_r5M=%|L^ zcB%{sN3^_~n^1Q7#uYz5Kj?T8&Q>4WvK@_wmZZbo)j7a?O`|W9mYy|%)UYXzYtsJA&bjugvQo)!A zAQ_qcH20P2vURk2w&{1*5!ZZKWfJkiUt3(exzlsmIfvUOVlMcP_L!lN@EvyCzzf{0 zgj=%#Eh?tA9ieJ84vtCTJ{wq@100vcdSRW1lMHMFXI)H8APiOdrLs~Gt>n;z1&&2m zv9U?F`}4fo$>Q7$KD}D2!;19}FE>`a7up(L-P-5Oz;FF%Z?ExDvIk@H)dC#Z?LXM> zN6(~Ab$LnqB-_5e78&b6W>!G(jNqYkR+QSSTM3L}@ zH&>*=s3;shd*plLz?>&94PRcN*LxI1W!-8JPLDqm_CAQ}vV?mt z_v_RT+Ie?X{rXl@R}=LXOsy3}3JLFv`y79`zU3_Au>>aWnKyH{fm956Ts>g0!jV!~=8sGvbIVEHZ5G<<{HF94f7Ra}cA9NF(_grmOt; zni0E+z^~clzMSQHzm#|5IpT7-4YKO$t)NRdAVfaIdC(sKzoBx^kXco3|j{1oC}jTto+r`RHzQtW>|(=VufNs8Q45y44#~$34K2)zI*$B9=J-V zPfe_Kurx%4DaqYzAed#-H{!XzgQfpSw5YGW=9$=*yoM*UAofq19#iF*@sK`hf(LsdcQ+nxy zilnav0oid@n#3z7*D2zcsPGeI^Q^g4V_aj8)6)z`2c8^zr<^<6Ns;VGaXEewAd~k*#E7#!!+WTWJq-@G4AE91EMnJ(>kM_ z$~@0O1*hA_#CIzgo5M5=mR-@OXkMu`K4>JuHcg{t9Tm5fBf9_9GgVnpyu0wjlA{YB zAAxB#*EBUb*Jafg7b>-IhE7TXe~S#Isw)ed>2QgEr0>6DYoyeR8+}7UQH066SDVIi zKwGQW>aEG?@YB%@ZT=5TL05vjnkBhuw8-dFFq`tfvoPg$lxN%ZxBiXzKo=zW_zPjV zb0JUvfY@stJ_q{siEjateKwHq@$X)s0ys5n?I26m2yI+iC0M{?g_xSerp532`}^0D z_lh_;IiV%T$L1Ld!mF_5g8ZKrs9kWl>mD67&6?ok{kAqRU*V@}KmI^weIPyiu26GW zq!nXhbeK{QReV%nUA@{%`4NLse+*cC*lfdGEVC0ZIC|b*3G#0>6z*eZmrAyfI3F3K z;ggg`HBB`|yq=W*Lg1JVU9|F zRc?ejR?(!Sc@PIjXki3CCw~csT@^9?mrpLWq+PVS6w11sf+Znu8w2e6n|DIFx=X5} zqYU@!66?|PSla94*Za1pCvW-VwfP9qm6mg*MneN98+z7K`o%h*?zd+qJ1F7Z#$){? z?x(dIZ<4h^XwahU-?_xn57c{Wdm~{~}LKou@)IA$8 zkdf;EF$P%MKe<%>CF*fGG&K556wUonI{1yk+y zxx}3cBceZK<7s3r9$gpl)}4H_em)pJzHqsuN$q%w_|r3A?bF{x*sI)6>h<-_?HkEQ zPlue~y;YlH6`mX)791@Sx0~-apZfJ0qE(>jBE7Cmd-7`~ymT^E>1P&1SSPE=4!hr| zt(VN^Hr+}-B$nUAKeZ;mw)kehi%oN8yy1NLY3Od){`ZoWlFb{Xi+sv^nRE1IdaUxM zG1c9gdsr-~IbYoLh;l`=o2?e*J`nYtZV0{HowM_5f2O-bvY8_?*!kj`a^QNIi}8_X zptYI(xK&T)K=bc0rkOug!{RS2w=gqXnFU80Z_ZIsL}JJ>5inwob=d9zbX{gW1-^fNx;TY4ha?`7LB z-F&}6i}trxt*QK(5bvj0zEJME zC7X=b;UykGX=TZ|y|}~H!}4&mP4ssbQ=?Ilw%-rAqEZh#w>)GV_TC&9xU`l~iqyUG);iy2eB?)!oljPFB~=KG=YZf&%%Ziv2))yvxp zR)K5+u{?I_?g*7Q~<_>F^hI-5?=HjDM=MZ!J^nWO^)n04w!x>HtNZTuV_tr@9Rpo zBpIA=8)Gl#h(BfZeA`QrF1&o|iOg^8Sp?OZKnX za^uYx$DqNMX1R3jVS)2HnP&BD{^sA)^0!nHYMXh)a>tLHDK!qTw?Ds#dh9HH!%_D9 zVN+J5es-=jd)6nCoct$n1#7q4FfMr!-DPg%pb#-Y297=kuPa)I8LW8 zzL$31XN{1LX8p}=ZYDGpjKQC{F=HNajbN5Nr58`$3wqApn-X<-dnNDXP1veuRcaXr za^^Bv68sB8_}QTFC-k_4L<%-Qb8tBTz!y}tOe13NVswiT6r zZ@J#yF%tP$B_kfRcC~ncr(bHt_pzlu{-o9ZeAX&^^GsN~{q(5~r7M+sU#CKJN+R72 ztRTa5BiN1NMw3dkb}>X0l05FSzSD_)5aG1$baa=v0>467BW-L{s%Zus>gx(9ZurD{<_uE+O7^mUypWn-h>M<(e@nh+G^q!vAGeO zIH(Jzex|KFQLc2GqHbYo5_s)}_0y<;)ohd>#bVJ8ZMej$1lm0pL+>vc!^sWD3Tqo1 z5FzSIZ5AO4hT44~6&Bdv6YKW&s};Kjrlxw(?9bZP)X^df=U!8flrJz-5g zvH`VNCZ9J9sOib011YE9rp5bPTo8KJm?C=%PCP~_CwGk=iuAE>szh1V-Bl5=X41@I z5SR(%_XBRnH!qQUqtk)?_IatxdWKG`+Jq^lF!Wtf+fVL+Ik> zvrp1~uRC`&^;S0+l3Y#kMK&c~ZhG3;|FsIp({D1}(7P4%;ABi}hTrr{S`@>{2!Vr8Cx_s7?yug&$vKnNMfTfnF$p$Gcun<& zvkxtl1LYVk>Ez!f{vzWKHLjyhls!8yx;rI1&{}f%e5vz#`TB9F!-+rbyuh%;#F535 z2EN;NBDd9TNQ~{ZIV!J{<;F923`@ue)54c|tfqKQuBr1$a($3`poE$pFnU;c%kQlA zXcbQr(r!N6eCoq@DAT9*Dffm>xMqZBt?g2HKtS!>W)9SkQLjP_3=HI-0lE7-3@C(J z@7D=HZCacKHTQ&1P5u-82Zx3nwtJOelxa`ad9{Gu3sp6D50zn^rKF@p|6^}YzAtYh zn0?l;Rx8xU$#vrm!)~u!f%60uzm%=o&lCw9utK@F{j_3YvU^m)6^dUDr$k1>HvNe@ zZv3JWKWiUKKu=Z+I5zp0NW<##X6x>=0O1^l3&XCwi@Z-sLiM7qbX$9rc@i2g)8_Fv zKD7>7FDE%vfw^=t_r?#={!4r3sAgyrQi&?01h%+fY7Kj4DR(6+<~r|A(ZuaF+-M@< zzkAlk*Eu&M2nfZk5}m@@25pZ_$<_zF5^pBIr<(Xn0tJS!x^i7c+k2JQaRe~S#7RQ^ zIcmJq?c8@NGJoYhG1lXU8VUXjv<-?Y!09EU%DH<{Jmj{)LOtI!bqRNGF@8Urq~tS3 z|Kg|TD$lt12|Q^Kx$*UePsY=$`Pd}aZURnGVd zY(!n81QPw*ALc0g=4c1G6TMh4TM?1xc<$ZhZ@7G&*Myrb?R`6y#%lz_9^b&!zvn*0#O4F#y~R;L|t!_`N%=y0ni0hyP#!( zEEsK=2@`X2t``mY)lS?M5+VcJ2o!ZZamZ-y-}i&|y?Yr;Ok`Iv)(?)jDJWzG6Hf$I zw7)=YjbPM1a<)*~b$vOT>=s|FA5HdRlK-5O{-X_wp1(i(?_W56l>gSkWZ@}(*~PbU zLI(NIbT6mZivFAuGWwaVt*}OB5o;{>!-Mqj(Yc^Y_Q$_+*CTR8$mg+O0sf_kgPjT8Embvu)(-YCkyheK!WN3Rz3I45s7o#I8G5$~); zgM?KvF2PVJL@2Y8rZ2u+QcUt8P^7!4j>>&DnCy-{VYjfL ztrTVdy=;pddeE8yZNvccJQ3-v9iy^`v3oS#$LO}xuEu+~r+yGHqy?a)_y<29{Z7kD zSZvs??2atF`h32<{4I4?%-9cj$^qx`@~vZ?C?`XybKMG^NkGekMqBN1xJt? zwM@_8>?s%O3AC%5vl$a=ritv^^G#IgIO|@=qww(~xlST=6m8|kON8H4!!0%;7rb$W zz@t-HO7SV- z7IJ!<=3=v?aqt_>v?i)JnyyQl!>$W2R!SVD?f3F;KNm}}UDmHkj`=oz>A+KpfI5o9 z`k^RIHBmFS7&#t=#3ztVA}`OCfOP>tN#W4%Sk6c0q>Pu3&*5)s@?H%=rFo08Sg;wCrrJ!s3p9;F&vBY5bEH5uZuWHu}mf6bC4w zUdqpSXF@o*uj2HOIBkdQRpVr+KWy)fBKS(C0@DAAt=ntMzyVdc6UA@tE`a2Ke8<*&c>2~QjCIV0m|7{^3y*N6IY6Dh;8!9hqYKZ>=Am+~5sA!wXG(r+jc&hN zT%w@`H{hq*;!yerD4v~reKjH z%SkVPfIFUPr=)5A;S0KRGHvCC!Ta4VLWxvDT>n0F=!Je0&O6t4kURw!1%Ew<1rSP; zzSi!Z{wyHxus_|`r4hRc_rsmdq-FZM=PVb0_=@+xcVfu5vE3Z?$lSug{`l{wb5%1D zHPQLl=Mbl4z?uK>K-={=*$tTw z;Ev?~dMY)U%flxA$qO5YL4P!dw!hOj1J zLPiB*Ysbg`y8&?V>gu1!tAxoUPU&2I4g(F>J+Bvjs;_!#b7CXPoiT=G+vtEIDeR=q> z<;d3w@_#RLUv$_M+vn@QJ7eWV(F}J&cmIFy%O>8d|CSn{*B$az1huc{`;VOq*N@MsqFwl}h zN6A{#pH#YYM&WRA9rN6*nqs{JPfHm8^>mR(-8QzXncqtb1@kKj>AdTT-}CE9$6R`N zmyo?k?&fW&?!edKO;ZwK{NFB|al8BL&xljM+Zrxs`q$1xLAQn%S1ei2uI(RZjOIuG z@t20QbE#>D;m$(y0~&gA>@(Tz?Li8QgrpYV=vdQ|uHT**|Lrq}OGb2EkeR5;fU&TE?ZZLf#XF*pNmp`14?e6Nt|}V#aM$b zh``s4=DmFek`!r~`byh^jQI6O!?*AnLfkRrGAqYw$d#5u;A9C za1d{l`g-#+a~l|i6y#IsNE&;*zRz;1+OB?^{rQN|``itKwBJX!<>`MnpM9vnp=dJr zOhSw{m&$X;CR{>ahLTU<8hjV+5zzw-&(E)$7^?>4o0~41uyM1uMBL|_$1%Zsp)jef z9i}cPEoyY*Ote6S@u0HE>G)l+Ng5Kdbau8xYCJNUcQRQ0tJR(L48y}Chwe%QHcQ)6 zL7PrvE3ciMEYd%w1EybM89}^D^}4KP(a8w1;2EjRW%RIgrv7D@`hItaPDq*ax3k$X zdEv_72P)!2^Sg1ZhR)a7emA!`YN;w*{P%v>m^;HNB4Bc~D;KqWq3+BSHf&(O%^ zgKW4e;}teqnMCdfm{4Var*Nb^dS^xB^TR%NiY415DTeRd?JrC0?Ca{2)D`k=t;4G< zl54A5n(&&Mf1imnd-bWcjKOeqh2t;16tt|f99X)YNKO2DSctn0-eI1E@M`bt@gGCQ ze}hWu0QKnoO)Df*J)nJ#%MHg1=r0bP#uSgS&KB9)ZTlE2g~EsB67mAKR;HsBJuKmW@SG zm^Eb*#i4!O?e(%@+isfL+Odt+wVKXVm&_$9(m{7$Kj|sSAG#QF%ANOP3BQxjAm!NT zDEbG6xc4W&X6ocJrcNw1lh?k6Lwx6#kD#d^6NOF zqR=!Aka*&OpO}@e%j4nk=U!&@`b{_@oyOdbs>bBf5;J)XkGQ%2u_tIa+(LxShA-eJ zJtdj)@x^BH>gws`2M<1q+v7!%Wjr1aGb$!Bp|HSAUVG~s_M zGh@;OtQHHZsy>Kd*-=6DRQ4&%bXbuYC=N z`1zxMrKP{PIqrVR*UfizHIJH=1iH4)#3nMXKQ6O-@gB0bj|odYr4+oufNJnUH~iCZ{eqp z{0Y0=hOUD@;O7TlyVFcw01KDC%U@quNQB)El2KlN`}I%FAdwA$?&rnm>fUL;)0|By9Q~BLbzh@?|j_zI_`rFe~*EN{GyYWT& z{PsuRF_TwAQwtCN^(m@r>xr=0@dpBw<~_yPg4Qd4-~2ltxEtG%n6N1u9;4cm6&a2WMed|V9AJ@QL4d9`^?l|1+QV*G(1pkuSyxc81*nOs_eBuRLEK3-nDoaYz4 zjVwv1nu;^h!ME=EqM5vg-EN+L^KD*uZ3zyCgP^M7h_La{55H|DufgFF{`%rVmcO^o ztWScf%3Du9$|bX=6CK*WPGroMm#S(sw|CIi*^STVBRVRIN#l#m!s;6sWKXCyBuNsQ zs*;!x&$xnIbDOrVZW@}J392fxWV9SolM*S+&BksscI?A#9UN|LC!hw6of1e(Nunq> z8%0sjb)CkRHk#Wy&_YK8vLum_mO@dkF@1=tsx-E=ak#C+JW7)!iM*@~ax>Eb2&yXe zjfZLP=t2%vQUIkz1!lz>2nMOCYoLE%5IOYPx~?<5e1cio`2#_AR`0{(^_s0AyUoVr z(h_soYPZMBj_SRrs%Dl=Omq|ziVJXrl6LRFAbSrS47JXTZQ|o%Dap?zGIW5@(cMGC z;THVWvA&H)wK=u_79lvMV2JWN(xDgHxlybSq7Ke7=NkjI(EB_arwFCHZG5s zy$2c?al6gmU8KW7Nq!FTu`v)j;;%c@gv;$Q%P-Oq!T7>_^LywY9HQ<}6K;3U(ZUQRgX+2l0Ho08PDx6jw5R|%R9-C|og8R9 zjEwOdx~7qxnNDF&mRY6^P0cj7cQQ)Xb&B(I$V^Q^3bnlU)*qz1_k;04vMf`SmrZ(d z5|Shl2nN}Epn?9uVe`G%Y*q@gvq(=dz6X!jN8O<&`UVD%+DD6Wb4W=v4xU_Y548uI z7#tch>k6yILRm>6aiN1)m)m1}4=xX~V(fo5tCflgk(3zE_`-aw7NhOa*452{Lx+#5k2BIzD9p*i653|8j?^^G z{Oq}z>Evc+poHFEePc82UELqlwX#fhdMbHY8Ay`Rif?FYroF4jXnCQd$O<``>1JK) z4+LmvYN4a6+bkPdmMPB5G0WKJ4^VsX5WRf^AJix4RFsZ0_t6tcx%2+9lb0X}f*_o& zQtrHe><$}(AP9nRHWSH95ClOu=ZNGb2!bG-b42nI1VIqaIU;!pf*=Uz9Fe>PK@fy< yj!0gDAPB-aM@qiqzJ9LeuF9*~fb%2Vvb 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 [!NOTE] +> +> * This field might support other values in future iterations as feature support evolves. + Benefits of Declaring Tier1 Support: - Enable your app to appear in shared and private channels. @@ -572,7 +576,12 @@ Update your app manifest and permissions to support shared and private channels - Omit this setting, and your app doesn't appear in shared or private channels. - Remove this setting later, and your app stops showing up in those channels. - Update your manifest with Resource Specific Consent (RSC) permissions, as many APIs now require them for shared/private channel functionality. -- Check the API documentation and confirm the RSC permissions required for your app. + +> [!NOTE] +> +> * RSC permissions are optional. +> * You can choose to use regular permissions instead. +> * RSC is one way to access resources, and its use depends entirely on the app’s design. ### Privacy & Security @@ -592,7 +601,7 @@ If you're having trouble installing the app in shared or private channels, check | Problem | Cause | Resolution | |--------|-------|------------| -| App doesn't appear in shared or private channels | `supportsChannelFeatures` not set in manifest | Add `'supportsChannelFeatures': 'tier 1'` in the app manifest. Reinstall the app. | +| App doesn't appear in shared or private channels | `supportsChannelFeatures` not set in manifest | Add `'supportsChannelFeatures': 'tier1'` in the app manifest. Reinstall the app. | | 403 error - Caller isn't enabled for requesting the [xyz] channel of shared channel type | App installed at team level but not added to the channel | Install the app both at the team level and the specific channel. | ### Membership & Identity Issues From 9ee9af12a0d02fecb5318c32d34936384000f3b7 Mon Sep 17 00:00:00 2001 From: KirtiJha-MSFT Date: Thu, 21 Aug 2025 12:30:10 +0530 Subject: [PATCH 42/44] Update the links --- ...eveloper-guidance-shared-private-channel.md | 6 +++--- .../concepts/build-and-test/image.png | Bin 0 -> 118020 bytes 2 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 msteams-platform/concepts/build-and-test/image.png diff --git a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md index e82aa741e85..7e76989590d 100644 --- a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md +++ b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md @@ -116,9 +116,9 @@ Microsoft Teams supports different types of channels—Standard, Private, and Sh ### Core Implementation Concepts for Shared and Private Channels - :::image type="content" source="../../assets/images/membership-types-shared-channels.png" alt-text=""This diagram shows how membership works in shared channels across organizations."::: - -:::image type="content" source="../../assets/images/membership-types-private-channels.png" alt-text="This diagram shows how direct membership works in a private channel."::: +![This diagram shows how membership works in shared channels across organizations.](../../assets/images/membership-types-shared-channels.png) + +![This diagram shows how direct membership works in a private channel.](../../assets/images/membership-types-private-channels.png) ### Channel Membership Basics diff --git a/msteams-platform/concepts/build-and-test/image.png b/msteams-platform/concepts/build-and-test/image.png new file mode 100644 index 0000000000000000000000000000000000000000..906ee267dbb7e44849662e57b203ce44afa1bf98 GIT binary patch literal 118020 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 z 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⋙0G7(kWY7aq1AZ}}8S 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 literal 0 HcmV?d00001 From 440ab5f9102372408c29446eee4b4a545ddbcbba Mon Sep 17 00:00:00 2001 From: SirajShaik-MSFT Date: Tue, 26 Aug 2025 14:19:00 +0530 Subject: [PATCH 43/44] Update app-developer-guidance-shared-private-channel.md --- ...pp-developer-guidance-shared-private-channel.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md index 7e76989590d..3455317753c 100644 --- a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md +++ b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md @@ -71,10 +71,8 @@ Before diving into implementation, learn about the different channel models avai > [!NOTE] > -> * Currently, only apps that include tabs are supported in private and shared channels in Microsoft Teams. -> * Tab apps in shared channels are available in [Government Community Cloud (GCC), GCC High, Department of Defense (DoD)](../cloud-overview.md#teams-app-capabilities), and [Teams operated by 21Vianet](../sovereign-cloud.md) environments. -> * SharePoint and the SharePoint pages apps aren't supported for shared channels in GCC, GCC High, DoD, and Teams operated by 21Vianet environments. -> * Bots and message extensions aren't supported in shared channels. +> - Tab apps in shared channels are available in [Government Community Cloud (GCC), GCC High, Department of Defense (DoD)](../cloud-overview.md#teams-app-capabilities), and [Teams operated by 21Vianet](../sovereign-cloud.md) environments. +> - SharePoint and the SharePoint pages apps aren't supported for shared channels in GCC, GCC High, DoD, and Teams operated by 21Vianet environments. In addition to channel models and capabilities, understand how your team app behaves in these environments. @@ -462,7 +460,7 @@ To support shared and private channels, set supportsChannelFeatures = tier1. > [!NOTE] > -> * This field might support other values in future iterations as feature support evolves. +> - This field might support other values in future iterations as feature support evolves. Benefits of Declaring Tier1 Support: @@ -579,9 +577,9 @@ Update your app manifest and permissions to support shared and private channels > [!NOTE] > -> * RSC permissions are optional. -> * You can choose to use regular permissions instead. -> * RSC is one way to access resources, and its use depends entirely on the app’s design. +> - RSC permissions are optional. +> - You can choose to use regular permissions instead. +> - RSC is one way to access resources, and its use depends entirely on the app’s design. ### Privacy & Security From fd0549af02a2897f3192200ee23c884dbfe88369 Mon Sep 17 00:00:00 2001 From: v-shgarcha Date: Fri, 5 Sep 2025 14:18:46 +0530 Subject: [PATCH 44/44] Update app-developer-guidance-shared-private-channel.md Updated content changes --- ...veloper-guidance-shared-private-channel.md | 94 ++----------------- 1 file changed, 10 insertions(+), 84 deletions(-) diff --git a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md index 3455317753c..f992f136d56 100644 --- a/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md +++ b/msteams-platform/concepts/build-and-test/app-developer-guidance-shared-private-channel.md @@ -7,7 +7,7 @@ ms.localizationpriority: high ms.topic: conceptual ms.date: 04/09/2025 --- -# Adapting Microsoft Teams App for Private and Shared Channels: A Developer's Guide +# Adapt Microsoft Teams App for Private and Shared Channels: A Developer's Guide As Microsoft Teams evolves, shared and private channels introduce new collaboration patterns that differ significantly from Standard channels. To function reliably and securely across all channel types, apps must become context-aware—specifically in terms of: @@ -26,9 +26,9 @@ This guide helps you understand the updates, best practices, and testing steps n ### What This Guide Covers? -- key concepts (membership, access, installation, storage) +- Key concepts (membership, access, installation, storage) - Implementation steps -- testing guidance +- Testing guidance - Best practices Before diving into implementation, learn about the different channel models available in Microsoft Teams. @@ -516,80 +516,6 @@ To make sure your app works smoothly in shared, private, and standard channels, - Test your app with all kinds of users—owners, members, guests, and external users—across every channel type and confirm everything works as expected. - Watch for updates in Microsoft Teams documentation and changelogs. For example, keep your app updated when APIs, permissions, or channel features change. -## Technical Appendix: Teams App Update Guide for Shared & Private Channel Support - -### Mandatory Updates for Teams Apps in Shared & Private Channels - -To ensure proper functionality in shared and private channels, all apps must include these updates. - -| Change Type | What to Do | Why It Matters | Example | -|-------------|------------|----------------|---------| -| **Mandatory** | Use the Channel Members API | Shared/Private channels have different members than the team. Using the wrong API can miss users or cause data leaks. | **Task app**: Assign tasks only to channel members, not all team members. | -| **Mandatory** | Access the Channel's SharePoint Site | Each channel has its own SharePoint. Using the team site can break file access or expose data. | **Document app**: Store and retrieve files from the channel’s SharePoint site. | -| **Mandatory** | Respect Channel Boundaries | Don’t access or post across channels unless the user allows it. | **Summary app**: Only summarize messages from channels the user opts into. | -| **Mandatory** | Update the App Manifest | Declare support for Shared/Private channels so your app shows up there. | **Any app**: Add `"supportsChannelFeatures": "tier1"` to your manifest. | - -### Optional UX Improvements for Shared & Private Channels - -These improvements enhance user experience and app reliability, but they're optional. - -| Area | What to Do | Why It Helps | Example | -|------|------------|--------------|---------| -| **Privacy & Access Controls** | Add logic to limit features for guests/external users | Keeps sensitive data safe and follows company policies | **Poll app**: Guests can vote, but only members can create polls or see results | -| **Collaboration Features** | Adjust tools based on channel roles and members | Prevents confusion and accidental changes by guests | **Whiteboard app**: Guests can draw, but not erase others’ work | -| **Smart Notifications** | Customize alerts by channel type and user role | Cuts down noise and makes alerts more useful | **Helpdesk app**: IT gets all alerts. vendors only see their tickets | - -### Context & Event Payloads - -Follow these guidelines to process events and payloads correctly in shared and private channels. - -- Use teamId for the host team and channelId for the shared channel in context and event payloads. -- Apply hostTeamId and hostTenantId when handling cross-tenant scenarios. -- Detect external users by comparing a user’s tenantId with hostTenantId. -- Listen for events like channelShared, channelUnshared, channelMemberAdded, and channelMemberRemoved to track changes in shared channels. -- Ensure your app is present in the channel so it receives these events. - -### API Changes - -Use the latest APIs to support shared and private channels. Earlier versions might have limited support. - -- Review the API Change Table in the Appendix for updates to Graph and Activity Payload Extensions (APX) APIs. -- Switch to the latest APIs that support shared and private channels. - -### Handling External Users - -Follow these steps to identify and manage external or guest users when your app is used across tenants. - -- Identify B2B Guests using role = guest in Graph or user role = guest in APX. -- Detect B2B Native users by comparing their tenantId with the hostTenantId from getContext(). -- Fetch members using /teams/{teamId}/channels/{channelId}/allmembers for tabs. -- Use channelMemberAdded and /v3/conversations/{conversationId}/pagedMembers to get members in bots. -- Classify users as external if their tenantId doesn’t match the host tenant. - -### Manifest and Permissions - -Update your app manifest and permissions to support shared and private channels and enable required capabilities. - -- Include supportsChannelFeatures = "tier1" in your app manifest so it supports shared and private channels. -- Omit this setting, and your app doesn't appear in shared or private channels. -- Remove this setting later, and your app stops showing up in those channels. -- Update your manifest with Resource Specific Consent (RSC) permissions, as many APIs now require them for shared/private channel functionality. - -> [!NOTE] -> -> - RSC permissions are optional. -> - You can choose to use regular permissions instead. -> - RSC is one way to access resources, and its use depends entirely on the app’s design. - -### Privacy & Security - -Follow these best practices to protect user data, respect privacy, and manage access in shared and private channels." - -- Use channel-specific APIs—don’t assume team members are also channel members. -- Access storage through channel-specific APIs and avoid cross-posting unless allowed. -- Respect privacy boundaries, and avoid leaking data between channels or user types. -- Handle internal users, B2B Guests, and B2B Direct Connect users correctly. -- Test all scenarios, including edge cases. ## Troubleshooting Guide @@ -672,21 +598,21 @@ If you have questions about shared or private channels, permissions, or function | Can I be part of a shared channel without being in the parent team? | Yes, shared channels allow external users to join if invited and granted permissions. | | Who can create shared or private channels? | Typically, team owners or users with specific permissions. Admins might restrict this capability via policy settings. | -### Access & Permissions +### Access and Permissions | Question | Answer | |----------|--------| -| Why can’t I see a private channel I was added to? | You must be a member of both the parent team and the private channel. Removal from the team revokes access. | +| Why can’t I see a private channel I was added to? | You must be a member of both the parent team and the private channel. Removal from the team revokes access to the channel. | | Can guests or external users access shared channels? | Yes, if both organizations enable external access and the user is explicitly invited. | -| How do I know if a channel is private or shared? | A lock icon indicates private channel. A link icon indicates shared channel = shared channel. | -| Why am I seeing an 'Access Denied' error when joining a shared channel? | Possible causes: incorrect invitation, disabled external access, or wrong account/tenant. | +| How do I know if a channel is private or shared? | A lock icon indicates a private channel. A link icon indicates shared channel = shared channel. | +| Why am I seeing an 'Access Denied' error when joining a shared channel? | Possible causes are incorrect invitation, disabled external access, or wrong account or tenant. | -### Functionality & Limitations +### Functionality and Limitations | Question | Answer | |----------|--------| | Can I add apps or tabs to a private channel? | Yes, but some apps might not be supported due to permissions or compatibility. Check before adding. | -| Are files in private channels stored differently? | Yes, they’re stored in a separate SharePoint site accessible only to channel members. | +| Are files in private channels stored differently? | Yes, they are stored in a separate SharePoint site accessible only to channel members. | | Can I convert a private channel to a shared channel (or vice versa)? | No, channel types are permanent. Create a new channel and migrate content manually. | -| What should I do if files or tabs aren’t loading in a channel? | Refresh the app/browser, clear cache, try another device, and verify permissions. | +| What should I do if files or tabs aren’t loading in a channel? | Refresh the app or browser, clear cache, try another device, and verify permissions. | | How do I report issues with shared or private channels? | Contact your IT admin or support team with: channel name, type, and error message or screenshot. |