cnc_rs/config/
email.rs

1use anyhow::Result;
2use lettre::{
3    message::{header::ContentType, Mailbox},
4    transport::smtp::authentication::Credentials,
5    Message, SmtpTransport, Transport,
6};
7
8use serde::Deserialize;
9
10#[derive(Deserialize, Debug)]
11pub struct SMTP {
12    pub enabled: bool,
13
14    pub username: String,
15    pub password: String,
16    pub smtp_host: String,
17    pub smtp_port: u16,
18
19    pub from: String,
20    pub to: Vec<String>,
21    pub cc: Option<Vec<String>>,
22}
23
24impl SMTP {
25    pub fn send_email(&self, subjet: String, body: String) -> Result<()> {
26        let from_address: Mailbox = self.from.parse()?;
27        let to_addresses: Vec<Mailbox> = self
28            .to
29            .iter()
30            .filter_map(|email| email.parse().ok())
31            .collect();
32
33        let mut builder = Message::builder().from(from_address).subject(subjet);
34        for to_addr in &to_addresses {
35            builder = builder.to(to_addr.clone());
36        }
37
38        if let Some(cc_list) = &self.cc {
39            for email in cc_list {
40                if let Ok(cc_addr) = email.parse() {
41                    builder = builder.cc(cc_addr);
42                }
43            }
44        }
45
46        let email = builder.header(ContentType::TEXT_PLAIN).body(body)?;
47        let creds = Credentials::new(self.username.to_owned(), self.password.to_owned());
48
49        let mailer = SmtpTransport::relay(&self.smtp_host)
50            .unwrap()
51            .credentials(creds)
52            .build();
53
54        match mailer.send(&email) {
55            Ok(_) => Ok(()),
56            Err(e) => Err(anyhow::anyhow!("Could not send email: {e:?}")),
57        }
58    }
59}