How to Send Email
Problem
You want to send plain-text or HTML emails in your Djangors application using SMTP, or write outgoing messages to local disk during development.
Solution
Use djangors_mail::Message and configure a backend implementing the MailBackend trait, such as SmtpBackend, FileBackend, or ConsoleBackend.
Code Example
1. Sending via SMTP (Production)
#![allow(unused)]
fn main() {
use djangors_mail::{Message, SmtpConfig, SmtpBackend, MailBackend};
pub async fn send_welcome_email(user_email: &str) -> Result<(), djangors_mail::MailError> {
// Construct email message
let message = Message {
to: vec![user_email.to_string()],
from: "noreply@example.com".to_string(),
subject: "Welcome to our platform!".to_string(),
body: "Hello, welcome to our service!".to_string(),
html_body: Some("<h1>Hello!</h1><p>Welcome to our service!</p>".to_string()),
};
// Configure SMTP backend
let config = SmtpConfig::new("smtp.example.com")
.port(587)
.credentials("smtp_user", "smtp_pass")
.use_tls(true);
let backend = SmtpBackend::new(config)?;
backend.send(&message).await?;
Ok(())
}
}
2. Saving Emails to Disk (Development)
#![allow(unused)]
fn main() {
use djangors_mail::{Message, FileBackend, MailBackend};
use std::path::PathBuf;
pub async fn send_dev_email(message: &Message) -> Result<(), djangors_mail::MailError> {
// Writes emails as `.eml` files in the specified directory
let backend = FileBackend::new(PathBuf::from("/tmp/app_emails"));
backend.send(message).await?;
Ok(())
}
}
3. Asserting Sent Emails in Tests (InMemoryBackend)
InMemoryBackend keeps every sent Message in memory and exposes
sent_messages() — pair it with djangors-test or a plain #[tokio::test]
when your test asserts that “an email was sent with this subject”:
#![allow(unused)]
fn main() {
use djangors_mail::{Message, InMemoryBackend, MailBackend};
fn build_message() -> Message { Message { to: vec!["a@b.c".into()], from: "noreply@example.com".into(), subject: "reset".into(), body: "hi".into(), html_body: None } }
async fn run() -> Result<(), djangors_mail::MailError> {
let backend = InMemoryBackend::default();
let sent: Result<(), _> = backend.send(&build_message()).await;
assert!(sent.is_ok());
let messages = backend.sent_messages();
assert_eq!(messages.len(), 1);
assert_eq!(messages[0].subject, "reset");
Ok(())
}
}
ConsoleBackend is the fourth backend: it logs the message body via tracing
to stdout/stderr, useful for local development when you want to see emails
without an SMTP server or files on disk.