使用 Rust 發送郵件

SMTP 協議與 MIME 協議

SMTP(簡單郵件傳輸協議,Simple Mail Transfer Protocol)是一種用於發送和接收電子郵件的互聯網標準通信協議。它定義了電子郵件服務器如何相互發送、接收和中繼郵件。SMTP 通常用於發送郵件,而郵件的接收通常由 POP(郵局協議)或 IMAP(互聯網消息訪問協議)來處理。

POP3,全名爲 “Post Office Protocol - Version 3”,即 “郵局協議版本 3”。是 TCP/IP 協議族中的一員,由 RFC1939 定義。本協議主要用於支持使用客戶端遠程管理在服務器上的電子郵件。提供了 SSL 加密的 POP3 協議被稱爲 POP3S

因特網信息訪問協議(縮寫爲 IMAP,以前稱作交互郵件訪問協議)是一個應用層協議,用來從本地郵件客戶端(如 Microsoft Outlook、Outlook Express、Foxmail、Mozilla Thunderbird)訪問遠程服務器上的郵件。

SMTP 的作用包括:

  1. 郵件發送:它允許用戶通過電子郵件客戶端(如 Outlook、Thunderbird 等)發送郵件。

  2. 郵件中繼:SMTP 服務器可以將郵件從一個服務器轉發到另一個服務器,最終到達收件人的郵箱服務器。

  3. 郵件排隊:如果目標服務器不可用,SMTP 服務器可以將郵件保存在隊列中,稍後再次嘗試發送。

SMTP 基於 TCP(傳輸控制協議),而不是 UDP(用戶數據報協議)。TCP 提供了一種可靠的方式來確保數據包的順序和完整性,這對於電子郵件傳輸非常重要。

儘管 SMTP 非常有效於處理文本信息的發送,但它本身並不支持非文本附件(如圖片、視頻、文檔等)。

MIME 擴展了電子郵件標準,使其能夠支持:
非 ASCII 字符文本;
非文本格式附件(二進制、聲音、圖像等);
由多部分(multiple parts)組成的消息體;
包含非 ASCII 字符的頭信息(Header information)

MIME(多用途互聯網郵件擴展,Multipurpose Internet Mail Extensions)協議, 是一種擴展 SMTP 的標準,使電子郵件能夠支持諸如文本、圖像、音頻和視頻等不同格式的內容,以及多部分消息體和字符編碼。通過 MIME,電子郵件能夠包含豐富的多媒體內容,這在現代通信中是非常必需的。


使用 Rust 發送郵件

在 Rust 中發送電子郵件可以通過使用第三方庫來實現,例如 lettre 庫 [1]。lettre 提供了發送郵件的功能,包括與 SMTP 服務器的交互。此外,可能還需要使用 mime 庫來設置郵件內容的類型。

lettremime 庫添加到項目的 Cargo.toml 文件中:

[dependencies]
lettre = "0.11.2"
mime = "0.3"

可用以下代碼來發送一封簡單的電子郵件:

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

fn send_email() -> Result<(), Box<dyn Error>> {
    let from = "xxxx"; // 發件郵箱
    let to = "yyyy@163.com"; // 收件郵箱

    let email = Message::builder()
        .from(from.parse()?)
        .to(to.parse()?)
        .subject("Rust Email Test")
        .body("Hello from Rust with lettre!".to_string())?;

    let smtp_server = "smtp.qq.com"; // 根據郵件服務商而定
    let smtp_username = "xxxx"; // 發件郵箱
    let smtp_password = "xxxxxxx"; // 授權碼,不同郵件服務商獲取方式有所不同,可搜索解決;qq郵箱可參考 https://codeantenna.com/a/PwKbc0S5dd



    let creds = Credentials::new(smtp_username.to_string(), smtp_password.to_string());

    let mailer = SmtpTransport::relay(smtp_server)?
        .credentials(creds)
        .build();

    match mailer.send(&email) {
        Ok(_) => println!("Email sent successfully"),
        Err(e) => eprintln!("Could not send the email: {:?}", e),
    }

    Ok(())
}

fn main() {
    if let Err(e) = send_email() {
        eprintln!("An error occurred: {}", e);
    }
}

cargo run 執行以上代碼, 郵件發送成功

參考資料

[1]

lettre 庫: https://github.com/lettre/lettre

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/sT8MJGUa-Bs6Nr9NWvTg0g