Email delivery libs not working

463 views
Skip to first unread message

The Dude (Abides)

unread,
Feb 24, 2014, 5:33:59 AM2/24/14
to clo...@googlegroups.com
Hi, I'm new to clojure and have got a productive handle on CRUD, sessions, routing, writing functions. Last couple things are email delivery, image processing (resizing).

So I looked on the clojure-toolbox site for email delivery libs with smtp authentication for a Mandrill acct fo transactional emails. I've used Mandrill in other langs right away zero glitch. Here's the results thus far in Clojure as a frame of reference for web domain use 2014:

POSTAL
https://github.com/drewr/postal#encryption-gmail-example

Doesn't deliver. Tried number of examples in the docs.

MAILER
https://github.com/clojurewerkz/mailer

Worked briefly, but not via Mandrill, no emails reached there. Authentication settings have no impact, uses Postal above lib for delivery. Tried number of examples in the docs.

CLJ MAIL
https://github.com/MayDaniel/clj-mail

Out of date syntax.

I googled and found a couple more in the quest to avoid having to do this via java heaven forbid:

MMEmail
http://blog.8thlight.com/micah-martin/2010/04/21/mmemail-my-first-clojure-open-source-contribution.html

Says cannot connect to port 25 although my settings specify port 587 for Mandrill

POSTMARK
http://sjl.bitbucket.org/clojure-postmark/

Transactional email delivery service with a clojure lib. Will create an acct in morning and try it out.

Doe anyone know of any other smooth workable out the gate solutions for email delivery?

Jim - FooBar();

unread,
Feb 24, 2014, 6:06:28 AM2/24/14
to clo...@googlegroups.com
How about the JavaMail API? here is an example :

