[solved] Receiving mails

Hi!

I would like to write an email game in Rust and wondered if there is any crate which has a nice API for receiving emails. I have only found lettre on the web, but I think it is only possible to send emails with this crate.

Thanks

You could poll your existing provider’s email box using pop3 or imap, or if you’re running your own SMTP server (e.g. Postfix) you could parse the Maildir files.

1 Like

Great!

Thanks for the ideas

In /etc/aliases you can use mailbox-name: "|/path/to/exe" syntax to have received e-mails piped directly to the program. It’s like cgi-bin of e-mail.

Thanks, the easiest way was to choose the imap crate!

For the sake of completeness, here is my a minimal example:

Cargo.toml

imap = "0.8.1"
native-tls = "0.1" #this might be 0.2 in the near future
mailparse = "0.6.2"

main.rs

extern crate imap;
extern crate mailparse;
extern crate native_tls;

use native_tls::{TlsConnector, TlsStream};
use std::net::TcpStream;
use imap::client::Client;

use mailparse::*;

fn main() {
    let socket_addr = ("imap domain.com", 993);
    let ssl_connector = TlsConnector::builder().unwrap().build().unwrap();
    let mut imap_socket =
        imap::client::Client::secure_connect(socket_addr, "imap domain.com", &ssl_connector)
            .unwrap();

    imap_socket
        .login("email@example.com", "password")
        .unwrap();

    match imap_socket.select("INBOX") {
        Ok(mailbox) => {
            println!("{}", mailbox);
        }
        Err(e) => println!("Error selecting INBOX: {}", e),
    };

    let mut unseen = imap_socket
        .run_command_and_read_response("UID SEARCH UNSEEN 1:*")
        .unwrap();

    // remove last line of response (OK Completed)
    unseen.pop();

    let mut uids = Vec::new();
    let unseen = ::std::str::from_utf8(&unseen[..]).unwrap();
    let unseen = unseen.split_whitespace().skip(2);
    for uid in unseen.take_while(|&e| e != "" && e != "Completed") {
        if let Ok(uid) = usize::from_str_radix(uid, 10) {
            uids.push(format!("{}", uid));
        }
    }

    uids.reverse(); //latest first

    for uid in uids.iter() {
        let raw = imap_socket.uid_fetch(uid, "RFC822").unwrap();

        for message in raw.iter() {
            let m = message.rfc822();

            if m.is_none() {
                continue;
            }

            let parsed = parse_mail(m.unwrap()).unwrap();

            let subject = parsed.headers.get_first_value("Subject").unwrap().unwrap();
            let from = parsed.headers.get_first_value("From").unwrap().unwrap();

            if parsed.subparts.len() > 0 {
                let body = parsed.subparts[0].get_body().unwrap();

                println!("From: {}", from);
                println!("Subject: {}", subject);
                println!("Body: {}", body);
            }
        }
    }
}
3 Likes

This caused an error in compiling.
claims client to be private!
I used latest versions of crates.

What is wrong?

The imap libary changed since this post 3 years ago : imap::Client.

Don't post in old threads please.

1 Like

ok, thanks for advice.