Cail is a small library for parsing the insane javax.mail library classes into Clojure data structures. It doesn't do everything, but it should help with the 99% use case of "give me the emails and their attachments".
(require [cail.core :refer [message->map]])
(def original
(.getJavaMailMessageFromSomewhereIn javaLand))
(def message
(message->map original))
(:subject message) ; => "The Subject"
(count
(:attachments message)) ; => 3
; etc...
The message body will prefer HTML content types.
When given a message to parse it will still require the connection
to its associated folder to fetch its data from. Also be aware that
the :id attached to each message is dependent on its folder, and
can change depending on if messages get deleted or moved - so use uid
where available.
Due to the possible (and probable) size of attachment content this is not extracted by default. All the metadata for attachments will be available after parsing a message, but to fetch the content you need to ask for it.
(def msg
(with-content-stream
(message->map message)))
(def attachments
(:attachments msg))
(println
(count attachments )) ; => 2
(def attachment
(first attachments))
(:content-type attachment) ; => "application/pdf"
(spit
"~/file.pdf"
(:content-stream attachment))
The :content-stream is an input stream for reading the attachment.
Attachments come with an :id
property you can use to ask for them individually...
; (message->map msg)
; {:attachments [{:id 1} {:id 2}]}
(def attachment
(message->attachment msg 1))
By default this will not return the content stream for the attachment, just wrap it in with-content-stream to fetch that.
(def attachment
(with-content-stream
(message->attachment message 1)))
The message->map function returns a bunch of fields by default. If you want to only return a subset of these (eg. for working with FetchProfiles) then you can specify these as the second argument.
(message->map msg [:id :subject :from])
One goal of Cail is to allow messages to be cacheable. So after parsing they don't rely on any internal state (connections to mail stores) that the Java versions do.
This means that after parsing and caching a message the only time you need to go back to the mail store is to fetch the content of attachments.
Tests use Midje.
lein midje
Cail is available from Clojars