Skip to content

Commit

Permalink
Support deferred Mailer deliver with deliver_later
Browse files Browse the repository at this point in the history
Re-opens [#4224][]

By default, all `Devise::Models::Authenticatable`-initiated Action
Mailer deliveries are transmitted immediately (within the
request-response cycle).

Transmitting emails and interacting with any third-party services over
SMTP or HTTP risk service outages and other types of network-related
failures.

This commit adds support for deferring delivery to be done from an
Action Job background worker queue through the [deliver_later][] method.

```ruby
 # config/initializers/devise.rb
Devise.mailer_delivery_method = :deliver_later
```

[#4224]: #4224
[deliver_now]: https://edgeapi.rubyonrails.org/classes/ActionMailer/MessageDelivery.html#method-i-deliver_now
[deliver_later]: https://edgeapi.rubyonrails.org/classes/ActionMailer/MessageDelivery.html#method-i-deliver_later
  • Loading branch information
seanpdoyle committed Jul 26, 2023
1 parent ec06745 commit 4170a05
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

* enhancements
* Removed deprecations warning output for `Devise::Models::Authenticatable::BLACKLIST_FOR_SERIALIZATION` (@soartec-lab)
* Added `Devise.mailer_delivery_method` configuration to enable deferring email delivery with `:deliver_later` [#5610](https://github.com/heartcombo/devise/pull/5610) [@seanpdoyle](https://github.com/seanpdoyle)

### 4.9.2 - 2023-04-03

Expand Down
4 changes: 4 additions & 0 deletions lib/devise.rb
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ module Test
mattr_accessor :send_password_change_notification
@@send_password_change_notification = false

# Used to control when to deliver Action Mailer emails
mattr_accessor :mailer_delivery_method
@@mailer_delivery_method = :deliver_now

# Scoped views. Since it relies on fallbacks to render default views, it's
# turned off by default.
mattr_accessor :scoped_views
Expand Down
6 changes: 4 additions & 2 deletions lib/devise/models/authenticatable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,11 @@ def devise_mailer
#
def send_devise_notification(notification, *args)
message = devise_mailer.send(notification, self, *args)
mailer_delivery_method = Devise.mailer_delivery_method

# Remove once we move to Rails 4.2+ only.
if message.respond_to?(:deliver_now)
message.deliver_now
if message.respond_to?(mailer_delivery_method)
message.send(mailer_delivery_method)
else
message.deliver
end
Expand Down
3 changes: 3 additions & 0 deletions lib/generators/templates/devise.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
# Configure the class responsible to send e-mails.
# config.mailer = 'Devise::Mailer'

# Configure when to send e-mails.
# config.mailer_delivery_method = :deliver_now

# Configure the parent class responsible to send e-mails.
# config.parent_mailer = 'ActionMailer::Base'

Expand Down
16 changes: 16 additions & 0 deletions test/mailers/mailer_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,20 @@ def computed_reply_to
assert mail.from, "[email protected]"
assert mail.reply_to, "[email protected]"
end

test "defaults to immediate delivery" do
create_user

assert_not_empty ActionMailer::Base.deliveries
assert_empty ActiveJob::Base.queue_adapter.enqueued_jobs
end

test "supports deferred delivery with Devise.mailer_delivery_method = :deliver_later" do
swap Devise, mailer_delivery_method: :deliver_later do
create_user

assert_empty ActionMailer::Base.deliveries
assert_not_empty ActiveJob::Base.queue_adapter.enqueued_jobs
end
end
end

0 comments on commit 4170a05

Please sign in to comment.