Custom Emails (#4526)

* Dynamic email template

* Set lower cache expiry for templates

* Custom email route

* Fix subject line on custom emails

* chore: query cache, clippy, fmt

* Bugfixes

* Key-based caching on custom emails

* Sequentially process emails prone to causing cache stampede

* Fill variables in dynamic body + subject line

* Update apps/labrinth/src/queue/email/templates.rs

Co-authored-by: aecsocket <aecsocket@tutanota.com>
Signed-off-by: François-Xavier Talbot <108630700+fetchfern@users.noreply.github.com>

* Update apps/labrinth/src/queue/email/templates.rs

Co-authored-by: aecsocket <aecsocket@tutanota.com>
Signed-off-by: François-Xavier Talbot <108630700+fetchfern@users.noreply.github.com>

---------

Signed-off-by: François-Xavier Talbot <108630700+fetchfern@users.noreply.github.com>
Co-authored-by: aecsocket <aecsocket@tutanota.com>
This commit is contained in:
François-Xavier Talbot
2025-10-10 17:30:38 +01:00
committed by GitHub
parent aec49cff7c
commit 0c66fa3f12
6 changed files with 342 additions and 65 deletions

View File

@@ -139,6 +139,11 @@ pub enum LegacyNotificationBody {
amount: u64,
date_available: DateTime<Utc>,
},
Custom {
key: String,
title: String,
body_md: String,
},
Unknown,
}
@@ -217,6 +222,7 @@ impl LegacyNotification {
NotificationBody::PayoutAvailable { .. } => {
Some("payout_available".to_string())
}
NotificationBody::Custom { .. } => Some("custom".to_string()),
NotificationBody::LegacyMarkdown {
notification_type, ..
} => notification_type.clone(),
@@ -378,6 +384,15 @@ impl LegacyNotification {
service,
currency,
},
NotificationBody::Custom {
title,
body_md,
key,
} => LegacyNotificationBody::Custom {
title,
body_md,
key,
},
NotificationBody::PaymentFailed { amount, service } => {
LegacyNotificationBody::PaymentFailed { amount, service }
}

View File

@@ -56,6 +56,7 @@ pub enum NotificationType {
ProjectStatusNeutral,
ProjectTransferred,
PayoutAvailable,
Custom,
Unknown,
}
@@ -89,6 +90,7 @@ impl NotificationType {
NotificationType::ProjectStatusApproved => {
"project_status_approved"
}
NotificationType::Custom => "custom",
NotificationType::ProjectStatusNeutral => "project_status_neutral",
NotificationType::ProjectTransferred => "project_transferred",
NotificationType::Unknown => "unknown",
@@ -125,6 +127,7 @@ impl NotificationType {
}
"project_status_neutral" => NotificationType::ProjectStatusNeutral,
"project_transferred" => NotificationType::ProjectTransferred,
"custom" => NotificationType::Custom,
"unknown" => NotificationType::Unknown,
_ => NotificationType::Unknown,
}
@@ -236,6 +239,11 @@ pub enum NotificationBody {
date_available: DateTime<Utc>,
amount: u64,
},
Custom {
key: String,
title: String,
body_md: String,
},
Unknown,
}
@@ -313,6 +321,7 @@ impl NotificationBody {
NotificationBody::PayoutAvailable { .. } => {
NotificationType::PayoutAvailable
}
NotificationBody::Custom { .. } => NotificationType::Custom,
NotificationBody::Unknown => NotificationType::Unknown,
}
}
@@ -557,6 +566,12 @@ impl From<DBNotification> for Notification {
"#".to_string(),
vec![],
),
NotificationBody::Custom { title, .. } => (
"Notification".to_string(),
title.clone(),
"#".to_string(),
vec![],
),
NotificationBody::Unknown => {
("".to_string(), "".to_string(), "#".to_string(), vec![])
}