email-service 0.1.0

An easy way to configure simple mail sender
Documentation
use lettre::{
    transport::smtp::{self, authentication::Credentials},
    Address, Message, Transport,
};

pub struct EmailClientConfig {
    pub smtp_host: String,
    pub smtp_port: u16,
    pub smtp_username: String,
    pub smtp_password: String,
}

pub struct EmailClient {
    config: EmailClientConfig,
}

impl EmailClient {
    pub fn new(config: EmailClientConfig) -> Self {
        EmailClient { config }
    }

    pub async fn send_email(
        &self,
        to: String,
        subject: String,
        body: String,
    ) -> Result<(), Box<dyn std::error::Error>> {
        let smtp_config = smtp::SmtpTransport::starttls_relay(&self.config.smtp_host)
            .unwrap()
            .port(self.config.smtp_port)
            .credentials(Credentials::new(
                self.config.smtp_username.clone(),
                self.config.smtp_password.clone(),
            ))
            .build();

        let _conn = smtp_config.test_connection()?;

        let address = self.config.smtp_username.parse::<Address>()?;

        let mailbox = lettre::message::Mailbox::new(None, address);

        let email = Message::builder()
            .from(mailbox)
            .to(to.parse().unwrap())
            .subject(subject)
            .body(body)
            .unwrap();

        smtp_config.send(&email)?;

        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use dotenv::dotenv;
    use std::env;

    #[tokio::test]
    async fn test_smtp_connection() -> Result<(), Box<dyn std::error::Error>> {
        dotenv().ok();

        let smtp_host = env::var("SMTP_HOST").expect("SMTP_HOST is missing");
        let smtp_port = env::var("SMTP_PORT")
            .expect("SMTP_PORT is missing")
            .parse::<u16>()?;
        let smtp_username = env::var("SMTP_USERNAME").expect("SMTP_USERNAME is missing");
        let smtp_password = env::var("SMTP_PASSWORD").expect("SMTP_PASSWORD is missing");

        let config = EmailClientConfig {
            smtp_host,
            smtp_port,
            smtp_username,
            smtp_password,
        };

        let email_client = EmailClient::new(config);

        // Attempt to send a test email (replace with a valid recipient)
        let result = email_client
            .send_email(
                "test@example.com".to_string(),
                "Test Connection".to_string(),
                "Test".to_string(),
            )
            .await;

        // Assert that the connection was successful (no error)
        assert!(result.is_ok());

        Ok(())
    }
}