The Microsoft Graph endpoints for Teams are not something new. You can easily find online multiple blog posts containing sample requests on how to retrieve the teams that a user is a member of. Instead, in this blog post, I will share some code blocks that I used to accomplish this on a SharePoint Framework project.
A sample SharePoint Framework web part solution (react-my-teams) can be found on the PnP Web Part Samples repository once the pull request is merged.
Feel free to use the solution as a starting point and implement the user interface to your needs. And you are also welcome to submit updates to it 🙂
Setting required API permissions
The SharePoint Framework project will use the MSGraphClient to retrieve data from Microsoft Graph. In order to be allowed to get the data we need, we will need to request the following permissions (declared on package-solution.json):
"webApiPermissionRequests": [
{
"resource": "Microsoft Graph",
"scope": "User.ReadWrite.All"
},
{
"resource": "Microsoft Graph",
"scope": "Group.ReadWrite.All"
}
]
Alternatively, you can use the Office 365 CLI to grant the required permissions. This blog post will give you all the info you need.
Get Tenant information
In order to open Teams channel links on the client application, you need to include the tenant Id as one of the URL parameters. You can get the Tenant Id using the code below
private _getTenantInfo = async (): Promise<ITenant> => {
let tenant: ITenant = null;
try {
const tenantResponse = await this._graphClient.api('organization').select('id').version('v1.0').get();
tenant = tenantResponse.value as ITenant;
console.log(tenant);
} catch (error) {
console.log('Error getting tenant information');
}
return tenant;
}
Get teams a user is a member of
The me/joinedTeams Graph endpoint will return the teams for the user. The following code block will allow you to get the data
private _getTeams = async (): Promise<ITeam[]> => {
let myTeams: ITeam[] = [];
try {
const teamsResponse = await this.props.graphClient.api('me/joinedTeams').version('v1.0').get();
myTeams = teamsResponse.value as ITeam[];
} catch (error) {
console.log('Error getting teams');
}
return myTeams;
}
Get team channels
Next, you will need to retrieve the channels for a given team. This will allow us to get the information of the default channel (General) that we will use on the links.
private _getTeamChannels = async (teamId): Promise<IChannel[]> => {
let channels: IChannel[] = [];
try {
const channelsResponse = await this.props.graphClient.api(`teams/${teamId}/channels`).version('v1.0').get();
channels = channelsResponse.value as IChannel[];
} catch (error) {
console.log('Error getting channels for team ' + teamId);
}
return channels;
}
Dynamically building the links on click
To improve performance on page load, we only load the list of teams by default. The channels information is only loaded when the user clicks on the link, which is then used to generate the final link that will take the user to Teams.
The link will look something like this:
<a href="#" title='Click to open channel' onClick={this._openChannel.bind(this, team.id, this.props.tenantId)}>
<span>{team.displayName}</span>
</a>
And the following code will generate the required Teams link and open the selected team on Teams (browser or client App)
private _openChannel = async (teamId: string, tenantId: string): Promise<void> => {
let link = '#';
const teamChannels: IChannel[] = await this._getTeamChannels(teamId);
const channel = teamChannels[0];
if (this.props.openInClientApp) {
link = `https://teams.microsoft.com/l/channel/${channel.id}/${channel.displayName}?groupId=${teamId}&tenantId=${tenantId}`;
} else {
link = `https://teams.microsoft.com/_#/conversations/${channel.displayName}?threadId=${channel.id}&ctx=channel`;
}
window.open(link, '_blank');
}
Enjoy!
Hello Joel, thank you for the great article.
Just a heads up on webApiPermissionRequests object. You can omit the Read scope when you use the ReadWrite – the ReadWrite always overlaps and ignores the Read
Hey Carlos! Good spot will update now.