40

What would be the best way to go about making ActionMailer send mail via Amazon SES in Rails 3?

Edit:

This is now a gem:

gem install amazon-ses-mailer

https://rubygems.org/gems/amazon-ses-mailer

https://github.com/abronte/Amazon-SES-Mailer

Loren Segal
  • 3,251
  • 1
  • 28
  • 29
AdamB
  • 3,101
  • 4
  • 34
  • 44
  • In case anyone is still visiting this answer, the above gem has certificate verification issues with SSL in JRuby (maybe outside of JRuby as well), which can be fixed as by modifying the gem like so: http://martinottenwaelter.fr/2010/12/ruby19-and-the-ssl-error/ – laker Sep 21 '12 at 23:45

10 Answers10

83

Setting up Rails 3.2 for sending emails using Amazon's Simple Email Service (SES) is easy. You do not require any additional gem or monkey patching to make it work.

SES supports both STARTTLS over SMTP as well as TLS/SSL. The following demonstrates how to set up Rails for STARTTLS with SES.

Prerequisites

  1. If you are running rails Mac OS X, you may need to configure OpenSSL for Ruby correctly before you can use STARTTLS. If you are using Ruby 1.9.3 and RVM, here is one way to do this:

    rvm pkg install openssl
    rvm reinstall 1.9.3 --with-openssl-dir=$rvm_path/usr 
    

If you do not do this, there is a possibility that Ruby will segfault when you try to send an email.

  1. Make sure you have verified your sender email address with AWS. You can only send emails with a verified email address as the sender. Go to the "Verified Senders" option on the left menu in AWS console for SES.

  2. Make sure you have the AWS SMTP user name and password for authentication. Go to the "SMTP Settings" option on the left menu in AWS console for SES to set this up. You will first be prompted to create an IAM user (default: ses-smtp-user) and then you will be shown the SMTP user and password, which look like usual AWS key and secret. Note that the IAM user, i.e., ses-smtp-user is not the SMTP user that you will be using for authentication.

Configuring Rails

In config/environments/development.rb and config/environments/production.rb, add the following:

  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
      :address => "email-smtp.us-east-1.amazonaws.com",
      :port => 587, # Port 25 is throttled on AWS
      :user_name => "...", # Your SMTP user here.
      :password => "...", # Your SMTP password here.
      :authentication => :login,
      :enable_starttls_auto => true
  }

Sending an email

This is it. Now you can go ahead and create a mailer and start sending emails for fun and profit!

Create a sample mailer

rails g mailer user_mailer

In app/mailer/user_mailer.rb:

    class UserMailer < ActionMailer::Base
      # Make sure to set this to your verified sender!
      default from: "your@verifiedsender.com"  

      def test(email)
        mail(:to => email, :subject => "Hello World!")
      end
    end 

In views/user_mailer/test.erb:

    A quick brown fox jumped over the lazy dog.

Now, launch the console and shoot off a test email:

    rails c

    Loading development environment (Rails 3.2.1)
    1.9.3p125 :001 > UserMailer.test("your@email.com").deliver
Undo
  • 25,519
  • 37
  • 106
  • 129
Sujoy Gupta
  • 1,424
  • 1
  • 10
  • 12
  • I have to specify the `:domain` parameter in `smtp_settings` to get this to work. It doesn't seem to matter what I set it to, so I have gone for `example.com` for now. Thanks! – Robert Haines Oct 24 '12 at 11:09
  • @RobertHaines, I am using Rails 3.2.10 and I did not have to specify any :domain parameter. – Sujoy Gupta Jan 04 '13 at 23:56
  • @SujoyGupta - I should have mentioned that this app is using the 2.3.x branch of rails. – Robert Haines Jan 24 '13 at 16:25
  • 1
    Thank you for the complete tutorial, Sir @SujoyGupta. – FRAGA Sep 20 '13 at 20:49
  • Thanks helped loads; one thing though I had to set the return_path default in the UserMailer too. – Neil Billingham Oct 18 '13 at 22:17
  • Tutorials like these are lifesavers. – Kasperi Mar 14 '14 at 16:56
  • where to put the access_keys ? – argentum47 Apr 02 '15 at 11:26
  • i tried your solution but could send email. ended up with timeout error – aashish May 03 '15 at 10:31
  • @aashish, I am now using Rails 4.2.1 and everything still works. The only difference is, I added an explicit entry for using port 587 instead of 25. Please recheck that you are following the instructions and AWS SES is configured correctly. – Sujoy Gupta May 08 '15 at 21:59
  • @sujoy Gupta, I tried by changing port to 587 but no luck. – aashish May 10 '15 at 07:55
  • @aashish, I'll begin by verifying the AWS SES configuration, making sure all the values in smtp settings are correct and then using some local proxy like Charles to see what exactly is hanging. Good luck with the investigation. – Sujoy Gupta May 10 '15 at 21:55
  • I'm having the same problem (in my dev environment using Cloud9). Do I need to set up Cloud9 as a verified sender domain in AWS SES (doesn't seem possible since I don't control this DNS) or should it suffice to set up verified emails? If the latter, any other ideas? – steve klein May 12 '15 at 21:21
  • @steveklein I'd try connecting to the SES endpoint directly and seeing if that works from your environment. Next, I'd seek help from AWS support. – Sujoy Gupta May 29 '15 at 23:02
