Rust邮件发送库mail-send的使用,支持SMTP和IMAP协议的高效邮件发送与接收

Rust邮件发送库mail-send的使用,支持SMTP和IMAP协议的高效邮件发送与接收

mail-send是一个Rust库,用于构建、签名和通过SMTP发送电子邮件。它包含以下特性:

  • 生成符合互联网消息格式标准(RFC 5322)的电子邮件
  • 完整的MIME支持(RFC 2045-2049),自动为每个消息体部分选择最佳编码
  • 支持DKIM签名(RFC 6376),包括ED25519-SHA256、RSA-SHA256和RSA-SHA1
  • SMTP(RFC 5321)发送
  • 支持TLS的SMTP安全扩展(RFC 3207)
  • SMTP认证扩展(RFC 4954),支持多种认证机制:
    • CRAM-MD5
    • DIGEST-MD5
    • XOAUTH2
    • LOGIN
    • PLAIN
  • 完全异步(需要Tokio)

使用示例

示例1:通过需要认证的SMTP服务器发送消息

// 构建一个简单的多部分消息
let message = MessageBuilder::new()
    .from(("John Doe", "john@example.com"))
    .to(vec![
        ("Jane Doe", "jane@example.com"),
        ("James Smith", "james@test.com"),
    ])
    .subject("Hi!")
    .html_body("<h1>Hello, world!</h1>")
    .text_body("Hello world!");

// 连接到SMTP提交端口,升级到TLS并使用提供的凭据进行认证
SmtpClientBuilder::new("smtp.gmail.com", 587)
    .implicit_tls(false)
    .credentials(("john", "p4ssw0rd"))
    .connect()
    .await
    .unwrap()
    .send(message)
    .await
    .unwrap();

示例2:使用DKIM签名消息并通过SMTP中继服务器发送

// 构建一个带有单个附件的简单文本消息
let message = MessageBuilder::new()
    .from(("John Doe", "john@example.com"))
    .to("jane@example.com")
    .subject("Howdy!")
    .text_body("These pretzels are making me thirsty.")
    .attachment("image/png", "pretzels.png", [1, 2, 3, 4].as_ref());

// 使用RSA-SHA256签名电子邮件
let pk_rsa = RsaKey::<Sha256>::from_rsa_pem(TEST_KEY).unwrap();
let signer = DkimSigner::from_key(pk_rsa)
    .domain("example.com")
    .selector("default")
    .headers(["From", "To", "Subject"])
    .expiration(60 * 极速 60 * 7); // 签名过期前的秒数(可选)

// 通过TLS连接到SMTP中继服务器
// 使用配置的DKIM签名器为每条消息签名
SmtpClientBuilder::new("smtp.gmail.com", 465)
    .connect()
    .await
    .unwrap()
    .send_signed(message, &signer)
    .await
    .unwrap();

完整示例代码

use mail_send::{MessageBuilder, SmtpClientBuilder};
use mail_send::dkim::{DkimSigner, RsaKey, Sha256};

#[tokio::main]
async fn main() {
    // 示例1:基本SMTP发送
    // 构建包含文本和HTML内容的邮件
    let basic_message = MessageBuilder::new()
        .from(("Sender Name", "sender@example.com"))
        .to("receiver@example.com")
        .subject("Test Email")
        .text_body("This is a test email sent using mail-send library.")
        .html_body("<h1>Test Email</h1><p>This is a test email sent using mail-send library.</p>");

    // 连接到SMTP服务器并发送邮件
    SmtpClientBuilder::new("smtp.example.com", 587)
        .implicit_tls(false)  // 显式TLS
        .credentials(("username", "password"))  // 认证凭据
        .connect()
        .await
        .unwrap()
        .send(basic_message)
        .await
        .unwrap();

    // 示例2:带DKIM签名的发送
    // 构建带附件的邮件
    let dkim_message = MessageBuilder::new()
        .from(("Sender Name", "sender@example.com"))
        .to("receiver@example.com")
        .subject("Test DKIM Signed Email")
        .text_body("This email is signed with DKIM.")
        .attachment(
            "text/plain",  // MIME类型
            "note.txt",    // 附件文件名
            "This is an attached file.".as_bytes()  // 附件内容
        );

    // 加载RSA私钥
    let private_key = "-----BEGIN RSA PRIVATE KEY-----\n...";
    let pk_rsa = RsaKey::<Sha256>::from_rsa_pem(private_key).unwrap();
    
    // 配置DKIM签名器
    let signer = DkimSigner::from_key(pk_rsa)
        .domain("example.com")  // 域名
        .selector("default")    // 选择器
        .headers(["From", "To", "Subject"]);  // 需要签名的头字段

    // 连接到SMTP服务器并发送带DKIM签名的邮件
    SmtpClientBuilder::new("smtp.example.com", 465)
        .connect()
        .await
        .unwrap()
        .send_signed(dkim_message, &signer)
        .await
        .unwrap();
}

