Send Emails with Rust – SMTP and API Methods with Examples

This article explores the practical steps and considerations for utilizing Rust to manage email sending, from setting up SMTP to leveraging APIs for both sending and testing emails.

How to send emails using Rust and SMTP

The lettre crate is among the most straightforward methods to send emails from Rust via SMTP. The following sections cover different scenarios using lettre crate and they include:

  • Sending a simple plain.txt email
  • Sending an HTML email
  • Sending attachments
  • Sending to multiple recipients

Feel free to copy-paste the scripts below minding your credentials as well as recipient and sender addresses, and SMTP endpoints. Also, note that these are designed for Mailtrap Email Sending SMTP users.

Later in the article, we cover the API method. And here, we’d like to offer some pointers for Mailtrap users.

  • Before you start sending your emails, you need to verify your domain with Mailtrap.
  • Make sure to use the script with TLS handling, since Mailtrap requires STARTTLS.
  • Use only the domain that you set up and verified with Mailtrap. Or, you’ll get the “Unauthorized 401” error.

Send emails using lettre crate

  1. Add ‘lettre’ to the ‘Cargo.toml’ file:
[dependencies]
lettre = "0.10"
lettre_email = "0.9"

Note: the lettre and lettre_email versions might be updated when you’re reading this article. Click here for the latest versions.

  1. Write the email-sending script:
use lettre::{Message, SmtpTransport, Transport};
use lettre::smtp::authentication::Credentials;

fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
// Define the email
let email = Message::builder() .from("Your Name <your.email@example.com>".parse().unwrap()) .reply_to("your.email@example.com".parse().unwrap()) .to("Recipient Name <recipient.email@example.com>".parse().unwrap()) .subject("Rust Email") .body(String::from("Hello, this is a test email from Rust!")) .unwrap();
// Set up the SMTP client let creds = Credentials::new("Mailtrap_smtp_username".to_string(), "Mailtrap_smtp_password".to_string());
// Open a remote connection to gmail let mailer = SmtpTransport::relay("your_mailtrap_Host.io")? .credentials(creds) .build();
// Send the email match mailer.send(&email) { Ok(_) => println!("Email sent successfully!"), Err(e) => eprintln!("Could not send email: {:?}", e), }
Ok(())
}

Important: Replace all the variables with your actual credentials, relay endpoints, and corresponding email addresses.

  1. TLS handling

If you’re a Mailtrap user, TLS handling is required. lettre supports ‘None’, ‘Starttls’ and ‘Required’ TLS settings. The TLS settings are specified in the SmtpTransport block, and here’s what the TLS-enabled script might look like.

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

fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
// Build an email message using the builder pattern
let email = Message::builder()
// Set the sender's name and email address
.from("Your Name <your address@gmail.com>".parse().unwrap())
// Set the recipient's name and email address
.to("Recipient Name <receiver address@gmail.com>".parse().unwrap())
// Set the subject of the email
.subject("Rust Email")
// Set the body content of the email
.body(String::from("Hello World, this is a test email from Rust!"))
.unwrap();

// Create SMTP client credentials using username and password
let creds = Credentials::new("mailtrap_username".to_string(), "mailtrap_password".to_string());

// Open a secure connection to the SMTP server using STARTTLS
let mailer = SmtpTransport::starttls_relay("your_mailtrap_host.io")
.unwrap() // Unwrap the Result, panics in case of error
.credentials(creds) // Provide the credentials to the transport
.build(); // Construct the transport

// Attempt to send the email via the SMTP transport
match mailer.send(&email) {
// If email was sent successfully, print confirmation message
Ok(_) => println!("Email sent successfully!"),
// If there was an error sending the email, print the error
Err(e) => eprintln!("Could not send email: {:?}", e),
}

Ok(())
}

Note: your_mailtrap _host will vary depending on your purpose. For example, if you’re using Mailtrap Email Testing, then the Host is sandbox.smtp.mailbox.io

  1. Run your application

Use the cargo run command to run your application. Assuming the setup is correct, rust will send the email to specified recipients.

How to send HTML email with Rust?

To send an HTML email, we’ll reuse and modify the lettre script with STARTTLS.

Simply, you need to set the content type of the email body to text/html. This can be done by using the message::SinglePart and message::MultiPart modules to construct the email body properly.

Here’s the modified code:

use lettre::{transport::smtp::authentication::Credentials, Message, SmtpTransport, Transport};
use lettre::message::{Mailbox, MultiPart, SinglePart};

fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {

// Define the HTML content
let html_content = r#"
<html>
<body>
<h1>Hello!</h1>
<p>This is a <strong>test email</strong> from Rust!</p>
</body>
</html>
"#;

let from_email = "Your Name <sender@example.com>".parse::<Mailbox>().unwrap();
let to_email = "Recipient Name <recipient@example.com>".parse::<Mailbox>().unwrap();

// Define the email with HTML part
let email = Message::builder()
.from(from_email)
.to(to_email)
.subject("Rust Email")
.multipart(
MultiPart::alternative().singlepart(SinglePart::html(html_content.to_string())),
)
.unwrap();

// Set up the SMTP client credentials
let creds = Credentials::new("username".to_string(), "password".to_string());

// Open a remote connection to the SMTP server with STARTTLS
let mailer = SmtpTransport::starttls_relay("your_mailtrap_host.io")
.unwrap()
.credentials(creds)
.build();

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

Ok(())
}

Notes on code modifications:

  • The html_content variable holds the HTML content of the email.
  • The Message::builder() is used to set up the headers of the email.
  • The multipart() method is used to create a MultiPart email, which can contain both text and HTML parts. In this case, we’re only adding an HTML part using SinglePart::html(html_content.to_string())

It is a part of article about the methods that you can use to send emails with Rust. To read the full version and find out how to send emails with attachments click here.