Rust SDK
The official Render25 Rust crate. Asynchronous, high-performance, and type-safe using tokio and reqwest.
Rust 2021 Editioncrates.io: render25Async / Tokio
Installation
bash
cargo add render25 tokio --features tokio/fullOr add manually to Cargo.toml:
Cargo.toml
[dependencies]
render25 = "1.0"
tokio = { version = "1.0", features = ["full"] }Basic Usage
Initialize the client. It automatically detects RENDER25_API_KEY from the environment.
src/main.rs
use render25::{Render25, SendEmailOptions};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
// Reads RENDER25_API_KEY automatically from environment
let client = Render25::new(None)?;
let response = client.emails.send(SendEmailOptions {
from: "support@yourdomain.com".to_string(),
to: vec!["customer@example.com".to_string()],
subject: "Welcome to Render25!".to_string(),
html: Some("<h1>Welcome aboard!</h1><p>Transactional email sent via Rust.</p>".to_string()),
text: Some("Welcome aboard! Transactional email sent via Rust.".to_string()),
..Default::default()
}).await?;
println!("Dispatched Message ID: {}", response.id);
Ok(())
}Note
Set
RENDER25_API_KEY in your environment variables.CC, BCC & Custom Reply-To
src/advanced.rs
use render25::{Render25, SendEmailOptions};
async fn send_invoice_notification(client: &Render25) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
client.emails.send(SendEmailOptions {
from: "support@yourdomain.com".to_string(),
to: vec!["client@example.com".to_string()],
cc: Some(vec!["manager@example.com".to_string()]),
bcc: Some(vec!["archive@example.com".to_string()]),
reply_to: Some("helpdesk@yourdomain.com".to_string()),
subject: "Order #1042 Confirmed".to_string(),
html: Some("<p>Your order has been confirmed.</p>".to_string()),
..Default::default()
}).await?;
Ok(())
}File Attachments
Attach files by passing raw bytes with Attachment::from_bytes:
src/attachments.rs
use render25::{Attachment, Render25, SendEmailOptions};
async fn send_receipt(client: &Render25) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let pdf_bytes = std::fs::read("invoice.pdf")?;
client.emails.send(SendEmailOptions {
from: "billing@yourdomain.com".to_string(),
to: vec!["client@example.com".to_string()],
subject: "Your Invoice #1042".to_string(),
html: Some("<p>Your invoice is attached below.</p>".to_string()),
attachments: Some(vec![
Attachment::from_bytes("invoice_1042.pdf", &pdf_bytes, Some("application/pdf")),
]),
..Default::default()
}).await?;
Ok(())
}Axum Web Framework Example
src/main.rs
use axum::{routing::post, Json, Router};
use render25::{Render25, SendEmailOptions};
use serde::{Deserialize, Serialize};
use std::sync::Arc;
#[derive(Deserialize)]
struct WelcomeRequest {
email: String,
name: String,
}
#[derive(Serialize)]
struct WelcomeResponse {
success: bool,
message_id: String,
}
#[tokio::main]
async fn main() {
let client = Arc::new(Render25::new(None).expect("Invalid Render25 client"));
let app = Router::new().route("/send-welcome", post({
let client = Arc::clone(&client);
move |Json(payload): Json<WelcomeRequest>| {
let client = Arc::clone(&client);
async move {
let res = client.emails.send(SendEmailOptions {
from: "welcome@yourdomain.com".to_string(),
to: vec![payload.email],
subject: format!("Welcome {}!", payload.name),
html: Some(format!("<h1>Welcome {}!</h1>", payload.name)),
..Default::default()
}).await.unwrap();
Json(WelcomeResponse {
success: true,
message_id: res.id,
})
}
}
}));
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
axum::serve(listener, app).await.unwrap();
}