From 6195dff02be8414ce205d4223a3181d82858b032 Mon Sep 17 00:00:00 2001 From: hi-rustin Date: Fri, 5 Apr 2024 13:17:18 +0800 Subject: [PATCH] feat: send emails --- src/worker/jobs/expiry_notification.rs | 41 ++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/src/worker/jobs/expiry_notification.rs b/src/worker/jobs/expiry_notification.rs index 2637f7d1296..1c98ac51d5b 100644 --- a/src/worker/jobs/expiry_notification.rs +++ b/src/worker/jobs/expiry_notification.rs @@ -1,9 +1,10 @@ -use std::sync::Arc; -use diesel::{Connection, PgConnection}; - +use crate::{email::Email, models::User, worker::Environment, Emails}; +use anyhow::anyhow; use crates_io_worker::BackgroundJob; -use crate::Emails; -use crate::worker::Environment; +use diesel::{ + dsl::now, Connection, ExpressionMethods, NullableExpressionMethods, PgConnection, RunQueryDsl, +}; +use std::sync::Arc; /// The threshold in days for the expiry notification. const EXPIRY_THRESHOLD: i64 = 3; @@ -38,6 +39,19 @@ fn check(emails: &Emails, conn: &mut PgConnection) -> anyhow::Result<()> { conn.transaction(|conn| { for token in chunk { // Send notification. + let user = User::find(conn, token.user_id)?; + let Some(recipient) = user.email(conn)? else { + return Err(anyhow!("No address found")); + }; + let email = ExpiryNotificationEmail { + token_name: token.name.clone(), + expiry_date: token.expired_at.unwrap().date().to_string(), + }; + emails.send(&recipient, email)?; + // Also update the token to prevent duplicate notifications. + diesel::update(token) + .set(crate::schema::api_tokens::expiry_notification_at.eq(now.nullable())) + .execute(conn)?; } Ok::<_, anyhow::Error>(()) })?; @@ -45,3 +59,20 @@ fn check(emails: &Emails, conn: &mut PgConnection) -> anyhow::Result<()> { Ok(()) } + +#[derive(Debug, Clone)] +struct ExpiryNotificationEmail { + token_name: String, + expiry_date: String, +} + +impl Email for ExpiryNotificationEmail { + const SUBJECT: &'static str = "Token Expiry Notification"; + + fn body(&self) -> String { + format!( + "The token {} is about to expire on {}. Please take action.", + self.token_name, self.expiry_date + ) + } +}