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 in their E-Mails, they also want to format it nicely and often hit the CRM template editor limit for related entities, so that you can’t insert them using the editor.
Some even want to insert information on child records as table to their e-mails, which is not manageable in the default editor.

Luckily we are able to deploy XTL.

In this post I’m going to show you how to use XTL for creating e-mails with data from related entities and how to add information of multiple records as table. Our example will send an e-mail with information on a new opportunity and its products for the owner of the associated email.

 

Getting started

I already explained how to install XTL in an earlier post, please refer to it: Generating salutations for CRM contacts.

 

Fiddling out our template

First things first: We want to create our e-mail template first.

As we’ll use XTL for templating, we can use the XTL editor for trying this out.

For using the editor, we need to ensure that we already have some test data available. Verify that you have an opportunity in your system, which is connected to an account. It should also have some write-in opportunity products attached to it. Then create an email that references your opportunity as regarding and save it.

Of course you can adopt it to your needs, there is no constraint to anything of this.

Open the XTL solution and choose the configuration page. Select “Email” as entity and choose the email referencing  your demo opportunity that you just created as target using the “Select Target” button.

Afterwards toggle the “Is HTML template” checkbox (this will ensure proper line breaks for html content) and copy the following template to the template input:

Hello ${{Value("regardingobjectid.customerid.ownerid.firstname")}},

the sales person ${{Value("regardingobjectid.ownerid.fullname")}} created a new opportunity regarding your account ${{Value("regardingobjectid.customerid.name")}}.

Here is an overview of the new opportunity:
Name: '${{Value("regardingobjectid.name")}}'
Products:

${{RecordTable ( Fetch ( "<fetch no-lock='true'><entity name='opportunityproduct'><attribute name='productdescription'/><attribute name='priceperunit'/><attribute name='quantity'/><attribute name='extendedamount'/><attribute name='opportunityproductid'/><attribute name='manualdiscountamount'/><order attribute='productdescription' descending='false'/><filter type='and'><condition attribute='opportunityid' operator='eq' value='{1}'/></filter></entity></fetch>", Array ( Value ( "regardingobjectid" ) ) ), "opportunityproduct", Array ( "productdescription:Product", "priceperunit", "quantity", "manualdiscountamount", "extendedamount" ) )}}

For more information regarding this record, please click the following link: ${{RecordUrl ( Value ( "regardingobjectid") )}}.

Have a great day!

Hint: Since XTL v3.0.0, the RecordTable function signature changed, you don’t pass a boolean for adding the record url to rows in front of the column definition anymore, it is now configurable in a config object. An example of a styled table can be found at the very bottom of this post.

Hit the preview button and the result window should show you a properly formatted e-mail with all the data for your opportunity.

This is a short video showing the described steps:

If everything is how you expected it to look like, continue with the next steps.

 

Configuring the XTL execution steps

For XTL to do any text templating, you will need to register some execution steps on the creation (and depending on your use case also on update) of e-mail records inside your system.

As we don’t have a static template for e-mail templating, but every e-mail can contain its own templates, we define the plugin target field to be the description field (where CRM stores the e-mail text by default) and the template field to be the description as well, as we want to put the per-record template inside the record itself.

You can refresh the XTL editor or just empty the fields that you set during trying out the template, we won’t set them in here, but in our email template later on.

Your plugin is missing the execution criteria and the configuration, let’s get this done first.

Click on “Manage SDK Steps”, select “Create New”, “Email” and “Create” inside the drop downs.

Give a meaningful name to the step, and set the target and template field both to “description”, as explained earlier on.

Obviously we don’t want our e-mail templates to be applied every time.

For this reason we can use the execution criteria to define, that we only want to apply templating when sending e-mails, not when receiving them:

IsEqual ( Value ( "directioncode" ), true )

This will only execute XTL on e-mails that are being sent from CRM. Incoming e-mails will be skipped after checking the criteria.

Toggle the “Is HTML template” checkbox and hit the save button, followed by the activate button. We’re now done in here.

Following video shows you the steps from above again:

Create the e-mail template

