diff options
Diffstat (limited to 'src/mail.rs')
-rw-r--r-- | src/mail.rs | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/src/mail.rs b/src/mail.rs index e69de29..841b552 100644 --- a/src/mail.rs +++ b/src/mail.rs @@ -0,0 +1,81 @@ +use std::{str::FromStr, sync::Arc, time::Duration}; + +use anyhow::{anyhow, Result}; +use lettre::{ + message::Mailbox, transport::smtp::authentication::Credentials, Message, SmtpTransport, + Transport, +}; +use log::info; +use serde::Deserialize; + +use crate::Config; + +#[derive(Debug, Deserialize)] +pub struct MailConfig { + from: String, + to: Vec<String>, + smtp_auth: SmtpAuth, + smtp_port: u16, + smtp_timeout: Option<f64>, + smtp_server: String, + smtp_username: Option<String>, + smtp_password: Option<String>, +} + +#[derive(Clone, Deserialize, Debug)] +#[serde(rename_all = "snake_case")] +enum SmtpAuth { + Plain, + Tls, + Starttls, +} + +pub async fn send_mail( + config: &Arc<Config>, + service: usize, + check: usize, + error: String, +) -> Result<()> { + let config = config.to_owned(); + tokio::task::spawn_blocking(move || { + if let Some(mconfig) = &config.mail { + info!("sending mail!"); + let mut transport = match mconfig.smtp_auth { + SmtpAuth::Plain => SmtpTransport::builder_dangerous(&mconfig.smtp_server), + SmtpAuth::Tls => SmtpTransport::relay(&mconfig.smtp_server)?, + SmtpAuth::Starttls => SmtpTransport::starttls_relay(&mconfig.smtp_server)?, + } + .port(mconfig.smtp_port); + + if let Some(username) = mconfig.smtp_username.clone() { + let password = mconfig + .smtp_password + .clone() + .ok_or(anyhow!("smtp password missing"))?; + transport = transport.credentials(Credentials::new(username, password)); + } + if let Some(timeout) = mconfig.smtp_timeout { + transport = transport.timeout(Some(Duration::from_secs_f64(timeout))) + } + let transport = transport.build(); + + for recipient in &mconfig.to { + let service = &config.services[service]; + + let message = Message::builder() + .from(Mailbox::from_str(&mconfig.from)?) + .to(Mailbox::from_str(&recipient)?) + .subject(format!("{} failed.", service.title)) + .body(format!( + "Check {:?} reported:\n{}", + service.checks[check].display(), + error + ))?; + transport.send(&message)?; + } + } + Ok::<_, anyhow::Error>(()) + }) + .await??; + Ok(()) +} |