drewr / postal

Clojure email support
MIT License
585 stars 85 forks source link

Message format #13

Open pepijndevos opened 12 years ago

pepijndevos commented 12 years ago

I'm working on an IMAP wrapper that I'd like to integrate with Postal later on, but there are a few incompatibilities or inconsistencies.

For a multipart message, you suggest

{:from "me@draines.com"
 :to "foo@example.com"
 :subject "Hi!"
 :body [{:type "text/html"
     :content "<b>Test!</b>"}
     ;;;; supports both dispositions:
     {:type :attachment
     :content (java.io.File. "/tmp/foo.txt")}
     {:type :inline
     :content (java.io.File. "/tmp/foo.txt")}]}

This is almost equal to what I produce, except that you use both :content and :body, and :type for both :content-type and :content-disposition, why? Are they interchangeable, or is there a difference?

An example message of mine, which is a rather straightforward conversion:

{:subject "anther test",
 :from "Pepijn de Vos <pepijndevos@gmail.com>",
 :date "Thu, 17 Nov 2011 17:28:50 +0100",
 :to "postmaster@wishfulcoding.mailgun.org",
 :content
 ({:content "Hi\r\n\r\n",
   :content-type "text/plain; charset=\"us-ascii\"",
   :mime-version "1.0",
   :content-transfer-encoding "7bit"}
  {:content
   ({:content
     "<html><head></head><body style=\"word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; \">Hi<div><br></div><div><img height=\"240\" width=\"240\" apple-width=\"yes\" apple-height=\"yes\" id=\"e5e7beb3-323d-4657-8018-bac9bf8fdfc2\" src=\"cid:02374C7B-D4AB-4D39-A892-8FC5B025A9EF@lan\"><img height=\"240\" width=\"240\" apple-width=\"yes\" apple-height=\"yes\" id=\"c87d9bc1-42ac-4c78-b8b8-efb050267160\" src=\"cid:E986AD1E-5A70-4301-89D1-0AB4BD62181E@lan\"></div></body></html>",
     :content-type "text/html; charset=\"us-ascii\"",
     :mime-version "1.0",
     :content-transfer-encoding "7bit"}
    {:content
     #<BufferedImage BufferedImage@64900079: type = 6 ColorModel: #pixelBits = 32 numComponents = 4 color space = java.awt.color.ICC_ColorSpace@2a0f3b83 transparency = 3 has alpha = true isAlphaPre = false ByteInterleavedRaster: width = 240 height = 240 #numDataElements 4 dataOff[0] = 3>,
     :content-type "image/png; name=\"illusion.png\"",
     :mime-version "1.0",
     :content-id "<02374C7B-D4AB-4D39-A892-8FC5B025A9EF@lan>",
     :content-disposition "inline; filename=\"illusion.png\"",
     :content-transfer-encoding "base64"}
    {:content
     #<BufferedImage BufferedImage@4e0c2b07: type = 6 ColorModel: #pixelBits = 32 numComponents = 4 color space = java.awt.color.ICC_ColorSpace@2a0f3b83 transparency = 3 has alpha = true isAlphaPre = false ByteInterleavedRaster: width = 240 height = 240 #numDataElements 4 dataOff[0] = 3>,
     :content-type "image/png; name=\"square.png\"",
     :mime-version "1.0",
     :content-id "<E986AD1E-5A70-4301-89D1-0AB4BD62181E@lan>",
     :content-disposition "inline; filename=\"square.png\"",
     :content-transfer-encoding "base64"}),
   :content-type
   "multipart/related;\r\n boundary=\"===============7617467129600379649==\"",
   :mime-version "1.0"}),
 :received
 "from ubuntu.lan (ip4da451b5.direct-adsl.nl. [77.164.81.181]) by\r\n mx.google.com with ESMTPS id f41sm91056321eec.5.2011.11.17.08.28.50\r\n (version=TLSv1/SSLv3 cipher=OTHER); Thu, 17 Nov 2011 08:28:53 -0800 (PST)",
 :content-type
 "multipart/alternative;\r\n boundary=\"===============4025336257788734124==\"",
 :mime-version "1.0",
 :dkim-signature
 "v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma;\r\n h=from:content-type:subject:date:message-id:to:mime-version:x-mailer;\r\n bh=aHrYvWBg8oYhUws6PWTTAvMs9wUsBG0OfADodtVoP40=;\r\n b=TH+x17rro680gVsA0e5numk5JiOJPnaYCNafeN4ubkJCG3r5y4Ttk2xw+cN35wqaop\r\n zeqO1RcRfVWXozquGNIWa6Xo7E/JPSvH62jnionnrnZU7qN2Vyr0SIFwZWcCFMR5Wxkd\r\n 0JqJLT4hbQ+W1HM+W5AGTGntYNDw7OfDG7emI=",
 :message-id "<D58523A8-9C2B-4698-BCB7-71E845E80472@gmail.com>",
 :x-mailer "Apple Mail (2.1251.1)"}
drewr commented 12 years ago

Hi Pepijin!

I use :body because that's the RFC822-ish way to refer to whatever is not part of the headers. When I switch to MIME context I begin thinking in terms of content. The reason for only having :content and :type is that between those two values I can provide a MIME library what it needs to know. It is a string? OK, what kind of string? If it's a file I can figure out the mimetype for myself and then you just need to tell me if you want it inlined or attached.

It's possible this is too much magic and it would be easier to not have those things conflated. I haven't found that to be true yet.