

Sylvain Kerkour - How to send emails with Rust
source link: https://kerkour.com/blog/rust-send-email/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

How to send emails with Rust
Tue, Mar 16, 2021
Sending emails in Rust can be achieved in two ways: either by using an SMTP server or by using a third-party service with an API such as AWS SES or Sendgrid.
SMTP is the standard protocol for sending emails. Thus, it’s the most portable way to send emails as every provider accepts it.
Cargo.toml
[dependencies]
tokio = { version = "1", features = ["full"] }
lettre = "0.10.0-beta.2"
main.rs
use lettre::{
transport::smtp::authentication::Credentials, AsyncSmtpTransport, AsyncTransport, Message,
Tokio1Executor,
};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let smtp_credentials =
Credentials::new("smtp_username".to_string(), "smtp_password".to_string());
let mailer = AsyncSmtpTransport::<Tokio1Executor>::relay("smtp.email.com")?
.credentials(smtp_credentials)
.build();
let from = "Hello World <[email protected]>";
let to = "42 <[email protected]>";
let subject = "Hello World";
let body = "<h1>Hello World</h1>".to_string();
send_email_smtp(&mailer, from, to, subject, body).await
}
async fn send_email_smtp(
mailer: &AsyncSmtpTransport<Tokio1Executor>,
from: &str,
to: &str,
subject: &str,
body: String,
) -> Result<(), Box<dyn std::error::Error>> {
let email = Message::builder()
.from(from.parse()?)
.to(to.parse()?)
.subject(subject)
.body(body.to_string())?;
mailer.send(email).await?;
Ok(())
}
AWS SES
Unfortunately, using SMTP may not be possible all the time because the port might be blocked to avoid spam or because your email provider imposes a limit on the messages' throughout sent through SMTP.
To send an email with SES, we first need to create and format the email appropriately and then send it through its API.
We need to use the lettre
crate with only the builder
feature enabled (to reduces bloat) to format the email and send it with the rusoto
crate which is the unofficial AWS SDK.
Cargo.toml
[dependencies]
tokio = { version = "1", features = ["full"] }
lettre = { version = "0.10.0-beta.2", default-features = false, features = ["builder"] }
rusoto_core = { version = "0.46", default-features = false, features = ["rustls"] }
rusoto_ses = { version = "0.46", default-features = false, features = ["rustls"] }
base64 = "0.13"
main.rs
use lettre::Message;
use rusoto_ses::{RawMessage, SendRawEmailRequest, Ses, SesClient};
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let ses_client = SesClient::new(rusoto_core::Region::UsEast1);
let from = "Hello World <[email protected]>";
let to = "42 <[email protected]>";
let subject = "Hello World";
let body = "<h1>Hello World</h1>".to_string();
send_email_ses(&ses_client, from, to, subject, body).await
}
async fn send_email_ses(
ses_client: &SesClient,
from: &str,
to: &str,
subject: &str,
body: String,
) -> Result<(), Box<dyn std::error::Error>> {
let email = Message::builder()
.from(from.parse()?)
.to(to.parse()?)
.subject(subject)
.body(body.to_string())?;
let raw_email = email.formatted();
let ses_request = SendRawEmailRequest {
raw_message: RawMessage {
data: base64::encode(raw_email).into(),
},
..Default::default()
};
ses_client.send_raw_email(ses_request).await?;
Ok(())
}
If you want to learn more from real-world Rust experience, I’m writing a book (available in early access). Here is a coupon to save 10€ on the book: https://academy.kerkour.com/black-hat-rust?coupon=BLOG
You can subscribe by Email or RSS
Recommend
-
7
The biggest threat to Rust's sustainability Thu, Mar 18, 2021 Its fast-paced development cycles. For more data points, please
-
7
How to execute shellcodes from memory in Rust Tue, Mar 23, 2021 Executing code from memory in Rust is very dependant of the platform as all modern Operating Systems implement security measures to avoid...
-
15
How to create small Docker images for Rust Tue, Apr 6, 2021 Building minimal Docker images to deploy Rust brings up a lot of benefits: it’s not only good for security (reduced attack surface) but also...
-
9
42 Companies using Rust in production Thu, Apr 8, 2021 A lot of people want to learn Rust but...
-
9
Botpress: Natural Language Processing with Sylvain Perron By SE Daily Podcast Friday, May 7 2021
-
4
How to implement worker pools in Rust Tue, Jul 20, 2021 Don’t. Worker pools are not a great fit for Rust due to its ownership model. Instead, embrace functional programming and immutable data. Rust pro...
-
6
A fast port scanner in 100 lines of Rust Wed, Aug 11, 2021 To write a fast port scanner, a programming language requires: A Good I/O model, not to eat all the resources of...
-
4
How to deal with large Cargo workspaces in Rust Tue, Aug 17, 2021 I’m a big fan of monoliths, but when Rust projects become larger and larger, we have to use
-
6
2022年选择哪个Rust Web框架 2022年可选择的三个Rust Web框架:actix-web、
-
11
什么情况下不要用Rust语言? - kerkour Rust 在软件可靠性和性能方面向前迈出了一大步,这直接转化为 $$ 和节省的时间。它解决了开发人员每天面临的许多问题,例如不变性和良好的抽象。但与所有技术一样,它也有一些缺点,可能不会使其成为...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK