Отправка email на Rust: библиотеки lettre и mailparse
Rust — язык системного программирования, который всё чаще используется для создания высоконагруженных веб-сервисов и микросервисов. Одной из типовых задач в таких проектах является отправка электронных писем. В экосистеме Rust есть несколько зрелых библиотек для работы с email, среди которых выделяются lettre и mailparse.
В этой статье мы подробно разберём, как настроить отправку писем на Rust с использованием SMTP, как добавлять вложения и формировать HTML-письма, а также как парсить входящие сообщения. Материал ориентирован на разработчиков, уже знакомых с основами Rust.
Библиотека lettre: основа для отправки писем
Lettre — это современная, асинхронная и синхронная библиотека для работы с email в Rust. Она поддерживает:
- SMTP-транспорт (включая STARTTLS и SSL/TLS);
- Формирование писем в формате MIME (текст, HTML, вложения);
- Работу с кодировками (Base64, Quoted-Printable);
- Асинхронные транспорты через tokio или async-std.
Для добавления lettre в проект выполните команду:
cargo add lettre
cargo add tokio --features full # для асинхронного режима
Базовая отправка email через SMTP
Рассмотрим простейший пример — отправка текстового письма через SMTP-сервер Gmail (или любого другого провайдера).
use lettre::transport::smtp::authentication::Credentials;
use lettre::{Message, SmtpTransport, Transport};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Формируем письмо
let email = Message::builder()
.from("Отправитель <from@example.com>".parse()?)
.to("Получатель <to@example.com>".parse()?)
.subject("Привет из Rust!")
.body("Это тестовое письмо, отправленное на Rust.".to_string())?;
// Настройки SMTP (пример для Gmail)
let creds = Credentials::new(
"your_email@gmail.com".to_string(),
"your_app_password".to_string(),
);
// Создаём транспорт
let mailer = SmtpTransport::relay("smtp.gmail.com")?
.credentials(creds)
.build();
// Отправляем
match mailer.send(&email) {
Ok(_) => println!("Email отправлен успешно!"),
Err(e) => eprintln!("Ошибка отправки: {}", e),
}
Ok(())
}
Обратите внимание: для Gmail потребуется пароль приложения, а не основной пароль. Для других провайдеров (Yandex, Mail.ru, собственный SMTP) измените адрес сервера и порт.
Отправка HTML-писем с вложениями
Lettre позволяет легко формировать многочастные MIME-сообщения. Добавим HTML-тело и вложение:
use lettre::message::header::ContentType;
use lettre::message::{Attachment, MultiPart, SinglePart};
use lettre::{Message, SmtpTransport, Transport};
fn send_html_with_attachment() -> Result<(), Box<dyn std::error::Error>> {
// HTML-тело письма
let html_body = "<h1>Привет!</h1><p>Это HTML-письмо из Rust.</p>".to_string();
// Формируем многочастное письмо
let email = Message::builder()
.from("Отправитель <from@example.com>".parse()?)
.to("Получатель <to@example.com>".parse()?)
.subject("HTML-письмо с вложением")
.multipart(
MultiPart::mixed()
.singlepart(
SinglePart::builder()
.header(ContentType::TEXT_HTML)
.body(html_body),
)
.singlepart(
Attachment::new("document.pdf".to_string())
.body(vec![0x25, 0x50, 0x44, 0x46], ContentType::parse("application/pdf")?),
),
)?;
// Отправка (аналогично предыдущему примеру)
let creds = Credentials::new("user".to_string(), "pass".to_string());
let mailer = SmtpTransport::relay("smtp.example.com")?
.credentials(creds)
.build();
mailer.send(&email)?;
println!("Письмо с вложением отправлено");
Ok(())
}
Асинхронная отправка с tokio
Для высокопроизводительных приложений используйте асинхронный транспорт:
use lettre::transport::smtp::authentication::Credentials;
use lettre::{AsyncSmtpTransport, AsyncTransport, Message, Tokio1Executor};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>&