8
votes

Ok I have seen many discussions about customizing devise email subject but none seems to solve what I want. Currently my confirmation email subject reads "Confirm your Qitch.com account". I want to customize this email subject and add a dynamic value of a user's name in it such that if user ALEX signs up for an account, he should get an email address with the subject, Welcome ALEX, confirm your Qitch.com account. How can I achieve this in devise?

devise.en.yml

mailer:
  confirmation_instructions:
    subject: 'Confirm your Qitch.com account'
  reset_password_instructions:
    subject: 'Reset your Qitch.com password'
  unlock_instructions:
    subject: 'Unlock your Qitch.com account'

Lastly, how do I add a name in the reply address or from address, currently when you receive the mail, it says sender: [email protected] Is there a way I can customize it to Qitch

Thanks

5
As of 23.10.2014, this will be a better solution as it might be the simplest one, on top of that is does work stackoverflow.com/a/21344142/102133 – Ben

5 Answers

15
votes

I see that no answers are clean enough so I would like to make a short summary here.

  1. First of all, you have to tell Devise you're going to override its origin mailer methods by:

config/initializers/devise.rb

config.mailer = 'MyOverriddenMailer'

  1. After that, you need to create your overridden mailer class and override whatever method you want like this:

app/mailers/my_overridden_mailer.rb

class MyOverriddenMailer < Devise::Mailer
  helper :application # gives access to all helpers defined within `application_helper`.
  include Devise::Controllers::UrlHelpers # Optional. eg. `confirmation_url`
  default template_path: 'devise/mailer' # to make sure that you mailer uses the devise views

  def confirmation_instructions(record, token, opts={})
    if record.name.present?
      opts[:subject] = "Welcome #{record.name}, confirm your Qitch.com account"
    else
      opts[:subject] = "Confirm your Qitch.com account"
    end

    super
  end

end
  1. Remember to restart your Rails server to apply the changes! :)

Note:

  • List of opts options: subject, to, from, reply_to, template_path, template_name.
  • record is the instance of User model
  • And of course, origin document
5
votes

Devise helper here and How To: Use custom mailer

class MyMailer < Devise::Mailer


   def confirmation_instructions(record, opts={})
    headers = {
        :subject => "Welcome  #{resource.name}, confirm your Qitch.com account"
    }
    super
  end

  def reset_password_instructions(record, opts={})
    headers = {
        :subject => "Welcome  #{resource.name}, reset your Qitch.com password"
    }
    super
  end

  def unlock_instructions(record, opts={})
    headers = {
        :subject => "Welcome  #{resource.name}, unlock your Qitch.com account"
    }
    super
  end

end

Or

class MyMailer < Devise::Mailer
...
...
private

 def headers_for(action)
  if action == :confirmation_instructions
    headers = {
      :subject => "Welcome  #{resource.name}, confirm your Qitch.com account"
    }
  elsif action == :reset_password_instructions
    headers = {
      :subject => "Welcome  #{resource.name}, reset your Qitch.com password"
    }
  else
    headers = {
      :subject => "Welcome  #{resource.name}, unlock your Qitch.com account"
        }
  end
 end
end

And tell devise to use your mailer:

#config/initializers/devise.rb
config.mailer = "MyMailer"

NOTE : I haven't tried them yet, but they may be helpful and for anyone, please correction my answer, if there is an error you could edit my answer

4
votes

I'm working with devise (3.2.1) and I've implemented the following solution, but to modify the from: field with localization:

# app/mailers/devise_mailer.rb
class DeviseMailer < Devise::Mailer

  def confirmation_instructions(record, token, opts={})
    custom_options(opts)
    super
  end

  def reset_password_instructions(record, token, opts={})
    custom_options(opts)
    super
  end

  def unlock_instructions(record, token, opts={})
    custom_options(opts)
    super
  end

  private

  def custom_options(opts)
    opts[:from] = I18n.t('devise.mailer.from', name: Tenancy.current_tenancy.name, mail: ENV['FROM_MAILER'] )
  end
end

Then I've defined the message in my locale files

# config/locales/devise.es.yml
es:
  devise:
    mailer:
      from: "Portal de trabajo %{name} <%{mail}>"

To modify the subject, it should be almost the same:

  def confirmation_instructions(record, token, opts={})
    custom_options(opts, :confirmation_instructions)
    super
  end

  private

  def custom_options(opts, key)
    opts[:from] = I18n.t('subject', scope: [:devise, :mailer, key])
  end

# and in your locale file
es:
  devise:
    mailer:
      confirmation_instructions:
        subject: Instrucciones de confirmación
0
votes

Hook in headers_for to e.g. prefix the subject for all devise mails.

# config/initializers/devise.rb

Devise.setup do |config|
  # ...
  config.mailer = 'DeviseMailer'
  # ...
end
# app/mailers/devise_mailer.rb

class DeviseMailer < Devise::Mailer
  def headers_for(action, opts)
    super.merge!({ subject: 'Hi ALEX! ' + subject_for(action) })
  end
end
-2
votes

Yo should create an ActionMailer like this one:

class Sender < ActionMailer::Base
   default :from => "'Eventer' <[email protected]>"

   def send_recover(user, pw)
      mail(:to => user.email , :subject => "You have requested to change your password from Eventer") do |format|
             format.text { 
             render :text =>"Dear #{user.name}, 

                             **Body**

                             Regards."
            }
      end
   end
end

Then you should call it from the controller this way:

Sender.send_recover(@mail, current_user, @meetup).deliver

I hope it works for you!

Regards