Skip to content

Commit 30e02db

Browse files
authored
Add recipients feature for defining recipients inside the notifier (#459)
* Add feature for defining recipients inside the notifier * Also support blocks
1 parent 49477ee commit 30e02db

File tree

4 files changed

+76
-0
lines changed

4 files changed

+76
-0
lines changed

CHANGELOG.md

+23
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,28 @@
11
### Unreleased
22

3+
* Add `recipients` feature to let Notifiers determine their recipients
4+
5+
```ruby
6+
class CommentNotifier < ApplicationNotifier
7+
# Notify all the commenters on this post except the new comment author
8+
9+
# Can be given a lambda or Proc
10+
recipients ->{ params[:comment].post.commenters.excluding(params[:comment].user).distinct }
11+
12+
# Can be given a block
13+
recipients do
14+
params[:comment].post.commenters.excluding(params[:comment].user).distinct
15+
end
16+
17+
# Or can call a method
18+
recipients :fetch_recipients
19+
20+
def fetch_recipients
21+
params[:comment].post.commenters.excluding(params[:comment].user).distinct
22+
end
23+
end
24+
```
25+
326
### 2.3.3
427

528
* Use `public_send` for Email delivery so it doesn't accidentally call private methods.

app/models/concerns/noticed/deliverable.rb

+17
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ module Deliverable
66
class_attribute :bulk_delivery_methods, instance_writer: false, default: {}
77
class_attribute :delivery_methods, instance_writer: false, default: {}
88
class_attribute :required_param_names, instance_writer: false, default: []
9+
class_attribute :_recipients, instance_writer: false
910
end
1011

1112
class_methods do
@@ -39,6 +40,10 @@ def deliver_by(name, options = {})
3940
delivery_methods[name] = DeliverBy.new(name, config)
4041
end
4142

43+
def recipients(option = nil, &block)
44+
self._recipients = block || option
45+
end
46+
4247
def required_params(*names)
4348
required_param_names.concat names
4449
end
@@ -79,6 +84,8 @@ def deliver(recipients = nil, **options)
7984
# CommentNotifier.deliver(User.all, wait: 5.minutes)
8085
# CommentNotifier.deliver(User.all, wait_until: 1.hour.from_now)
8186
def deliver(recipients = nil, enqueue_job: true, **options)
87+
recipients ||= evaluate_recipients
88+
8289
validate!
8390

8491
transaction do
@@ -108,6 +115,16 @@ def deliver(recipients = nil, enqueue_job: true, **options)
108115
end
109116
alias_method :deliver_later, :deliver
110117

118+
def evaluate_recipients
119+
return unless _recipients
120+
121+
if _recipients.respond_to?(:call)
122+
instance_exec(&_recipients)
123+
elsif _recipients.is_a?(Symbol) && respond_to?(_recipients)
124+
send(_recipients)
125+
end
126+
end
127+
111128
def recipient_attributes_for(recipient)
112129
{
113130
type: "#{self.class.name}::Notification",

test/dummy/app/notifiers/comment_notifier.rb

+2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
class CommentNotifier < ApplicationNotifier
2+
recipients -> { params[:recipients] }
3+
24
deliver_by :test
35

46
# delivery_by :email, mailer: "UserMailer", method: "new_comment"

test/notifier_test.rb

+34
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,24 @@
33
class NotifierTest < ActiveSupport::TestCase
44
include ActiveJob::TestHelper
55

6+
class RecipientsBlock < Noticed::Event
7+
recipients do
8+
params.fetch(:recipients)
9+
end
10+
end
11+
12+
class RecipientsLambda < Noticed::Event
13+
recipients -> { params.fetch(:recipients) }
14+
end
15+
16+
class RecipientsMethod < Noticed::Event
17+
recipients :recipients
18+
19+
def recipients
20+
params.fetch(:recipients)
21+
end
22+
end
23+
624
test "includes Rails urls" do
725
assert_equal "http://localhost:3000/", SimpleNotifier.new.url
826
end
@@ -40,6 +58,22 @@ class NotifierTest < ActiveSupport::TestCase
4058
assert_equal ["can't be blank"], notifier.errors[:record]
4159
end
4260

61+
test "recipients block" do
62+
assert_equal [:foo, :bar], RecipientsBlock.with(recipients: [:foo, :bar]).evaluate_recipients
63+
end
64+
65+
test "recipients lambda" do
66+
assert_equal [:foo, :bar], RecipientsLambda.with(recipients: [:foo, :bar]).evaluate_recipients
67+
end
68+
69+
test "recipients" do
70+
assert_equal [:foo, :bar], RecipientsMethod.with(recipients: [:foo, :bar]).evaluate_recipients
71+
end
72+
73+
test "deliver without recipients" do
74+
ReceiptNotifier.deliver
75+
end
76+
4377
test "deliver creates an event" do
4478
assert_difference "Noticed::Event.count" do
4579
ReceiptNotifier.deliver(User.first)

0 commit comments

Comments
 (0)