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
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
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.
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.
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
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
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.
email-smtp.us-east-1.amazonaws.com (for region us-east-1)
email-smtp.us-west-2.amazonaws.com (for region us-west-2)
email-smtp.eu-west-1.amazonaws.com (for region eu-west-1)
StackOverFlow |
Amazon-getting-started-send-using-smtp
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)
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
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
}
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.
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/
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.
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.
Related
the mail configuration is through smtp.
everything is working ok with localhost in dev mode, devise sends recover password email using smtp conf in development.rb
manual mail sending with action mail is also ok
when in production mode,
only the host is modified to match the host in production machine
the smtp conf is unchanged, and manually sending mail is ok in a rails console
BUT devise does not send recover password mail
how to debug that ?
is Devise really taking on the global mail conf in production.rb ?
there is no Devise::Mailer override.
and this is uncommented in initializer
please share the github page of your project, so we can have a look. Then also share the log of your production server. you can recover it with heroku logs. I did configure this for my apps, eventually it broke down. It is a little bit tricky. I did follow some guide. If you did the same quote the guide you followed. I followed this guide, I remember that I had to allow in my gmail account setting the usage of gmail account from my app. Then there is some settings that you need to do in production.rb, I am quoting the guide, go to that link to see the full guide and check also other guides online:
Setting Up Production Environment
Now you will need to edit the file “config/environments/production.rb”. We will be adding very similar things to this file. First you can add:
config.action_mailer.default_url_options = { :host => 'yoursite.herokuapp.com' }
NOTE: You may also need to add this line. When I was setting up the mailer, I did not find this line in any other tutorials. I had the development mailer working, however I could not get heroku to work. I received this error in the heroku logs:
ActionView::Template::Error: Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true
I found the answer here: ActionView::Template::Error: Missing host to link to on stackoverflow. If you come across this, then add:
Rails.application.routes.default_url_options[:host] = 'yoursite.herokuapp.com'
to your production.rb file.
Next you will have to add in these lines. Once again make sure that you leave the variables as they are.
config.action_mailer.delivery_method = :smtp
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = false
config.action_mailer.default :charset => "utf-8"
config.action_mailer.smtp_settings = {
address: "smtp.gmail.com",
port: 587,
domain: ENV["GMAIL_DOMAIN"],
authentication: "plain",
enable_starttls_auto: true,
user_name: ENV["GMAIL_USERNAME"],
password: ENV["GMAIL_PASSWORD"]
}
read the comments from this post and all the other relevant guides to configure this, you may need to use some smtp api to send the email....
I'm trying to send an email through gmail/actionmailer, it works perfectly on my local development box, but when I try and run the same code on production server it gives me an Net::SMTPAuthenticationError (535-5.7.8 Username and Password not accepted.. I think this is because gmail is rejecting my login credentials from an unknown server.But I'm not sure! How do I fix it?
Background:
I am using the figaro gem, and I am setting my environment variables on the openshift server with: rhc set-env. I've checked that the environment variables are set on the server.
The questions here, here, and here are all good, but have not done anything to solve my problem. My problem is a bit different because it only shows up on my server, everything works fine on my local box.
Development:
In development mode, I have the figaro gem installed, and I have my configuration file stored in application.yml which is not checked into git.
Here are it's contents:
## config/application.yml
# Add configuration values here, as shown below.
gmail_username: 'PLACE_HOLDER_EMAIL#gmail.com'
gmail_password: 'PLACE_HOLDER_PASSWORD'
In my controller:
## PLACEHOLDER_controller.rb
def create
#placeholder = Placeholder.new(placeholder_params)
respond_to do |format|
if #placeholder.save
puts "SENDING..."
puts "Sending to: #{ENV['gmail_username']}..."
PLACEHOLDERMailer.placeholder_email(some, params).deliver
puts "SENT!"
end
end
Production:
## /config/environments/production.rb
# SMTP
config.action_mailer.delivery_method = :smtp
# SMTP settings for gmail
config.action_mailer.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:user_name => "#{ENV['gmail_username']}",
:password => "#{ENV['gmail_password']}",
:authentication => "plain",
:enable_starttls_auto => true
}
Production:
I push the code to my OpenShift repo with git, the server restarts, ostensibly everything is fine. Except that when I create a new placeholder, I get a 500 back from the server.
Here is the log output:
>> rhc tail -a MY_APP
SENDING...
Sending to: "PLACE_HOLDER_EMAIL#gmail.com"... ## This is the correct email! It's clearly pulling the proper values from ENV.
INFO -- : Rendered placeholder_mailer/placeholder_email.text.erb (0.1ms)
INFO -- :
Sent mail to 9739069711#txt.att.net (132.3ms)
INFO -- : Completed 500 Internal Server Error in 224ms
FATAL -- :
Net::SMTPAuthenticationError (535-5.7.8 Username and Password not accepted. Learn more at
):
app/controllers/placeholders_controller.rb:35:in `block in create'
app/controllers/placeholders_controller.rb:29:in `create'
Which says that the username and password were not accepted. Now, I know that I have the correct username and password. I'm fairly certain that's not the issue. I suspect that (as mentioned in the linked questions) smtp.gmail.com is rejecting my login from an unknown server.
Before anyone suggests it, I have already:
Disabled Two Factor Authentication
Tried creating an application specific password and using that instead. (Didn't work, I've now switched back to the regular account password)
Enabled access to less secure applications.
TL;DR
I'm trying to send an email from the server. When I run it on the server it gives me: Net::SMTPAuthenticationError (535-5.7.8 Username and Password not accepted.. I think this is because gmail is rejecting my login credentials from an unknown server. How do I fix it?
It turns out that gmail blocks you temporarily if you try to access it programatically more than once every ten minutes. I suppose I must have did this while I was testing the functionality.
I have a rails project which sends an email using an ActionMailer. This seems to work fine with 'rails server' on localhost:3000 but when I use pow, I get authentication error messages from the smtp server. I'm guessing this has something to do with environment variables. Here is the config code
config.action_mailer.smtp_settings = {
address: "smtp.gmail.com",
port: 587,
domain: "railscasts.com",
authentication: "plain",
enable_starttls_auto: true,
user_name: ENV["GMAIL_USERNAME"],
password: ENV["GMAIL_PASSWORD"]
}
I'm on Mountain Lion.
Thanks
I have a different suggestion:
In dev, just use letter_opener. It's more useful in that context than actually sending emails, anyway.
In production, use SendGrid and not GMail. SendGrid is awesome and really easy to set up.
Pow loads environment variables from checking two files in the application root
.powrc
.powenv
I created the .powrc file using the touch command, then added my environment variables
export GMAIL_USERNAME=username
export GMAIL_PASSWORD="my password"
I then restarted the worker for the app this way:
touch tmp/restart.txt
E-mails now work!
As blamattina has suggested, it may have something to do with your domain in your configuration file! According to the example given by Ruby on Rails Guides:
The correct, Gmail compatible configuration looks like this:
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:domain => 'baci.lindsaar.net',
:user_name => '<username>',
:password => '<password>',
:authentication => 'plain',
:enable_starttls_auto => true }
Your domain is set to railscasts.com. Unless that's your website, my guess is that this domain is not correct. In fact, it is apparently optional as well.
This StackOverflow details that a plugin was once necessary, but is no longer needed if you're using Rails 3.2 or higher. A comment below the top answer in the article details that the domain is optional.
Update: Based on the error you described, it looks like you're hitting an authentication error! This may be because of your login credentials not properly registering.
This user is asking in the context of using Heroku, but the error is the same. If your app works properly with the Rails server, but not on Pow, it's a server-side setup issue. The solution involves needing to properly set your ENV (environment) variables to work with your server.
I'm using SendGrid to send emails on Heroku...
The problem so far is while it works great on Heroku, on my local host it fails.
Right now I have SendGrig install here, config/setup_mail.rb:
ActionMailer::Base.smtp_settings = {
:address => "smtp.sendgrid.net",
:port => "25",
:authentication => :plain,
:user_name => ENV['SENDGRID_USERNAME'],
:password => ENV['SENDGRID_PASSWORD'],
:domain => ENV['SENDGRID_DOMAIN']
}
What's a Heroku/SendGrid way to allow me to make sure my mailers work in DEV. Is this setup_mail.rb file a good thing? Should it be in the env file? Any other thoughts?
Thanks
Using config/environments/[development.rb | production.rb] as tfe mentioned above sounds like its the way to go. Just put the ActionMailer configuration in either of those files and change it to suit the development|production environment.
You can also find your SendGrid credentials used by Heroku by issuing the following command:
heroku config --long
These credentials are used for all SendGrid authentication (SMTP Auth, Website login to view stats, etc., API access)
-- Joe
SendGrid
Just set environment variables on your development environment for SENDGRID_USERNAME, SENDGRID_PASSWORD, and SENDGRID_DOMAIN. Then it will work.
You can get the correct values for these from your Heroku app. Open heroku console and get the values of ENV['SENDGRID_USERNAME'] and so on.
Or just use a different set of SMTP settings locally. Or use sendmail or something.
I've been working on learning to use Rails the last couple days and I've run into something that I haven't been able to solve with Google.
So I'm just creating a basic contact form that sends an email. Everything seems to be working ok in testing, which tells me that the form is working, and ActionMailer was implemented correctly, however, I'm having trouble configuring ActionMailer. I'm running OSX 10.6.2. I have postfix running and have verified that it's running using telnet localhost 25. When I try to use the form I get a "Connection refused" error.
This is my current configuration:
config.action_mailer.smtp_settings = {
:address => 'localhost',
:port => 25
}
I thought I might need to set :domain but I'm kind of confused on what that should be set to in this situation.
My life has been roughly 100x easier running :sendmail on my mac as a delivery method on my mac rather than :smtp, you might want to try giving that a shot. In this answer, I am assuming that you just want mail delivery on your Mac and don't actually care how it works.
The other thing I do, if I'm going to be connected to the net all the time on a project, is to configure my outgoing ActionMailer-originated mail to go through gmail rather than my local mac.
ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
:enable_starttls_auto => true,
:address => "smtp.gmail.com",
:port => 587,
:domain => "example.com",
:authentication => :plain,
:user_name => "address#example.com",
:password => "secret"
}
This is for a custom domain called example.com that is set up on google apps for domains. You can also just create a gmail account and send things through there. (By changing all instances of example.com to gmail.com)
You need to start the postfix daemon. you can tell if your port is open by typing in a terminal
telnet localhost 25
which will try to connect to the 25 port. It wont connect if postfix isnt running, if it does, hit ctl-] to stop the connection and 'quit' to quit telnet.
If it doesn't connect, you need to start the postfix daemon:
sudo launchctl start org.postfix.master
and then try to connect with telnet. it should connect. Now you are ready to send emails from your ActionMailer class.
sudo launchctl stop org.postfix.master
stops the postfix daemon
I followed this guide and everything works correctly. Mainly:
sudo postfix start
then
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => "localhost",
:port => 25
}
Does it work if you substitute '127.0.0.1' for 'localhost' to see if this is an IPv4 vs. IPv6 thing or an issue with your resolver?
Another great way of sending and verifying mails when development is using enter link description here.
Quote from their website:
MailCatcher runs a super simple SMTP server which catches any message sent to it to display in a web interface. Run mailcatcher, set your favourite app to deliver to smtp://localhost:1025 instead of your default SMTP server, then check out http://localhost:1080 to see the mail that's arrived so far.
It intercepts mail to all recipients and hence makes it really easy to check all mail in one place.