1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
//! Create a dynamic mailer trait object depending on runtime mailer configuration.
//!
//! Microsoft Outlook and SMTP mailer variants are available.
//!
//! Example:
//!
//! ```no_run
//! // Outlook configuration, e.g. from command line arguments or environment variables.
//! let mailer_configuration = MailerConfiguration::Outlook {
//! tenant: "<Microsoft Identity service tenant>",
//! app_guid: "<OAuth2 app GUID>",
//! secret: "<OAuth2 app secret>"
//! };
//!
//! // Alternative: SMTP configuration, e.g. from command line arguments or environment variables.
//! let mailer_configuration = MailerConfiguration::Outlook {
//! host: "smtp.example.com",
//! port: 465,
//! invalid_certs: SmtpInvalidCertsPolicy::Deny,
//! user: "<username>",
//! password: "<password>"
//! };
//!
//! // Create a `Box<dyn Mailer>`.
//! // The implementation is `Send` and `Sync` and may be store e.g. as part of your server state.
//! let mailer = new_mailer(mailer_configuration).await?;
//!
//! // Build a message using the re-exported `mail_builder::MessageBuilder'.
//! // For blazingly fast rendering of beautiful HTML mail, I recommend combining `askama` with `mrml`.
//! let message = MessageBuilder::new()
//! .from(("From Name", "from@example.com"))
//! .to("to@example.com")
//! .subject("Subject")
//! .text_body("Mail body");
//!
//! // Send the message using the implementation-agnostic `dyn Mailer`.
//! mailer.send_mail(&message).await?;
//! ```
use std::sync::Arc;
pub use secrecy::Secret;
#[cfg(feature = "tracing")]
use tracing::instrument;
pub use async_mailer_core::mail_send::mail_builder::MessageBuilder;
pub use async_mailer_core::mail_send::smtp::message::Message;
pub use async_mailer_core::Mailer;
#[cfg(feature = "outlook")]
pub use async_mailer_outlook::*;
#[cfg(feature = "smtp")]
pub use async_mailer_smtp::*;
/// Mailer configuration helper, which can be used with clap.
#[derive(Clone, Debug)]
pub enum MailerConfiguration {
#[cfg(feature = "outlook")]
Outlook {
/// Microsoft Active Directory tenant
tenant: String,
/// Outlook OAuth 2.0 application ID
app_guid: String,
/// Outlook OAuth 2.0 client secret
secret: Secret<String>,
},
#[cfg(feature = "smtp")]
Smtp {
/// SMTP host
host: String,
/// SMTP port
port: u16,
/// Allow or deny invalid (self-signed) certificates. Set to 'deny' except on local test environments
invalid_certs: SmtpInvalidCertsPolicy,
/// SMTP user
user: String,
/// SMTP password
password: Secret<String>,
},
}
/// Create a new dynamic mailer trait object depending on the provided [`MailerConfiguration`].
#[cfg_attr(feature = "tracing", instrument)]
pub async fn new_mailer(
mailer_configuration: MailerConfiguration,
) -> Result<Arc<dyn Mailer>, MailerError> {
match mailer_configuration {
// Outlook mailer - used in production
#[cfg(feature = "outlook")]
MailerConfiguration::Outlook {
tenant,
app_guid,
secret,
} => Ok(Arc::new(
OutlookMailer::new(tenant, app_guid, secret).await?,
)),
// SMTP mailer - used during development and testing
#[cfg(feature = "smtp")]
MailerConfiguration::Smtp {
host,
port,
invalid_certs,
user,
password,
} => Ok(Arc::new(SmtpMailer::new(
host,
port,
invalid_certs,
user,
password,
))),
}
}