Dynamics 365 entities, like accounts or opportunities, can be displayed inside of a tab on a Microsoft Teams channel. The tab can be added manually with just few simple steps, but sometimes it might be needed to automatically provision the tab, for example linking an account to General channel during team creation.

On this blog post I’ll go through the basics what are required when provisioning Dynamics 365 tab and to make collaboration integration work correctly. For examples I’m using Flow created with Power Automate. Flow creates a new team, when new account is created, and configures Dynamics 365 tab.

Adding a Dynamics 365 tab manually

For configuring a Dynamics 365 tab for the first time, Environment and Dynamics 365 sales app needs to be selected.

Configure Dynamics 365 tab

After that is done, only thing needed is searching and picking a Dynamics 365 entity to be displayed.

Configure Dynamics 365 tab

And when checked from Dynamics 365 side, clicking Collaborate button on that linked entity it shows that connection is made.

Collaboration entity on Dynamics 365

Seems fairly easy to reproduce in provisioning solution.

Dynamics 365 tab configuration

There isn’t actually official documentation what is required for Dynamics 365 tab configuration. Easiest way to discover tab configuration is utilizing Microsoft Graph Explorer (https://developer.microsoft.com/en-us/graph/graph-explorer/preview) and reading configuration from a Teams channel, where tab is already configured.

Here is the complete Dynamics 365 tab configuration fetched from Graph API (HTTP GET: https://graph.microsoft.com/v1.0/teams/<team id>/channels/<channel id>/tabs).

{
    "id": "535c1c4e-05ea-4ece-948e-f1f0605c1a72",
    "displayName": "D365",
    "webUrl": "https://teams.microsoft.com/l/channel/19%3a679cea04927947f3b5600c036a26ea4b%40thread.skype/tab%3a%3a9a2016df-9080-4cce-afd2-8ec94b50bdd4?webUrl=https%3a%2f%2forg-x.crm4.dynamics.com%2fmain.aspx%3fappid%3d10d23763-ba41-ea11-a813-000d3a6542c9%26pageType%3dentityrecord%26etn%3daccount%26id%3d714ce340-3b64-ea11-a811-000d3a654ce0&label=D365&groupId=cf373130-41cf-4556-9717-0d3bfdd9a655&tenantId=a8e7d2ad-32f9-4ee6-9fbe-f8ebe1f48871",
    "configuration": {
        "entityId": null,
        "contentUrl": "https://msteamstabintegration.crm.dynamics.com/Home/Bootstrapper#pageType=dynamics-host&dynamicsUrl=https%3A%2F%2Forg-x.crm4.dynamics.com%2Fmain.aspx%3Fappid%3D10d23763-ba41-ea11-a813-000d3a6542c9%26pageType%3Dentityrecord%26etn%3Daccount%26id%3D714ce340-3b64-ea11-a811-000d3a654ce0%26navbar%3Doff%26flags%3DFCB.AllowLegacyDialogsInUci%3Dfalse",
        "removeUrl": "https://msteamstabintegration.crm.dynamics.com/Home/Bootstrapper#pageType=tab-remove",
        "websiteUrl": "https://org-x.crm4.dynamics.com/main.aspx?appid=10d23763-ba41-ea11-a813-000d3a6542c9&pageType=entityrecord&etn=account&id=714ce340-3b64-ea11-a811-000d3a654ce0"
    }
}

Sections needed for provisioning are contentUrl, removeUrl and websiteUrl. Teams AppId is also required, which is for Dynamics 365 tab cd2d8695-bdc9-4d8e-9620-cc963ed81f41.

Example: Creating a team and a Dynamics 365 tab with Power Automate

For adding a Dynamics 365 tab to display an entity on Teams channel, you need to add Dynamics 365 app to a team, add a new tab to a channel and create Microsoft Teams Collaboration entity to Common Data Service (CDS). On my example I’m also provisioning a new team, when new Account is created on Dynamics 365.

Required parameters

For building a tab call these parameters are needed. For Dynamics, open an entity and you can get all needed parameters from the browser.

  • Environment – first part of Dynamics 365 Url, for examples https://org-x.crm4.dynamics.com
  • (Sales) AppId – Query string parameter appid
  • Organization ID – found from Dynamics on Setting -> Customizations -> Developer Resources and there Instance Reference Information

And when utilizing Power Automate, you need to create a new app registration to Azure AD and consent Group.ReadWrite.All permission to Microsoft Graph API, and use Tenant ID, Client ID and Client Secret on HTTP actions to call Graph.

More information about creating an Azure AD App Registration can be found here: https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app

My suggestion is to add all the required parameters as variables or store variables on a custom Common Data Service configuration entity.

Flow trigger

Flow is triggered with When a record is created CDS trigger and it trigger, when new Account entity is created.

CDS trigger for new accounts

Creating a team

For creating a team, first correct user id is needed from CDS. In the example the account owner is added as a team owner. For getting correct user id, Get record CDS action is used with returned Owner id from the trigger.

Get user from CDS

Next team is created with HTTP action. Action call Microsoft Graph Beta API teams endpoint. Entity name is the account name from the trigger, it is just added as a variable. For owners data bind user id is azureactivedirectoryobjecid, which is returned from Get User CDS action. Dynamics 365 teams app is also to newly created team in the same call.

Create a team

Body of the call:

{
"template@odata.bind": "https://graph.microsoft.com/beta/teamsTemplates('standard')",
"displayName": "@{variables('EntityName')}",
"description": "",
"owners@odata.bind": [
"https://graph.microsoft.com/beta/users('@{body('Get_User')?['azureactivedirectoryobjectid']}')"
],
"installedApps": [
{
"teamsApp@odata.bind": "https://graph.microsoft.com/v1.0/appCatalogs/teamsApps/cd2d8695-bdc9-4d8e-9620-cc963ed81f41"
}
]
}

After the call, id of the newly created team needs to be retrieved. The simple way is to just add a delay and parse the id from the Location header of the returned object, because usually team is created within seconds.

Location: /teams/{teamId}/operations/{operationId}

For my example I created a loop, which handles the status returned from Create Team call defined in Location header.

Handling team creation response

Creating a Dynamics 365 tab

A tab is created simply by doing a HTTP POST call to Graph’s tab endpoint.

https://graph.microsoft.com/v1.0/teams/<team id>/channels/<channel id>/tabs

More info: https://docs.microsoft.com/en-us/graph/api/teamstab-add?view=graph-rest-1.0

I have created variables for ContentUrl and WebUrl parameters, where Environment and SalesAppId are variables described earlier, EntityType is account and EntityId is accountid returned from the trigger.

ContentUrl variable
WebUrl variable

Channel id the the General channel on newly created team is also needed and it can be retrieved by calling:

https://graph.microsoft.com/beta/teams/<team id>/primaryChannel
Get General Channel

In my example channel id is also set as variable for later use.

Next Dynamics 365 tab can be created.

Create a Dynamics 365 tab call

After running the call, Dynamics 365 tab is visible on the channel.

Dynamics 365 tab on Teams

Creating a Teams collaboration entity to CDS

Finally Microsoft Teams Collaboration entity needs to be added to Common Data Service, otherwise collaboration features are not working correctly on the Dynamics 365 entity.

What needs to be added?

To see what is actually added to Common Data Service, add a tab to a channel using Teams in the browser. Using browser’s developer tools, you can see that HTTP POST call is made to PostPinTasks endpoint with CrmTeamsCollabEntity object.

CrmTeamsCollabEntity object

Next table describes properties of CrmTeamsCollabEntity.

PropertyProperty on CDS actionValue
RegardingObjectIDRelated Dynamics 365 Record IDID of the Dynamics 365 Entity
RegardingObjectTypeRelated Dynamics 365 Record ID (Entity Code)Dynamics 365 entity type code
RegardingObjectTypeNameRelated Dynamics 365 Record Type NameDynamics 365 entity type name
msdyn_ChannelFolderRelativeUrlCollaboration Channel Relative Folder URLTeams Channel Folder URL, i.e. /sites/<team name>/<channel name>
msdyn_ChannelIDCollaboration Channel IDTeams Channel ID
msdyn_ChannelNameCollaboration Channel NameTeams Channel Name
msdyn_ChannelTypeCollaboration Channel TypeTeams channel type (regular/private)
msdyn_GroupIDCollaboration Group IdentifierTeam id
msdyn_TeamIDCollaboration Team IDTeams channel id
msdyn_TeamNameCollaboration Team NameTeam Name
msdyn_TeamSiteURLTeam Site UrlURL of the underlying team site on SharePoiint
msdyn_TenantIDCollaboration Tenant IdentifierTenant ID
msdyn_WebUrlCollaboration tab web urlTab web url (from tab configuration)
msdyn_appIdCollaboration app id which was used to pinID of the Dynamics 365 Entity
msdyn_ContentUrlCollaboration tab content urlTab content url (from tab configuration)
msdyn_pipedEntityIdCollaboration piped entity id which was usedContains Dynamics 365 organization id, Sales app id, entity id, entity code and entity name

Retrieve the required parameters and create a CDS entity

For getting all required information, two Graph API calls are needed to get Url of the underlying team site, channel folder Url and Url of the default Documents library.

Get Documents library
Get SharePoint Team Site

Finally Microsoft Teams Collaboration Entity can be created.

Create CDS Collaboration entity

Next table explains properties, which are added as expressions

PropertyValue
Collaboration Channel Relative Folder URLReplacing ‘%20’ with ‘ ‘ on webUrl returned from Get Team Drive action and adding General channel URL (‘/General’)
Team Site URL
webUrl returned from Get team site action
Collaboration Channel Namename returned from Get Team Drive action
Collaboration Team NamedisplayName returned from Get team site action

When CDS collaboration entity is created correcly, you can see a collaboration entitity by clicking Collaborate on the account.

And files are also linked correctly on Document Associated Grid.

Findings

Here are my finding when I was investigating the CDS configuration.

When a team or a channel is created via Microsoft Graph API, a folder related to a channel is not available before you actually open the Files tab on Teams. Document Associated Grid also returns an error, before Files tab is accessed for the first time.

Also calling Microsoft Graph’s Get a DriveItem endpoint (/teams/{teamId}/channels/{channelId}/filesFolder), NotFound error is returned with a message “Sharepoint folder not found.”. Endpoint is available currently on Beta version, so that might be the issue. Workaround is to generate channel related folder URL based on SharePoint site URL, document library URL and channel name. This configuration is included in the example.

Afterword

When provisioning tabs to Microsoft Teams, which are integrating external systems, you need to take care of what is happening during tab creation. As you can see in this case, there is also some configuration happening outside Microsoft Teams. You can get some clues using a browser and browser’s developer tools to see what calls are created to external API’s. And, if there isn’t any documentation available, you just need to try things out and learn. Use Microsoft Graph Explorer for testing and debugging your Graph API calls, and when ready move them to your provisioning solution.

You can find my example Flow on my Github account: https://github.com/mpaukkon/Microsoft365Dev/blob/master/PowerAutomate/Dynamics365TabToTeams/Dynamics365tabintegration.zip