Rails ActionMailer with SendGrid - ruby-on-rails

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.

Related

Rails email with gmail smtp error "Errno::ECONNREFUSED - No connection could be made because the target machine actively refused it."

When attempting to send email from within my Rails 3 app in development mode on my local machine, I received the following error:
Errno::ECONNREFUSED in RemindersController#create
No connection could be made because the target machine actively
refused it. - connect(2)
After spending several hours sifting through similar questions on SO and blog posts with none of the proposed solutions working, here is the solution I finally arrived at:
tl;dr
Change your smtp port setting to 25, instead of 587 which is in all the tutorials & docs.
Detailed answer (for humans):
Step 1. Go watch railscast #206 then come back. I'll wait.
Step 2. Get extra aggravated at how easy he makes it seem even though you're getting ridiculous errors.
Step 3. Go to app/config/environments/development.rb and change line 17 from false to true. This will show you where things are getting messed up.
# config.action_mailer.raise_delivery_errors = false
config.action_mailer.raise_delivery_errors = true
Step 4. Still in app/config/environments/development.rb add the following code before the last end statement. (You no longer need the app/config/initializers/setup_mail.rb file created in the screencast when you are in development mode and can safely delete it.)
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => "smtp.gmail.com",
:port => 25,
:user_name => "<your username>#gmail.com",
:password => "<your password>",
:authentication => "plain",
:enable_starttls_auto => true
}
Notes:
Notice we did not specify the :domain setting like in the tutorials
and it works fine.
Notice also that we used your_username #gmail.com as the
:user_name setting.
If you use 2-step authentication for your gmail account you will have
to generate a special app-specific
password. disclaimer: I did not try this.
AND THE BIG FAT ELEPHANT IN THE ROOM, is that we used :port => 25
NOT 587 despite the fact that nearly every single tutorial, SO question, and the rails guide only suggest 587. Granted, this could
possibly be because my work blocks port 587? I have no idea. But
this was my key problem no one solved for me. The way to find out if
this is your problem is to use telnet. If you are on windows you
have to first enable telnet by following these
instructions.
Then go to your command prompt and type telnet smtp.gmail.com 587
if it works you will get a response like 220 mx.google.com ESMTP
pi6sm33274849wic.3 - gsmtp. Otherwise it will tell you it could not
connect, in which case you can try it on a different port eg. telnet
smtp.gmail.com 25.
I hope this helps some lost soul.
I encountered this issue whilst reading through Agile Web Development with Rails 4 chapter 13, and it turned out that any email config stuff added to config/environment.rb was being ignored, despite the book indicating that "shared" email settings for all environments could be added there.
Moving the settings into config/environments/development.rb (and restarting the Rails server) fixed the issue, allowing emails to be sent on either port 25 or port 587 without any problems:
# development.rb
Rails.application.configure do
# ...blah blah blah...
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: 'smtp.gmail.com',
port: 587,
user_name: 'yourusername#gmail.com',
password: 'yourpassword',
authentication: 'plain',
enable_starttls_auto: true
}
end
NOTE: development.rb didn't contain any email-related settings originally, so I don't think that the values in environment.rb were being superseded - it's more like they simply had no effect. The I18n.default_locale = 'en-GB' line in environment.rb was working, though, so it's not like the file was being completely disregarded...

Why am I unable to send an email with pow?

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.

Ruby on Rails/Devise smtp.rb segmentation fault

I have done quite a bit of research on this issue and have not been able to solve my issue. I am using Rails 3.0.3, Ruby 1.8.7 (patchlevel 334), Apache, Passenger 3.0.7 and the Devise gem 1.1.8. Also, I am using gmail for sending out emails. When I attempt to send a password reset I am getting an error in my Apache error_log:
[Tue Nov 01 19:40:31 2011] [error] Premature end of script headers: users
[ pid=9371 thr=3084437904 file=ext/apache2/Hooks.cpp:822 time=2011-11-01 19:40:31.664 ]: The backend application (process 9569) did not send a valid HTTP response; instead, it sent nothing at all. It is possible that it has crashed; please check whether there are crashing bugs in this application.
From my research, I found one reason that it could be due to Ruby on Rails looking for a version of OpenSSL that is buggy. I tried the suggestion of adding this to my .bashrc file:
export RUBYOPT="-ropenssl"
Also, I tried to update my SMTP configuration in my production.rb to not use TLS:
:enable_starttls_auto => false
My complete SMTP configuration:
config.action_mailer.default_url_options = { :host => '<domain>' }
ActionMailer::Base.smtp_settings = {
:enable_starttls_auto => false,
:address => "smtp.gmail.com",
:port => 587,
:domain => <domain>,
:user_name => <username>,
:password => <password>,
:authentication => "plain"
}
None of the suggestions I have found seem to have worked. I am not sure where to go from here as these are the only suggestions and fixes I have found. It does work without any issues on my development machine. Which is running the same versions of all the above except Apache/Passenger, which I do not us locally.
Mike
I was able to fix this by upgrading the Devise gem to version 1.4.8. However, after upgrading this I got an error "undefined method `new_session_path'." I then upgraded to Devise version 1.4.9 and everything is working fine now. Hope this helps someone.
Mike

Using Amazon SES with Rails ActionMailer

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.

Rails ActionMailer problems on Mac

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.

Resources