-
Notifications
You must be signed in to change notification settings - Fork 532
[Doc Feature] [Apps in shared channels - Notification for indirect membership update and notification for team (host/non-host)[4532183] #13010
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
91f1a14
b78c851
14240ed
92bc6a2
de0eaad
5603149
d70b08b
50788a1
8eadbc1
ba24731
828b89a
5581e2a
74da053
158d22e
d55c734
fb841dc
db71823
2091911
f095a4c
d90fb70
ac4b8ba
d1c5586
b8c656a
8da9aa6
4f2522d
da43d36
54bc2b3
400a3b3
6d4ae24
295ca05
31413fa
3e4106b
1cbd3b9
2e21f8d
649a7b8
f118565
0327214
899384b
9400b3c
e683c69
3fcb62a
93d26f6
7c016ac
b5e7eba
b9b0b4a
7291883
369ff86
423df66
c068eda
60f9f78
01c2f31
2547022
19eaaa2
e4db921
6a9f3aa
1693d84
0b95c7a
ede47b3
b4dd91b
1c69a8c
33ccb33
c63dcca
6498775
2883bfa
429b3f1
4054381
1bb3302
657a0e6
a60d56a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,23 +8,29 @@ ms.topic: conceptual | |
ms.date: 04/09/2025 | ||
--- | ||
|
||
# Microsoft Teams Connect shared channels | ||
# Microsoft Teams connect shared channels | ||
|
||
Microsoft Teams Connect shared channels allow members of a channel to collaborate with users across other teams and organizations. You can create and share a shared channel with: | ||
Teams connect shared channels, which facilitates secure collaboration seamlessly. Allow external members outside of your organization to collaborate with internal users in Teams without changing their user context. You can create and share a shared channel with: | ||
|
||
* Members of another team within the same organization. | ||
* Individuals within the same organization. | ||
* Individuals and other teams of other organizations. | ||
* Members of another team within the same organization | ||
* Individuals within the same organization | ||
* Individuals and other teams of other organizations | ||
|
||
Shared channels ensure: | ||
|
||
* Enhanced user experience through cross-tenants collaboration | ||
* Secure granular access control | ||
* Real-time membership syncing | ||
|
||
A sample illustration showing shared channel membership is as follows: | ||
|
||
:::image type="content" source="~/assets/images/app-fundamentals/shared-channels-teams.png" alt-text="Diagram shows Team B from organization A and Team C from organization B collaborating in a shared channel as Team A."::: | ||
|
||
> [!NOTE] | ||
> | ||
> * 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. | ||
|
||
Teams Connect shared channels facilitate secure collaboration seamlessly. Allow external users outside of your organization to collaborate with internal users in Teams without changing their user context. Enhance user experience unlike using guest accounts, for example, the members must sign out of Teams and sign in again using a guest account. Teams applications extend the powerful collaboration space. | ||
|
||
:::image type="content" source="~/assets/images/app-fundamentals/shared-channels-teams.png" alt-text="Diagram shows Team B from organization A and Team C from organization B collaborating in a shared channel as Team A."::: | ||
|
||
## Enable your app for shared channels | ||
|
||
SupportedChannelTypes is an optional property that enables your app in non-standard channels. If your app supports the team scope and the property is defined, Teams enables your app in each channel type accordingly. Private and shared channels are supported. For more information, see [supportedChannelTypes](/microsoft-365/extensibility/schema/root#supportedchanneltypes). | ||
|
@@ -36,15 +42,9 @@ SupportedChannelTypes is an optional property that enables your app in non-stand | |
] | ||
``` | ||
|
||
> [!NOTE] | ||
> | ||
> * If your app supports the team scope, it functions in standard channels, regardless of what values are defined in this property. | ||
> * Your app might need to account for the unique properties of each of these channel types in order to function properly. | ||
> * Only **tabs** are currently supported in **private** and **shared** channels in Microsoft Teams. | ||
|
||
## Get context for shared channels | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ajay has validated and confirmed that it is happening
NehaHEDAU-MSFT marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
When the content UX is loaded in a shared channel, use the data received from `getContext` call for shared channel changes. `getContext` call publishes two new properties, `hostTeamGroupID` and `hostTenantID`, which are used to retrieve channel membership using Microsoft Graph APIs. `hostTeam` is the team that creates the shared channel. | ||
When the content UX is loaded in a shared channel, use the data received from `getContext` call for shared channel changes. `getContext` call publishes two new properties, `ownerGroupID` and `ownerTenantID`, which are used to retrieve channel membership using Microsoft Graph APIs. `hostTeam` is the team that creates the shared channel. | ||
|
||
For more information to enable your tab, see: | ||
|
||
|
@@ -60,71 +60,129 @@ You can collaborate with external members outside of your organization using sha | |
|
||
## Get shared channel membership | ||
|
||
You can get direct shared channel membership by using the `hostTeamGroupID` from `getContext` and following these steps: | ||
Use the [List allMembers API](/graph/api/channel-list-allmembers?view=graph-rest-beta&tabs=http&preserve-view=true) to retrieve both direct and indirect members of a shared channel. | ||
|
||
1. Get direct members with [GET channel members API](/graph/api/channel-list-members?view=graph-rest-beta&tabs=http&preserve-view=true) API. | ||
### Identify direct or indirect members | ||
|
||
```http | ||
GET /teams/{host-team-group-id}/channels/{channel-id}/members | ||
``` | ||
* Direct Members: Users who are added directly to the channel, including users from other tenants (cross-tenants). | ||
|
||
2. Get each shared team with GET `sharedWithTeams` API. | ||
* Indirect Members: Users who are members of the team, with which the channel is shared, including teams in the same tenant or in a cross-tenant. | ||
|
||
```http | ||
GET /teams/{host-team-group-id}/channels/{channel-id}/sharedWithTeams | ||
``` | ||
Additionally, you can identify whether a member of a shared channel is direct or indirect by checking the **@microsoft.graph.originalSourceMembershipUrl** annotation. This property identifies the source of a member’s access to a shared channel, as shown in the following table. | ||
|
||
3. Use GET members of each shared team (Team X) with GET `sharedWithTeams` API. | ||
|Member Type |Annotation Present? |Description | | ||
|---------|---------|---------| | ||
|Direct Member | **Yes** | The user is added directly to the shared channel. | | ||
|Indirect Member| **Yes** | The user accesses the shared channel through another team. The *@microsoft.graph.originalSourceMembershipUrl* property includes a URL that points to the source team and indicates that the user is an indirect member of the shared channel. | | ||
|
||
```http | ||
GET /teams/{host-team-group-id}/channels/{channel-id}/sharedWithTeams/{teamX}/members | ||
``` | ||
> [!NOTE] | ||
> You might receive duplicate notifications when a member is added to a shared channel. This scenario can happen if the member is already part of the shared channel directly or through another linked team. Use the **List allMembers API** to view all the direct and indirect members. | ||
> Ignore the notification if the member already exists; either directly or indirectly. | ||
|
||
## Classify members in the shared channel as in-tenant or out-tenant | ||
## Get app notifications for direct and indirect membership changes | ||
|
||
You can classify members as in-tenant or out-tenant by comparing `tenantID` of the member or team with `hostTeamTenantID` as follows: | ||
Apps installed in shared channels receive notifications when users are added to or removed from a team that shares the channel. To receive these notifications, you must: | ||
|
||
1. Get the member you wish to compare. | ||
1. [Install the app](../deploy-and-publish/apps-upload.md) in a host team and enable it for the shared channel. | ||
1. Create a valid Microsoft Graph change notification subscription to monitor associated team membership changes and shared or unshared events using supported APIs. | ||
|
||
```http | ||
GET /teams/{host-team-group-id}/channels/{channel-id}/members | ||
``` | ||
To receive both direct and indirect member update notifications, you must include both the query string parameters when creating a subscription. If the query strings aren't provided, the subscription only delivers notifications for direct member updates. To learn more, see [Channel membership access](/graph/teams-changenotifications-channelmembership). | ||
|
||
2. Use `getContext`, compare the `tenantID` of the member to the `hostTenantID` property. | ||
```http | ||
`/teams/{team-id}/channels/getAllMembers?notifyOnIndirectMembershipUpdate=true&suppressNotificationWhenSharedUnsharedWithTeam=true` | ||
``` | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We also should update the new subscription that supports /shared with teams. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added the documentation for the new subscription that supports /shared with teams. We have tested and added it to the sample code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should add this line in a http markdown or something similar. Also, add the the link for channel membership for easy access?https://learn.microsoft.com/en-us/graph/teams-changenotifications-channelmembership There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
<a name='azure-ad-native-identity'></a> | ||
This subscription enables apps to monitor membership changes in shared channels and its associated teams. For more information on how to create a Microsoft Graph change notification subscription, see [Create a subscription.](/graph/teams-changenotifications-teammembership) | ||
|
||
## Microsoft Entra native identity | ||
### Validate user access for membership updates | ||
|
||
When an app receives a 'member removed' notification for an indirect membership update, it’s important to verify whether the user is removed from the shared channel, especially since the same user might have both direct and indirect membership. For example, if a user is removed from a team that shares a channel, the app should confirm whether the user's access to the shared channel is revoked. | ||
Use the **doesUserHaveAccess** API to determine whether the user is removed from the shared channel. | ||
See [doesUserHaveAccess API](/graph/api/channel-doesuserhaveaccess?view=graph-rest-beta&tabs=http&preserve-view=true) to learn more about user accesses and relevant permissions. | ||
|
||
```http | ||
GET /teams/{team-id}/channels/{channel-id}/doesUserHaveAccess(userId='@userid',tenantId='@TenantID',userPrincipalName='@UserPrincipalName') | ||
``` | ||
|
||
When a member receives a 'member added' notification for an indirect membership update, | ||
See [allMembers API](/graph/api/channel-list-allmembers?view=graph-rest-beta&branch=pr-en-us-27360&tabs=http&preserve-view=true), to refresh the list of all member. | ||
|
||
```http | ||
GET /teams/{team-id}/channels/{channel-id}/allMembers | ||
``` | ||
|
||
Apps must function cross-tenants in installation and usage. The following table lists the channel types and their corresponding group IDs: | ||
### Handle bulk membership changes | ||
|
||
|Channel type| groupId | hostTeamGroupId | | ||
|----------|---------|-----------------| | ||
|Regular | Team Microsoft Entra group ID | Team Microsoft Entra group ID | | ||
|Shared | Empty | Host Team Microsoft Entra group ID | | ||
If there are bulk membership changes, Teams curbs individual membership update notifications when a channel is shared or unshared with a team. This feature reduces notification volume and improves performance. | ||
|
||
## Apps in federated group chats with external users | ||
#### Use sharedWithTeams Subscription for Bulk Membership Changes | ||
|
||
To reduce notification overload during membership updates, such as when a shared channel is added to or removed from a team with thousands of members, use the new SharedWithTeams subscription resource: | ||
|
||
`/teams/{team-id}/channels/{channel-id}/sharedWithTeams` | ||
|
||
The sharedWithTeams subscription sends a single notification when a channel is shared or unshared with a team. It avoids thousands of per-user notifications and improves performance for apps that monitor membership changes. Ensure that you update the shared channel member list using the [allMembers](/graph/api/channel-list-allmembers?branch=main&branchFallbackFrom=pr-en-us-13010&view=graph-rest-1.0&tabs=http&preserve-view=true) API after receiving a 'shared with' or 'unshared from' team notification. | ||
|
||
> [!NOTE] | ||
> To support membership updates in shared channels, apps using resource-specific consent (RSC) must request extended permissions. | ||
> These permissions let the app: | ||
> | ||
> * Apps in federated group chats with external users aren't available in [Government Community Cloud (GCC), GCC High, Department of Defense (DoD)](../cloud-overview.md#teams-app-capabilities), and [Teams operated by 21Vianet](~/concepts/sovereign-cloud.md) environments. | ||
> * Apps aren't supported in one-on-one chats, channels, or meetings with external users. | ||
> * Access membership data (both direct and indirect members). | ||
> * Receive and respond to membership change notifications. | ||
|
||
### Manage indirect membership in shared channels | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You may also list does user have access api since that is newly added to this list to manage membership There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added to the list |
||
|
||
You can manage indirect membership in shared channels using the following Microsoft Graph APIs: | ||
|
||
* Use [allMembers](/graph/api/channel-list-allmembers?branch=main&branchFallbackFrom=pr-en-us-13010&view=graph-rest-1.0&tabs=http&preserve-view=true) API to retrieve all users who are members of a specific channel. | ||
|
||
```http | ||
GET /teams/{team-id}/channels/{channel-id}/allMembers | ||
``` | ||
|
||
* Use [doesUserHaveAccess API](/graph/api/channel-doesuserhaveaccess?view=graph-rest-beta&tabs=http&preserve-view=true) API to determine whether the user is removed from the channel and view all user accesses and relevant permissions. | ||
|
||
```http | ||
GET /teams/{team-id}/channels/{channel-id}/doesUserHaveAccess(userId='@userid',tenantId='@TenantID',userPrincipalName='@UserPrincipalName') | ||
``` | ||
|
||
Teams supports the use of apps in federated group chats with external users. These users can't add, update, or remove apps from the group chat. Only the host of the group chat can add, update, or remove apps. However, all members of the chat, including external users, can use apps under the following conditions: | ||
* Use [sharedWithTeams](/graph/api/sharedwithchannelteaminfo-list?branch=main&branchFallbackFrom=pr-en-us-13010&view=graph-rest-1.0&tabs=http&preserve-view=true) API to list all teams a channel is shared with. | ||
|
||
* The tenant admin of the group chat host's organization and the tenant admin of the external user's organization must allow the use of the app in federated group chats. For more information, see [Teams apps for external attendees or guests from outside an organization](/microsoftteams/apps-external-users). | ||
* The app allows access to external users in federated group chats. | ||
```http | ||
GET /teams/{team-id}/channels/{channel-id}/sharedWithTeams | ||
``` | ||
|
||
If you're developing an app for use in federated group chats with external users, register your app as a multitenant app in Microsoft Entra ID. This action allows users across multiple organizations to access your app. | ||
* Use the [allowedMembers](/graph/api/sharedwithchannelteaminfo-list-allowedmembers?branch=main&branchFallbackFrom=pr-en-us-13010&view=graph-rest-1.0&tabs=http&preserve-view=true) API to retrieve users from a shared team who can access a shared channel. | ||
|
||
```http | ||
GET /teams/{team-id}/channels/{channel-id}/sharedWithTeams/{sharewithteamsId}/allowedMembers | ||
``` | ||
|
||
> [!NOTE] | ||
> If you want to test the [code sample](#code-sample) with an external user in a federated group chat, you must first add the external user as a guest to your tenant. For more information, see [Quickstart: Add a guest user and send an invitation](/entra/external-id/b2b-quickstart-add-guest-users-portal). After adding the user to the tenant, go to the federated group chat and add the guest to test the app. | ||
> `allowedMembers` API returns only newly associated users and doesn't apply to unshared events. | ||
|
||
## Classify shared channel members as in-tenant or out-tenant | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since we are talking about shared channel here, replace members api with allMembers api. That will show cross tenant for both direct and indirect members. Please rephrase this section as needed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added allMembers api. Content reflects the as-is process, as confirmed with Ajay. |
||
|
||
You can classify members as in-tenant or out-tenant by comparing the `TenantId` of the member or team with `ownerTenantId` as follows: | ||
|
||
1. Get the TenantId of the member you wish to compare. | ||
|
||
```http | ||
GET /teams/{host-team-group-id}/channels/{channel-id}/allMembers | ||
``` | ||
|
||
2. Call microsoftTeams.app.getContext() in your tab from the Teams JavaScript client library (**TeamsJS SDK**). | ||
The getContext() call returns context of the shared channel, which contains the details such as **displayName**, **membershipType**, **ownerGroupId** , and **ownerTenantId**. | ||
|
||
3. Compare the `TenantId` of the member to the `ownerTenantId` property | ||
<a name='azure-ad-native-identity'></a> and determine if the member is an in-tenant or out-tenant. | ||
|
||
## Code sample | ||
|
||
| Sample name | Description | Node.js | | ||
|-------------|-------------|------|----| | ||
| Teams Conversation Bot | This sample app displays the names of the members in a federated group chat with external users. |[View](https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/bot-feed-members/nodejs/)| | ||
| Sample name | Description | .NET | Node.js | Python | | ||
|-------------|-------------|------|----|------|----| | ||
| Teams Conversation Bot | This sample app displays the names of the members in a federated group chat with external users.| NA |[View](https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/bot-feed-members/nodejs/) | NA | | ||
| Membership change notification | The sample application demonstrates how to send notifications for shared channel events in Microsoft Teams. Scenarios include users being added, removed, or membership being updated and when channel is shared or unshared with a team. | [View](https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/membershipChangeNotificationNodejs/samples/graph-membership-change-notification/csharp) |[View](https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/membershipChangeNotificationNodejs/samples/graph-membership-change-notification/nodejs) | [View](https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/membershipChangeNotificationNodejs/samples/graph-membership-change-notification/python) | | ||
|
||
## See also | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this is changing. Can you please sync with Gaurav to update this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes in new manifest versions supportedChannelFeatures will be rolled out, and supportedChannelTypes will not be available.
supportedChannelTypes will continue to be in the versions before this feature. However, since the future release cycle is TBD, we will document that after release.