Now we can use the e-mail template that we configured at the very beginning for creating an e-mail template. We will later use it inside a workflow for creating e-mails. If you do not wish to use e-mail templates, you can skip this step and use “Create New Email” as option inside the “Send email” operation of your workflow.

Head over to the Email templates section of your solution, and click new.

Choose the Template Type that you want. If you want to use a combination of the Microsoft default templating with the correct fields for your entity, you should choose an entity based type, such as Opportunity.

If you just want to use XTL, you can choose Global (which we will do).

Set a Title as you like and a subject such as “New opportunity for your account” (Note: For using XTL inside the subject as well, you can register the steps just as described above for the e-mail body. In this case however, don’t set the “Is HTML Template” checkbox, as the subject does not contain HTML).

Paste our template from the beginning. You could now also use the email editor formatting options, but be careful with formatting, as this will inject HTML, which might break the function calls.

Formatting is safe, if it wraps a whole XTL expression, or is just inside one single XTL string (without the quotes).

Hit Save and Close and our template is done.

Below video shows the steps described above:

Create a workflow that sends an email using our template

Now we want our system to automatically send the e-mails to the account owner.

Since there are no products directly after creating the opportunity, we add a new status reason to the opportunity to signalize that we are done configuring it. You can and should think of a logic for when to send e-mails as well. I added a new status reason “Ready” to the opportunity, that I will check for later.

Create a new workflow registered to creation of opportunities which uses our email template.

For testing purposes we’ll use a synchronous one, later on you will probably want an asynchronous one for better resource usage.

Go to Settings > Processes and click “New”. Give a reasonable process name, select “Workflow” as category and “Opportunity” as entity. For testing you can use the synchronous execution mode.

Inside the workflow, set the scope to organization and the trigger to “status changes”.

Then add a condition for status to equal “Ready” and a “Send Email” operation inside it.

Configure the Send email operation to use our template and set a recipient.

Hit Save and Close, Activate the workflow and we’re ready for testing.

Below you can find a video showing the described steps:

Test it

Create an opportunity regarding an account and add some write-in products.

Set the status to ready and wait for the email to be created by the workflow.

Check the e-mail and verify that it looks as defined.

See my example below:

Styled Table

Since XTL v3.0.0, you can also style tables in a custom way.

Below template demonstrates how to do this:

Hello ${{Value("regardingobjectid.customerid.ownerid.firstname")}},

the sales person ${{Value("regardingobjectid.ownerid.fullname")}} created a new opportunity regarding your account ${{Value("regardingobjectid.customerid.name")}}.

Here is an overview of the new opportunity:
Name: '${{Value("regardingobjectid.name")}}'
Products:

${{RecordTable ( Fetch ( "<fetch no-lock='true'><entity name='opportunityproduct'><attribute name='productdescription'/><attribute name='priceperunit'/><attribute name='quantity'/><attribute name='extendedamount'/><attribute name='opportunityproductid'/><attribute name='manualdiscountamount'/><order attribute='productdescription' descending='false'/><filter type='and'><condition attribute='opportunityid' operator='eq' value='{1}'/></filter></entity></fetch>", Array ( Value ( "regardingobjectid" ) ) ), "opportunityproduct", [ "productdescription:Product", "priceperunit", "quantity", "manualdiscountamount", "extendedamount" ], {tableStyle: "width: 100%", headerStyle: "border: 1px solid #ccc; text-align: left; background-color: blue; color: white;", evenDataStyle: "background-color: #f2f2f2; border: 1px solid #ccc;", unevenDataStyle: "background-color: #ddd; border: 1px solid #ccc;", optionSetLcid: -1, addRecordUrl: true, linkText: "Open"})}}

For more information regarding this record, please click the following link: ${{RecordUrl ( Value ( "regardingobjectid") )}}.

Have a great day!

Extend it – Use it – Love it

I hope everything worked out for you.

If you’re having problems, feedback or feature requests, please reach out on GitHub.

Happy CRMing! 🙂

 

 

Leave a Reply

Your email address will not be published.

RELATED POST

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…

Generating salutations for CRM contacts

Scope In this blog post I'm going to show you how to easily generate salutations for contacts inside your Dynamics365…