Introducing 'sparkpost' a Rust Crate for email API Harry Gill rust sparkpost api crate 2 minutes read 🦆

Rust is an enjoyable language, and I have been experimenting with it for a some time. I started with creating a few web servers using different crates including rocket and actix. I needed to use an email api to send messages from the backend to either myself or the user.

I have used Sparkpost as an email service for such purpose in some of my nodejs apps. Having not found any rust API lib for it I decided to create one for myself. It is available on https://crates.io/crates/sparkpost.

Current implementation includes transmission api only. That allows you to send emails with metadata, templates and other features.

Here is a complete example of how to use the lib

[ dependencies ] sparkpost = "0.4" serde_json = "1.0" serde_derive = "1.0" serde = "1.0" chrono = { version = "0.4" , features = [ "serde" ] } dotenv = "0.13"

// main.rs #[macro_use] extern crate serde_derive ; extern crate chrono ; // for setting dateTime option to an email extern crate dotenv ; // optional- to read api key from .env file extern crate serde ; extern crate sparkpost ; use chrono :: prelude :: * ; use sparkpost :: transmission :: { Attachment , EmailAddress , Message , Options , Recipient , Transmission , TransmissionResponse , }; // this could be any Type to replace vlaues in sparkpost template // only requirement is that it implements Serialize from serde #[derive(Debug, Serialize)] struct Data { name : String , } #[allow(unused)] fn get_api_key () -> String { use dotenv :: dotenv ; use std :: env ; dotenv (). ok (); env :: var ( "SPARKPOST_API_KEY" ). expect ( "SPARKPOST_API_KEY must be set" ) } fn main () { // for eu servers use // let tm = Transmission::new_eu(get_api_key()); let tm = Transmission :: new ( get_api_key ()); // new email message with sender name and email let mut email = Message :: new ( EmailAddress :: new ( "marketing@example.sink.sparkpostmail.com" , "Example Company" , )); let options = Options { open_tracking : true , click_tracking : true , transactional : false , sandbox : false , inline_css : false , start_time : Some ( Utc . ymd ( 2019 , 1 , 1 ). and_hms ( 0 , 0 , 0 )), }; // recipient with substitute data for the template let recipient = Recipient :: with_substitution ( EmailAddress :: new ( "bob@company.com" , "Bob" ), Data { name : "Bob" . into () }, ); let attachment = Attachment { file_type : "image/png" . into (), name : "AnImage.png" . into (), // data is base64 encoded string data : "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAAXxJREFUOBFjvJVg84P5718WBjLAX2bmPyxMf/+xMDH8YyZDPwPDXwYGJkIaOXTNGdiUtHAqI2jA/18/GUQzGsg3gMfKg4FVQo6BiYcPqyF4XcChaczA4+DP8P//f4b/P3+SZgAzvxCDSGYjAyMjI8PvZw+AoYXdLuyiQLtE0uoZWAREwLb+fnKXQTipkngXcJu7MnACQx8G2FX1GHgs3bDGBlYX8HlFM/z9+JbhzewWhmf1CQyfti9j+PfzBwO/ZxTMTDiNmQKBfmZX1GB42V/K8P38YbDCX/dvMDAwMzPwuYbBNcIYmC4AhfjvXwx/376AqQHTf96+ZPj34xuKGIiDaQBQ8PPBTQwCoZkMjJzcYA3MgqIMAr7xDJ/3rAHzkQnGO7FWf5gZ/qLmBSZmBoHgNAZee1+Gf18/MzCyczJ83LyQ4fPetch6Gf4xMP3FbgBMGdAgJqAr/n37zABMTTBROA0ygAWUJUG5Civ4B8xwX78CpbD6FJiHmf4AAFicbTMTr5jAAAAAAElFTkSuQmCC" . into (), }; // complete the email message with details email . add_recipient ( recipient ) . add_attachment ( attachment ) . options ( options ) . campaign_id ( "marketing_blitz" ) . subject ( "My Awesome email 😎" ) . html ( "<h1>hello {name}</h1>" ) . text ( "hello {name}" ); let result = tm . send ( & email ); match result { Ok ( res ) => { match res { TransmissionResponse :: ApiResponse ( api_res ) => { println ! ( "API Response:

{:#?}" , api_res ); assert_eq ! ( 1 , api_res . total_accepted_recipients ); assert_eq ! ( 0 , api_res . total_rejected_recipients ); } TransmissionResponse :: ApiError ( errors ) => { println ! ( "Response Errors:

{:#?}" , & errors ); } } } Err ( error ) => { println ! ( "error

{:#?}" , error ); } } }

As I mentioned above that there are many features that are lacking i.e. saving and retrieving templates and recipient list etc. Reason is that I don’t use those features for now. If anyone is interested I will be more than happy to help.