The following is my controller file:
class BiodataController < ApplicationController
def store
#user=params[:username]
#age=params[:age]
#gender=params[:gender]
#mstatus=params[:mstatus]
#language=params[:language]
#email=params[:email]
#mobile=params[:mobile]
if params[:username].present? && params[:age].present? && params[:gender].present? && params[:mstatus].present? && params[:language].present? && params[:email].present? && params[:mobile].present?
Biodatum.create(name: #user, age: #age, gender: #gender, mstatus: #mstatus, language: #language, email: #email, mobile: #mobile)
Infomail.sendmail(#email)
render 'store'
else
render 'Error'
end
end
end
My requirement is to send email to the address stored in #email. So I created the mailer as 'Infomail'. The following is my mailer file.
class Infomail < ApplicationMailer
default from: 'abc#xyz.co.in'
def sendmail(user)
#user = user
mail(to: #user.email, subject: 'sample mail')
end
end
And I also have html file under 'app/views/infomail/sendmail.html.erb'. But it doesn't work. Can any one explain me what is the bug in
my code.
I'll recommend that you take a look at http://guides.rubyonrails.org/action_mailer_basics.html for starters.
For sending mails, you'll have to use the deliver_now (Immediate) or deliver_later (Queue for worker) methods, like so:
InfoMailer.sendmail(#user).deliver_now
Note that I renamed it to InfoMailer, because that's the standard naming, of mailers.
If you want to test you mailer into development environment just open your development.rb file and write below code inside for smtp configuration.
config.action_mailer.default_url_options = { host: 'url of your application' }
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: 'address of your mailer',
port: 465,
domain: ENV['YOUR_DOMAIN_NAME'],
user_name: ENV['YOUR_USER_NAME'],
password: ENV['YOUR_PASSWORD'],
authentication: :plain,
ssl: true,
tls: true,
enable_starttls_auto: true
}
please change above configuration as per your mailer smtp settings.
Now create tamp let of your mail as per you requirements. file path as per below:
app -> view -> common_mailer inside of this please make sendmail.html.erb file.
You are sending #email which is a String in params while you are expecting Object on which you can call .email
#bio = Biodatum.create(name: #user, age: #age, gender: #gender, mstatus: #mstatus, language: #language, email: #email, mobile: #mobile)
Infomail.sendmail(#bio)
This will pass Biodatum instance on which you can call .email
Also to avoid confusion you can change your mailer method
def sendmail(bio)
#bio = bio
mail(to: #bio.email, subject: 'sample mail')
end
If you are making these changes, you will also need to change them in sendmail.html
EDIT
Make sure you have configured the settings in /config/environments/development.rb and /config/environments/production.rb
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
}
Related
When I try to use rails (5.1.4) mailer, I don't receive any email like I should do. I followed the official rails guide to make it. My config/environment/development.rb :
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: 'smtp.gmail.com',
port: 587,
domain: 'gmail.com',
user_name: 'username#gmail.com',
password: 'app-password-from-google',
authentication: 'plain',
enable_starttls_auto: true
}
With this config I made a new mailer in mailers/appointement_mailer.rb :
class AppointementMailer < ApplicationMailer
default :from => "username#gmail.com"
def appointement_information(user_email, data)
#email = user_email
#body = data
mail(:to => "username#gmail.com", :subject => "xxx")
end
end
This mailer is triggered by a form controlled by a controller, it is located under controllers/contacts_controller.rb :
def new
end
def create
#appointement = appointement_params
AppointementMailer.appointement_information(#appointement['email'], #appointement['body'])
flash[:notice] = "Some message"
redirect_to articles_path
end
private
def appointement_params
params.require('appointement').permit(:email, :body)
end
The form correctly display the flash "Some Message" and no error is written in the console.
You need to call deliver_now on your call to the mailer.
AppointementMailer.appointement_information(#appointement['email'], #appointement['body']).deliver_now
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.
I didn't figure out how I send mail from gmail in development environment.It didn't send email. I didn't understand the rails guide, and also I wonder if the production env is the same ?
config/development.rb
config.action_mailer.raise_delivery_errors = true
config.action_mailer.default_url_options = { :host => 'something.com' }
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: 'smtp.gmail.com',
port: 587,
domain: 'mail.google.com',
user_name: 'myusername#gmail.com',
password: 'mypassword',
authentication: 'plain',
enable_starttls_auto: true }
mailer/user_mailer.rb
default :from => 'something.com'
def welcome_email(user)
#user = user
#url = 'http://something.com'
mail(to: #user.email, subject: 'Welcome')
end
edit
where I call, in users create method,
UserMailer.welcome_email(#user).deliver_now
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true
Try this in development.rb It will either send mail or raise delivery error in console.
You can call your mailer methods in two way to send email,
In UsersController's create action
def create
#your codes and logics to save user...
UserMailer.welcome_email(#user).deliver_now
#your codes goes here ...
end
In User model after_create callback
class User < ActiveRecord::Base
after_create :send_email
def send_email
UserMailer.welcome_email(self).deliver_now
end
end
I would prefer second one for sending email, use model callback rather in controller.
I'm trying to set up ActionMailer's SMTP settings to be able to be configured at run time, but when that happens it doesn't seem to connect to the 3rd party service to deliver the mail. Below are 2 scenarios, the first of which the mail will send and deliver, the second of which nothing happens. I'm using the development environment for testing
This configuration is common to both scenarios
# config/environments/development.rb
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = false
config.action_mailer.default :charset => "utf-8"
config.action_mailer.delivery_method = :smtp
This works:
# config/environments/development.rb
config.action_mailer.default_url_options = { host: 'www.mysite.com' }
config.action_mailer.smtp_settings = {
:address => "smtp.thirdpartyservice.com",
:port => 587,
:domain => 'mysite.com',
:user_name => "me#mysite.com",
:password => "my-password",
:authentication => "plain",
:enable_starttls_auto => true
}
This delivers the mail, but also when tailing the logs, there is a slight delay in the request so I know the request is being made to the third party service.
This doesn't work:
This is the setup I want, using a custom mailer that I'm using.
class MyCustomMailer < Devise::Mailer
before_filter :use_smtp_settings
def example_mailer(record)
Rails.logger.warn self.smtp_settings
#resource = record
mail(to: record.email,
from: AppSettings.first.mailer_sender,
subject: "Example")
end
private
def use_smtp_settings
self.default_url_options[:host] = AppSettings.first.domain_address
self.smtp_settings = {
:address => AppSettings.first.smtp_address,
:port => AppSettings.first.smtp_port,
:domain => AppSettings.first.smtp_domain,
:user_name => AppSettings.first.smtp_username,
:password => AppSettings.first.smtp_password,
:authentication => "plain",
:enable_starttls_auto => true
}
end
end
The rails logger in the #example_mailer() method shows the same attributes that are used in the first example, albeit loaded from the app_settings table. However when tailing the logs this time, there is no delay so ActionMailer doesn't seem to even try making a request to the third party service.
This won't work because you're modifying the smtp settings on an instance of your mailer but the underlying mail gem reads it from the mailer class level attribute. The supported way to do this in Rails 4.0 and above is to pass a custom header called :delivery_method_options to the mail call, e.g:
class MyCustomMailer < Devise::Mailer
before_filter set_default_host
def example_mailer(record)
mail to: record.email,
from: app_mailer_sender,
subject: "Example",
delivery_method_options: app_smtp_settings
end
private
def app_settings
#app_settings || AppSettings.first
end
def app_domain_address
app_settings.domain_address
end
def app_mailer_sender
app_settings.mailer_sender
end
def app_smtp_settings
self.smtp_settings = {
address: app_settings.smtp_address,
port: app_settings.smtp_port,
domain: app_settings.smtp_domain,
user_name: app_settings.smtp_username,
password: app_settings.smtp_password,
authentication: "plain",
enable_starttls_auto: true
}
end
def set_default_host
default_url_options[:host] = app_settings.domain_address
end
end
end
One little tip - don't repeatedly call AppSettings.first since that re-queries the database (actually it'll be caught by the AR query cache but a new instance will be created every time). But you knew that right ;-)
I have a Rails app that handles two domains. The app is set up like described in this blogpost. In my controllers and views I am using request.domain to determine which app a visitor visits.
When someone signs up for an account, Devise sends out a confirmation email. This process depends on the following lines:
# config/environments/development.rb
MyApp::Application.configure do
...
config.action_mailer.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:domain => 'localhost',
:user_name => 'my#email.com',
:password => 'MyPassword',
:authentication => 'plain',
:enable_starttls_auto => true
}
...
end
# config/initializers/devise.rb
Devise.setup do |config|
...
# ==> Mailer Configuration
# Configure the e-mail address which will be shown in Devise::Mailer,
# note that it will be overwritten if you use your own mailer class with default "from" parameter.
config.mailer_sender = "my#email.com"
...
end
I need the :usernamein development.rb and the config.mailer_sender in devise.rb to depend on request.domain, because the user should of course receive an email from the domain he signs up for.
I use SiteSetting model to specify different mailboxes for each Site
SiteSetting contains configs for each mailboxes.
A code for mailer is:
# app/mailers/invitation_mailer.rb
class InvitationMailer < ActionMailer::Base
def invitation(invitation)
#site = invitation.site
#invitation = invitation
email_settings = #site.email_settings.first
mail(to: invitation.email,
from: email_settings.try(:from) || 'notifier#example.com',
subject: "Invitation",
delivery_method_options: delivery_options(email_settings))
end
private
def delivery_options(email_settings)
#_delivery_options ||=
if email_settings
{
address: email_settings.address,
port: email_settings.port,
domain: email_settings.domain,
user_name: email_settings.user_name,
password: email_settings.password,
authentication: email_settings.authentication,
enable_starttls_auto: email_settings.enable_startls_auto
}
else
{
address: 'smtp.google.com',
port: 587,
domain: 'example.com',
user_name: 'notifier#example.com',
password: 'secret',
authentication: 'plain',
enable_starttls_auto: true
}
end
end
end
Update
You can pass username like invitation in this examle
and then you can get acsess to username in your Mailer class (for example InvitationMailer)
# app/controller/users_controller.rb
class UsersController < ApplicationController
def invitation
invitation = Invitation.find(params[:invitation_id])
InvitationMailer.invitation(invitation).deliver
end
end