1 use crate::{error::LemmyError, settings::structs::Settings};
4 message::{Mailbox, MultiPart},
5 transport::smtp::{authentication::Credentials, extension::ClientId},
11 use std::str::FromStr;
14 pub mod translations {
15 rosetta_i18n::include_translations!();
24 ) -> Result<(), LemmyError> {
25 let email_config = settings
28 .ok_or_else(|| LemmyError::from_message("no_email_setup"))?;
29 let domain = settings.hostname.clone();
31 let (smtp_server, smtp_port) = {
32 let email_and_port = email_config.smtp_server.split(':').collect::<Vec<&str>>();
33 let email = *email_and_port
35 .ok_or_else(|| LemmyError::from_message("missing an email"))?;
36 let port = email_and_port
39 LemmyError::from_message("email.smtp_server needs a port, IE smtp.xxx.com:465")
46 // use usize::MAX as the line wrap length, since lettre handles the wrapping for us
47 let plain_text = html2text::from_read(html.as_bytes(), usize::MAX);
49 let email = Message::builder()
54 .expect("email from address isn't valid"),
57 Some(to_username.to_string()),
58 Address::from_str(to_email).expect("email to address isn't valid"),
60 .message_id(Some(format!("<{}@{}>", Uuid::new_v4(), settings.hostname)))
62 .multipart(MultiPart::alternative_plain_html(
66 .expect("email built incorrectly");
68 // don't worry about 'dangeous'. it's just that leaving it at the default configuration
72 let builder_dangerous = SmtpTransport::builder_dangerous(smtp_server).port(smtp_port);
74 let mut builder = match email_config.tls_type.as_str() {
75 "starttls" => SmtpTransport::starttls_relay(smtp_server)?,
76 "tls" => SmtpTransport::relay(smtp_server)?,
77 _ => builder_dangerous,
80 // Set the creds if they exist
81 if let (Some(username), Some(password)) = (email_config.smtp_login, email_config.smtp_password) {
82 builder = builder.credentials(Credentials::new(username, password));
85 let mailer = builder.hello_name(ClientId::Domain(domain)).build();
87 let result = mailer.send(&email);
91 Err(e) => Err(LemmyError::from_error_message(e, "email_send_failed")),