Added mail template for Welcome emails
This commit is contained in:
parent
52edae5470
commit
fd43ead960
|
@ -7,7 +7,6 @@
|
|||
@using System.Net
|
||||
@using Microsoft.EntityFrameworkCore
|
||||
@using Wave.Services
|
||||
@using Wave.Utilities
|
||||
|
||||
@inject ILogger<EmailSignup> Logger
|
||||
@inject IStringLocalizer<EmailSignup> Localizer
|
||||
|
@ -82,27 +81,15 @@
|
|||
Message = Localizer["Success_Message"];
|
||||
|
||||
await TemplateService.ValidateTokensAsync(Id, Token, deleteToken: true);
|
||||
|
||||
|
||||
var articles = await context.Set<EmailNewsletter>()
|
||||
.IgnoreAutoIncludes()
|
||||
.Include(a => a.Article).ThenInclude(a => a.Author)
|
||||
.OrderByDescending(a => a.DistributionDateTime)
|
||||
.Take(3)
|
||||
.ToListAsync();
|
||||
string body = $"<p>{Localizer["WelcomeEmailBody"]}</p>\n";
|
||||
|
||||
foreach (var n in articles) {
|
||||
string articleLink = ArticleUtilities.GenerateArticleLink(n.Article, new Uri(Customizations.Value.AppUrl, UriKind.Absolute));
|
||||
body = body +
|
||||
"<div style=\"padding: 10px; background: #333; color: #fff; margin-bottom: 10px\">" +
|
||||
$"<h3>{n.Article.Title}</h3>" +
|
||||
$"<small>{n.Article.Author.Name}</small>" +
|
||||
$"<p>{n.Article.Body[..Math.Min(100, n.Article.Body.Length)]}...</p>" +
|
||||
$"<a href=\"{articleLink}\">Link</a>" +
|
||||
"</div>";
|
||||
}
|
||||
await EmailSender.SendSubscribedMailAsync(subscriber,
|
||||
Localizer["WelcomeEmailSubject"], Localizer["WelcomeEmailTitle"], body, subscribedRole: "welcome");
|
||||
await EmailSender.SendWelcomeMailAsync(subscriber,
|
||||
Localizer["WelcomeEmailSubject"], Localizer["WelcomeEmailTitle"], Localizer["WelcomeEmailBody"], articles);
|
||||
} catch (Exception ex) {
|
||||
Logger.LogError(ex, "Error trying to confirm subscriber.");
|
||||
Message = Localizer["Failure_Message"];
|
||||
|
|
|
@ -6,7 +6,7 @@ namespace Wave.Services;
|
|||
|
||||
public partial class EmailTemplateService(ILogger<EmailTemplateService> logger, IDistributedCache tokenCache, FileSystemService fileSystem) {
|
||||
public enum Constants {
|
||||
BrowserLink, HomeLink, ContentLogo, ContentTitle, ContentBody, EmailUnsubscribeLink
|
||||
BrowserLink, HomeLink, ContentLogo, ContentTitle, ContentBody, EmailUnsubscribeLink, ArticleRecommendations
|
||||
}
|
||||
|
||||
private ILogger<EmailTemplateService> Logger { get; } = logger;
|
||||
|
@ -62,9 +62,21 @@ public enum Constants {
|
|||
});
|
||||
}
|
||||
|
||||
public string Welcome(string home, string logoLink, string title, string body, string unsubscribe, string articles) {
|
||||
return Process("welcome", new Dictionary<Constants, object?> {
|
||||
{ Constants.HomeLink, home },
|
||||
{ Constants.ContentLogo, logoLink },
|
||||
{ Constants.ContentTitle, title },
|
||||
{ Constants.ContentBody, body },
|
||||
{ Constants.EmailUnsubscribeLink, unsubscribe },
|
||||
{ Constants.ArticleRecommendations, articles }
|
||||
});
|
||||
}
|
||||
|
||||
public void TryCreateDefaultTemplates() {
|
||||
FileSystem.GetEmailTemplate("default", DefaultTemplates["default"]);
|
||||
FileSystem.GetEmailTemplate("newsletter", DefaultTemplates["newsletter"]);
|
||||
FileSystem.GetEmailTemplate("welcome", DefaultTemplates["welcome"]);
|
||||
}
|
||||
|
||||
public string ApplyTokens(string template, Func<string, string?> replacer) {
|
||||
|
@ -189,6 +201,60 @@ public enum Constants {
|
|||
</mj-body>
|
||||
</mjml>
|
||||
"""
|
||||
},
|
||||
{
|
||||
"welcome",
|
||||
$"""
|
||||
<mjml>
|
||||
<mj-head>
|
||||
<mj-preview />
|
||||
</mj-head>
|
||||
<mj-body>
|
||||
<mj-section direction="rtl" padding-bottom="5px" padding-left="0px" padding-right="0px" padding-top="15px" padding="15px 0px 5px 0px">
|
||||
<mj-column vertical-align="middle" width="33%">
|
||||
<mj-image align="center" alt="" border-radius="0" border="none" container-background-color="transparent" height="auto" padding-bottom="5px" padding-left="5px" padding-right="5px" padding-top="5px" padding="5px 5px 5px 5px" href="[[{Constants.HomeLink}]]" src="[[{Constants.ContentLogo}]]"></mj-image>
|
||||
</mj-column>
|
||||
<mj-column vertical-align="middle" width="67%">
|
||||
<mj-text font-size="13px" font-family="Ubuntu,Verdana">
|
||||
<h1>[[{Constants.ContentTitle}]]</h1>
|
||||
</mj-text>
|
||||
</mj-column>
|
||||
</mj-section>
|
||||
<mj-section padding-top="5px" padding-bottom="5px" padding="5px 0 5px 0">
|
||||
<mj-column>
|
||||
<mj-divider border-color="#9f9f9f" border-width="1px"></mj-divider>
|
||||
</mj-column>
|
||||
</mj-section>
|
||||
<mj-section>
|
||||
<mj-column>
|
||||
<mj-text color="#55575d" font-size="13px" font-family="Ubuntu,Verdana">[[{Constants.ContentBody}]]</mj-text>
|
||||
</mj-column>
|
||||
</mj-section>
|
||||
<mj-section padding-top="5px" padding-bottom="5px" padding="5px 0 5px 0">
|
||||
<mj-column>
|
||||
<mj-divider border-color="#9f9f9f" border-width="1px"></mj-divider>
|
||||
</mj-column>
|
||||
</mj-section>
|
||||
<mj-section>
|
||||
<mj-column>
|
||||
<mj-text color="#55575d" font-size="13px" font-family="Ubuntu,Verdana">[[{Constants.ArticleRecommendations}]]</mj-text>
|
||||
</mj-column>
|
||||
</mj-section>
|
||||
<mj-section padding-top="5px" padding-bottom="5px" padding="5px 0 5px 0">
|
||||
<mj-column>
|
||||
<mj-divider border-color="#9f9f9f" border-width="1px"></mj-divider>
|
||||
</mj-column>
|
||||
</mj-section>
|
||||
<mj-section>
|
||||
<mj-column>
|
||||
<mj-text align="center" font-size="13px" font-family="Ubuntu,Verdana">
|
||||
<a href="[[{Constants.EmailUnsubscribeLink}]]">Unsubscribe</a>
|
||||
</mj-text>
|
||||
</mj-column>
|
||||
</mj-section>
|
||||
</mj-body>
|
||||
</mjml>
|
||||
"""
|
||||
}
|
||||
};
|
||||
}
|
|
@ -8,4 +8,6 @@ public interface IAdvancedEmailSender : IEmailSender {
|
|||
Task SendDefaultMailAsync(string receiverMail, string? receiverName, string subject, string title, string bodyHtml);
|
||||
Task SendSubscribedMailAsync(EmailSubscriber subscriber, string subject, string title, string bodyHtml,
|
||||
string browserUrl = "", string subscribedRole = "-1");
|
||||
Task SendWelcomeMailAsync(EmailSubscriber subscriber, string subject, string title, string bodyHtml,
|
||||
IEnumerable<EmailNewsletter> articles);
|
||||
}
|
|
@ -1,10 +1,12 @@
|
|||
using System.Net;
|
||||
using System.Text;
|
||||
using MailKit.Net.Smtp;
|
||||
using MailKit.Security;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MimeKit;
|
||||
using Wave.Data;
|
||||
using Wave.Utilities;
|
||||
using Uri = System.Uri;
|
||||
|
||||
namespace Wave.Services;
|
||||
|
@ -97,6 +99,38 @@ public Task SendEmailAsync(string email, string? name, string subject, string ht
|
|||
new Header(HeaderId.ListUnsubscribe, $"<{unsubscribeLink}>"),
|
||||
new Header(HeaderId.ListUnsubscribePost, "One-Click"));
|
||||
}
|
||||
|
||||
public async Task SendWelcomeMailAsync(EmailSubscriber subscriber, string subject, string title, string bodyHtml,
|
||||
IEnumerable<EmailNewsletter> articles) {
|
||||
(string user, string token) = await TemplateService
|
||||
.CreateConfirmTokensAsync(subscriber.Id, "unsubscribe-welcome", TimeSpan.FromDays(30));
|
||||
var host = new Uri(string.IsNullOrWhiteSpace(Customizations.AppUrl) ? "" : Customizations.AppUrl); // TODO get link
|
||||
|
||||
var articlesHtml = new StringBuilder("");
|
||||
foreach (var n in articles) {
|
||||
string articleLink = ArticleUtilities.GenerateArticleLink(n.Article, new Uri(Customizations.AppUrl, UriKind.Absolute));
|
||||
articlesHtml.AppendFormat(
|
||||
"""
|
||||
<div style="padding: 10px; background: #333; color: #fff; margin-bottom: 10px">
|
||||
<h3>{0}</h3>
|
||||
<small>{1}</small>
|
||||
<p>{2}</p>
|
||||
<a href="{3}">Link</a>
|
||||
</div>
|
||||
""",
|
||||
n.Article.Title, n.Article.Author.Name, n.Article.Body[..Math.Min(100, n.Article.Body.Length)], articleLink);
|
||||
}
|
||||
|
||||
string logo = !string.IsNullOrWhiteSpace(Customizations.LogoLink)
|
||||
? Customizations.LogoLink
|
||||
: new Uri(host, "/img/logo.png").AbsoluteUri;
|
||||
string unsubscribeLink = new Uri(host,
|
||||
$"/Email/Unsubscribe?newsletter=welcome&user={WebUtility.UrlEncode(user)}&token={WebUtility.UrlEncode(token)}").AbsoluteUri;
|
||||
string body = TemplateService.Welcome(host.AbsoluteUri, logo, title, bodyHtml, unsubscribeLink, articlesHtml.ToString());
|
||||
await SendEmailAsync(subscriber.Email, subscriber.Name, subject, body,
|
||||
new Header(HeaderId.ListUnsubscribe, $"<{unsubscribeLink}>"),
|
||||
new Header(HeaderId.ListUnsubscribePost, "One-Click"));
|
||||
}
|
||||
}
|
||||
|
||||
public class EmailNotSendException(string message, Exception exception) : ApplicationException(message, exception);
|
Loading…
Reference in a new issue