Skip to content

Instantly share code, notes, and snippets.

@maxivak
Last active May 26, 2023 03:50
Show Gist options
  • Save maxivak/5d2d55586151606cf574 to your computer and use it in GitHub Desktop.
Save maxivak/5d2d55586151606cf574 to your computer and use it in GitHub Desktop.
Custom Rails Mailer

Custom Rails Mailer (custom deliver_method)

ActionMailer deliver_method can be different like :smtp, :test, etc.

We will create a new custom delivery method to do something along with (or instead of) sending email.

Create class for delivery

# lib/mail/my_test_delivery.rb

module Mail
  class MyTestDelivery
    attr_accessor :message

    def initialize(mail)
    end

    def deliver!(mail)
      # do smth with email
      
      puts "from: #{mail.from}"
      puts "to: #{mail.to}"
      
      # access mail content
      mail.parts.each do |m|
        puts "content: #{m.body.to_s}"
      end

      

    end

   
  end
end


Point ActionMailer to our delivery class

# config/environments/development.rb

Rails.application.configure do
   ...
   
  config.action_mailer.perform_deliveries = true
  config.action_mailer.raise_delivery_errors = true

  ActionMailer::Base.add_delivery_method :my_test_delivery, Mail::MyTestDelivery
  config.action_mailer.delivery_method = :my_test_delivery
   
end


Send email

Send email as usual and ActionMailer will use our custom method Mail::MyTestDelivery.delivery! to deliver emails.

#app/mailers/users_mailer.rb

class UsersMailer < BaseMailer
def welcome_email(user_id)
    @user = User.find(user_id)

    mail(   :to      => @user.email,
            :from    => "[email protected]",
            :subject => "Welcome"
    ) do |format|
      format.text
      format.html
    end
  end
end


Put html and text versions of your email in app/views/users_mailer/welcome_email.html(text).erb

send email:

user = User.first
UsersMailer.welcome_email(user.email).deliver_later
or
UsersMailer.welcome_email(user.email).deliver_now

Custom class for delivery using SMTP

In this example we will send email via SMTP and do something more before sending email.

Delivery class with SMTP

# lib/mail/my_test_smtp_delivery.rb

module Mail
  class MyTestSmtpDelivery < ::Mail::SMTP
    #attr_accessor :message
    attr_accessor :settings

    # SMTP configuration
    def initialize(values)
      self.settings = Rails.configuration.action_mailer.smtp_settings.merge!(values)
    end


    def deliver!(mail)
      # to smth with email here
      

      # SMTP standard
      # Redirect all mail to your inbox
      #mail['to'] = "[email protected]"
      #mail['bcc'] = []
      #mail['cc'] = []
      super(mail)
    end
  end

end

config:

# config/environments/development.rb

  config.action_mailer.perform_deliveries = true
  config.action_mailer.raise_delivery_errors = true

  ActionMailer::Base.add_delivery_method :my_test_smtp_delivery, Mail::MyTestSmtpDelivery
  config.action_mailer.delivery_method = :my_test_smtp_delivery
  
  ActionMailer::Base.smtp_settings = {
    :address        => "smtp.gmail.com",
    :port           => 587,
    :domain         => "gmail.com",
    :authentication => :plain,
    :user_name      => "[email protected]",
    :password       => "mypass",
    :enable_starttls_auto => true
  }


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment