debt-pirate/api/src/services/mailer/service.rs

106 lines
3.2 KiB
Rust
Raw Normal View History

use std::{
fs::File,
io::Read,
path::Path,
sync::{mpsc::Receiver, LazyLock},
thread,
};
use lettre::{
message::{header::ContentType, Mailbox},
transport::smtp::{
authentication::{Credentials, Mechanism},
PoolConfig,
},
AsyncSmtpTransport, AsyncTransport, Message, Tokio1Executor,
};
use tokio::runtime::Handle;
use super::UserConfirmationMessage;
static CREDENTIALS: LazyLock<Credentials> = LazyLock::new(|| {
Credentials::new(
"donotreply@mail.dziura.cloud".to_owned(),
"hunter2".to_owned(),
)
});
static NUM_CPUS: LazyLock<u32> = LazyLock::new(|| num_cpus::get() as u32);
static FROM_MAILBOX: LazyLock<Mailbox> = LazyLock::new(|| {
"No Not Reply Auth-Test <donotreply@mail.dziura.cloud>"
.parse()
.unwrap()
});
pub fn start_emailer_service(
runtime: Handle,
assets_dir: &Path,
email_message_rx: Receiver<UserConfirmationMessage>,
) {
let new_user_confirmation_template_path = assets_dir.join("new-user-confirmation.html");
// TODO: Validate that the new user confirmation template exists
let mut new_user_confirmation_template_text = String::with_capacity(8000);
File::open(new_user_confirmation_template_path)
.and_then(|mut file| file.read_to_string(&mut new_user_confirmation_template_text))
.unwrap();
thread::spawn(move || {
while let Some(message) = email_message_rx.iter().next() {
let new_user_confirmation_template_text = new_user_confirmation_template_text.clone();
let UserConfirmationMessage {
email: recipient_email,
name,
2024-11-15 22:17:09 -05:00
user_id,
2024-10-03 15:27:30 -04:00
verification_token,
} = message;
runtime.spawn(async move {
send_new_user_confirmation_email(
recipient_email.as_str(),
new_user_confirmation_template_text.as_str(),
name.as_str(),
2024-11-15 22:17:09 -05:00
user_id,
2024-10-03 15:27:30 -04:00
verification_token.as_str(),
)
.await;
});
}
});
}
async fn send_new_user_confirmation_email(
recipient_email: &str,
new_user_confirmation_template_text: &str,
name: &str,
2024-11-15 22:17:09 -05:00
user_id: i32,
2024-10-03 15:27:30 -04:00
verification_token: &str,
) {
let body = new_user_confirmation_template_text
.replace("$NAME", name)
2024-11-15 22:17:09 -05:00
.replace("$USER_ID", user_id.to_string().as_str())
2024-10-03 15:27:30 -04:00
.replace("$VERIFICATION_TOKEN", verification_token);
let message = Message::builder()
.from(FROM_MAILBOX.clone())
.reply_to(FROM_MAILBOX.clone())
.to(recipient_email.parse().unwrap())
.subject(format!(
"You're registered, {name}, please confirm your email address"
))
.header(ContentType::TEXT_HTML)
.body(body)
.unwrap();
let sender: AsyncSmtpTransport<Tokio1Executor> =
AsyncSmtpTransport::<Tokio1Executor>::starttls_relay("mail.dziura.cloud")
.unwrap()
.credentials(CREDENTIALS.clone())
.authentication(vec![Mechanism::Plain])
.pool_config(PoolConfig::new().max_size(*NUM_CPUS))
.build();
let _ = sender.send(message).await;
}