2 releases
0.1.1 | Oct 6, 2019 |
---|---|
0.1.0 | Oct 1, 2019 |
#203 in Email
56KB
843 lines
mda-rs
mda-rs is a Rust library for writing custom Mail Deliver Agents.
Documentation
The detailed module documentation, including code examples for all features, can be found at https://docs.rs/mda.
Usage
Add this to your Cargo.toml
:
[dependencies]
mda = "0.1"
If you are using Rust 2015 add the following to your crate root file (Rust 2018 doesn't require this):
extern crate mda;
See examples/personal-mda.rs for an example that uses mda-rs.
License
This project is licensed under the Mozilla Public License Version 2.0 (LICENSE or https://www.mozilla.org/en-US/MPL/2.0/).
lib.rs
:
The mda crate provides a library for writing custom Mail Deliver Agents. It supports local delivery to maildirs, access to normalized email byte data for easier processing, and access to individual header fields.
Email data normalization involves ensuring header fields are in single lines, decoding text parts of the message that use some kind of transfer encoding (e.g., base64), and converting all text to UTF-8. The original (non-normalized) email data is used during delivery.
This crate also exposes convenience methods for regular expression searching and processing/filtering of emails.
Email construction
The Email struct is the basic abstraction of the mda
crate. To construct an Email use the
Email::from_stdin or
Email::from_vec method.
use mda::Email;
let email = Email::from_stdin()?;
let email = Email::from_vec(vec![97, 98, 99])?;
Email delivery
Use the Email::deliver_to_maildir method to deliver the email to local maildir directories. Note that the original (non-normalized) email data is used during delivery.
use mda::Email;
let email = Email::from_stdin()?;
email.deliver_to_maildir("/my/maildir/path")?;
email.deliver_to_maildir("/my/other/maildir/path")?;
Accessing email header fields
Use the Email::header_field and Email::header_field_all_occurrences methods to access the email header fields. Any MIME encoded words in the header field values are decoded and the field value is converted to UTF-8.
use mda::Email;
let email = Email::from_stdin()?;
let to = email.header_field("To").unwrap_or("");
if to.contains("me@example.com") {
email.deliver_to_maildir("/my/maildir/path")?;
}
Searching with regular expressions
The EmailRegex trait provides convenience methods
for searching the header, the body or the whole email with regular
expressions. The convenience functions use case-insensitive, multi-line
search (^
and $
match beginning and end of lines). If the above don't
match your needs, or you require additional functionality, you can perform
manual regex search using the email data.
use mda::{Email, EmailRegex};
let email = Email::from_stdin()?;
if email.header().search(r"^To:.*me@example.com")? {
email.deliver_to_maildir("/my/maildir/path")?;
}
Processing and filtering the email with external programs
Use the Email::filter and Email::from_stdin_filtered methods to filter the email, in both cases creating a new email.
use mda::Email;
// Filtering directly from stdin is more efficient.
let email = Email::from_stdin_filtered(&["bogofilter", "-ep"])?;
let bogosity = email.header_field("X-Bogosity").unwrap_or("");
if bogosity.contains("Spam, tests=bogofilter") {
email.deliver_to_maildir("/my/spam/path")?;
}
// We can also filter at any other time.
let email = email.filter(&["bogofilter", "-ep"])?;
To perform more general processing use the Email::process method:
use mda::Email;
let email = Email::from_stdin()?;
let output = email.process(&["bogofilter"])?;
if let Some(0) = output.status.code() {
email.deliver_to_maildir("/my/spam/path")?;
}
Access to byte data
Use the Email::header, Email::body, Email::data methods to access the normalized byte data of the header, body and whole email respectively.
Normalization involves ensuring header fields are in single lines, decoding text parts of the message that use some kind of transfer encoding (e.g., base64), and converting all text to UTF-8 character encoding.
If for some reason you need access to non-normalized data use Email::raw_data.
use std::str;
use mda::Email;
let email = Email::from_stdin()?;
let body_str = String::from_utf8_lossy(email.header());
if body_str.contains("FREE BEER") {
email.deliver_to_maildir("/my/spam/path")?;
}
Decide delivery durability vs speed trade-off
Use the Email::set_delivery_durability to decide which DeliveryDurability method to use. By default the most durable (but also slower) method is used.
use mda::{Email, DeliveryDurability};
let mut email = Email::from_stdin()?;
email.set_delivery_durability(DeliveryDurability::FileSyncOnly);
Dependencies
~7MB
~182K SLoC