How to Generate Dynamics 365 Entity Record URLs in Power Automate

This post is about how to generate Dynamics 365 record URLs in Power Automate dynamically. The use case for this is often when you want to notify users of changes or reminders and you want to send a notification with a link so that they more easily can open the record. There are many different approaches on the web and this is a summary of what I’ve found.

The reason why we want to generate a record URL in Power Automate is that the Environment URL changes, and also the App Id might be different if you are moving your flow to different environments. In the image below we can see an example of what a Case record URL in Dynamics looks like. The record URL is built up with an environment URL, App Id, and a reference to the entity. To be able to send a notification to the users with the link to the record in the right environment we need to send them the correct URL based on the environment that the flow is running in. So, if we have three environments like dev, test, and production with different Environment URLs, we need to take this into consideration when creating the notification message for the user.

In this post, we look into how we can generate record URLs in Power Automate dynamically by creating a link below where the values in the image below are dynamically generated instead of “hardcoded”.

Image of an example URL of Case record URL in Dynamics.
Image of an example URL of Case record URL in Dynamics.

How to create the flow

In this section, we look at how we can create a flow for generating Dynamics 365 record URLs for the Case table in Dynamics 365 CE. The example will look at each step of creating a dynamics record URL based on when a Case record is modified in Dataverse.

1. First, we create a trigger using the “When a row is added, modified, or deleted” and we change that to only trigger when an owner is modified on a Case record. In this example, the flow will only trigger when the owner of the case is changed. This is to notify the new owner about the changes.

Image of the trigger, "When a Case is Modified"
Image of the trigger, “When a Case is Modified”

2. Next, we need to get the Case record that was triggered to get the field that we need for retrieving the information about the environment. In the “Get Case” action we use the Case Id (incidentid) in the Row Id and select the columns we need by specifying the columns in the “Select Columns”. This step continues after the image below.

Image of the action where we get the Case using the "Get a row by Id" action in the Dataverse connector.
Image of the action where we get the Case using the “Get a row by Id” action in the Dataverse connector.

The reason we need to get the Case record after the trigger is that the trigger only outputs data about the Case and not the environment. By retrieving the same Case record afterward we get more information about the environment and the record. The field we are looking for and are going to use later in the post is the OData Id field which is highlighted in the image below.

Image of the OData Id in the "Get Case" action in the example.
Image of the OData Id in the “Get Case” action in the example.

3. The last thing we need to retrieve before we are creating the dynamic URL is the App Id. In this example, we use the Customer Service Hub app from a trial environment. We are going to retrieve this in Power Automate and for that, we need to retrieve the unique name of the App, since the App Id may be different between environments.

To find the unique name we can either use Javascript by opening the Case record and opening the developer console and run the snippet from the post, https://fredrikengseth.com/javascript-code-snippets-for-dynamics-365-cheat-sheet/ and retrieve the value from the console. Or, we can get it by following the steps below:

Open all Apps > Then open the Customer Service Hub app in the App Designer > Look for Advanced settings in the side menu > Copy the unique name.

Image of how to navigating to the App Designer
Image of how to navigate to the App Designer
Image of how to find the Unique name of the Model-driven App
Image of how to find the Unique name of the Model-driven App

4. Next up, retrieve the App Id in Power Automate. For this, we need to use the “List rows” action from the Dataverse Connector (I renamed it to “Get Current AppId for the Environment”). Here we are listing Model-driven Apps, and by filtering on the Unique name that we found in the previous step get the app we want.

Image of how to get the App Id of a Model-driven App in Power Automate
Image of how to get the App Id of a Model-driven App in Power Automate

Now that we have retrieved the data we need we can start to create the dynamic URL.

5. To get the App Id from the action “Get Current AppId for the Environment” we can create a compose that we add the following expression to:

first(body('Get_Current_AppId_for_the_Environment')?['value'])?['appmoduleid']
Image of the expression to retrieve the App Id
Image of the expression to retrieve the App Id

If we run the flow, the compose step will output the App Id.

Output of the result of the AppId compose
The output of the result of the AppId compose

6. To get the Environment URL from the OData Id field in the “Get Case” action we can create another compose and add the following expression:

uriHost(outputs('Get_Case')?['body/@odata.id'])
Image of the expression to retrieve the Environment URL
Image of the expression to retrieve the Environment URL

If we run the flow, the compose step will output the Environment URL

Output of the result of the Environment URL compose
The output of the result of the Environment URL compose.

7. Now we want to stitch all things together. To test this, create another Compose action and paste the URL from the Case record URL that we looked at at the start of the post. Replace the parts with the dynamic values that we created in the previous steps. And, see below what the URL looks like in the Compose before and after.

URL before:

This is how the URL looks like in Dynamics when a specific case is open.

https://dynanamicsplayground.crm19.dynamics.com/main.aspx?appid=4266cc1e-1344-ed11-bba2-002248dc6459&pagetype=entityrecord&etn=incident&id=dfbbc145-2f3a-4183-a4b2-03e8f4b566d5

URL after:

We want to replace the Environment URL, App Id, and Case Id (incidentid) to generate Dynamic URLs when a case is updated.

https://@{outputs('Environment_URL')}/main.aspx?appid=@{outputs('AppId')}&pagetype=entityrecord&etn=incident&id=@{triggerOutputs()?['body/incidentid']}
Image of how to build the dynamic url in Power Automate.
Image of how to build the dynamic URL in Power Automate.

When testing the flow it will output the same URL as if it was “Hardcoded”.

Image of the Entity Record URL after succeded run
Image of the Entity Record URL after a succeded run

We can now use this URL in notifications, email messages, and more.

8. If you want to shorten the flow we can take the expression from the Compose steps and use them directly in the Compose step “Entity Record URL”. The other Compose steps were used to see how to retrieve each value before it was stitched together.

We can remove the Compose steps “Environment URL” and “App Id” and use the expression directly in the “Entity Record Url” as shown below:

https://@{uriHost(outputs('Get_Case')?['body/@odata.id'])}/main.aspx?appid=@{first(body('Get_Current_AppId_for_the_Environment')?['value'])?['appmoduleid']}&pagetype=entityrecord&etn=incident&id=@{triggerOutputs()?['body/incidentid']}
Image of the shortened flow.
Image of the shortened flow.

This will output the same result as the previous version of the flow, but now you have a shorter flow with fewer steps😉

Results after shortening the flow.
Results after shortening the flow.

Below is a gif of the first flow and what it looks like.

Gif of how it look when the flow runs.
Gif of how it looks when the flow runs.

Hope you found the post useful!


For More Content See the Latest Posts