测试

运行测试套件:

$ cargo test --all-features

或者使用MIRI运行测试套件:

$ cargo +nightly miri test --all-features

许可证

根据以下任一许可证授权:

  • Apache License, Version 2.0
  • MIT license

版权

Copyright © 2020-2022, Stalwart Labs Ltd.


1 回复

Rust邮件发送库mail-send的使用指南

mail-send是一个功能强大的Rust库,支持SMTP和IMAP协议,可以高效地发送和接收电子邮件。它提供了简单易用的API,同时保持了高性能和安全性。

主要特性

  • 支持SMTP协议发送邮件
  • 支持IMAP协议接收邮件
  • 异步/同步API
  • 支持TLS/SSL加密
  • 支持多种认证方式
  • 丰富的邮件构建功能

安装

在Cargo.toml中添加依赖:

[dependencies]
mail-send = "0.3"
tokio = { version = "1", features = ["full"] }  # 如果使用异步API

基本使用方法

1. 发送邮件

use mail_send::SmtpClientBuilder;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 创建SMTP客户端
    let client = SmtpClientBuilder::new("smtp.example.com", 587)
        .implicit_tls(false)
        .credentials(("username", "password"))
        .connect()
        .await?;
    
    // 构建并发送邮件
    client
        .send((
            "from@example.com",  // 发件人
            ["to@example.com"],  // 收件人
            "Subject: 测试邮件\r\n\
             Content-Type: text/plain; charset=utf-8\r\n\r\n\
             这是一封测试邮件"
        ))
        .await?;
    
    Ok(())
}

2. 接收邮件(IMAP)

use mail_send::ImapClientBuilder;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 创建IMAP客户端
    let mut client = ImapClientBuilder::new("imap.example.com", 993)
        .implicit_tls(true)
        .credentials(("username", "password"))
        .connect()
        .await?;
    
    // 选择收件箱
    client.select("INBOX").await?;
    
    // 获取最新的5封邮件
    let messages = client.fetch("1:5", "RFC822").await?;
    
    for message in messages {
        println!("邮件内容: {:?}", message.body());
    }
    
    Ok(())
}

高级用法

构建复杂邮件

use mail_send::{MailBuilder, SmtpClientBuilder};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = SmtpClientBuilder::new("smtp.example.com", 587)
        .credentials(("username", "password"))
        .connect()
        .await?;
    
    // 使用MailBuilder构建复杂邮件
    let message = MailBuilder::new()
        .from(("发件人", "from@example.com"))
        .to(("收件人1", "to1@example.com"))
        .to("to2@example.com")
        .cc("cc@example.com")
        .subject("测试邮件")
        .text_body("这是纯文本内容")
        .html_body("<h1>这是HTML内容</h1>")
        .attachment("text/plain", "附件内容", "example.txt")
        .build();
    
    client.send(message).await?;
    
    Ok(())
}

使用TLS加密

use mail_send::SmtpClientBuilder;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 使用隐式TLS(端口465)
    let client = SmtpClientBuilder::new("smtp.example.com", 465)
        .implicit_tls(true)  // 启用隐式TLS
        .credentials(("username", "password"))
        .connect()
        .await?;
    
    // 发送邮件...
    
    Ok(())
}

错误处理

use mail_send::{SmtpClientBuilder, Error};

#[tokio::main]
async fn main() -> Result<(), Error> {
    match SmtpClientBuilder::new("smtp.example.com", 587)
        .credentials(("username", "wrong_password"))
        .connect()
        .await
    {
        Ok(client) => {
            // 发送邮件...
            Ok(())
        },
        Err(Error::AuthenticationFailed) => {
            eprintln!("认证失败,请检查用户名和密码");
            Ok(())
        },
        Err(err) => {
            eprintln!("发生错误: {}", err);
            Err(err)
        }
    }
}

性能提示

  1. 重用客户端连接可以显著提高性能
  2. 对于批量发送,考虑使用连接池
  3. 异步API适合高并发场景

总结

mail-send库为Rust开发者提供了强大而灵活的邮件处理能力,无论是简单的邮件发送还是复杂的邮件接收处理,都能轻松应对。它的异步支持和丰富的功能使其成为Rust生态中处理电子邮件任务的优秀选择。

回到顶部