ActionMailer not sending mail in development Rails 4 - ruby-on-rails

Why is this mailer not sending any mail? (Or any ideas for debugging?)
In my_app/config/environments/development.rb I have this code:
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: 'smtp.gmail.com',
port: 587,
domain: 'my_app.com',
user_name: ENV['GMAIL_USERNAME'],
password: ENV['GMAIL_PASSWORD'],
authentication: 'plain',
enable_starttls_auto: true }
Then on my local computer in ~/.bash_profile I have this code:
export GMAIL_USERNAME='blah#my_app.com'
export GMAIL_PASSWORD='***'
When I run $ env in my terminal, I see that both environment variables are correctly set.
I have also restarted my rails server.

You should add
config.action_mailer.perform_deliveries = true
as by default this is on false, preventing mails to be sent from your development environment...

For anyone not using smtp, switching the delivery method to sendmail helped me in addition to explicitly setting deliveries to be performed:
config.action_mailer.delivery_method = :sendmail

If you're having issues sending email from console, you have to call the deliver method on your mail.
MyMailer.create_email.deliver

All of these answers are great, but there is another place where you can get burned, especially in the context of debugging.
In development.rb make sure you set config.action_mailer.raise_delivery_errors = true
If your .deliver method seems to be working without issue, but you never actually receive the email across the wire, your delivery method may be throwing an exception and rails is swallowing the error. This is very true if you simply have something as simple as a misconfigured credentials, or an aws access denied API error. Save ripping your hair out and make sure you have raise_delivery_errors turned on. It wants to tell you something but can't.

So I've figured it out. Having the line ActionMailer::Base.delivery_method = :smtp in config/environment.rb overrides ActionMailer::Base.delivery_method = :test in config/environments/test.rb.
So, delete that line, ActionMailer::Base.delivery_method = :smtp from config/environment.rb and place it in config/environments/production.rb. That allows you to place ActionMailer::Base.delivery_method = :test in config/environments/test.rb and the version you want in config/environments/development.rb. I made development.rb :test as I populated my database using Faker and changed it to :smtp so I was sure that real emails were sent as an additional check.
Note: You must restart your server for these changes to take effect.
Another note: Heroku's current SendGrid Instructions (https://devcenter.heroku.com/articles/sendgrid) put the SendGrid Heroku configuration code in a new config/initializers/mail.rb file which will likely require removing its last line and placing the desired version in each config/environments/[production.rb, development.rb, test.rb]

Related

devise not sending recover password email

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....

On Heroku when sending mail through action mailer gives error

I created rails g mailer from this reference site. It is working fine on local there is no error. I also added {config.action_mailer.delivery_method = :smtp} with did smtp settings and deployed on heroku,
but now its giving error
We're sorry, but something went wrong. Please help.
For sending mail in production environment, do following thing -
1. In config/environments/production.rb
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: 'smtp.mail.com',
port: 587,
domain: 'YOUR_DOMAIN_GOES_HERE',
user_name: 'YOUR_EMAIL_ID_GOES_HERE',
password: 'YOUR_PASSWORD_GOES_HERE',
authentication: 'plain',
enable_starttls_auto: true }
and deploy this change on heroku and if you again found any error there, please check -
heroku stack:set cedar-14
then again deploy on heroku - git push heroku master.
Try it.
The Heroku platform itself doesn’t provide an email service. You need to use external services. Read their documentation about how to send emails from your app.

how to place SMTP configuration on a separate file?

I'm configuring my app to send emails through gmail smtp, so I'm writing the action_mailer setup in the production.rb file.
Though I don't want to have my gmail credentials written in the production.rb file, which is git versioned.
this is what I have made so far:
in production rb:
require "SmtpData"
config.action_mailer.default_url_options = {:host => 'my server's ip'}
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
enable_starttls_auto: "true",
address: SmtpData::ADDRESS,
port: SmtpData::PORT,
domain: "pjforex.com",
authentication: :plain,
:user_name => SmtpData::USER,
:password => SmtpData::PASS
}
then I created config/initializers/smtp_data.rb containing:
class SmtpData
USER = 'user#gmail.com'
PASS = 'password'
ADDRESS = "smtp.gmail.com"
PORT = "587"
end
But when my capistrano tries to precompile the assets, I get :
rake aborted!
uninitialized constant SmtpData
any clue on how to solve this. or better approach to this issue?
thanks,
You need to store your configuration in a file excluded from Git but shared between deployments. Assuming you are using Capistrano 3, it would be something like this:
1) On your server create a file shared/config/smtp.yml (using YAML is not something crucial, but it's just cleaner for configs) in Capistrano root folder with the following content:
user: user#gmail.com
pass: your_password
address: smtp.gmail.com
port: 587
2) Add this file to your linked_files in config/deploy.rb (ideally, config/database.yml should be stored this way too):
set :linked_files, %w{config/database.yml config/smtp.yml}
3) Read SMTP config in production.rb from config/smtp.yml.
4) You can also have config/smtp.yml locally for your development environment, but don't forget to add it to your .gitignore then.
I believe that production.rb gets loaded before smtp_data.rb, which is why production.rb isn't able to access the class you have defined.
One solution we use, to keep sensitive credentials out of our git versions, is to create (as in your example) production.rb.template and add this to your git repository. This file is pretty much a copy of what you currently have for production.rb, except that you would have placeholders for where credentials should go. For example,
:username => USERNAME GOES HERE
Then, we remove production.rb from the repository (and, optionally, set it to be ignored by git). When you check out your local copy of the repository, you copy production.rb.template as production.rb, and you fill in the credential information. This will only exist in your local deployment and would not be pushed to git.

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...

Thin server not loading environment variables with Capistrano

I'm deploying my rails app with capistrano and using the thin server. I have 2 env vars for my mailer username and password defined in ~/.bash_profile with export SMTP_USERNAME=....
When I ssh to the server and try to send emails from the rails console it works fine but it looks like they are not loaded by thin when I run cap deploy or any other command.
What's the correct way to define them? I've seen some posts where they suggest to define them directly in the config/environments/production.rb or in some other file related to the code itself. I was trying to avoid that for security reasons.
UPDATE: I tried to use a yml file to store this but I ran into this problem:
I created a new file email_config.rb in config/initializers. Its content is:
EMAIL_CONFIG = YAML.load_file("#{RAILS_ROOT}/config/email.yml")[RAILS_ENV]
In config/email.yml I have:
production:
username: username
password: password
In my config/environments/production.rb I have:
config.action_mailer.delivery_method = :smtp
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true
config.action_mailer.default :charset => "utf-8"
config.action_mailer.smtp_settings = {
address: "smtp.gmail.com",
port: 587,
authentication: :plain,
enable_starttls_auto: true,
user_name: EMAIL_CONFIG[:username],
password: EMAIL_CONFIG[:password]
}
Now the problem is that initializers are loaded after environments.rb and if I put the definition of the EMAIL_CONFIG variable just before my email configuration, then the RAILS_ROOT variable is not define.
Like you're saying, not a god idea to save a password directly in the production.rb. A better option would be to reference them from shell variables (closer to your current setup) or from a yaml file (what I do personally). You can find more information in this post

Resources