Shared Channel support comes to Microsoft Graph: 10 new API calls, 2 known issues
As announced last month, Microsoft Teams Connect shared channels is now rolling out to public preview. Now, we are seeing the Microsoft Graph REST API updated with new API calls built for shared channels, new functionality for developers and updated examples.
In the blog post are all the new Graph calls for shared channels, what they do, what’s been updated and what to watch out for.
What are the new API calls?
Firstly, there is a new API call on the /Users endpoint. There was already a call for “List joined teams” which listed which teams a user is a member of. There is now another call – “List associated teams” which lists teams a user is a member of and any teams where the user is a member of a shared channel in that team.
Differently from the “List joined teams” call, this new call also includes the tenant ID in the response so you can identify the difference between teams in the user’s home tenant, and any shared teams:
HTTP/1.1 200 OK
Content-Type: application/json
{
"value": [
{
"@odata.type": "#microsoft.graph.associatedTeamInfo",
"id": "b695c5a5-c5a5-b695-a5c5-95b6a5c595b6",
"tenantId": "c013e718-a232-430e-a128-c83bc5c1b103",
"displayName": "Contoso Team"
},
{
"@odata.type": "#microsoft.graph.associatedTeamInfo",
"id": "b695c5a5-8934-b695-a5c5-95b6a5c595b6",
"tenantId": "b1a95649-cf51-461e-844b-64933b316d9c",
"displayName": "ThoughtStuff Team"
}
]
}
Then, there are lots of new new methods on the /Channels endpoint.
Viewing Shared Channels
There was already a “List channels” method, but now there are new “List incoming channels” and “List all channels” methods. The “List all channels” method includes both channels in the teams and channels shared with the team. There is a membershipType property of “shared” to identify those, and the tenantId is also included:
HTTP/1.1 200 OK
Content-Type: application/json
{
"value": [
{
"@odata.id": "https://graph.microsoft.com/beta/tenants/b3246f44-b4gb-4627-96c6-25b18fa2c910/teams/893075dd-5678-4122-925f-022c42e20265/channels/19:561fbdbbfca848a484f0a6f00ce9dbbd@thread.tacv2",
"id": "19:561fbdbbfca848a484f0a6f00ce9dbbd@thread.tacv2",
"createdDateTime": "2020-05-27T19:22:25.692Z",
"displayName": "Contoso Sales channel",
"description": "channel created in Contoso to be shared with other teams/tenants.",
"membershipType": "shared",
"tenantId": "b3246f44-b4gb-4627-96c6-25b18fa2c910"
}
]
}
There are no additional permissions needed to see shared channels – it’s the same as reading a “normal” channel in a team.
Known Issue: Bad odata.id values
There is currently a known issue with the values of the @odata.id property that are returned from the “List incoming channels” and “List all channels” method. You ought to be able to call the URL that’s returned from the @odata.id property to get more information about the object, but doing this with these values will fail with the message:
“TenantId in the optional tenants/{tenantId} segment should match the tenantId(tid) in the token used to call Graph.”
To workaround this issue, remove the /tenants/{tenant-id} part from the URL provided in @odata.id.
Removing Shared Channels
There’s a new API method called Remove incoming channel to remove a shared channel (called an incoming channel in the documentation), which is a DELETE method call that requires the Channel.Delete.All permission, and takes the ID of the teams and ID of the shared channel (which you could get from List incoming channels):
DELETE /teams/{teamsId}/channels/{channelId}/sharedWithTeams/{sharedWithChannelTeamInfoId}
Creating Shared Channels
Today, although the API documentation details how to create a shared channel, there is a warning that support for this is not widely available. The workaround is to manually create a shared channel using the Teams client until using the API is supported:
It looks like the creation process will be very similar to creating a private team, but using a membershipType of shared instead of private.
However, there is an important change happening with the response type. Today, when creating a channel the API will return a 201 created response with the channel object in the body.
When creating a shared channel however, the API will return a 202 Accepted response, and the response body will contain a link to a teamsAsyncOperation. Presumably this is because shared channels take longer to create and so a synchronous API call might time-out before they complete.
For developers creating channels and validating response code this is something to be aware of: different channel types will generate different response codes and payload.
Managing which teams have access to a shared channel
There are new API methods to give visibility and management to which teams are seeing a shared channel as well.
Firstly, the “List teams shared with channel” provides a list of all the teams and their tenant IDs that the channel is shared with. Notice as well that this includes the team that “owns” the channel in the home tenant, the “host team”:
HTTP/1.1 200 OK
Content-Type: application/json
{
"value": [
{
"@odata.type": "#microsoft.graph.sharedWithChannelTeamInfo",
"id": "2173de69-de69-2173-69de-732169de7321",
"tenantId": "95d7faf8-39c5-4d44-b270-40ebffcefff5",
"displayName": "ThoughtStuff",
"isHostTeam": true
},
{
"@odata.type": "#microsoft.graph.sharedWithChannelTeamInfo",
"id": "893075dd-2487-4122-86db-022c42e20265",
"displayName": "ACME Corp",
"isHostTeam": false,
"tenantId": "04ed602b-4430-4f75-ba1d-7bd06314692f"
}
]
}
There is also a “Get teams shared with channel” API call which takes the ID of the team and returns a single object instead of the array shown above. The actual object is the same though, so this call is of limited value.
If you want to remove a team from this list (and remove its ability to access the shared channel) then you can make a DELETE method call using the “Unshare channel with team” method, passing in the ID of the team:
DELETE /teams/{teamsId}/channels/{channelId}/sharedWithTeams/{sharedWithChannelTeamInfoId}
Can I see who has access to my shared channel in other tenants?
Yes! If you have a shared channel which users in other tenants have access to, you can get a list of members by calling the “List allowed members” method.
There are some caveats thought: this method doesn’t return any users with the Guest role, or any users who are externally authenticated in the tenant.
For those users that are returned, however, the tenant ID and user ID are provided, as well as the display name and email address:
HTTP/1.1 200 OK
Content-Type: application/json
{
"value": [
{
"@odata.type": "#microsoft.graph.conversationMember",
"id": "MmFiOWM3OTYtMjkwMi00NWY4LWI3MTItN2M1YTYzY2Y0MWM0IyNlZWY5Y2IzNi0wNmRlLTQ2OWItODdjZC03MGY0Y2JlMzJkMTQ",
"roles": [
"owner"
],
"displayName": "Eric Solomon",
"userId": "eef9cb36-06de-469b-87cd-70f4cbe32d14",
"email": "ericsol@fabrikam.com",
"tenantId": "df81db53-c7e2-418a-8803-0e68d4b88607"
},
{
"@odata.type": "#microsoft.graph.conversationMember",
"id": "MmFiOWMFxTYtMjkwMi00NWY4LWI3MTItN2M1YTYzY2Y0MWM0IyNlZWY5Y2IzNi0wNmRlLTQ2OWItODdjZC03MGY0Y2JlMzJkMTQ",
"roles": [
"user"
],
"displayName": "Caleb Foster",
"userId": "eef9cb36-06de-469b-87cd-70f4cbe32d14",
"email": "calfos@fabrikam.com",
"tenantId": "df81db53-c7e2-418a-8803-0e68d4b88607"
}
]
}
Adding new users to shared channels
The “Add member” method for Channels has been updated to support adding users from other tenants to a shared channel. As a reminder, to add a user from the same tenant to a channel, a developer can perform a POST method with a payload similar to this:
POST https://graph.microsoft.com/beta/teams/{teamId}/channels/{channelId}/members
Content-type: application/json
{
"@odata.type": "#microsoft.graph.aadUserConversationMember",
"roles": [],
"user@odata.bind": "https://graph.microsoft.com/beta/users/24b3819b-4e1d-4f3e-86bd-e42b54d0b2b4"
}
In contrast, to add a user who is a member of a different tenant to a shared channel, use the same payload but with the addition of the tenant ID:
POST https://graph.microsoft.com/beta/teams/{teamId}/{channelId}/members
Content-type: application/json
{
"@odata.type": "#microsoft.graph.aadUserConversationMember",
"roles": [],
"user@odata.bind": "https://graph.microsoft.com/beta/users/bc3598dd-cce4-4742-ae15-173429951408",
"tenantId": "a18103d1-a6ef-4f66-ac64-e4ef42ea8681"
}
Can I tell if a user has access to a shared channel or not?
Finally, there is a new API method which can be used to check if a user has access to a shared channel, called “Check user access“. This method can be used to check both users in the home tenant and also users in any other tenant.
It’s a slightly unusual format, where the User ID (and Tenant ID if supplied) are passed across the URL as parameters.
For checking a user in the home tenant:
GET https://graph.microsoft.com/beta/teams/{teamID}/channels/{sharedChannelID}/doesUserHaveAccess(userId='6285581g-484b-4845-9e01-60667f8b12ae')
For internal users (only) you can also use the UPN:
GET https://graph.microsoft.com/beta/teams/{teamID}/channels/{sharedChannelID}/doesUserHaveAccess(userPrincipalName='joe.blogs@contoso.com')
For checking a user in another tenant:
GET https://graph.microsoft.com/beta/teams/{teamID}/channels/{sharedChannelID}/doesUserHaveAccess(userId='62855810-484b-4823-9e01-60667f8b12ae', tenantId='57fb72d0-d811-46f4-8947-305e6072eaa5')
In both cases the result is a simple Boolean indicating whether or not the user is a member of the channel.
All the new and updated Shared Channel API calls in one place
- Users
- Channels
- Known Issues