bits and pieces

April 6, 2011

Grails: Using Mail Plugin With Amazon Email Service

Filed under: Uncategorized — Tags: — roshandawrani @ 11:26 pm

This is a quick note on how to use Grails Mail plugin with Amazon’s Simple Email Service – an inexpensive, hassle-free, reliable, scalable mail-sending solution. It’s not meant to cover any details about Amazon SES itself, because those are pretty well documented, but here are some links to get started:

It is assumed from here on that you have registered with Amazon Web Services and have valid credentials to login with.

Grails Mail plugin is based on Spring Mail support and by default uses “smtp” as the mailing protocol. With SMTP, it can be configured as below:

grails {
    mail {
        host = '<some host>'
        port = <some port>
        username = 'foo@example.org'
        password = 'xxxxxxx'
        props = ['mail.smtp.auth': 'true', ...]
    }
}

However, when you want to use the Mail plugin with Amazon SES, you need to switch the protocol to “aws” and specify the transport implementation class, as shown in the configuration below:

grails {
    mail {
        props = [ 
            'mail.transport.protocol': 'aws', 
            'mail.aws.class': 'com.amazonaws.services.simpleemail.AWSJavaMailTransport',
            'mail.aws.user': '<your aws access key>',
            'mail.aws.password': '<your aws secret key>' 
        ]
    }
}

While above configuration change is the primarily required one, there are 2 more little changes that need to be made to switch to SES:

a) While the above configuration change registers “aws” protocol with its implementation transport class, you need to explicitly tell Mail plugin again that you want to use “aws” as the protocol in your application

grails.mail.protocol = 'aws'

