use rustlavel::prelude::*;
use rustlavel::mail::{Mailer, Message};
use crate::support::settings::Settings;
async fn mailer_for(req: &Request) -> Option<Mailer> {
let settings = req.state::<Settings>()?;
let mut config = rustlavel::mail::MailConfig::from_app_config(req.config()).ok()?;
if let Ok(transport) = rustlavel::mail::TransportKind::parse(&settings.get("mail.driver").await) {
config.transport = transport;
}
let host = settings.get("mail.host").await;
if !host.is_empty() {
config.host = host;
}
if let Ok(port) = settings.get("mail.port").await.parse::<u16>()
&& port > 0
{
config.port = port;
}
if let Ok(encryption) = rustlavel::mail::Encryption::parse(&settings.get("mail.encryption").await) {
config.encryption = encryption;
}
config.username = settings.get("mail.username").await;
config.password = settings.get("mail.password").await;
config.from_address = settings.get("mail.from.address").await;
config.from_name = settings.get("mail.from.name").await;
Mailer::build(&config).ok()
}
pub async fn send(req: &Request, message: Message) -> Result<()> {
let mailer = match mailer_for(req).await {
Some(built) => built,
None => match req.state::<Mailer>() {
Some(booted) => booted.clone(),
None => {
warn!(
"no mailer is configured; a message to {} was not sent",
message.envelope_recipients().join(", ")
);
return Ok(());
}
},
};
mailer.send(with_from(req, message).await).await
}
pub async fn with_from(req: &Request, message: Message) -> Message {
if message.sender().is_some() {
return message;
}
let (address, name) = from_address(req).await;
if address.is_empty() {
return message;
}
match name.is_empty() {
true => message.from(address.as_str()),
false => message.from((name.as_str(), address.as_str())),
}
}
pub async fn from_address(req: &Request) -> (String, String) {
match req.state::<Settings>() {
Some(settings) => (
settings.get("mail.from.address").await,
settings.get("mail.from.name").await,
),
None => (
req.config().string("mail.from.address", ""),
req.config().string("mail.from.name", ""),
),
}
}