Crate mailstrom [] [src]

Mailstrom handles email delivery in a background worker thread, with the following features:

  • Accepts an email from the caller and then does everything necessary to get it delivered to all recipients without blocking the caller.
  • Allows the caller to query the status of an earlier submitted email at any time, to determine if it is Queued, Delivered, Deferred, or has Failed, with details as to why, on a per-recipient basis.
  • Handles all parsing, validation, and encoding of email content and headers, in compliance with RFC 5322 (and other RFCs). Uses the email-format library for this.
  • Looks up the DNS MX records of the recipients, and delivers directly to those Internet mail servers over SMTP, thus not requiring any local SMTP relay. Uses the trust-dns library for DNS lookups
  • SMTP transport "heavy lifting" is performed via the lettre library. Uses STARTTLS where available.
  • Retries with exponential backoff for a fixed number of retries (currently fixed at 3), when the send result is Deferred
  • Uses a pluggable user-defined state management (persistence) layer.

Limitations

  • The email-format crate is somewhat incomplete and clunky still. It doesn't incorporate RFC 6854 (updated From and Sender syntax) yet. It defines types one-to-one with ABNF parsing units, rather than as semantic units of meaning. And it doesn't let you use obvious types yet like setting the date from a DateTime type. However, these issues will be worked out in the near future.

You can use it as follows:

extern crate email_format;
extern crate mailstrom;

use email_format::Email;
use mailstrom::{Mailstrom, Config, MemoryStorage};

fn main() {
    let mut email = Email::new(
        "myself@mydomain.com",  // "From:"
        "Wed, 05 Jan 2015 15:13:05 +1300" // "Date:"
    ).unwrap();

    email.set_bcc("myself@mydomain.com").unwrap();
    email.set_sender("from_myself@mydomain.com").unwrap();
    email.set_reply_to("My Mailer <no-reply@mydomain.com>").unwrap();
    email.set_to("You <you@yourdomain.com>, AndYou <andyou@yourdomain.com>").unwrap();
    email.set_cc("Our Friend <friend@frienddomain.com>").unwrap();
    email.set_subject("Hello Friend").unwrap();
    email.set_body("Good to hear from you.\r\n\
                    I wish you the best.\r\n\
                    \r\n\
                    Your Friend").unwrap();

    let mut mailstrom = Mailstrom::new(
        Config {
            helo_name: "my.host.domainname".to_owned(),
            ..Default::default()
        },
        MemoryStorage::new());

    // We must explicitly tell mailstrom to start actually sending emails.  If we
    // were only interested in reading the status of previously sent emails, we
    // would not send this command.
    mailstrom.start().unwrap();

    let message_id = mailstrom.send_email(email).unwrap();

    // Later on, after the worker thread has had time to process the request,
    // you can check the status:

    let status = mailstrom.query_status(&*message_id).unwrap();
    println!("{:?}", status);
}

Reexports

pub use message_status::MessageStatus;
pub use prepared_email::PreparedEmail;
pub use message_status::InternalMessageStatus;

Modules

error
message_status
prepared_email

Structs

Config
Mailstrom
MemoryStorage
RecipientStatus

Per-Recpiient Delivery Information

Enums

DeliveryResult

The result (so far) of the sending of an email to a particular recipient

WorkerStatus

Traits

MailstromStorage

A trait for implementing Mailstrom storage

MailstromStorageError