Отправка email на Rust: библиотеки lettre и mailparse для писем

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Отправка email на Rust: мощные инструменты для работы с почтой

Rust — язык системного программирования, который всё чаще используется для создания надёжных и производительных веб-сервисов. Одной из типовых задач является отправка электронных писем. В этой статье мы подробно разберём две ключевые библиотеки экосистемы Rust для работы с email: lettre (отправка) и mailparse (парсинг). Вы узнаете, как настроить SMTP-клиент, отправить письмо с вложениями и обработать входящую почту.

Библиотека lettre: отправка писем через SMTP

lettre — это современная, асинхронная и синхронная библиотека для отправки email через SMTP, SMTP-SSL и STARTTLS. Она поддерживает:

  • Отправку текстовых и HTML-писем
  • Вложения (изображения, документы, архивы)
  • Аутентификацию (LOGIN, PLAIN, XOAUTH2)
  • Подпись DKIM и шифрование TLS
  • Работу с async/await (tokio, async-std)

Для начала работы добавьте зависимость в Cargo.toml:

[dependencies]
lettre = { version = "0.11", features = ["builder", "smtp-transport", "tokio1-rustls-tls"] }
tokio = { version = "1", features = ["full"] }

Базовый пример: отправка текстового письма

use lettre::transport::smtp::authentication::Credentials;
use lettre::{Message, SmtpTransport, Transport};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Формируем письмо
    let email = Message::builder()
        .from("Отправитель <sender@example.com>".parse()?)
        .to("Получатель <recipient@example.com>".parse()?)
        .subject("Привет из Rust!")
        .body("Это тестовое письмо, отправленное с помощью библиотеки lettre.".to_string())?;

    // Настройка SMTP (Gmail, Yandex, Mail.ru и т.д.)
    let creds = Credentials::new("sender@example.com".to_string(), "your_password".to_string());
    let mailer = SmtpTransport::relay("smtp.gmail.com")?
        .credentials(creds)
        .build();

    // Отправка
    match mailer.send(&email) {
        Ok(_) => println!("Письмо отправлено успешно!"),
        Err(e) => eprintln!("Ошибка отправки: {}", e),
    }
    Ok(())
}

Отправка HTML-письма с вложениями

Чтобы отправить письмо с HTML-разметкой и файлом, используйте MultiPart:

use lettre::message::{header, MultiPart, SinglePart};
use lettre::{Message, SmtpTransport, Transport};
use std::fs;

let file_content = fs::read("document.pdf")?;
let attachment = SinglePart::builder()
    .header(header::ContentType::parse("application/pdf")?)
    .header(header::ContentDisposition::attachment("document.pdf"))
    .body(file_content);

let html_part = SinglePart::builder()
    .header(header::ContentType::TEXT_HTML)
    .body(String::from("<h1>Привет!</h1><p>Это HTML-письмо с вложением.</p>"));

let email = Message::builder()
    .from("sender@example.com".parse()?)
    .to("recipient@example.com".parse()?)
    .subject("HTML + вложение")
    .multipart(
        MultiPart::mixed()
            .multipart(MultiPart::alternative().singlepart(html_part))
            .singlepart(attachment),
    )?;

Библиотека mailparse: разбор входящих писем

mailparse — лёгкая библиотека для парсинга email-сообщений в формате MIME. Она полезна, если вы обрабатываете почту через IMAP/POP3 или читаете файлы .eml. Основные возможности:

  • Извлечение заголовков (From, To, Subject, Date)
  • Получение тела письма (текст/HTML)
  • Извлечение вложений с MIME-типами
  • Декодирование Base64 и Quoted-Printable

Пример: чтение .eml файла

use mailparse::*;

fn main() {
    let eml_content = std::fs::read("email.eml").unwrap();
    let parsed = parse_mail(&eml_content).unwrap();

    // Заголовки
    println!("От: {}", parsed.headers.get_first_value("From").unwrap());
    println!("Тема: {}", parsed.headers.get_first_value("Subject").unwrap());

    // Извлечение текста
    if let Some(text) = parsed.get_first_plaintext_part() {
        println!("Текст письма:\n{}", text.get_body().unwrap());
    }

    // Вложения
    for part in                    

Рекомендаций