Implemented mail notifications.

This commit is contained in:
2024-02-12 17:17:26 +01:00
parent d18ef72d03
commit 1b6f544e55
9 changed files with 720 additions and 78 deletions
+74
View File
@@ -10,6 +10,13 @@ cfg_if! { if #[cfg(feature = "ssr")] {
use crate::backend::get_pool;
use crate::error::AppError;
use log::info;
use crate::config::Mailing;
use crate::config::MailTransport;
use crate::backend::data::ResSumWithItems;
use lettre::message::Message as LettreMessage;
use lettre::{AsyncSmtpTransport, AsyncFileTransport, AsyncTransport, Tokio1Executor};
use lettre::transport::smtp::authentication::Credentials;
use std::ops::Add;
pub async fn message_for_type(msg_type: &MessageType, pool: &PgPool) -> Result<Message, Error> {
Ok(query_as::<_, Message>("SELECT * FROM message WHERE msg_type = $1")
@@ -48,6 +55,73 @@ cfg_if! { if #[cfg(feature = "ssr")] {
Ok(())
}
pub struct MailMessage {
reply_to: String,
to: String,
subject: String,
text: String
}
impl MailMessage {
pub fn new(reply_to: String, to: String, message: Message, reservation: &ResSumWithItems) -> Self {
Self {
reply_to,
to,
subject: message.subject,
text: Self::replace_body_vars(message.text, &reservation)
}
}
fn replace_body_vars(text: String, reservation: &ResSumWithItems) -> String {
text
.replace("#date#", &reservation.summary.date.format("%d. %m. %Y").to_string())
.replace("#summary#", &{
let mut sum = "".to_string();
for p in &reservation.reservations {
sum = sum.add(&format!("{}: {} - {}",
p.property.name,
p.reservation.from.format("%H:%M").to_string(), p.reservation.to.format("%H:%M").to_string()));
}
sum
}
)
}
pub fn build_mail(&self, from: String) -> Result<LettreMessage, AppError> {
Ok(LettreMessage::builder()
.from(from.parse()?)
.reply_to(self.reply_to.parse()?)
.to(self.to.parse()?)
.subject(&self.subject)
.body(self.text.clone())?)
}
}
impl Mailing {
pub async fn send_mail(&self, msg: MailMessage) -> Result<(), AppError> {
match self.transport() {
MailTransport::Smtp => {
let transport = if self.tls().unwrap_or(false) {
AsyncSmtpTransport::<Tokio1Executor>::starttls_relay(&self.server().clone().unwrap_or_default())
} else {
AsyncSmtpTransport::<Tokio1Executor>::relay(&self.server().clone().unwrap_or_default())
}.expect("Cannot create SMTP mail transport");
if self.user().is_some() && self.password().is_some() {
let cred = Credentials::new(self.user().clone().unwrap(), self.password().clone().unwrap());
transport.credentials(cred).build().send(msg.build_mail(self.from().to_string())?).await?;
} else {
transport.build().send(msg.build_mail(self.from().to_string())?).await?;
}
}
MailTransport::File => {
AsyncFileTransport::<Tokio1Executor>::new(self.path().clone().unwrap_or_default())
.send(msg.build_mail(self.from().to_string())?).await?;
}
}
Ok(())
}
}
}}
#[server]