When working with email templates in Microsoft Dynamics 365 CRM, it’s often useful to dynamically insert the recipient’s name (such as a Contact, Account, or User) into the email body before sending.
In this article, I’ll show you how to achieve this using a plugin that intercepts the email creation process, retrieves the recipient’s full name, and replaces a placeholder in the email body (like ##ToRecipient##
) with that name.
The Scenario
Imagine you have an email template that includes a placeholder such as:
Dear ##ToRecipient##,
When the system sends the email, you want the placeholder ##ToRecipient##
to be replaced with the actual name of the recipient — whether it’s a Contact, Account, User, or Queue.
The Code
Here’s an example of a C# plugin that accomplishes this in Dynamics 365 CRM:
if (targetImage.Contains(email.to))
{
var toParties = targetImage.GetAttributeValue<EntityCollection>(email.to)?.Entities;
if (toParties != null && toParties.Count > 0)
{
foreach (Entity party in toParties)
{
tracing?.Trace($"Party: {party}");
if (party != null && party.Contains("partyid"))
{
var userRef = party.GetAttributeValue<EntityReference>("partyid");
tracing?.Trace($"UserRef: {userRef}");
if (userRef != null)
{
var name = string.Empty;
switch (userRef.LogicalName.ToLower())
{
case terna_utente.EntityName:
name = terna_utente.nome;
break;
case account.EntityName:
name = account.PrimaryName;
break;
case contact.EntityName:
name = contact.PrimaryName;
break;
case queue.EntityName:
name = queue.PrimaryName;
break;
case systemuser.EntityName:
name = systemuser.PrimaryName;
break;
default:
return;
}
tracing?.Trace($"Party Entity: {name}");
Entity partyEntity = serviceAdmin.Retrieve(userRef.LogicalName, userRef.Id, new ColumnSet(name));
tracing?.Trace($"Party Entity: {partyEntity}");
var fullName = partyEntity.GetAttributeValue<string>("terna_name");
tracing?.Trace($"FullName: {fullName}");
var toRecipientPlaceholder = "##ToRecipient##";
if (descrition.Contains(toRecipientPlaceholder))
{
targetImage[email.description] = descrition.Replace(toRecipientPlaceholder, fullName);
tracing?.Trace($"Replaced placeholder {toRecipientPlaceholder} with {fullName}");
}
}
}
}
}
}
How It Works
-
Intercepts the Email Entity
The plugin checks if theemail.to
field exists in thetargetImage
(the email being processed). -
Retrieves Recipients
It extracts all recipient entities (toParties
) from theto
field. -
Identifies Recipient Type
Depending on whether the recipient is aContact
,Account
,Queue
,SystemUser
, or custom entity (terna_utente
), it selects the proper name attribute. -
Retrieves Full Name
The plugin uses the CRMserviceAdmin.Retrieve()
method to get the full name of the recipient. -
Replaces the Placeholder
It finds the placeholder##ToRecipient##
in the email body (description
) and replaces it with the retrieved full name.
Example Output
If the email template body is:
Dear ##ToRecipient##,
Thank you for contacting us.
and the recipient is John Doe, the plugin will automatically modify it to:
Dear John Doe,
Thank you for contacting us.
Why This Is Useful
-
Makes your emails more personalized without needing manual updates.
-
Works for multiple entity types (Contacts, Accounts, Users, Queues).
-
Keeps your email automation templates clean and flexible.
Tips
-
Make sure your plugin is registered on the Pre-Operation or Post-Operation stage of the
Create
message for the Email entity. -
Always include tracing logs to simplify debugging.
-
Ensure that your attribute names (like
"terna_name"
) match the schema names in your CRM environment.
By adding this simple logic, you can enhance your Dynamics 365 CRM email templates with personalized recipient data. This approach ensures that all automated emails are dynamic, professional, and user-friendly — improving your communication quality without additional manual work.