Adding Dataverse Record Links in HTML Tables in Power Automate

I want to send a weekly summary of Open Opportunities & Activities to all the sales users to help them manage workload - nothing new or novel here (e.g. this post). I also needed to include a clickable link for each row in the emailed table. This included Opportunities, Activities and also the ‘Regarding’ record to the activity. So that the receiver of the email can quickly jump directly into the app.

In terms of creating HTML tables with CSS formatting in Power Automate - I always use this blog post (thanks Ryan!). Plus how to create a single dynamic URL for a dataverse record - I always use this blog post (thanks Linn!). This post will focus on creating dynamic URLs for different dataverse tables into a HTML table using Power Automate:

  • Opportunities

  • Activities (Task, Email, Appointment, SMS etc.)

  • Regarding (anything enabled for activities e.g. Contact, Account, Opportunity, Lead, User etc.)

Create this guy for later

Add this action at the top of your flow, we will use and reuse it later. You could declare a string variable also but I’m lazy and this allows me one or two less clicks.

Opportunities

1.1) Search for Opportunities

Using the Dataverse List Rows action and using the OData filter to retrieve only the relevant opportunities for each user.

1.2) Did you find any Opportunitties?

If the user is a goody two shoes (or just a really bad salesperson) and they don’t have any opportunities due to close, then there is no point sending an empty table. Using a Condition action we can use the following formula to see if any rows were returned from the search.

empty(body('OppDueThisMonth')?['value'])

This returns either true or false, if its false then the search has successfully found at least one opportunity - proceed to table creation.

1.3) Create the HTML table

Use the Create HTML Table action, where the ‘From’ input is the search results from the Opportunity list rows action above. Select the custom option to map the columns yourself. We are going to make the title into a clickable link by combining the a href compose outputs from above, uriHost, Opportunity ID and Opportunity Name like so ->

<AHREF OUTPUTS="https://URI HOST/main.aspx?pagetype=entityrecord&etn=opportunity&id=OPPORTUNITY ID">OPPORTUNITY NAME</a>

AHREF OUTPUTS

See above “Create this guy for later“ - if you type this section ‘a href’ it seems to loose the space between a and href, which then breaks the link

URI HOST

Using uriHost ensures that when you move this flow between environments, it will always be creating the correct link without modifying any environment variables or the flow itself. Like so:

uriHost(item()?['@odata.id'])

More info on uriHost -> this blog post

OPPORTUNITY ID & OPPORTUNITY NAME

Select them from the Dynamics Content list or use the below syntax as an expression:

item()?['opportunityid']
item()?['name']

The rest is just text and HTML tags - copy pasta (paste) away!

BONUS TIP

If you type directly into the Header column the name of the column, it will not allow you to add any spaces. BUT if you copy the column names from elsewhere and paste them in - you can have a space - yay!

1.4) Make the HTML table look pretty-ish

This step is entirely optional and just allows you to style the HTML table before dropping it in the email. More info on HTML table CSS styling -> this blog post.

1.5) Make the links clickable

If you skip this step - the HTML above will not be interpreted and instead your link will be surrounded by <a> tags and totally non-clickable. This step is ugly but its pure copy & paste, just replace CSS STYLED OUTPUTS with the outputs from the step above using the dynamics content builder.

replace(replace(replace(CSS STYLED OUTPUTS,'&lt;a href=&quot;','<a href="'),'&quot;&gt;','">'),'&lt;/a&gt;','</a>')

This converts the HTML tags into actual tags rather than HTML interpreted symbols

Finito - your opportunity links are ready to go. Next up the troublesome ones - ‘Activities’ and ‘Regarding’.

Activities & Regarding

Step 2.1) and 2.2) are the same as step 1.1) and 1.2) above, but with Activities instead of Opportunities

2.1) Search for Activities

Using the Dataverse List Rows action and using the OData filter to retrieve only the relevant openn Activities for each user.

2.2) Did you find any Activities?

No open activities = no table. Using a Condition action we can use the following formula to see if any rows were returned from the search.

empty(body('OpenActivities')?['value'])

This returns either true or false, if its false then the search has successfully found at least one activity - proceed to table creation.

2.3) Create the HTML table - Activity link

Follow all the same steps for 1.3) above, just using Activity instead of Opportunity List Row results. We are going to make the Subject into a clickable link by combining the a href compose outputs from above, uriHost, Activity Type, Activity ID and Subject like so ->

<AHREF OUTPUTS="https://URI HOST/main.aspx?pagetype=entityrecord&etn=ACTIVITY TYPE&id=ACTIVITY ID">SUBJECT</a>

AHREF OUTPUTS & URI HOST

Same as 3) above

ACTIVITY TYPE

A new piece of Gymnastics for this post - and it’s a beauty! There are many different types on activity (Task, Email, Appointment, SMS etc.). This impacts what follows etn= in the link. Fortunately this is passed as part of the Activity List Rows results in activitytypecode@OData.Community.Display.V1.FormattedValue. Then we need to convert it to lowercase, using toLower() as the URL is case sensitive

e.g. Activity type=Task -> URL Text=task

toLower(item()?['activitytypecode@OData.Community.Display.V1.FormattedValue'])

More stuff like this -> Power Automate Gymnastics Reference Guide

ACTIVITY ID & SUBJECT

Similar to 1.3) above - select them from the Dynamics Content list or use the below syntax as an expression:

item()?['activityid']
item()?['subject']

The rest is just text and HTML tags - copy pasta (paste) away!

2.4) Create the HTML table - Regarding link

Finally our good friend ‘Regarding’ - it is a similar premise to the activity URL that it has many different types. Se we use all of the stuff above in 2.3). However, ‘Regarding’ is an optional column for an activity record, not all Activities are linked to another table using ‘Regarding’. The function toLower() doesn’t handle null values, causing the rest of the flow to fail.

If ‘regarding’ is blank - do nothing. Otherwise combine all the pieces of the regarding URL using concat(). Anything that is text must be wrapped in single quotes (‘), each item of the string is connected with a comma (,).

if(empty(REGARDING, null,concat('<',outputs('ahref'),'="https://',URI HOST,'/main.aspx?pagetype=entityrecord&etn=',ACTIVTY TYPE,'&id=',ACTIVITY ID,'">',SUBJECT,'</a>'))

Yikes!

2.5) Make the HTML table look pretty-ish

Optional HTML table CSS styling, same as 1.3) from above

2.6) Make the links clickable

If you skip this step - the HTML above will not be interpreted and instead your link will be surrounded by <a> tags and totally non-clickable. Same as 1.4) from above.

Create and Send the Weekly Summary Email

Finally we need to check how much of a good two shoes our user really is - if they have no pending Opportunities or Activities - they don’t need an email. Combine the expressions from the two ‘Did you find any Opportunities/Activities’ steps into a condition.

empty(body('OppDueThisMonth')?['value'])
empty(body('OpenActivities')?['value'])

If they have any Activities and or Opportunities, we need to send them an email. Use the outputs from steps 1.5) and 2.6) where the links become clickable and the tables are ready to go to create the email. Then perform a bound action to send the email from dataverse.

Clickable links in HTML Table for Opportunities, Activities and Regarding

Congratulations for completing this gymnastics tutorial of HTML Tables and clickable links - I hope you survived! Questions comments etc. always welcome 😊

Previous
Previous

Upload Documents from Model-driven apps or Dynamics 365 to SharePoint - with metadata!

Next
Next

Prevent submission of a non-business email address in Dynamics 365 Marketing forms