b) This second bit is needed because if you don’t provide any mail host, the mail plugin takes “localhost” as the default, which confuses AWS mail API because it thinks that you are trying to override the default endpoint of the SES mail service by another specific endpoint (host). So, it needs to be explicitly cleared to let SES API use its default endpoint (https://email.us-east-1.amazonaws.com)

beans {
    mailSender.host = ''
}

That’s all!

Just point your Grails app to AWS SDK on maven repository, make the above configuration changes and start using Mail plugin to send mails through your Amazon Simple Email Service account and enjoy the hassle-free mailing from your Grails application!

About these ads

20 Comments »

  1. Excellent!

    Using the Spring Mail API this way, is there any possibility to get the id of the email sent? Amazon generates these ids and in a (hope near) future, we will be able to track the message info with it.

    Is there any problem to link this blog post to the Grails AWS Plugin page? People really need to know this possibility instead of just the pure SES API.

    Thanks,

    Comment by Lucas Teixeira — April 6, 2011 @ 11:56 pm

    • Thanks, Lucas.

      No, there is no problem at all in getting this blogpost linked with Grails AWS Plugin page. Please go ahead and link it. I will be happy about it.

      I am pretty sure, at this point, any email id returned by SES must be getting lost while returning through Spring mail api and Mail plugin, but will try to have a look around it tomorrow anyway.

      Comment by roshandawrani — April 7, 2011 @ 12:11 am

      • Thanks Roshan!

        Comment by Lucas Teixeira — April 7, 2011 @ 9:44 am

      • Just added this blog post under the FaQ section.
        Best regards
        George

        Comment by George — January 2, 2012 @ 7:47 pm

  2. Nice blog, I had an error though after setting everything up. I also needed to add the stax jar in my dependencies to fix the exception I was getting – javax.xml.stream.FactoryConfigurationError: Provider com.bea.xml.stream.MXParserFactory not found

    i.e.
    dependencies {
    runtime ‘com.amazonaws:aws-java-sdk:1.1.9′
    runtime ‘stax:stax:1.2.0′
    }

    Comment by Matt G — April 14, 2011 @ 3:19 am

    • Thank you.

      Yes, I had got the stax dependency error too.

      It seems while stax-api was a regular dependency, stax was an optional dependency of aws-java-sdk and didn’t get pulled-in. We ended up excluding stax-api dependency, as it didn’t seem needed for the mail functionality we were using. :-)

      Comment by roshandawrani — April 14, 2011 @ 8:05 am

  3. Great, but there is one problem… Why do I have to setup my AWS credentials in one another place (grails.mail.props slurp) if I had configured them before in grails.plugin.aws.credentials closure?

    Comment by Yuriy Yarovoy — September 16, 2011 @ 8:41 am

    • Thanks, Yuriy. The technique discussed in the blogpost is absolutely independent of Grails AWS plugin. I wanted to try and make it work with just standard Grails Mail plugin – that was the main attraction of the experiment :-)

      Comment by roshandawrani — September 16, 2011 @ 8:55 am

  4. Any way to have the AWS credentials in a .properties file as per the Grails AWS plugin. I have just switched to the mail plugin so I can send attachments, I am waiting for either one of them to support S3 at rest encrypted files.

    Comment by stevef — November 11, 2011 @ 4:18 am

  5. Estou tentando implementar mas estou com problemas…

    Comment by Edson de Almeida — July 14, 2012 @ 1:39 am

    • Que tipo de problemas?

      Comment by roshandawrani — July 14, 2012 @ 9:01 am

      • Dá pra usar o plugin mail normal, sem este procedimento, uma vez que o SES agora tem suporte nativo a SMTP.
        Basta habilitar no console e usar as credenciais que ele fornecerá. Bem tranquilo…

        Comment by lucastex — July 16, 2012 @ 7:56 pm

  6. Could you explain a bit more about the change you mentioned under b) ?
    You say “mailSender.host” needs to be set, i suppose you mean in resources.groovy? Adding just the one line won’t work of course, since it needs to be an instance of a class. Adding two lines instead, like so;
    def mailSender = new MailSender()
    mailSender.host = ”

    doesn’t work either. Without this change i’m indeed stuck on the localhost problem you mention.

    Comment by Robert — July 19, 2012 @ 8:46 pm

    • Hi Robert,

      You can put this block in your Config.groovy.
      ——————————–
      beans {
      mailSender.host = ”
      }
      ——————————–

      The idea is to clear this piece of configuration (so that Grails mail plugin does not send “localhost” as the mail server to AWS), so that AWS Mail API uses the default end-point.

      You can only do two things with this config – a) clear it (and use the default), or b) override it to another specific AWS endpoint (I guess you have no reason to choose this option)

      Hope it helps.

      Comment by roshandawrani — July 20, 2012 @ 3:03 pm

      • Yep, that did the trick. That is, after i solved;
        – a PermGen error i got on Elastic Beanstalk (solved by raising the default 64MB set for “Maximum JVM Permanent Generation Size (MB)”) when it tried to generate the certificate, and
        – used the correct AWS credentials from here (https://portal.aws.amazon.com/gp/aws/securityCredentials) instead of the SMTP credentials…

        But in the end it works. Thanks roshandawrani, your blog entry has been a great help.

        Comment by Robert — July 20, 2012 @ 5:59 pm

  7. None of this is necessary anymore as you can just use the standard SMTP protocol with SES. Works flawless. You don’t need to set any special protocol

    Comment by Peter Locke (@pdlocke) — July 21, 2012 @ 8:12 am

    • to clarify

      mail {
      host = “email-smtp.us-east-1.amazonaws.com”
      port = 465
      username = “YOUR_SES_USERNAME”
      password = “YOUR_SES_PW”
      props = ["mail.smtp.auth": "true",
      "mail.smtp.socketFactory.port": "465",
      "mail.smtp.socketFactory.class": "javax.net.ssl.SSLSocketFactory",
      "mail.smtp.socketFactory.fallback": "false"]
      }

      Comment by Peter Locke (@pdlocke) — July 21, 2012 @ 8:14 am

    • Worth checking out! Thanks.

      Comment by roshandawrani — July 21, 2012 @ 8:15 am

  8. I still need to use aws protocol and I’ve some problems:
    – The bean to set the host don’t work for me, I set it in grails.mail.host
    – The mail is not sent at all with this exception:

    Class
    org.springframework.mail.MailSendException
    Message
    Failed messages: javax.mail.SendFailedException: Unable to send email; nested exception is: com.amazonaws.AmazonClientException: Unable to execute HTTP request: null

    Config.groovy (related only)

    grails {
    plugin {
    aws {
    credentials {
    accessKey = “ADFAJMX7OH5ZLDEFFLIPPB6Q”
    secretKey = “jrdadsfsdfasdfefe0kSYovG/+p3uLnTV8PxrqXCR”
    }
    ses {
    enable = true
    catchall = “XXX@gmail.com”
    from =”XX@xx.com”
    }
    }
    }
    }
    grails {
    mail {
    host = ‘email-smtp.us-east-1.amazonaws.com’

    props = [
    'mail.transport.protocol': 'aws',
    'mail.aws.class': 'com.amazonaws.services.simpleemail.AWSJavaMailTransport',
    'mail.aws.user': 'ADFAJMX7OH5ZLDEFFLIPPB6Q',
    'mail.aws.password': 'jrdadsfsdfasdfefe0kSYovG/+p3uLnTV8PxrqXCR'
    ]
    }
    }
    grails.mail.protocol = ‘aws’

    Comment by linsmso — September 22, 2012 @ 8:34 pm


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Silver is the New Black Theme. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: