Creating HTML emails from D365 Power Automate / Flows

A lot of times I am asked by colleagues whether I can help them sending emails from within their Flows.

Sending emails using Flows can be done in two ways by default:

Either you add a create step in your flow and write your text inside the description field, or you use the default email templates of D365 CE.

The first approach reaches its limits very fast, as you have to fetch data yourself for every placeholder that you want to use. Imagine you want to send a case autoresponse and need the contact name. You would have to fetch the contact record inside your flow first for being able to use it.
This is making your flow bigger and more complex with every placeholder that you need.

Fetch data first
Use in plain description field

The second approach of using the default email templates works better, because you can use the email template editor of D365 CE. It has its limits as well however, because you can only use data from the target record and records which are directly connected to it. In addition to that, you can not style it and at the time of writing, the action for creating an email based on a template without directly sending it does not work in flows, only the action for creating and sending does.

So what other alternatives exist?

Open Source meets D365

I’m the author of XRM-OSS-Xrm-Templating-Language and XRM-OSS-HtmlTemplating. These are two open source solutions for D365 CE systems, which can be used in a modular way.

Xrm-Templating-Language is a small and easy to learn interpreted language, which allows for excel like expressions that can be used for any text processing purposes. It can be used as standalone for generating default names, salutations, formatted addresses and more inside your D365 CE data.

Xrm-HtmlTemplating is a module which was built on top of the Xrm-Templating-Language. It provides you with a new Entity “HTML Template” inside D365 CE where you can use the awesome Drag and Drop HTML Email designer by unlayer. In addition to that, the default email entity gets a lookup to the HTML template entity, so when you reference a template in an email record, the subject and body of the template are applied and all placeholders are processed.

Getting started

First up, install the latest solution of Xrm-Templating-Language, followed by the latest solution of Xrm-Html-Templating. The order matters, Xrm-Templating-Language needs to be first.

After installing the solutions, you can start an advanced search for the HTML template entity.

Create a new HTML template and you will be greeted by the unlayer Drag and Drop editor.

You can choose a column layout, add your company’s logo and a headline, format it just as you like and add content. For media, such as pictures, please remind that you must include it via url, so they have to be hosted somewhere publicly, for example on a CDN.
Everywhere XTL (Xrm-Templating-Language) snippets can be used, even in the subject of the template.

But writing big expressions clutters up your template? That’s right, so let’s outsource them to the XTL Snippet entity.

Creating snippets

Snippets are a store for your XTL expressions, which can be organized hierarchically. This is what I would also advice you to do and what I do myself.

So imagine we want to create snippets that we want to use inside emails that target the case (incident) entity.

I would then create a XTL snippet called “Email”, which contains nothing.

Then I would go to the related entities and choose the child relation to XTL snippets. In there, I create a new snippet called “Case”, which is thus a child of the Email snippet.

Now I need the case title and the ticket number. Let’s create these as snippets which are children of the “Case” snippet. When creating snippets with values, I advise to set a unique name as well. That way, the snippets don’t get injected with their current expression, but with a call to the snippet function instead. This makes it easier to change expressions that you use in a lot of places and it is usually shorter to embed. A good pattern for unique names might be the full path of your snippets. So for our title and ticketnumber, we could call the uniquename “email_case_title” and “email_case_ticketnumber”.

The XTL expression for the title would be

The XTL expression for the ticketnumber has no surprises either

But what if we now would also like to generate a salutation for the primary contact? No problem at all, let’s create a sibling snippet called Salutation with the unique name “email_case_salutation” and the XTL expression
Dear ${{If(IsEqual(Value("regardingobjectid.primarycontactid.gendercode"), 1), "Mr.", "Mrs.")}} ${{Value("regardingobjectid.primarycontactid.lastname")}}

As you can see, the snippet above contains not only an XTL expression, but plain text inline with the snippets, while the snippets are surrounded by the ${{…}} braces. That’s how XTL marks placeholders, which have to be replaced by the values they generate. For this to work inside snippets, be sure to check the “Snippet contains plain text” checkbox on this snippet.

Together, the snippets in our demo look like this:

Using snippets

So now that we have our snippets, let’s see how we can select them inside the template. Click anywhere inside the Drag and Drop editor and check the toolbar that appears. See the “Merge Tags” dropdown? Click on it and see what appears:

Yes, the full snippet hierarchy has been rendered, we can just navigate through it and click on the snippet that we want to use. It will be added at the current cursor position. Easy!

Save your template and we’re ready to go.

Usage in Power Automate / Flows

So now that we have our template, how to use it inside our flows?

Create an email record inside your flow and make sure to set the recipient / sender and also (for our demo use case) the corresponding incident as regarding object.

Setting sender and recipient of your mail

Now for applying the template to our email, we can either use the HTML Template lookup and set it to a value such as /oss_htmltemplates(Id_Of_Your_Template), where you can grab the ID from the CRM url when opening the HTML template, it’s the paramater named “id” inside the url.
If you do not want to set the lookup, make sure to set a unique name on your HTML template and enter the same unique name inside the “HTML Template Unique Name” field on your email. XTL will resolve the template with this name and use it, just as with the lookup.

In both cases, the email will have the content of the template with replaced placeholders and the subject of the template with replaced placeholders.

If you want, you can now send your mail using the SendMail action.

This is what this email now looks like in D365:

Takeaway and further resources

Templating with those two modules combined is really powerful and can provide you with nice looking HTML templates, that also contain all the data you would ever need, without any restrictions on “how remotely” they are connected to your current record.

What we looked at however is only the basic functions of what XTL can do. Want to fetch data and use those values in your content? No problem. Want to render a list of data as table in your content? No problem either. Convert datetime time zones dynamically? Go ahead. A reference of what XTL can currently do can be found here.

Need some inspiration for nice looking templates? Unlayer has a whole website with nice looking templates here.

When you have issues, please reach out on GitHub either in the Xrm-Templating-Language repo if it is about expressions and snippets, or the Xrm-Html-Templating repo if is about the editor or applying of the templates.


Show bing maps with Pin in Dynamics 365 custom entities

The default map control of Dynamics CRM can not be shown by selection from the custom controls. So it is…

Link to Dynamics 365 records in UCI

Scope With the UCI getting used more and more, some have already noticed that the record links that can be…

HTML E-Mails with place holders in Dynamics 365

Scope E-Mails in CRM are very simple by default. But what if we want to have styles in them by…

Advanced Dynamics CRM E-Mail Templating

Scope Often customers have extended requirements for their mailing purposes. Not only do they often need a lot of information…