Sending Email
We can use the excellent library Lettre for sending emails. I recommend installing Mailhog into your .devcontainer/docker-compose.yml
as an email catcher.
Simply add the following config.
smtp:
image: mailhog/mailhog
Then update your .devcontainer/.env
with some email configuration env vars.
SMTP_HOST: smtp
SMTP_PORT: 1025
SMTP_USERNAME: thisisnotused
SMTP_PASSWORD: thisisnotused
SMTP_TLS_OFF: 'true'
We then update our app/src/config.rs
.
use std::env;
#[derive(Clone, Debug)]
pub struct Config {
pub database_url: String,
pub smtp_config: Option<SmtpConfig>,
}
#[derive(Clone, Debug)]
pub struct SmtpConfig {
pub host: String,
pub port: u16,
pub tls_off: bool,
pub username: String,
pub password: String,
}
impl SmtpConfig {
pub fn new() -> Option<SmtpConfig> {
let host = env::var("SMTP_HOST");
let username = env::var("SMTP_USERNAME");
let password = env::var("SMTP_PASSWORD");
let smtp_port = env::var("SMTP_PORT");
if let (Ok(host), Ok(username), Ok(password), Ok(smtp_port)) =
(host, username, password, smtp_port)
{
Some(SmtpConfig {
host,
port: smtp_port.parse::<u16>().unwrap(),
tls_off: env::var("SMTP_TLS_OFF").is_ok(),
username,
password
})
} else {
None
}
}
}
impl Config {
pub fn new() -> Config {
let database_url =
env::var("DATABASE_URL")
.expect("DATABASE_URL not set");
Config {
database_url,
smtp_config: SmtpConfig::new(),
}
}
}
Create a helper function for email in app/src/email.rs
.
use lettre::transport::smtp::authentication::Credentials;
use lettre::{Message, SmtpTransport, Transport};
pub fn send_email(config: &crate::config::Config, email: Message) {
if let Some(smtp_config) = &config.smtp_config {
let creds = Credentials::new(smtp_config.username.clone(), smtp_config.password.clone());
let sender = if smtp_config.tls_off {
SmtpTransport::builder_dangerous(smtp_config.host.clone())
.port(smtp_config.port)
.credentials(creds)
.build()
} else {
SmtpTransport::relay(&smtp_config.host)
.unwrap()
.port(smtp_config.port)
.credentials(creds)
.build()
};
match sender.send(&email) {
Ok(_) => println!("Email sent successfully!"),
Err(e) => panic!("Could not send email: {:?}", e),
}
}
}
We should now be able to form a message and call our helper function and see the results in Mailhog.