#211 Email API

brian Tue 29 Apr 2008

I've been reading thru the various RFCs to tackle my next project - Fan's email API. The new email pod will have the following responsibilities:

  • Email - models a multipart MIME email document (RFC 2045)
  • SmtpClient - client side of the SMTP protocol (RFC 2821)
  • Pop3Client - client side of the POP3 protocol (RFC 1939)
  • ImapClient - client side of the IMAP protocol (RFC 3501)

For the first version I will be implementing only Email and SmtpClient. POP3 and IMAP will be future work (hopefully by a new contributor if anyone is interested).

I'll need to go through some iterations to decide the best way to model email documents, although I'm thinking something like this:

@serializable
class Email
{
  Str:Str headers
  Str[] to
  Str[] cc
  Str[] bcc
  Str subject
  EmailPart[] parts
}

// construct simple email message
email := Email
{
  to = ["[email protected]"]
  subject = "hi"
  parts = [EmailPart.makeText("hello world")]
}

The Email class will be serializable so that it can be easily passed between threads and queued on disk.

The SmtpClient will implement direct access to the SMTP protocol:

mailer := SmtpClient { host = "mail.foo.com"; username = "brian"; password = "pass" }
mailer.send(email)

I plan to implement the SMTP-Auth extension because it is pretty much required these days. Although I'm not planning on implementing any other extensions not needed for character encodings.

The SmtpClient will provide synchronous access to the SMTP protocol - it won't do any persistent queuing or retries. The email pod will be responsible only for the lowest level of the email stack. However I do plan for Fan to have a reusable persistent queuing pod which will be composable with email to easily implement fire-and-forget email.

brian Sat 3 May 2008

Update on this feature - the SmptClient class is pretty much done. I've done PLAIN and LOGIN authentication mechanisms so far - I can add new mechanisms as needed easily.

I've got an API I'm pretty happy with for modeling MIME messages. I still need to handle Unicode encodings. Until we do POP3, this API will probably only support encoding (not decoding MIME messages).

Some working examples to give a feel for the API:

// simple plain text message
email := Email
{
  to = ["[email protected]", "[email protected]"]
  from = "[email protected]"
  subject = "hello"
  body = TextPart { text = "hello world" }    
}

// multipart with both html and plain text
email := Email
{
  to = ["[email protected]", "[email protected]"]
  from = "[email protected]"
  subject = "hello"
  body = MultiPart
  {
    headers["Content-Type"] = "multipart/alternative"
    parts =
    [
      TextPart 
      { 
        headers["Content-Type"] = "text/plain"
        text = "this is bold and italics!" 
      },
      TextPart 
      {
        headers["Content-Type"] = "text/html"
        text = "this is <b>bold</b> and <i>italics</i>!"
      }
    ]
  }
}

I'm out of town for the next two weeks, so things will be a bit slow.

brian Sun 18 May 2008

Multipart MIME and SMTP support is complete and documented.

Andy is using this new code to add email notification to sidewalk (plus he has Atom feeds).

I got a couple more little things to take care of, then I will be posting a new build.

Login or Signup to reply.