#![warn(clippy::too_many_arguments)] use lettre_email::Email; use std::env; pub use self::mailer::*; #[cfg(feature = "debug-mailer")] mod mailer { use lettre::{SendableEmail, Transport}; use std::io::Read; pub struct DebugTransport; impl<'a> Transport<'a> for DebugTransport { type Result = Result<(), ()>; fn send(&mut self, email: SendableEmail) -> Self::Result { println!( "{}: from=<{}> to=<{:?}>\n{:#?}", email.message_id().to_string(), email .envelope() .from() .map(ToString::to_string) .unwrap_or_default(), email.envelope().to().to_vec(), { let mut message = String::new(); email .message() .read_to_string(&mut message) .map_err(|_| ())?; message }, ); Ok(()) } } pub type Mailer = Option; pub fn init() -> Mailer { Some(DebugTransport) } } #[cfg(not(feature = "debug-mailer"))] mod mailer { use lettre::{ smtp::{ authentication::{Credentials, Mechanism}, extension::ClientId, ConnectionReuseParameters, }, SmtpClient, SmtpTransport, }; use std::env; pub type Mailer = Option; pub fn init() -> Mailer { let server = env::var("MAIL_SERVER").ok()?; let helo_name = env::var("MAIL_HELO_NAME").unwrap_or_else(|_| "localhost".to_owned()); let username = env::var("MAIL_USER").ok()?; let password = env::var("MAIL_PASSWORD").ok()?; let mail = SmtpClient::new_simple(&server) .unwrap() .hello_name(ClientId::Domain(helo_name)) .credentials(Credentials::new(username, password)) .smtp_utf8(true) .authentication_mechanism(Mechanism::Plain) .connection_reuse(ConnectionReuseParameters::NoReuse) .transport(); Some(mail) } } pub fn build_mail(dest: String, subject: String, body: String) -> Option { Email::builder() .from( env::var("MAIL_ADDRESS") .or_else(|_| { Ok(format!( "{}@{}", env::var("MAIL_USER")?, env::var("MAIL_SERVER")? )) as Result<_, env::VarError> }) .expect("The email server is not configured correctly"), ) .to(dest) .subject(subject) .text(body) .build() .ok() }