I'm trying to send an email when a new English-Grade is created in my rails app. In this app it may be relevant that Student is an inherited (STI) type of devise User and I'm trying to send them an email when a teacher (another type of inherited devise User) creates a grade.
At the moment just trying to get it to work locally using gmail. I used
rails g mailer UserMailer
to setup.
This is the error I get when I create an English-grade.
Net::SMTPAuthenticationError in EnglishGradesController#create
530-5.5.1 Authentication Required. Learn more at
#student = Student.find_by_id(#english_grade.student_id)
if #english_grade.save
**UserMailer.new_grade(#student).deliver**
redirect_to(student_path(#student), :notice => "Post was successfully created.")
else // etc
(** is the highlighted error)
The above is also where I'm calling the mailer so I won't repeat it.
My development.rb file:
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.default_url_options = { :host => "my ip address" }
config.action_mailer.smtp_settings = {
:address => "smtp.gmail.com",
:domain => 'my ip address:3000', //where 3000 is the port I'm running on locally
:port => 587,
:user_name => ENV['example#gmail.com'],
:password => ENV['password'],
:authentication => "plain",
:enable_starttls_auto => true
}
config.action_mailer.perform_caching = false
My mailer:
class UserMailer < ApplicationMailer
default from: "example#gmail.com"
def new_grade(user)
#user = user
mail to: #user.email, subject: "New grade created"
end
end
From reading some of the other Qs:
In the development.rb I have tried without the 'domain:' and without having the host IP address stuff
I have tried:
http://www.google.com/accounts/DisplayUnlockCaptcha
I have also allowed access for less secure apps https://www.google.com/settings/security/lesssecureapps
I have changed my password to something complicated
I also tried changing port to 465 but got an end of file error.
Also if it's of any relevance I created this gmail account today specifically to send emails for the app
Any help would be greatly appreciated, thanks!
The problem was actually that
:authentication => "plain",
needed to be:
:authentication => "login",
Related
I am trying to send a notification email when a resume file is uploaded to a job posting. I am trying to use Gmail SMTP in Production but I keep getting these error messages in Heroku logs:
Completed 500 Internal Server Error in 505ms (ActiveRecord: 11.3ms)
Net::SMTPAuthenticationError (530-5.5.1 Authentication Required. Learn more at
Everything works perfectly in Development.rb and I can't figure out why it won't work in production.
Here is my Controller: Please see 'create'
class ResumesController < ApplicationController
helper_method :count
def new
#resume = Resume.new
#post = Post.find(params[:post_id])
end
def create
#resume = Resume.new(resume_params)
#resume.user_id = current_user.id
#resume.post_id = params[:post_id]
if #resume.save
ResumeMailer.resume_received(#resume).deliver_now
current_user.credits = current_user.credits + 1
current_user.save!
flash[:success] = "Congratulations! Your Candidate has been submitted and 1 Credit has been added to your account!"
redirect_to :root
end
end
def show
resume = Resume.find(params[:id])
if current_user.unlocks.where(resume_id: resume.id).length > 0
send_file resume.document.path.split('?')[0], :filename => resume.document_file_name, :type => ["application/pdf", "application/doc", "application/docx"], :disposition => "attachment"
elsif current_user.credits > 0
current_user.credits = current_user.credits - 1
current_user.save!
Unlock.create(user_id: current_user.id, resume_id: resume.id)
send_file resume.document.path.split('?')[0], :filename => resume.document_file_name, :type => ["application/pdf", "application/doc", "application/docx"], :disposition => "attachment"
else
flash[:success] = "Your Credit balance is zero. Submit more resumes for more Credits!"
redirect_to inbox_path
end
end
def inbox
#resumes = current_user.incoming_resumes.order("created_at DESC")
end
def destroy
#resume = Resume.find(params[:id])
#resume.destroy
flash[:success] = "Your Resume has been successfully deleted!"
redirect_to inbox_path
end
def count
current_user.resumes.count
end
private
def resume_params
params.require(:resume).permit(:document)
end
end
Here is my Mailer:
class ResumeMailer < ApplicationMailer
default from: "MYEMAIL#gmail.com"
def resume_received(resume)
#resume = resume
#post = #resume.post
mail to: #post.user.email,
subject: "You have received a new Candidate for the #{#post.title} posting!"
end
end
Here is my Development.rb SMTP:
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
config.active_record.raise_in_transactional_callbacks = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: "smtp.gmail.com",
port: 587,
domain: "gmail.com",
authentication: "plain",
enable_starttls_auto: true,
user_name: ENV["GMAIL_USERNAME"],
password: ENV["GMAIL_PASSWORD"]
}
Here is my Production.rb SMTP:
config.action_mailer.default_url_options = { host: 'MYSITE.herokuapp.com', protocol: 'http' }
# Do not dump schema after migrations.
config.active_record.dump_schema_after_migration = false
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: "smtp.gmail.com",
port: 587,
domain: "gmail.com",
authentication: "plain",
enable_starttls_auto: true,
user_name: ENV["GMAIL_USERNAME"],
password: ENV["GMAIL_PASSWORD"],
openssl_verify_mode: 'none'
}
}
This set up works perfectly fine in Development and I have also already gone into GMAIL settings to allow access to less secure apps. Any help or resources to point me in the right direction would be greatly appreciated.
how about change the host without http (see sample below)
another idea is also check your system environment access your secret_data variabel whether it's work / not (ENV["GMAIL_PASSWORD"]
config.action_mailer.default_url_options = { :host => "xxx.xxx.xxx.xxx" }
config.action_mailer.delivery_method=:smtp
config.action_mailer.raise_delivery_errors = true
# Gmail SMTP server setup
ActionMailer::Base.smtp_settings = {
:address => "smtp.gmail.com",
:enable_starttls_auto => true,
:port => 587,
:authentication => :plain,
:user_name => "your username",
:password => 'your pass'
}
Though the OP's issue has been solved apparently, I am putting this out for reference of future visitors who encounter a similar problem.
When the error is "Authentication Required" during an attempt to send an email, the first thing to do may be to check if the related config parameters are set exactly as you expect.
Launch the console (if you can) with bin/rails c and run, for example, if Rails 6 (and 5?),
Rails.application.config.action_mailer.smtp_settings[:user_name][-10..-1]
# => "#gmail.com" (providing your user_name is at Gmail.)
Rails.application.config.action_mailer.smtp_settings[:password].size > 0
# => true
Obviously, you can browse them directly if your security policy allows.
Note that although you probably specify these pieces of information in an encrypted way in your code, the contents of the Hash above are a plain String.
A potential trap in Rails 6 is that the encrypted strings for your run-time environment may differ from the global one in your Rails application. For example, once you have run bin/rails credentials:edit --environment development, the file config/credentials/development.key (and development.yml.enc) are created even if you add nothing in the credentials, and then your credential items in the development environment will differ from the global one from the moment. So, make sure what are set in your config in your run-time environment are what you intend.
Alternatively, to specify bare plain-text strings for user_name and password in development.rb (or production.rb) temporarily and to run the process to send an email would be a simple experiment, providing the security policy allows you to do so.
As an added note, if the error is "Username and Password not accepted" despite they are correctly set, and if you are using the Gmail server, then chances are it is because of the server setting of the Gmail account used. Specifically, the option "Access for less secure apps" must be turned ON at the Gmail setting.
See this Rails-specific answer, or in more detail, this answer at serverfault about the Gmail-specific issue.
UPDATE:
I got it to send emails by actually accessing my app through heroku's website, but it still fails when I run the app from a production server in my cloud9 ide. Is that normal? Is that the way the tutorial wants me to do it?
In chapter 11 of Michael Hartl's Ruby on Rails Tutorial you are asked to signup for the Sample App in deployment mode with an email you control and check your email account for the account activation email. I did not receive any emails and the sendgrid add-on for heroku reports that no email requests have been sent. However, in the cloud 9 ide puma server console it reports that the email was sent with the correct format, to the correct address, and I can retrieve the activation token and email address from the console. I'm not sure what I'm doing wrong. Hopefully, all the relevant code is included below. Please help.
I actually went to the sample app website and clicked sign-up and then waited for the email. Is this not what Hartl means by "sign-up for a new account in production"?
config/environment.rb:
# Load the Rails application.
require_relative 'application'
# Initialize the Rails application.
Rails.application.initialize!
#Sendgrid configurations from their website
ActionMailer::Base.smtp_settings = {
:user_name =>ENV['SENDGRID_USERNAME'],
:password =>ENV['SENDGRID_PASSWORD'],
:domain => 'heroku.com',
:address => 'smtp.sendgrid.net',
:port => 587,
:authentication => :plain,
:enable_starttls_auto => true
}
mailers/application_mailer:
class ApplicationMailer < ActionMailer::Base
default from: 'noreply#example.com'
layout 'mailer'
end
environments/production.rb:
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
host = 'gentle-lake-88943.herokuapp.com'
config.action_mailer.default_url_options = { host: host }
ActionMailer::Base.smtp_settings = {
:address => 'smtp.sendgrid.net',
:port => '587',
:authentication => :plain,
:user_name => ENV['SENDGRID_USERNAME'],
:password => ENV['SENDGRID_PASSWORD'],
:domain => 'heroku.com',
:enable_starttls_auto => true
}
users_controller.rb:
def create
#user = User.new(user_params)
if #user.save
#user.send_activation_email
flash[:info] = "Please check your email to activate your account"
redirect_to root_url
else
render 'new'
end
end
user.rb:
def activate
update_columns(activated: true, activated_at: Time.zone.now)
end
def send_activation_email
UserMailer.account_activation(self).deliver_now
end
routes.rb:
resources :account_activations, only: [:edit]
I just resolved this tutorial's problem. My initial problem was i did not write the variable name correctly. I had reviewed my code and I fixed it. My app works fine now, as tutorial says.
As Igor says at his last answer, you dont need any special code in config/environments.rb so you should erase it if you keep it.
Check your environment's variables in Heroku with heroku run printenv. If those are correct, try the BAD way, just as test: replace ENV['SENDGRID_xxx'] by your sendgrid's username and password.
Thanks to Nathan Road
I have a Rails application which uses a form to collect message details and emails the message to my gmail/yahoo account.
I have added this to setup_mail.rb in config/initializers:
ActionMailer::Base.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:user_name => "my_user",
:password => "my_pass",
:authentication => "plain",
:enable_starttls_auto => true
}
and use the controller like so for the POST route:
def create
#message = Message.new(params[:message])
if #message.valid?
NotificationsMailer.new_message(#message).deliver!
redirect_to(root_path, :notice => "Message was successfully sent.")
else
flash.now.alert = "Please fill all fields."
redirect_to('#')
end
end
The Message Parameters are accepted from the form cleanly like so:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"4xgV0umvaTPzYxd18qdJq/GT7QCdXjrPTGR7D9R3AC4=", "message"=>{"name"=>"Deepak", "email"=>"deepakm.ccx#gmail.com", "subject"=>"Hi", "body"=>"Hi"}, "commit"=>"Send"}
No matter if I use Yahoo credentials or Gmail Credentials in the setup, I keep getting the same error message. I commented all the settings in ActionMailer::Base.smtp_settings and still get this issue. This leads me to believe the issue could be related to something else outside this code but I have no clue whatsoever.
-Deepak
You mention your code is in config/initializers - we have ActionMailer working, and it sends through Gmail, except we put this into our config/environments/developer.rb file:
#Send Email In Development (Use Gmail's Servers)
config.action_mailer.raise_delivery_errors = true
config.action_mailer.perform_deliveries = true
config.action_mailer.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:domain => "*****.co.uk",
:user_name => "******#gmail.com",
:password => "******",
:authentication => :plain,
:enable_starttls_auto => true
}
config.action_mailer.default_url_options = {
:host => "localhost:3000"
}
Maybe you could try copy-and-pasting the above code?
While I am still unable to send emails via ActionMailer still, I thought I would post an alternative.
https://github.com/nu7hatch/gmail
Works well and is easier because you dont need to use any config files.
Thanks.
I am creating a simple non-profit application with Ruby on Rails. I have to set up the following settings in order to be able to send emails with Gmail:
Depot::Application.configure do
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address:"smtp.gmail.com",
port:587,
domain:"domain.of.sender.net",
authentication: "plain",
user_name:"dave",
password:"secret",
enable_starttls_auto: true
}
end
I am completely new with this stuff and have no idea what exactly I should do.
How to populate the settings above if I have gmail account? Do I
need to buy a domain and can be it bought from google in order to
use the settings above?
Is it better to set up mail server on my PC? I looked though
this tutorial but as far as I understand I still need to buy a
domain.
Also, as it is said here:
Setting up an email server is a difficult process involving a number
of different programs, each of which needs to be properly configured.
because of this and my poor skills I am looking for the simplest solution.
I have read the rails action mailer tutorial and have an idea about what these parameters are used for, but the things around the Gmail and the mail server are not clear at all.
The configuration of your mailer should/can be defined in both development and production the purpose of this configuration is that when you set this up when you use the actionmailer these SMTP options will be used. You could have a simple mailer like the following:
Mailer
class UserMailer < ActionMailer::Base
default :from => DEFAULT_FROM
def registration_confirmation(user)
#user = user
#url = "http://portal.herokuapp.com/login"
mail(:to => user.email, :subject => "Registered")
end
end
Controller
def create
#title = 'Create a user'
#user = User.new(params[:user])
if #user.save
UserMailer.registration_confirmation(#user).deliver
redirect_to usermanagement_path
flash[:success] = 'Created successfully.'
else
#title = 'Create a user'
render 'new'
end
end
So what happens here is that when the create action is being used this fires the mailer UserMailer Looking at the above UserMailer it uses the ActionMailer as the base. Following the SMTP setup shown below which can be defined in both config/environments/production.rb and development.rb
You would have the following:
config.action_mailer.default_url_options = { :host => 'portal.herokuapp.com' }
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => 'smtp.gmail.com',
:port => 587,
:domain => 'gmail.com',
:user_name => 'EMAIL_ADDRESS#gmail.com',
:password => 'pass',
:authentication => 'login',
:enable_starttls_auto => true
}
If you want to define the SMTP settings in development mode you would replace
config.action_mailer.default_url_options = { :host => 'portal.herokuapp.com' }
with
config.action_mailer.default_url_options = { :host => 'IP ADDRESS HERE:3000' }
This should be a thorough enough explanation to kick start you in the right direction.
The above answer worked for me in development once I changed it to
authentication: 'plain'
and included
config.action_mailer.raise_delivery_errors = true
in my development environment.
I'm trying to implement a "contact us" form on my rails 3.0.10 project. Following the RailsGuides I created a mailer.
class QuestionMailer < ActionMailer::Base
default :to => "%mail#mydomain" #gmail for domains
def ask(message)
#content = message.content
unless message.name.nil? or message.name.empty?
from = "#{message.name} <#{message.email}>"
else
from = message.email
end
mail(:subject => message.subject, :from => from)
end
end
In my controller I have these lines:
if #question.valid?
QuestionMailer.ask(#question).deliver
redirect_to root_url, :notice => "Сообщение отправлено"
else
Production.rb:
config.action_mailer.delivery_method = :smtp
config.action_mailer.default_url_options = { :host => '%mydomain%' }
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']
}
I didn't have this config at first, but when I didn't receive the email, I added it.
The problem is, the Heroku log says, that the corresponding view has been rendered, but I don't receive the email. And because I use sendgrid, I cant test it locally.
upd
Note to self. After creating gmail for domain account, don't forget to your DNS settings. >_<
You can test locally still using sendgrid - from the command line do heroku config and you can grab the values that Heroku has set for sendgrid username, password and domain and then set them in your development.rb along with the actionmailer settings and it will route your message through sendgrid from your local development app.
I also find this heroku plugin https://github.com/hone/heroku-sendgrid-stats very useful for checking on my message sending numbers.