From 36520b6adea775f2d0841bca9dd18c239545d072 Mon Sep 17 00:00:00 2001 From: Vebjorn Ljosa Date: Wed, 3 Jan 2018 01:02:12 -0500 Subject: [PATCH 1/2] Return the reply from SMTP server when sending single message Return the reply because it may contain useful information for logging and tracking. In particular, Amazon SES insists on assigning a new Message ID rather than trusting the one we send them, and they return the assigned Message ID in the reply, after "250 Ok". Only do this when `smtp-send` is called with a single message. (This is the common use case, which is documented and supported by postal.core.) If someone manages to call `smtp-send` with multiple messages, then return a response without the server replies, as before. (The alternative, which is to complicate the response from `smtp-send` to incorporate multiple replies while remaining backwards compatible, does not seem worth it---especially because sending multiple messages at a time is not something you should do if you care to know which ones succeeded.) --- README.md | 48 ++++++++++++++++++++++----------------------- src/postal/smtp.clj | 17 +++++++++++++--- 2 files changed, 38 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 1d63c9d..637dd43 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ To use SMTP, add an argument map before the message with at least :to "foo@example.com" :subject "Hi!" :body "Test."}) - {:code 0, :error :SUCCESS, :message "message sent"} + {:code 250, :error :SUCCESS, :message "250 Ok\n"} postal.core> For legacy compatibility, you can also supply these connection @@ -74,7 +74,7 @@ Authenticate to SMTP server with `:user` and `:pass`. :to "foo@example.com" :subject "Hi!" :body "Test."}) - {:code 0, :error :SUCCESS, :message "message sent"} + {:code 250, :error :SUCCESS, :message "250 Ok\n"} postal.core> #### Encryption (Gmail example) @@ -98,7 +98,7 @@ anyway.) :to "foo@example.com" :subject "Hi!" :body "Test."}) - {:code 0, :error :SUCCESS, :message "message sent"} + {:code 250, :error :SUCCESS, :message "250 Ok\n"} postal.core> #### Amazon @@ -113,7 +113,7 @@ you can only send *to* a verified address as well. Example: :port 587} {:from "me@draines.com" :to "me@draines.com" :subject "Test from Amazon SES" :body "Test!!!11"}) - {:error :SUCCESS, :code 0, :message "messages sent"} + {:code 250, :error :SUCCESS, :message "250 Ok 01020160ba715c7e-0268d4ae-4189-4020-80c0-23328e018775-000000\n"} postal.core> #### Attachments @@ -132,7 +132,7 @@ Attachments and multipart messages can be added as sequences of maps: {:type :inline :content (java.io.File. "/tmp/a.pdf") :content-type "application/pdf"}]}) - {:code 0, :error :SUCCESS, :message "message sent"} + {:code 250, :error :SUCCESS, :message "250 Ok\n"} postal.core> If your attachment has a content-type that is not recognized by @@ -212,25 +212,25 @@ You can stress-test a server by: ## Contributors -Allen Rohner -Andre Branco -Andy Fingerhut -Christoph Henkelmann -Colin Jones -Dante Briones -Dimas Guardado -Gerrit Hentschel -J. David Lowe -Jeff Palmucci -Joe Gallo -Kevin DeJong -Kyle Kingsbury -Paul Biggar -Paul Stadig -Phil Hagelberg -Roman Flammer -Sam Ritchie -Stephen Nelson +Allen Rohner +Andre Branco +Andy Fingerhut +Christoph Henkelmann +Colin Jones +Dante Briones +Dimas Guardado +Gerrit Hentschel +J. David Lowe +Jeff Palmucci +Joe Gallo +Kevin DeJong +Kyle Kingsbury +Paul Biggar +Paul Stadig +Phil Hagelberg +Roman Flammer +Sam Ritchie +Stephen Nelson ## License diff --git a/src/postal/smtp.clj b/src/postal/smtp.clj index b40cf8d..bb702d8 100644 --- a/src/postal/smtp.clj +++ b/src/postal/smtp.clj @@ -26,15 +26,26 @@ [postal.support :only [make-props]]) (:import [javax.mail Transport Session])) +(defn- send-single [transport ^javax.mail.Message jmsg] + (.sendMessage transport jmsg (.getAllRecipients jmsg)) + {:code (.getLastReturnCode transport) + :error :SUCCESS + :message (.getLastServerResponse transport)}) + +(defn- send-multiple [transport jmsgs] + (doseq [^javax.mail.Message jmsg jmsgs] + (.sendMessage transport jmsg (.getAllRecipients jmsg))) + {:code 0 :error :SUCCESS :message "messages sent"}) + (defn ^:dynamic smtp-send* [^Session session ^String proto {:keys [host port user pass]} msgs] (assert (or (and (nil? user) (nil? pass)) (and user pass))) (with-open [transport (.getTransport session proto)] (.connect transport host port user pass) (let [jmsgs (map #(make-jmessage % session) msgs)] - (doseq [^javax.mail.Message jmsg jmsgs] - (.sendMessage transport jmsg (.getAllRecipients jmsg))) - {:code 0 :error :SUCCESS :message "messages sent"}))) + (if (= (count msgs) 1) + (send-single transport (first jmsgs)) + (send-multiple transport jmsgs))))) (defn smtp-send ([msg] From 93dd22e62369bbd101a10a14953e68c0c03bcb6e Mon Sep 17 00:00:00 2001 From: Vebjorn Ljosa Date: Thu, 4 Jan 2018 15:21:11 -0500 Subject: [PATCH 2/2] Avoid duplicate code https://github.com/drewr/postal/pull/92#pullrequestreview-86744038 --- src/postal/smtp.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/postal/smtp.clj b/src/postal/smtp.clj index bb702d8..3643a69 100644 --- a/src/postal/smtp.clj +++ b/src/postal/smtp.clj @@ -34,7 +34,7 @@ (defn- send-multiple [transport jmsgs] (doseq [^javax.mail.Message jmsg jmsgs] - (.sendMessage transport jmsg (.getAllRecipients jmsg))) + (send-single transport jmsg)) {:code 0 :error :SUCCESS :message "messages sent"}) (defn ^:dynamic smtp-send* [^Session session ^String proto