Sitecore Version: 9.3
- In Sitecore Email Experience Manager (EXM), email campaigns can be
personalize using tokens.
- For example, at the beginning of a message, you can use the token $name$ in the greeting so that when you send your email campaign, the token is replaced with the name of the contact.
The following tokens are by default available in EXM:
- $email$
- $fullname$
- $firstname$
- $lastname$
- $name$
- $phone$
How to use tokens in EXM:
- Go to EXM email editor, message tab.
- Assume we want to
insert the token in the subject line, click on the subject and then choose insert
token from the options in the details section.
3. You’ll see all the defaults tokens list.
![](https://sitecorewithraman.files.wordpress.com/2021/05/96bcb-image-15.png?w=599)
5. Select any token and click ok. As an example: $firstname$ is what a token looks like.
Custom Tokens in EXM:
- However, If you want to use tokens that are not available by default,
you can create a custom token that you can use for your email
campaigns.
- In our example, we will create a token for CustomerID. We’ll follow below four steps to achieve this:
- Create a custom contact facet
- Create a custom dispatch task
- Override the default token map
- Extending the getContact pipeline
- Create a custom contact facets: We’ve already created a custom facet for storing the value of CustomerID in xDB as explained in my previous blogs. (Part 1 and Part 2)
- Create a custom dispatch task:
- Create a CustomDispatchTask class overriding the default dispatch task.
- Create a CustomDispatchTask class overriding the default dispatch task.
namespace DemoSitecore.CustomRulesAndTokens.Tokens.Email
{
internal class CustomDispatchTask : DispatchTask
{
private IContactService _contactService;
public CustomDispatchTask([NotNull] ShortRunningTaskPool taskPool, [NotNull] IRecipientValidator recipientValidator,
[NotNull] IContactService contactService, [NotNull] EcmDataProvider dataProvider, [NotNull] ItemUtilExt itemUtil,
[NotNull] IEventDataService eventDataService, [NotNull] IDispatchManager dispatchManager,
[NotNull] EmailAddressHistoryManager emailAddressHistoryManager,
[NotNull] IRecipientManagerFactory recipientManagerFactory, [NotNull] SentMessageManager sentMessageManager)
: base(taskPool, recipientValidator, contactService, dataProvider, itemUtil, eventDataService, dispatchManager,
emailAddressHistoryManager, recipientManagerFactory, sentMessageManager)
{
_contactService = contactService;
}
protected override IReadOnlyCollection<IEntityLookupResult<Contact>> GetContacts(List<DispatchQueueItem> dispatchQueueItems)
{
return _contactService.GetContacts(dispatchQueueItems.Select(x => x.ContactIdentifier),
PersonalInformation.DefaultFacetKey, EmailAddressList.DefaultFacetKey, ConsentInformation.DefaultFacetKey,
PhoneNumberList.DefaultFacetKey, ListSubscriptions.DefaultFacetKey, EmailAddressHistory.DefaultFacetKey,
ExmKeyBehaviorCache.DefaultFacetKey, CustomerID.DefaultFacetKey);
}
}
}
- Deploy the DLL to CM and DDS roles.
- Go to \App_Config\Sitecore\EmailExperience and open Sitecore.EmailExperience.ContentManagement.config and replace the default dispatch task with your custom dispatchTask
(I’ve created a patch for this z.Demo.EmailExperience.ContentManagement.config.)
<?xml version="1.0"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/" xmlns:role="http://www.sitecore.net/xmlconfig/role/">
<sitecore role:require="Standalone or ContentManagement">
<exm>
<dispatchTask>
<patch:attribute name="type">DemoSitecore.CustomRulesAndTokens.Tokens.Email.CustomDispatchTask, DemoSitecore.CustomRulesAndTokens</patch:attribute>
</dispatchTask>
</exm>
</sitecore>
</configuration>
3. Override the default token map:
- Create your custom token map by adding your custom token. Eg. CustomerPropertyTokenMap.cs and DLL to CM and DDS role.
namespace DemoSitecore.CustomRulesAndTokens.Tokens.Email
{
internal class CustomerPropertyTokenMap : DefaultRecipientPropertyTokenMap
{
protected static readonly MethodInfo GetCustomerIDFacetValue = typeof(FacetExtensions).GetMethod(nameof(FacetExtensions.GetCustomerIDFacetValueExt), new[] { typeof(CustomerID) });
static CustomerPropertyTokenMap()
{
if (TokenBindings == null)
{
TokenBindings = new Dictionary<Token, RecipientPropertyTokenBinding>();
}
RecipientPropertyTokenBinding CustomerIDTokenBinding = RecipientPropertyTokenBinding.Build<CustomerID>(new Token("CustomerID"), null, GetCustomerIDFacetValue);
TokenBindings.Add(CustomerIDTokenBinding.Token, CustomerIDTokenBinding);
}
}
public static class FacetExtensions
{
public static string GetCustomerIDFacetValueExt(this CustomerID facet)
{
if (facet != null)
{
return facet.CustID.ToString();
}
else
{
return string.Empty;
}
}
}
}
- Replace the recipients/recipientPropertyTokenMap element in App_Config\Sitecore\EmailExperience\Sitecore.EmailExperience.Core.config file with your custom token map. (I’ve created a patch file for this z.Demo.EmailExperience.Core.config) Patch is shown after step 4.
4. Extending the getContact pipeline: For custom tokens to be replaced in the online Preview mode, you must extend the getContact pipeline. To extend the getContact pipeline:
- Create a new pipeline processor extending the GetContact processor:
namespace DemoSitecore.CustomRulesAndTokens.Tokens.Email
{
class GetContact
{
private readonly IContactService _contactService;
public GetContact([NotNull] IContactService contactService)
{
Condition.Requires(contactService, nameof(contactService)).IsNotNull();
_contactService = contactService;
}
public void Process([NotNull] GetContactPipelineArgs args)
{
Condition.Requires(args, nameof(args)).IsNotNull();
if (args.ContactIdentifier == null && ID.IsNullOrEmpty(args.ContactId))
{
throw new ArgumentException("Either the contact identifier or the contact id must be set");
}
string[] facetKeys = args.FacetKeys.Concat(new[]
{
CustomerID.DefaultFacetKey //all of the custom facets name
}).ToArray();
args.Contact =
args.ContactIdentifier != null ?
_contactService.GetContact(args.ContactIdentifier, facetKeys)
:
_contactService.GetContact(args.ContactId, facetKeys);
}
}
}
- Deploy the DLL to CM and other DDS roles.
- Replace the Sitecore.Modules.EmailCampaign.Core.Pipelines.GetContact.GetContact pipeline processor in the getContact pipeline in Sitecore.EmailExperience.Core.config file.
<?xml version="1.0"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/" xmlns:role="http://www.sitecore.net/xmlconfig/role/">
<sitecore role:require="Standalone or ContentManagement">
<recipients>
<recipientPropertyTokenMap>
<patch:attribute name="type">DemoSitecore.CustomRulesAndTokens.Tokens.Email.CustomerPropertyTokenMap, DemoSitecore.CustomRulesAndTokens</patch:attribute>
</recipientPropertyTokenMap>
</recipients>
<pipelines>
<group groupName="exm">
<pipelines>
<getContact>
<processor>
<patch:attribute name="type">DemoSitecore.CustomRulesAndTokens.Tokens.Email.GetContact, DemoSitecore.CustomRulesAndTokens</patch:attribute>
</processor>
</getContact>
</pipelines>
</group>
</pipelines>
</sitecore>
</configuration>
- Go to the EXM email campaign message tab and click on Insert Token button, You will see custom token has been added now along with the default tokens.
![](https://sitecorewithraman.files.wordpress.com/2021/05/cd6ca-image-13.png?w=604)
Hope this post helps you implementing custom tokens in EXM.
Comments
Post a Comment