31

I also have a gem out that supports sending e-mail through SES from Rails 3:

https://github.com/drewblas/aws-ses

It also has all the API for verifying/managing e-mail addresses

Drew Blas
  • 3,028
  • 1
  • 21
  • 11
  • It is not working now. I have exception: SignatureDoesNotMatch – ka8725 Feb 28 '12 at 23:57
  • I created a new gem using Signature V4. It is for basic SES API transactional email integrated with rails. https://github.com/cickes/ses_api-rails – csi Oct 21 '15 at 14:42
14

For TLS SSL setup [Recommended by Amazon SES]

Spoiler Alert: NO GEM Required

smtp is defualt way of sending email in rails but you can add this line to explicitly define in config/application.rb file

config.action_mailer.delivery_method = :smtp

In config/application.rb or you can specify in certain environment file

config.action_mailer.smtp_settings = {
    address: 'Amazon SES SMTP HOSTNAME',
    port: 465,   #TLS port
    domain: 'example.com',
    user_name: 'SMTP_USERNAME',
    password: 'SMTP_PASSWORD',
    authentication: 'plain',   #you can also use login
    ssl: true,   #For TLS SSL connection
}

The Amazon SES SMTP HOSTNAME is specific for every region, so you that name which you are in, following are hostnames wrt regions.

  1. email-smtp.us-east-1.amazonaws.com (for region us-east-1)
  2. email-smtp.us-west-2.amazonaws.com (for region us-west-2)
  3. email-smtp.eu-west-1.amazonaws.com (for region eu-west-1)

StackOverFlow | Amazon-getting-started-send-using-smtp

Taimoor Changaiz
  • 10,250
  • 4
  • 49
  • 53
9

After poking around a bit I ended up just making a simple class to do this.

https://github.com/abronte/Amazon-SES-Mailer

In rails, you can get the encoded email message:

m = UserMailer.welcome.encoded
AmazonSES.new.deliver(m)
AdamB
  • 3,101
  • 4
  • 34
  • 44
  • Thanks for this. It's weird cause the first few times I tried this it didn't encode the body properly so it sent an email without any contents. For an unknown reason when I tried it later it did work. Regardless, this solution worked for me, good to know! Amazon SES is a very nice new option for sending emails and it's extremely cheap. I believe it has less features than for example SendGrid, but if you don't particularly need them this seems like the way to go if you want something very affordable. And it just released and is only in beta right now. :) – Michael van Rooijen Jan 30 '11 at 00:10
7

I use the following gem:

https://github.com/aws/aws-sdk-rails

It pulls in the standard aws-sdk, plus allows to set ActionMailer to use AWS SES. Example:

# config/production.rb
# ...
config.action_mailer.delivery_method     = :aws_sdk
Andreas Profous
  • 1,384
  • 13
  • 10
  • 1
    This is the way. This allowed me to use instance credentials to send emails. For the V3 AWS SDK this is just `config.action_mailer.delivery_method = :ses` – BenV Jun 23 '20 at 22:13
4

Configuring your Rails application with Amazon SES

set action_mailer.perform_deliveries to true as it is set to false by default in the development/production environment

config.action_mailer.perform_deliveries = true

then paste this code in your development/production environment

config.action_mailer.smtp_settings = {
  :address => ENV["SES_SMTP_ADDRESS"],
  :port => 587,
  :user_name => ENV["SES_SMTP_USERNAME"], 
  :password => ENV["SES_SMTP_PASSWORD"],
  :authentication => :login,
  :enable_starttls_auto => true
}
Marcelo Austria
  • 861
  • 8
  • 16
0

I created a simple Rails / SES API gem that uses Signature v4 to sign the request. This is best used for transactional emails such as contact us, user registration, etc.

Rails SES API integration gem

Please feel free to improve on it & contribute.

csi
  • 9,018
  • 8
  • 61
  • 81
-1

using :sendmail, I managed to get all emails to send running apt-get install postfix as root on my AWS machine and using all the default answers.

bigpotato
  • 26,262
  • 56
  • 178
  • 334
-1

SES just was released into beta today, so I doubt that there is a ready-to-go gem (at least, not that I've seen). You could write a custom module based upon their developer documents:

http://docs.amazonwebservices.com/ses/latest/DeveloperGuide/
jschorr
  • 3,034
  • 1
  • 17
  • 20
  • I know it's still really early to be asking this question. The main thing is I would like to use the MIME encoded message rails generates through its mailer. – AdamB Jan 25 '11 at 21:31
-2

You can provide delivery method to action mailer in your environment.

config.action_mailer.delivery_method = AmazonSES.deliver

For now you are likely on your own writing the delivery code.

bbck
  • 39
  • 3