I am trying to send mail using actionmailer on a Rails 3.0.1 application. Here is my setup
config/initializers/setup_mail.rb
ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:domain => "saidyes.co.uk",
:user_name => "username",
:password => "password",
:authentication => "plain",
:enable_starttls_auto => true
}
ActionMailer::Base.default_url_options[:host] = "localhost:3000"
ActionMailer::Base.register_interceptor(DevelopmentMailInterceptor) if Rails.env.development?
config/environments/development.rb
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.perform_deliveries = true
app/mailers/user_mailer.rb
class UserMailer < ActionMailer::Base
default :from => "info#saidyes.co.uk"
def self.registration_confirmation(user)
#user = user
attachments["rails.png"] = File.read("#{Rails.root}/public/images/rails.png")
mail(:to => "#{user.email}", :subject => "Welcome")
end
end
app/models/user.rb
require "#{Rails.root}/app/mailers/user_mailer"
after_create :send_welcome_email
private
def send_welcome_email
UserMailer.registration_confirmation(self).deliver
end
The first error i got was an uninitialized constant UserMailer in my Users model class. I fixed it by adding the require at the top of the User model definition. Now I get
undefined local variable or method `attachments' for UserMailer:Class
I must have configured actionmailer incorrectly or my rails app is not configured correctly to use mailer.
Anyway any advice or help would be appreciated.
Cheers
I think the simple problem you've encountered is that the mail methods should be defined on instances of your mailer class.
Namely it should be
class UserMailer < ActionMailer::Base
def registration_confirmation(user)
#user = user
attachments["rails.png"] = File.read("#{Rails.root}/public/images/rails.png")
mail(:to => "#{user.email}", :subject => "Welcome")
end
end
Note there is no self
Take a look at the helpful Rails Guide on the subject
As in your example you'll still call the method on the class
UserMailer.registration_confirmation(user).deliver
The class method does some magic to instantiate an instance, and ensure the correct template is rendered.
Related
This is the method inside ApplicationMailer
class CancelTrip < ApplicationMailer
default from: 'xyz#gmail.com'
def cancel_trip
#recvr= "ssdd#gmail.com"
mail(to: #recvr, subject: 'Your trip has been cancelled as per your request' )
end
end
And the environmental variables as follows:
SMTP_ADDRESS: 'smtp.gmail.com'
SMTP_PORT: 587
SMTP_DOMAIN: 'localhost:3000'
SMTP_USERNAME: 'xyz#gmail.com'
SMTP_PASSWORD: 'gggh2354'
And I am call the mailer method in my controller as follows:
def cancel
xxxxx
CancelTrip.cancel_trip.deliver_now
end
developement.rb has following
config.action_mailer.raise_delivery_errors = false
config.action_mailer.default_url_options = {host: 'localhost', port:3000}
config.action_mailer.perform_deliveries = true
Log shows the email being sent. But I dont see any email in inbox.
My rails version is 4.2.6.
Add following smtp setting on config/application.rb file:
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
config.action_mailer.delivery_method = :smtp
config.action_mailer.raise_delivery_errors = true
config.action_mailer.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:domain => "gmail.com",
:user_name => "xxxxxxxxx#gmail.com",
:password => "xxxxxxxx",
:authentication => "plain",
:enable_starttls_auto => true
}
Check in junk mail... I had this problem a little while back
use letter opener in development for be sure your actionmailer delivered your mail. after that you can finding deliver error to gmail or other.
Make sure that your ApplicationMailer is inheriting from ActionMailer::Base.
class ApplicationMailer < ActionMailer::Base
default from: 'from#exmaple.com'
layout 'mailer'
end
One possibility may be your firewall not allows to send email. Try connect different network.
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 the following code in my registration controller
def new
Rails.logger.debug "#{params[:email]}"
if !params[:email].blank? && !params[:invoke].blank? && params[:invoke].casecmp('Send') == 0
MyMailer.send_email(params[:email]).deliver
end
end
My params[:email] gets populated correctly.
in my_mailer.rb i have the following code
class MyMailer < ActionMailer::Base
default from: 'someaddress#yahoo.com'
def send_email(emailaddress)
#emailaddress=emailaddress
Rails.logger.debug "{#{emailaddress}}"
mail(to: #emailaddress ,subject: 'asdasd')
end
end
I have set the following properties in development.rb
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.perform_deliveries = true
I have also done the smtp configurations in setup_mail.rb under the initializers
ActionMailer::Base.smtp_settings = {
:address => "smtp.yahoo.com",
:port => 587,
:domain => "yahoo.com",
:user_name => "someaddress#yahoo.com",
:password => "somepass",
:authentication => "plain",
:enable_starttls_auto => true
}
My logs say that the mail has been sent to the respective person but my gmail shows no mail has arrived . Not even in the spams. Is there any configuration settings i am missing out on ?
I am a complete beginner in Rails and I'm trying to send an email after someone signs up using Action Mailer.
My logs say that the email is sending, but Gmail never gets it.
config/initializers/setup_mail.rb
ActionMailer::Base.smtp_settings = {
:address => "smtp.gmail.com",
:port => 587,
:domain => "asciicasts.com",
:user_name => "asciicasts",
:password => "secret",
:authentication => "plain",
:enable_starttls_auto => true
}
mailers/user_mailer.rb
class UserMailer < ActionMailer::Base
default :from => "eifion#asciicasts.com"
def registration_confirmation(user)
mail(:to => user.email, :subject => "Registered")
end
end
controllers/users_controller.rb
...
def create
#user = User.new(params[:user])
if #user.save
UserMailer.registration_confirmation(#user).deliver
sign_in #user
flash[:success] = "Welcome to the Sample App!"
redirect_to #user
else
render 'new'
end
end
...
Thanks!
Make sure you have this option set in your config/environments/development.rb :
config.action_mailer.delivery_method = :smtp
Also, in ActionMailer::Base.smtp_settings you need to specify a valid gmail account. Copy-pasting (asciicasts) is not gonna cut it here.
See this question for reference: Sending mail with Rails 3 in development environment
Instead of 'smtp' you can use 'sendmail'
ActionMailer::Base.delivery_method = :sendmail
ActionMailer::Base.sendmail_settings = { :address => "smtp.gmail.com",
:port => "587", :domain => "gmail.com", :user_name => "xxx#gmail.com",
:password => "yyy", :authentication => "plain", :enable_starttls_auto => true }
I ran into this same problem for a new mailer I had setup. I couldn't figure out for the life of me why this new mailer couldn't send emails, or even get to the method in the mailer when I stepped through it.
Solution
It ended up being that if you put the deliver_now or deliver* code within the mailer, it does not send the email.
Example Broken
def email_message()
message = mail(to: User.first, subject: 'test', body: "body text for mail")
message.deliver_now
end
Corrected
#Different class; in my case a service
def caller
message = MyMailer.email_message
message.deliver_now
end
def email_message()
mail(to: User.first, subject: 'test', body: "body text for mail")
end
This solved the problem for me, I hope it solves it for someone else.
I have a button 'buy' which links to the 'review' page like so:
<%= button_to 'Buy', review_hvacs_path(:b => true, :h => hvac, :a => params[:a], :s => params[:s]) %>
This calls the review action in the controller, 'hvacs_controller' which contains..
#buy = params[:b]
if !#buy.nil?
#currentHvac = Hvac.find(params[:h])
#supplier = HvacSupplier.find(#currentHvac.hvac_supplier_id)
Notifier.gmail_message(#supplier)
end
I am trying to send the message if the user presses the buy button.
My development environment looks like this:
# Don't care if the mailer can't send
config.action_mailer.raise_delivery_errors = false
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:enable_smarttls_auto => true,
:address => 'smtp.gmail.com',
:port => 587,
:authentication => :plain,
:domain => 'gmail.com',
:username => '<my email address>#gmail.com',
:password => '<my password>'
}
...and my mailer looks like this:
class Notifier < ActionMailer::Base
default from: "user#address.com"
# Subject can be set in your I18n file at config/locales/en.yml
# with the following lookup:
#
# en.notifier.gmail_message.subject
#
def gmail_message(supplier)
#greeting = "HVAC Equipment Purchase"
#supplier = supplier
mail(:to => supplier.email, :subject => "HVAC Equipment Enquiry")
end
end
Message:
Notifier#gmail_message
<%= #greeting %>, I am interesting in purchasing replacement equipment, and would like an evaluation.
Would anyone have any insight? I am missing something? If I left out any details, I will post them.
Notifier.gmail_message(#supplier).deliver