Implemented Author cards for email newletter

This commit is contained in:
Mia Rose Winter 2024-03-14 14:23:16 +01:00
parent 7cd24d29f7
commit 8d0a21c833
Signed by: miawinter
GPG key ID: 4B6F6A83178F595E
3 changed files with 32 additions and 4 deletions

View file

@ -82,6 +82,14 @@ public class EmailFactory(IOptions<Customization> customizations, EmailTemplateS
}.ToFrozenDictionary());
}
public async ValueTask<string> CreateAuthorCard(ApplicationUser user, Uri host) {
var profileLink = new Uri(host, "/profile/" + user.Id);
var pfpLink = new Uri(host, "api/user/pfp/" + user.Id + "?size=100");
string partial = await TemplateService.GetPartialAsync("email-author");
return string.Format(partial, pfpLink, user.FullName, user.AboutTheAuthor, profileLink.AbsoluteUri);
}
public async ValueTask<Guid?> IsTokenValid(string id, string token) {
return await TemplateService.ValidateTokensAsync(id, token, deleteToken: false);
}

View file

@ -98,6 +98,7 @@ public enum Constants {
FileSystem.GetEmailTemplate("welcome", DefaultTemplates["welcome"]);
FileSystem.GetPartialTemplate("email-article", DefaultPartials["email-article"]);
FileSystem.GetPartialTemplate("email-plain-footer", DefaultPartials["email-plain-footer"]);
FileSystem.GetPartialTemplate("email-author", DefaultPartials["email-author"]);
}
public string ApplyTokens(string template, Func<string, string?> replacer) {
@ -312,6 +313,20 @@ public enum Constants {
{
"email-plain-footer",
$"Unsubscribe: [[{Constants.EmailUnsubscribeLink}]]"
},
{
"email-author",
"""
<div style="padding: 1em; border: 1px solid black; box-shadow: 4px 4px 0 0 currentColor; background: #ffb3c8; margin-top: 12px; min-height: 108px">
<img style="float: left; margin: 0 8px 8px 0; border: 1px solid transparent; border-radius: 4px"
src="{0}" alt="" width="100" />
<span style="margin: 0; color: black">
<h2 style="color: black; margin-top: 0;">{1}</h2>
<p>{2}</p>
<a target="_blank" style="color: black" href="{3}">Profile</a>
</span>
</div>
"""
}
};
}

View file

@ -18,9 +18,10 @@ public class NewsletterBackgroundService(ILogger<NewsletterBackgroundService> lo
await using var context = await ContextFactory.CreateDbContextAsync(cancellationToken);
var now = DateTimeOffset.UtcNow;
var newsletters = context.Set<EmailNewsletter>()
.IgnoreQueryFilters()
.Include(n => n.Article.Author)
.Include(n => n.Article.Categories)
.Where(n => !n.IsSend && n.DistributionDateTime <= now)
.Where(n => !n.Article.IsDeleted && !n.IsSend && n.DistributionDateTime <= now)
.ToList();
if (newsletters.Count < 1) return;
@ -38,6 +39,9 @@ public class NewsletterBackgroundService(ILogger<NewsletterBackgroundService> lo
string replyTo = "";
if (!string.IsNullOrWhiteSpace(newsletter.Article.Author.ContactEmail))
replyTo = $"{newsletter.Article.Author.Name} <{newsletter.Article.Author.ContactEmail}>";
string aboutTheAuthor = await factory.CreateAuthorCard(
newsletter.Article.Author,
new Uri(Customizations.AppUrl, UriKind.Absolute));
Logger.LogInformation("Processing '{title}'.", newsletter.Article.Title);
// set newsletter to send first, so we don't spam people
@ -55,10 +59,11 @@ public class NewsletterBackgroundService(ILogger<NewsletterBackgroundService> lo
last = subscribers.Last();
foreach (var subscriber in subscribers) {
var email = await factory.CreateSubscribedEmail(subscriber, articleLink,
var email = await factory.CreateSubscribedEmail(
subscriber, articleLink,
newsletter.Article.Title,
newsletter.Article.Title,
newsletter.Article.BodyHtml,
newsletter.Article.BodyHtml + aboutTheAuthor,
newsletter.Article.BodyPlain,
"newsletter-" + newsletter.Id, replyTo);
await client.SendEmailAsync(email);