(defn- map->properties
"Converts a Map<String, String> to a java.util.Properties object."
[^java.util.Map property-value-map]
{:pre [(every? #(every? string? %) property-value-map)]}
(doto (java.util.Properties.)
(.putAll property-value-map)))

(defn mail "Send email programmatically."
[{:keys [from to subject text password host ssl? port]}]
{:pre [(string? from) (string? host) (string? subject)
(string? text) (string? password) (seq to)]}
(let [auth (proxy [Authenticator] []
(getPasswordAuthentication []
(PasswordAuthentication. from password)))
props (map->properties {"mail.smtp.user" from
"mail.smtp.host" host
"mail.smtp.starttls.enable" (str ssl?)
"mail.smtp.auth" "true"
"mail.smtp.port" (str port)})
session (Session/getInstance props auth)
msg (doto (MimeMessage. session)
(.setText text)
(.setSubject subject)
(.setFrom (InternetAddress. from))) ]
(doseq [addr to]
(.addRecipient msg Message$RecipientType/TO (InternetAddress. addr)))
(Transport/send msg)
(println (str "The e-mail titled <" subject "> has left the
building..."))))

(defn gmail "Send email with GMail."
[opt-map]
(mail
(merge opt-map {:host "smtp.gmail.com"
:ssl? true
:port 587})))

Jim
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@googlegroups.com
> Note that posts from new members are moderated - please be patient
> with your first post.
> To unsubscribe from this group, send email to
> clojure+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to clojure+u...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

The Dude (Abides)

unread,
Feb 24, 2014, 6:23:18 AM2/24/14
to clo...@googlegroups.com
Hi Jim, am not opposed to using java and put the code in a diff namespace to reuse.

Am going to try out a lib for delivery svc, one for Mandrill and the other for Postmark.

If any glitches there, will use java as you suggested.

Thanks for the working example.

Pardeep.

Dave Della Costa

unread,
Feb 24, 2014, 8:42:20 AM2/24/14
to clo...@googlegroups.com
I'm sending authenticated emails via Mandrill with Postal and not having
any trouble, and setting it up was pretty much a "smooth workable
out-of-the-gate solution." If you describe the errors or issues you're
experiencing someone may be able to help, but it's absolutely not the
case that these libraries don't work.

László Török

unread,
Feb 24, 2014, 8:55:00 AM2/24/14
to clo...@googlegroups.com
same here, we are using Postal with Mailgun, no issues so far
--
László Török

Sam Ritchie

unread,
Feb 24, 2014, 11:14:00 AM2/24/14
to clo...@googlegroups.com
If you want to use Mandrill, here's a gist with my core.async mandrill API code I wrote for PaddleGuru:

https://gist.github.com/sritchie/9191297

You can figure out the requires from the namespace declaration, I think. I use the conf namespace to get my API key (toggled for prod and dev), and "collectify" is just this:

(defn collectify [obj]
    (cond (nil? obj) []
          (or (sequential? obj) (instance? List obj)) obj
          :else [obj]))

It's not the full API, of course, but it should get you going.
February 24, 2014 3:33 AM
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

--
Sam Ritchie (@sritchie)
Message has been deleted
Message has been deleted

The Dude (Abides)

unread,
Feb 24, 2014, 6:52:07 PM2/24/14
to clo...@googlegroups.com

I'm not inferring it doesn't work at all as obviously over the years some of these libs have worked for someone. However these libs are not working for me with Mandrill which has worked seamlessly for email delivery in other langs. I checked the API logs on Mandrill and it appears in the last 100 succeeded API calls, not a failed API call.  Yet in the API log full response it says "Status: invalid"

I don't think the Mandrill acct is the problem as I'm using it to deliver email invoices and receipts in another language. Its likely something missing in the email body perhaps. Here's my code to send email with Postal, perhaps there is something wrong or missing in the syntax:

(ns myapp.routes.members
  (:use   compojure.core
            [clojure.string :only (join split)])
  (:require [myapp.views.layout :as layout]
            [noir.session :as session]
            [noir.response :as resp]
            [noir.io :refer [upload-file resource-path]]
            [noir.validation :as vali]
            [noir.util.crypt :as crypt]
            [ring.util.response :refer [file-response]]
            [ring.middleware [multipart-params :as mp]]
            [myapp.models.members :as memberdb]
            [clojure.java.jdbc :as jdbc]
            [clojure.java.io :as io]
            [myapp.models.schema :as schema]
            [clj-time.core :as time]
            [clj-time.coerce :as tc]
            [postal.core :as postal]
            [myapp.util
            :refer [galleries img-path]])
  (:import [java.io File FileInputStream FileOutputStream]
                javax.imageio.ImageIO))

(postal/send-message
     ^{:host "smtp.mandrillapp.com"
       :user "testg4521@****.com"
       :pass "rssvZq9llJ7pjkjkj8989hjhj"
       :port 587}
      {:from "testg4521@****.com"
       :to "testg4521@****.com"
       :subject "Hi from Scrappy Doo"
       :body "How are you Uncle Scooby?"})

Maybe there's a conflict with my libs? I changed the email and api key as its for a client.

And here is the info in the Mandrill log file, its not in the fail section yet it doesn't get delivered. I have another option with a clojure lib for Postmark which I'll try out in the next couple hours.

{
    "from_email": null,
    "ip_pool": null,
    "raw_message": "Received: from 192.163.1.145 (unknown [69.106.86.42])\n\t(Authenticated sender: rshjkhjkhjk...@gmail.com)\n\tby ip-10-244-148-99 (Postfix) with ESMTPA id 35E1C3A0086\n\tfor <testg4521@****.com>; Mon, 24 Feb 2014 23:10:07 +0000 (UTC)\nDate: Mon, 24 Feb 2014 15:10:07 -0800 (PST)\nFrom: testg4521@****.com\nTo: testg4521@****.com\nMessage-ID: <WwH5GWZnxz2WHlSEM...@postal.Comp.local>\nSubject: Hi from Scrappy Doo\nMIME-Version: 1.0\nContent-Type: text/plain; charset=utf-8\nContent-Transfer-Encoding: 7bit\nUser-Agent: postal/1.11.1\n\nHow are you Uncle Scooby?",
    "async": false,
    "key": "rshjkhjkhjkhk098904YEiQ",
    "send_at": null,
    "from_name": null,
    "return_path_domain": null,
    "to": [
        "testg4521@****.com"
    ]
}
Full Response

[
    {
        "email": "testg4521@****.com",
        "status": "invalid",
        "_id": "fcbb8fbb76124f31b88b3c4f4ae10b10",
        "reject_reason": null
    }
]

Perhaps Mandrill needs something in the body of the email to verify its a legit sendable email?

In either event its not been a smooth journey trying out a few diff libs. I will get in touch with Mandrill ref why the email is not delivered and try out some of the other options mentioned here. Thank you for the feedback and tips.

The Dude (Abides)

unread,
Feb 25, 2014, 5:08:07 AM2/25/14
to clo...@googlegroups.com
I managed to get Postal delivery working with Mandrill, still use of templates with formatting v helpful. Mailer and Postal have a slight problem on recognizing the meta info for smtp auth.

So with some fiddling figured out how to merge Clostache into Postal for html templates with dynamic vars as follows:

dependencies:  [com.draines/postal "1.11.1"]
                         [de.ubercode.clostache/clostache "1.3.1"]

(:use       clostache.parser)
(:require  [postal.core :as postal]

(postal/send-message
    ^{:host "smtp.mandrillapp.com"
      :user "your mandrill acct email address"
      :pass "your mandrill api key"
      :port 587}
     {:type "text/html"
      :from "from email address"
      :to "to email address"
      :subject (render "Hi from {{firstname}}" {:firstname (session/get :firstname)})
      :body [{:type "text/html; charset=utf-8"
              :content (render-resource "email/templates/hello.html.mustache"
               {:name "Uncle Scooby" :memberid (session/get :member-id)}) }] })

The hello.html.mustache template file:

    Hello {{name}},<br /><br />

    My member id is: {{memberid}}<br /><br />

    Best,<br />
    Scrappy Doo.

The template path root is the app src folder. So your app/src/email/templates/hello.html.mustache

So this works but the use of Clostache still seems a bit boilerplatish. Does anyone know of a more elegant option if possible.

Thank you for the other tips, will try out the native java and the other Mandrill code option, see which is the best overall approach long term.

Michael Klishin

unread,
Feb 25, 2014, 5:12:57 AM2/25/14
to clo...@googlegroups.com
2014-02-25 14:08 GMT+04:00 The Dude (Abides) <exe...@gmail.com>:
(postal/send-message
    ^{:host "smtp.mandrillapp.com"
      :user "your mandrill acct email address"
      :pass "your mandrill api key"
      :port 587}
     {:type "text/html"
      :from "from email address"
      :to "to email address"
      :subject (render "Hi from {{firstname}}" {:firstname (session/get :firstname)})
      :body [{:type "text/html; charset=utf-8"
              :content (render-resource "email/templates/hello.html.mustache"
               {:name "Uncle Scooby" :memberid (session/get :member-id)}) }] })

Let me just say that the choice to use metadata to pass crucial connection arguments
in Postal was wrong.

We will be replacing Postal in ClojureWerkz Mailer for this reason.
--
MK

http://github.com/michaelklishin
http://twitter.com/michaelklishin

exe...@gmail.com

unread,
Feb 25, 2014, 6:00:41 AM2/25/14
to clo...@googlegroups.com
Let me know whenever its updated, dynamic email and img resize v heavy use cases. 

You guys are doing an amazing job with all the libs, most of them higher end stuff. I've never done msg queuing or used a graph db, so looking forward to expanding. Its a polygot reality hereon.

P.


--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to a topic in the Google Groups "Clojure" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/U8U8WfV0GR8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojure+u...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages