Guest User

Xperience Email Template Sender

a guest
Mar 16th, 2026
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.06 KB | None | 0 0
  1. //////////// Interfaces
  2. public interface ICustomSystemEmailService
  3. {
  4. /// <summary>
  5. /// Will send an email out using, replacing {% PropertyName %} values with the values found in the ICustomSystemEmailTemplate class.
  6. /// A general {% Body %} macro can be used and the body content will be placed in that macro if provided
  7. /// </summary>
  8. /// <typeparam name="T"></typeparam>
  9. /// <param name="emailProperties">The model that has properties that match the macro names of the email template</param>
  10. /// <param name="emailMessage">The basic email message. The body will be replaced with the given template. If the macro {% body %} is present in the template and the emailMessage has content in it's body, it will put that in there.</param>
  11. /// <returns></returns>
  12. Task SendEmail<T>(T emailProperties, EmailMessage emailMessage) where T : ICustomSystemEmailTemplate;
  13. }
  14.  
  15. public interface ICustomSystemEmailTemplate
  16. {
  17. string EmailLibraryEmailTemplateName { get; }
  18. }
  19.  
  20. ////////// Implementation
  21. public partial class CustomSystemEmailService(IProgressiveCache progressiveCache,
  22. IInfoProvider<EmailTemplateInfo> emailTemplateInfoProvider,
  23. IEmailService emailService) : ICustomSystemEmailService
  24. {
  25. private readonly IProgressiveCache _progressiveCache = progressiveCache;
  26. private readonly IInfoProvider<EmailTemplateInfo> _emailTemplateInfoProvider = emailTemplateInfoProvider;
  27. private readonly IEmailService _emailService = emailService;
  28.  
  29. public async Task SendEmail<T>(T emailProperties, EmailMessage emailMessage) where T : ICustomSystemEmailTemplate
  30. {
  31.  
  32. var macroResolver = MacroResolver.GetInstance(false);
  33. var data = new Dictionary<string, object>();
  34. var body = emailMessage.Body;
  35. var templateName = emailProperties.EmailLibraryEmailTemplateName;
  36. // get the email template
  37.  
  38. var bodyContent = await _progressiveCache.LoadAsync(async cs => {
  39. if (cs.Cached) {
  40. cs.CacheDependency = CacheHelper.GetCacheDependency([$"{EmailTemplateInfo.OBJECT_TYPE}|byname|{templateName}"]);
  41. }
  42. var items = (await _emailTemplateInfoProvider.Get().WhereEquals(nameof(EmailTemplateInfo.EmailTemplateName), templateName).GetEnumerableTypedResultAsync());
  43. var templateCode = items.FirstOrMaybe().TryGetValue(out var item) ? item.EmailTemplateCode : "<!DOCTYPE html><html><head></head><body>{% body %}</body></html>";
  44. return templateCode.Replace("{%body%}", "{% body %}", StringComparison.OrdinalIgnoreCase).Replace("{% body %}", "{% body |(encode)false %}", StringComparison.OrdinalIgnoreCase);
  45. }, new CacheSettings(CacheMinuteTypes.Short.ToDouble(), nameof(CustomSystemEmailService),"GetEmailTemplateByName", templateName));
  46.  
  47. foreach (var property in typeof(T).GetProperties()) {
  48. if(!property.Name.Equals(nameof(ICustomSystemEmailTemplate.EmailLibraryEmailTemplateName))) {
  49. var value = property.GetValue(emailProperties);
  50. if(value !=null) {
  51. data.TryAdd(property.Name, value);
  52. } else {
  53. data.TryAdd(property.Name, string.Empty);
  54. }
  55. }
  56. }
  57. // Add body
  58. if(!data.ContainsKey("body")) {
  59. data.Add("body", body.GetValueOrDefault(string.Empty));
  60. }
  61.  
  62. macroResolver.SetNamedSourceData(data);
  63.  
  64. var messageHtml = macroResolver.ResolveMacros(bodyContent);
  65.  
  66. // Clone and send
  67. var newMessage = new EmailMessage() {
  68. //Attachments = emailMessage.Attachments,
  69. BccRecipients = emailMessage.BccRecipients,
  70. CcRecipients = emailMessage.CcRecipients,
  71. EmailFormat = emailMessage.EmailFormat,
  72. From = emailMessage.From,
  73. Guid = emailMessage.Guid,
  74. //Headers = emailMessage.Headers,
  75. MailoutGuid = emailMessage.MailoutGuid,
  76. Priority = emailMessage.Priority,
  77. Recipients = emailMessage.Recipients,
  78. ReplyTo = emailMessage.ReplyTo,
  79. Subject = emailMessage.Subject
  80. };
  81. switch(emailMessage.EmailFormat) {
  82. case EmailFormatEnum.Both:
  83. newMessage.Body = messageHtml;
  84. newMessage.PlainTextBody = HttpUtility.HtmlDecode(HtmlStripRegex().Replace(messageHtml, string.Empty));
  85. break;
  86. case EmailFormatEnum.PlainText:
  87. newMessage.PlainTextBody = HttpUtility.HtmlDecode(HtmlStripRegex().Replace(messageHtml, string.Empty));
  88. break;
  89. case EmailFormatEnum.Html:
  90. newMessage.Body = messageHtml;
  91. break;
  92. }
  93.  
  94. foreach (var headerKey in emailMessage.Headers.AllKeys) {
  95. newMessage.Headers.Add(headerKey, emailMessage.Headers[headerKey]);
  96. }
  97. foreach (var attachment in emailMessage.Attachments) {
  98. newMessage.Attachments.Add(attachment);
  99. }
  100.  
  101. // Send out
  102. await _emailService.SendEmail(newMessage);
  103.  
  104. return;
  105. }
  106.  
  107. [GeneratedRegex("<.*?>")]
  108. private static partial Regex HtmlStripRegex();
  109. }
  110.  
  111. ///////////////////////////// Email Template "Model"
  112.  
  113. public class ClientTokenAuthenticationEmailTemplate : ICustomSystemEmailTemplate
  114. {
  115. public ClientTokenAuthenticationEmailTemplate(string authenticationUrl, string memberFullName)
  116. {
  117. AuthenticationUrl = authenticationUrl;
  118. MemberFullName = memberFullName;
  119. }
  120. // This is the Email Template Code Name
  121. public string EmailLibraryEmailTemplateName => "ClientTokenAuthenticationEmailTemplate";
  122.  
  123. public string AuthenticationUrl { get; set; }
  124.  
  125. public string MemberFullName { get; set; }
  126. }
  127.  
  128. ///////////////////// Usage
  129.  
  130. var tokenGuid = await _clientRepository.GetAuthToken(client.Identity.Value.Id, false);
  131.  
  132. // The Guid (token) should now be set
  133. var emailModel = new ClientTokenAuthenticationEmailTemplate(
  134. authenticationUrl: $"https://www.mysite.com/client/token-authenticate?token={tokenGuid}{(redirectUrl.AsNullOrWhitespaceMaybe().TryGetValue(out var redirectUrlVal) ? $"&returnUrl={HttpUtility.UrlEncode(redirectUrlVal)}" : "")}",
  135. memberFullName: $"{client.FirstName} {client.LastName}");
  136.  
  137. await _customSystemEmailService.SendEmail(emailModel, new EmailMessage() {
  138. From = EmailConstants._NoReplyEmailAddress,
  139. Subject = "Temporary Authentication Token",
  140. Recipients = client.Email,
  141. EmailFormat = EmailFormatEnum.Both,
  142. });
  143.  
  144. /////////////////////// Email template Content
  145.  
  146. <!DOCTYPE html>
  147. <html>
  148. <head></head>
  149. <body>
  150. <p>{%MemberFullName%},</p>
  151. <p>Since your account does not have a user login, in order to proceed please use the link below to temporarily authenticate.</p>
  152. <p><a href="{%AuthenticationUrl%}">{%AuthenticationUrl%}</a></p>
  153. <p>This token is only valid for 1 hour, or until leveraged and then logged out. If you did not request this, please disregard and delete this email.</p>
  154. </body>
  155. </html>
Advertisement
Add Comment
Please, Sign In to add comment