Skip to content

Instantly share code, notes, and snippets.

@arichiardi
Created July 15, 2016 18:28
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arichiardi/63103e6920391212546485f645949651 to your computer and use it in GitHub Desktop.
Save arichiardi/63103e6920391212546485f645949651 to your computer and use it in GitHub Desktop.
Send an email with attachments using SES, postal and selmer
ns services.email
(:require [clojure.tools.logging :as log]
[clojure.string :as string]
[clojure.java.io :as io]
[schema.core :as s]
[camel-snake-kebab.core :as csk]
[camel-snake-kebab.extras :as cske]
[amazonica.core :as aws]
[amazonica.aws.simpleemail :as ses]
[selmer.parser :as selmer]
[postal.message :as msg]
[clj-time.core :as time]
[clj-time.periodic :as period]
[cemerick.url :as url]
[clj-http.client :as http]
[cheshire.core :as json]
[cats.core :as m]
[cats.builtin]
[cats.monad.exception :as exc]
[clj-http.client :as http]
...)
(:import java.io.ByteArrayOutputStream
java.nio.ByteBuffer
java.net.URLConnection)
(defn render-email
[opts {:keys [content] :as template}]
(assoc template
:content (selmer/render content opts)))
(defn guess-mime
"Try to guess the mime type, returning default if it cannot."
[path default]
(or (URLConnection/guessContentTypeFromName path) default))
(defn normalize-path
[path]
(if (= \/ (last path))
(string/join (drop-last path))
path))
(s/defn workflow-emailer! :- hs/WorkflowStatus
"Concretely send the email given the input email configuration and workflow.
Returns the new workflow status or throws if there is an error."
[email-conf :- hs/EmailConf workflow :- hs/EmailWorkflow]
(log/debugf "Templating against workflow: %s" workflow)
(let [subject (selmer/render (get-in email-conf [:templates :subject]) workflow)]
(log/debugf "Sending email \"%s\"" subject)
(let [scan-right (-> workflow :scan-right :url normalize-path)
scan-left (-> workflow :scan-left :url normalize-path)
photo (-> workflow :photo :url normalize-path)
msg (msg/make-jmessage
{:from (:source email-conf)
:to (:to-addresses email-conf)
:subject subject
:body [:mixed
[(into [:alternative]
(map (partial render-email workflow)
(get-in email-conf [:templates :body])))]
{:type :attachment
:content-type (guess-mime scan-right "image/jpeg")
:content (io/as-url scan-right)}
{:type :attachment
:content-type (guess-mime scan-left "image/jpeg")
:content (io/as-url scan-left)}
{:type :attachment
:content-type (guess-mime photo "image/jpeg")
:content (io/as-url photo)}]})]
(ses/send-raw-email :source (:source email-conf)
:destinations (:to-addresses email-conf)
:raw-message {:data (ByteBuffer/wrap
(.toByteArray
(let [baos (ByteArrayOutputStream.)]
(.writeTo msg baos)
baos)))})))
wf/email-submitted-status)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment