Sending delayed email from devise

后端 未结 4 1882
长情又很酷
长情又很酷 2021-02-03 13:43

Is there a simple way of telling Devise to send all email via delayed_job?

相关标签:
4条回答
  • 2021-02-03 14:28

    Alternatively, instead of using the Delayed::Mailer gem, you can quite easily implement and use your own ActionMailer "delivery method", one that...

    1. intercepts mail delivery from ActionMailer
    2. stores the email in a table (optional)
    3. creates a Delayed::Job that references the stored email
    4. delivers the stored email when the delayed job is executed

    Do something along the lines of:

    # in config/application.rb
    ActionMailer::Base.add_delivery_method :queued, Mail::QueuedDelivery
    
    # in config/environment.rb (or one of the config/environments/*.rb files)
    config.action_mailer.delivery_method = :queued # ie. Mail::QueuedDelivery
    
    # in lib/mail/queued_delivery.rb
    module Mail
      class QueuedDelivery
    
        def initialize(values = {})
          # (optional)
        end
    
        def deliver!(mail)
          email = Email.create!(:delivery_handler => mail.delivery_handler.name, :message => mail.to_s)
          Delayed::Job.enqueue Jobs::Email::DeliverEmail.new(email.id)
        end
    
      end # class QueueDelivery
    end # module Mail
    

    The Delayed::Job you need to implement would then...

    1. retrieve the stored email from the database -- email = ::Email.find_by_id(email_id)
    2. deliver the email via the mail gem -- Mail::Message.new(email.message).deliver

    That's it... hope this help!

    0 讨论(0)
  • 2021-02-03 14:32

    I found that none of the above worked for me. I'm using Devise 2.0.4 and Rails 3.2.2 with delayed_job_active_record 0.3.2

    The way devise actually talks about doing something like this in the comments in the code is to override the methods in the User class. Thus, I solved it like so, and it works perfectly:

    app/models/User.rb

    def send_on_create_confirmation_instructions
      Devise::Mailer.delay.confirmation_instructions(self)
    end
    def send_reset_password_instructions
      Devise::Mailer.delay.reset_password_instructions(self)
    end
    def send_unlock_instructions
      Devise::Mailer.delay.unlock_instructions(self)
    end
    
    0 讨论(0)
  • 2021-02-03 14:36

    There is now the devise-async project which achieves exactly this:

    • https://github.com/mhfs/devise-async
    • https://github.com/plataformatec/devise/wiki/How-To:-Send-devise-emails-in-background-(Resque,-Sidekiq-and-Delayed::Job)
    0 讨论(0)
  • 2021-02-03 14:41

    I have no idea what Devise is but I guess it is third-party gem you don't want to modify. Try delayed_job_mailer. You can extend Devise mailers by monkey patching them to use delayed_job.

    class SomeExistingMailer
      include Delayed::Mailer
    end
    

    or if you want to send all app emails via delayed job by default:

    # config/initializers/delayed_mailer.rb
    class ActionMailer::Base
      include Delayed::Mailer
    end
    
    0 讨论(0)
提交回复
热议问题