]> Untitled Git - lemmy.git/blob - crates/utils/src/email.rs
Upgrading deps (#1995)
[lemmy.git] / crates / utils / src / email.rs
1 use crate::settings::structs::Settings;
2 use lettre::{
3   message::{header, Mailbox, MultiPart, SinglePart},
4   transport::smtp::{
5     authentication::Credentials,
6     client::{Tls, TlsParameters},
7     extension::ClientId,
8   },
9   Address,
10   Message,
11   SmtpTransport,
12   Transport,
13 };
14 use std::str::FromStr;
15 use uuid::Uuid;
16
17 pub fn send_email(
18   subject: &str,
19   to_email: &str,
20   to_username: &str,
21   html: &str,
22   settings: &Settings,
23 ) -> Result<(), String> {
24   let email_config = settings.email.to_owned().ok_or("no_email_setup")?;
25   let domain = settings.hostname.to_owned();
26
27   let (smtp_server, smtp_port) = {
28     let email_and_port = email_config.smtp_server.split(':').collect::<Vec<&str>>();
29     (
30       email_and_port[0],
31       email_and_port[1]
32         .parse::<u16>()
33         .expect("email needs a port"),
34     )
35   };
36
37   let email = Message::builder()
38     .from(
39       email_config
40         .smtp_from_address
41         .parse()
42         .expect("email from address isn't valid"),
43     )
44     .to(Mailbox::new(
45       Some(to_username.to_string()),
46       Address::from_str(to_email).expect("email to address isn't valid"),
47     ))
48     .message_id(Some(format!("{}@{}", Uuid::new_v4(), settings.hostname)))
49     .subject(subject)
50     .multipart(
51       MultiPart::mixed().multipart(
52         MultiPart::alternative()
53           .singlepart(
54             SinglePart::builder()
55               .header(header::ContentType::TEXT_PLAIN)
56               .body(html.to_string()),
57           )
58           .multipart(
59             MultiPart::related().singlepart(
60               SinglePart::builder()
61                 .header(header::ContentType::TEXT_HTML)
62                 .body(html.to_string()),
63             ),
64           ),
65       ),
66     )
67     .expect("email built incorrectly");
68
69   // don't worry about 'dangeous'. it's just that leaving it at the default configuration
70   // is bad.
71   let mut builder = SmtpTransport::builder_dangerous(smtp_server).port(smtp_port);
72
73   // Set the TLS
74   if email_config.use_tls {
75     let tls_config = TlsParameters::new(smtp_server.to_string()).expect("the TLS backend is happy");
76     builder = builder.tls(Tls::Wrapper(tls_config));
77   }
78
79   // Set the creds if they exist
80   if let (Some(username), Some(password)) = (email_config.smtp_login, email_config.smtp_password) {
81     builder = builder.credentials(Credentials::new(username, password));
82   }
83
84   let mailer = builder.hello_name(ClientId::Domain(domain)).build();
85
86   let result = mailer.send(&email);
87
88   match result {
89     Ok(_) => Ok(()),
90     Err(e) => Err(e.to_string()),
91   }
92 }