noticed 2.0.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +624 -185
- data/app/jobs/noticed/event_job.rb +5 -7
- data/app/models/concerns/noticed/deliverable.rb +60 -18
- data/app/models/concerns/noticed/notification_methods.rb +1 -1
- data/app/models/concerns/noticed/readable.rb +32 -8
- data/app/models/noticed/deliverable/deliver_by.rb +28 -7
- data/app/models/noticed/ephemeral.rb +63 -0
- data/app/models/noticed/event.rb +13 -0
- data/app/models/noticed/notification.rb +3 -3
- data/db/migrate/20231215190233_create_noticed_tables.rb +16 -5
- data/db/migrate/20240129184740_add_notifications_count_to_noticed_event.rb +5 -0
- data/lib/generators/noticed/delivery_method_generator.rb +9 -1
- data/lib/generators/noticed/notifier_generator.rb +14 -1
- data/lib/generators/noticed/templates/application_bulk_delivery_method.rb.tt +2 -0
- data/lib/generators/noticed/templates/application_delivery_method.rb.tt +2 -0
- data/lib/generators/noticed/templates/application_notifier.rb.tt +2 -0
- data/lib/generators/noticed/templates/bulk_delivery_method.rb.tt +14 -0
- data/lib/generators/noticed/templates/delivery_method.rb.tt +10 -8
- data/lib/generators/noticed/templates/notifier.rb.tt +8 -2
- data/lib/noticed/api_client.rb +3 -1
- data/lib/noticed/bulk_delivery_method.rb +19 -7
- data/lib/noticed/bulk_delivery_methods/bluesky.rb +51 -0
- data/lib/noticed/bulk_delivery_methods/discord.rb +2 -0
- data/lib/noticed/bulk_delivery_methods/slack.rb +25 -1
- data/lib/noticed/bulk_delivery_methods/test.rb +13 -0
- data/lib/noticed/bulk_delivery_methods/webhook.rb +4 -1
- data/lib/noticed/coder.rb +5 -1
- data/lib/noticed/delivery_method.rb +21 -8
- data/lib/noticed/delivery_methods/action_cable.rb +11 -5
- data/lib/noticed/delivery_methods/action_push_native.rb +24 -0
- data/lib/noticed/delivery_methods/discord.rb +2 -0
- data/lib/noticed/delivery_methods/email.rb +13 -5
- data/lib/noticed/delivery_methods/fcm.rb +19 -2
- data/lib/noticed/delivery_methods/ios.rb +15 -4
- data/lib/noticed/delivery_methods/microsoft_teams.rb +2 -0
- data/lib/noticed/delivery_methods/slack.rb +25 -1
- data/lib/noticed/delivery_methods/test.rb +2 -0
- data/lib/noticed/delivery_methods/twilio_messaging.rb +9 -1
- data/lib/noticed/delivery_methods/vonage_sms.rb +2 -0
- data/lib/noticed/delivery_methods/webhook.rb +4 -1
- data/lib/noticed/engine.rb +10 -0
- data/lib/noticed/has_notifications.rb +49 -0
- data/lib/noticed/notification_channel.rb +19 -0
- data/lib/noticed/version.rb +1 -1
- data/lib/noticed.rb +15 -27
- metadata +14 -6
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
module Noticed
|
|
2
|
-
class EventJob <
|
|
3
|
-
queue_as :default
|
|
4
|
-
|
|
2
|
+
class EventJob < Noticed.parent_class.constantize
|
|
5
3
|
def perform(event)
|
|
6
4
|
# Enqueue bulk deliveries
|
|
7
|
-
event.bulk_delivery_methods.
|
|
8
|
-
deliver_by.perform_later(event)
|
|
5
|
+
event.bulk_delivery_methods.each_value do |deliver_by|
|
|
6
|
+
deliver_by.perform_later(event) if deliver_by.perform?(event)
|
|
9
7
|
end
|
|
10
8
|
|
|
11
9
|
# Enqueue individual deliveries
|
|
12
10
|
event.notifications.each do |notification|
|
|
13
|
-
event.delivery_methods.
|
|
14
|
-
deliver_by.perform_later(notification)
|
|
11
|
+
event.delivery_methods.each_value do |deliver_by|
|
|
12
|
+
deliver_by.perform_later(notification) if deliver_by.perform?(notification)
|
|
15
13
|
end
|
|
16
14
|
end
|
|
17
15
|
end
|
|
@@ -6,14 +6,7 @@ module Noticed
|
|
|
6
6
|
class_attribute :bulk_delivery_methods, instance_writer: false, default: {}
|
|
7
7
|
class_attribute :delivery_methods, instance_writer: false, default: {}
|
|
8
8
|
class_attribute :required_param_names, instance_writer: false, default: []
|
|
9
|
-
|
|
10
|
-
attribute :params, default: {}
|
|
11
|
-
|
|
12
|
-
if Rails.gem_version >= Gem::Version.new("7.1.0.alpha")
|
|
13
|
-
serialize :params, coder: Coder
|
|
14
|
-
else
|
|
15
|
-
serialize :params, Coder
|
|
16
|
-
end
|
|
9
|
+
class_attribute :_recipients, instance_writer: false
|
|
17
10
|
end
|
|
18
11
|
|
|
19
12
|
class_methods do
|
|
@@ -35,24 +28,54 @@ module Noticed
|
|
|
35
28
|
def deliver_by(name, options = {})
|
|
36
29
|
raise NameError, "#{name} has already been used for this Notifier." if delivery_methods.has_key?(name)
|
|
37
30
|
|
|
31
|
+
if name == :database
|
|
32
|
+
Noticed.deprecator.warn <<-WARNING.squish
|
|
33
|
+
The :database delivery method has been deprecated and does nothing. Notifiers automatically save to the database now.
|
|
34
|
+
WARNING
|
|
35
|
+
return
|
|
36
|
+
end
|
|
37
|
+
|
|
38
38
|
config = ActiveSupport::OrderedOptions.new.merge(options)
|
|
39
39
|
yield config if block_given?
|
|
40
40
|
delivery_methods[name] = DeliverBy.new(name, config)
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
+
def recipients(option = nil, &block)
|
|
44
|
+
self._recipients = block || option
|
|
45
|
+
end
|
|
46
|
+
|
|
43
47
|
def required_params(*names)
|
|
44
48
|
required_param_names.concat names
|
|
45
49
|
end
|
|
46
50
|
alias_method :required_param, :required_params
|
|
47
51
|
|
|
52
|
+
def params(*names)
|
|
53
|
+
Noticed.deprecator.warn <<-WARNING.squish
|
|
54
|
+
`params` is deprecated and has been renamed to `required_params`
|
|
55
|
+
WARNING
|
|
56
|
+
required_params(*names)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def param(*names)
|
|
60
|
+
Noticed.deprecator.warn <<-WARNING.squish
|
|
61
|
+
`param :name` is deprecated and has been renamed to `required_param :name`
|
|
62
|
+
WARNING
|
|
63
|
+
required_params(*names)
|
|
64
|
+
end
|
|
65
|
+
|
|
48
66
|
def with(params)
|
|
49
|
-
|
|
50
|
-
|
|
67
|
+
if self < Ephemeral
|
|
68
|
+
new(params: params)
|
|
69
|
+
else
|
|
70
|
+
record = params.delete(:record)
|
|
71
|
+
new(params: params, record: record)
|
|
72
|
+
end
|
|
51
73
|
end
|
|
52
74
|
|
|
53
|
-
def deliver(recipients = nil, options
|
|
54
|
-
new.deliver(recipients, options)
|
|
75
|
+
def deliver(recipients = nil, **options)
|
|
76
|
+
new.deliver(recipients, **options)
|
|
55
77
|
end
|
|
78
|
+
alias_method :deliver_later, :deliver
|
|
56
79
|
end
|
|
57
80
|
|
|
58
81
|
# CommentNotifier.deliver(User.all)
|
|
@@ -60,16 +83,19 @@ module Noticed
|
|
|
60
83
|
# CommentNotifier.deliver(User.all, queue: :low_priority)
|
|
61
84
|
# CommentNotifier.deliver(User.all, wait: 5.minutes)
|
|
62
85
|
# CommentNotifier.deliver(User.all, wait_until: 1.hour.from_now)
|
|
63
|
-
def deliver(recipients = nil,
|
|
86
|
+
def deliver(recipients = nil, enqueue_job: true, **options)
|
|
87
|
+
recipients ||= evaluate_recipients
|
|
88
|
+
|
|
64
89
|
validate!
|
|
65
90
|
|
|
66
91
|
transaction do
|
|
67
|
-
save!
|
|
68
|
-
|
|
69
92
|
recipients_attributes = Array.wrap(recipients).map do |recipient|
|
|
70
93
|
recipient_attributes_for(recipient)
|
|
71
94
|
end
|
|
72
95
|
|
|
96
|
+
self.notifications_count = recipients_attributes.size
|
|
97
|
+
save!
|
|
98
|
+
|
|
73
99
|
if Rails.gem_version >= Gem::Version.new("7.0.0.alpha1")
|
|
74
100
|
notifications.insert_all!(recipients_attributes, record_timestamps: true) if recipients_attributes.any?
|
|
75
101
|
else
|
|
@@ -83,15 +109,26 @@ module Noticed
|
|
|
83
109
|
end
|
|
84
110
|
|
|
85
111
|
# Enqueue delivery job
|
|
86
|
-
EventJob.set(options).perform_later(self)
|
|
112
|
+
EventJob.set(options).perform_later(self) if enqueue_job
|
|
87
113
|
|
|
88
114
|
self
|
|
89
115
|
end
|
|
116
|
+
alias_method :deliver_later, :deliver
|
|
117
|
+
|
|
118
|
+
def evaluate_recipients
|
|
119
|
+
return unless _recipients
|
|
120
|
+
|
|
121
|
+
if _recipients.respond_to?(:call, true)
|
|
122
|
+
instance_exec(&_recipients)
|
|
123
|
+
elsif _recipients.is_a?(Symbol) && respond_to?(_recipients, true)
|
|
124
|
+
send(_recipients)
|
|
125
|
+
end
|
|
126
|
+
end
|
|
90
127
|
|
|
91
128
|
def recipient_attributes_for(recipient)
|
|
92
129
|
{
|
|
93
130
|
type: "#{self.class.name}::Notification",
|
|
94
|
-
recipient_type: recipient.class.name,
|
|
131
|
+
recipient_type: recipient.class.base_class.name,
|
|
95
132
|
recipient_id: recipient.id
|
|
96
133
|
}
|
|
97
134
|
end
|
|
@@ -103,7 +140,7 @@ module Noticed
|
|
|
103
140
|
|
|
104
141
|
def validate_params!
|
|
105
142
|
required_param_names.each do |param_name|
|
|
106
|
-
raise ValidationError, "Param `#{param_name}` is required for #{self.class.name}." unless params
|
|
143
|
+
raise ValidationError, "Param `#{param_name}` is required for #{self.class.name}." unless params.has_key?(param_name)
|
|
107
144
|
end
|
|
108
145
|
end
|
|
109
146
|
|
|
@@ -111,5 +148,10 @@ module Noticed
|
|
|
111
148
|
bulk_delivery_methods.values.each(&:validate!)
|
|
112
149
|
delivery_methods.values.each(&:validate!)
|
|
113
150
|
end
|
|
151
|
+
|
|
152
|
+
# If a GlobalID record in params is no longer found, the params will default with a noticed_error key
|
|
153
|
+
def deserialize_error?
|
|
154
|
+
!!params[:noticed_error]
|
|
155
|
+
end
|
|
114
156
|
end
|
|
115
157
|
end
|
|
@@ -6,7 +6,7 @@ module Noticed
|
|
|
6
6
|
# Generate a Notification class each time a Notifier is defined
|
|
7
7
|
def inherited(notifier)
|
|
8
8
|
super
|
|
9
|
-
notifier.const_set :Notification, Class.new(Noticed::Notification)
|
|
9
|
+
notifier.const_set :Notification, Class.new(const_defined?(:Notification) ? const_get(:Notification) : Noticed::Notification)
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def notification_methods(&block)
|
|
@@ -10,20 +10,28 @@ module Noticed
|
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
class_methods do
|
|
13
|
-
def
|
|
14
|
-
update_all(read_at: Time.current)
|
|
13
|
+
def mark_as_read_and_seen(**kwargs)
|
|
14
|
+
update_all(**kwargs.with_defaults(read_at: Time.current, seen_at: Time.current, updated_at: Time.current))
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
def
|
|
18
|
-
update_all(read_at: nil)
|
|
17
|
+
def mark_as_unread_and_unseen(**kwargs)
|
|
18
|
+
update_all(**kwargs.with_defaults(read_at: nil, seen_at: nil, updated_at: Time.current))
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
def
|
|
22
|
-
update_all(
|
|
21
|
+
def mark_as_read(**kwargs)
|
|
22
|
+
update_all(**kwargs.with_defaults(read_at: Time.current, updated_at: Time.current))
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
def
|
|
26
|
-
update_all(
|
|
25
|
+
def mark_as_unread(**kwargs)
|
|
26
|
+
update_all(**kwargs.with_defaults(read_at: nil, updated_at: Time.current))
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def mark_as_seen(**kwargs)
|
|
30
|
+
update_all(**kwargs.with_defaults(seen_at: Time.current, updated_at: Time.current))
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def mark_as_unseen(**kwargs)
|
|
34
|
+
update_all(**kwargs.with_defaults(seen_at: nil, updated_at: Time.current))
|
|
27
35
|
end
|
|
28
36
|
end
|
|
29
37
|
|
|
@@ -31,18 +39,34 @@ module Noticed
|
|
|
31
39
|
update(read_at: Time.current)
|
|
32
40
|
end
|
|
33
41
|
|
|
42
|
+
def mark_as_read!
|
|
43
|
+
update!(read_at: Time.current)
|
|
44
|
+
end
|
|
45
|
+
|
|
34
46
|
def mark_as_unread
|
|
35
47
|
update(read_at: nil)
|
|
36
48
|
end
|
|
37
49
|
|
|
50
|
+
def mark_as_unread!
|
|
51
|
+
update!(read_at: nil)
|
|
52
|
+
end
|
|
53
|
+
|
|
38
54
|
def mark_as_seen
|
|
39
55
|
update(seen_at: Time.current)
|
|
40
56
|
end
|
|
41
57
|
|
|
58
|
+
def mark_as_seen!
|
|
59
|
+
update!(seen_at: Time.current)
|
|
60
|
+
end
|
|
61
|
+
|
|
42
62
|
def mark_as_unseen
|
|
43
63
|
update(seen_at: nil)
|
|
44
64
|
end
|
|
45
65
|
|
|
66
|
+
def mark_as_unseen!
|
|
67
|
+
update!(seen_at: nil)
|
|
68
|
+
end
|
|
69
|
+
|
|
46
70
|
def read?
|
|
47
71
|
read_at?
|
|
48
72
|
end
|
|
@@ -19,25 +19,46 @@ module Noticed
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def perform_later(event_or_notification, options = {})
|
|
22
|
-
options
|
|
23
|
-
|
|
24
|
-
options[:queue] = evaluate_option(:queue, event_or_notification) if config.has_key?(:queue)
|
|
25
|
-
options[:priority] = evaluate_option(:priority, event_or_notification) if config.has_key?(:priority)
|
|
22
|
+
constant.set(computed_options(options, event_or_notification)).perform_later(name, event_or_notification)
|
|
23
|
+
end
|
|
26
24
|
|
|
27
|
-
|
|
25
|
+
def ephemeral_perform_later(notifier, recipient, params, options = {})
|
|
26
|
+
constant.set(computed_options(options, recipient))
|
|
27
|
+
.perform_later(name, "#{notifier}::Notification", recipient: recipient, params: params)
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
def evaluate_option(name, context)
|
|
31
31
|
option = config[name]
|
|
32
32
|
|
|
33
|
-
if option
|
|
33
|
+
if option.respond_to?(:call)
|
|
34
34
|
context.instance_exec(&option)
|
|
35
|
-
elsif option.is_a?(Symbol) && context.respond_to?(option)
|
|
35
|
+
elsif option.is_a?(Symbol) && context.respond_to?(option, true)
|
|
36
36
|
context.send(option)
|
|
37
37
|
else
|
|
38
38
|
option
|
|
39
39
|
end
|
|
40
40
|
end
|
|
41
|
+
|
|
42
|
+
def perform?(notification)
|
|
43
|
+
return true unless config.key?(:before_enqueue)
|
|
44
|
+
|
|
45
|
+
perform = false
|
|
46
|
+
catch(:abort) {
|
|
47
|
+
evaluate_option(:before_enqueue, notification)
|
|
48
|
+
perform = true
|
|
49
|
+
}
|
|
50
|
+
perform
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
def computed_options(options, recipient)
|
|
56
|
+
options[:wait] ||= evaluate_option(:wait, recipient) if config.has_key?(:wait)
|
|
57
|
+
options[:wait_until] ||= evaluate_option(:wait_until, recipient) if config.has_key?(:wait_until)
|
|
58
|
+
options[:queue] ||= evaluate_option(:queue, recipient) if config.has_key?(:queue)
|
|
59
|
+
options[:priority] ||= evaluate_option(:priority, recipient) if config.has_key?(:priority)
|
|
60
|
+
options
|
|
61
|
+
end
|
|
41
62
|
end
|
|
42
63
|
end
|
|
43
64
|
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
module Noticed
|
|
2
|
+
class Ephemeral
|
|
3
|
+
include ActiveModel::Model
|
|
4
|
+
include ActiveModel::Attributes
|
|
5
|
+
include Noticed::Deliverable
|
|
6
|
+
include Noticed::Translation
|
|
7
|
+
include Rails.application.routes.url_helpers
|
|
8
|
+
|
|
9
|
+
attribute :record
|
|
10
|
+
attribute :params, default: {}
|
|
11
|
+
|
|
12
|
+
class Notification
|
|
13
|
+
include ActiveModel::Model
|
|
14
|
+
include ActiveModel::Attributes
|
|
15
|
+
include Noticed::Translation
|
|
16
|
+
include Rails.application.routes.url_helpers
|
|
17
|
+
|
|
18
|
+
attribute :recipient
|
|
19
|
+
attribute :event
|
|
20
|
+
|
|
21
|
+
delegate :params, :record, to: :event
|
|
22
|
+
|
|
23
|
+
def self.new_with_params(recipient, params)
|
|
24
|
+
instance = new(recipient: recipient)
|
|
25
|
+
instance.event = module_parent.new(params: params)
|
|
26
|
+
instance
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Dynamically define Notification on each Ephemeral Notifier
|
|
31
|
+
def self.inherited(notifier)
|
|
32
|
+
super
|
|
33
|
+
notifier.const_set :Notification, Class.new(Noticed::Ephemeral::Notification)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.notification_methods(&block)
|
|
37
|
+
const_get(:Notification).class_eval(&block)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def deliver(recipients = nil)
|
|
41
|
+
recipients ||= evaluate_recipients
|
|
42
|
+
recipients = Array.wrap(recipients)
|
|
43
|
+
|
|
44
|
+
bulk_delivery_methods.each do |_, deliver_by|
|
|
45
|
+
deliver_by.ephemeral_perform_later(self.class.name, recipients, params)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
recipients.each do |recipient|
|
|
49
|
+
delivery_methods.each do |_, deliver_by|
|
|
50
|
+
deliver_by.ephemeral_perform_later(self.class.name, recipient, params)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
self
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def record
|
|
58
|
+
params[:record]
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
ActiveSupport.run_load_hooks :noticed_ephemeral, Noticed::Ephemeral
|
data/app/models/noticed/event.rb
CHANGED
|
@@ -11,5 +11,18 @@ module Noticed
|
|
|
11
11
|
accepts_nested_attributes_for :notifications
|
|
12
12
|
|
|
13
13
|
scope :newest_first, -> { order(created_at: :desc) }
|
|
14
|
+
|
|
15
|
+
attribute :params, :json, default: {}
|
|
16
|
+
|
|
17
|
+
# Ephemeral notifiers cannot serialize params since they aren't ActiveRecord backed
|
|
18
|
+
if respond_to? :serialize
|
|
19
|
+
if Rails.gem_version >= Gem::Version.new("7.1.0.alpha")
|
|
20
|
+
serialize :params, coder: Coder
|
|
21
|
+
else
|
|
22
|
+
serialize :params, Coder
|
|
23
|
+
end
|
|
24
|
+
end
|
|
14
25
|
end
|
|
15
26
|
end
|
|
27
|
+
|
|
28
|
+
ActiveSupport.run_load_hooks :noticed_event, Noticed::Event
|
|
@@ -4,13 +4,13 @@ module Noticed
|
|
|
4
4
|
include Readable
|
|
5
5
|
include Translation
|
|
6
6
|
|
|
7
|
-
belongs_to :event
|
|
7
|
+
belongs_to :event, counter_cache: true
|
|
8
8
|
belongs_to :recipient, polymorphic: true
|
|
9
9
|
|
|
10
10
|
scope :newest_first, -> { order(created_at: :desc) }
|
|
11
11
|
|
|
12
12
|
delegate :params, :record, to: :event
|
|
13
|
-
|
|
14
|
-
attribute :params, default: {}
|
|
15
13
|
end
|
|
16
14
|
end
|
|
15
|
+
|
|
16
|
+
ActiveSupport.run_load_hooks :noticed_notification, Noticed::Notification
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
class CreateNoticedTables < ActiveRecord::Migration[6.1]
|
|
2
2
|
def change
|
|
3
|
-
|
|
3
|
+
primary_key_type, foreign_key_type = primary_and_foreign_key_types
|
|
4
|
+
create_table :noticed_events, id: primary_key_type do |t|
|
|
4
5
|
t.string :type
|
|
5
|
-
t.belongs_to :record, polymorphic: true
|
|
6
|
+
t.belongs_to :record, polymorphic: true, type: foreign_key_type
|
|
6
7
|
if t.respond_to?(:jsonb)
|
|
7
8
|
t.jsonb :params
|
|
8
9
|
else
|
|
@@ -12,14 +13,24 @@ class CreateNoticedTables < ActiveRecord::Migration[6.1]
|
|
|
12
13
|
t.timestamps
|
|
13
14
|
end
|
|
14
15
|
|
|
15
|
-
create_table :noticed_notifications do |t|
|
|
16
|
+
create_table :noticed_notifications, id: primary_key_type do |t|
|
|
16
17
|
t.string :type
|
|
17
|
-
t.belongs_to :event, null: false
|
|
18
|
-
t.belongs_to :recipient, polymorphic: true, null: false
|
|
18
|
+
t.belongs_to :event, null: false, type: foreign_key_type
|
|
19
|
+
t.belongs_to :recipient, polymorphic: true, null: false, type: foreign_key_type
|
|
19
20
|
t.datetime :read_at
|
|
20
21
|
t.datetime :seen_at
|
|
21
22
|
|
|
22
23
|
t.timestamps
|
|
23
24
|
end
|
|
24
25
|
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def primary_and_foreign_key_types
|
|
30
|
+
config = Rails.configuration.generators
|
|
31
|
+
setting = config.options[config.orm][:primary_key_type]
|
|
32
|
+
primary_key_type = setting || :primary_key
|
|
33
|
+
foreign_key_type = setting || :bigint
|
|
34
|
+
[primary_key_type, foreign_key_type]
|
|
35
|
+
end
|
|
25
36
|
end
|
|
@@ -11,8 +11,16 @@ module Noticed
|
|
|
11
11
|
|
|
12
12
|
desc "Generates a class for a custom delivery method with the given NAME."
|
|
13
13
|
|
|
14
|
+
class_option :bulk, desc: "Generate as a bulk delivery method", type: :boolean, default: false
|
|
15
|
+
|
|
14
16
|
def generate_notification
|
|
15
|
-
|
|
17
|
+
if options[:bulk]
|
|
18
|
+
template "application_bulk_delivery_method.rb", "app/notifiers/application_bulk_delivery_method.rb"
|
|
19
|
+
template "bulk_delivery_method.rb", "app/notifiers/bulk_delivery_methods/#{singular_name}.rb"
|
|
20
|
+
else
|
|
21
|
+
template "application_delivery_method.rb", "app/notifiers/application_delivery_method.rb"
|
|
22
|
+
template "delivery_method.rb", "app/notifiers/delivery_methods/#{singular_name}.rb"
|
|
23
|
+
end
|
|
16
24
|
end
|
|
17
25
|
end
|
|
18
26
|
end
|
|
@@ -7,12 +7,25 @@ module Noticed
|
|
|
7
7
|
class NotifierGenerator < Rails::Generators::NamedBase
|
|
8
8
|
include Rails::Generators::ResourceHelpers
|
|
9
9
|
|
|
10
|
+
check_class_collision suffix: "Notifier"
|
|
11
|
+
|
|
10
12
|
source_root File.expand_path("../templates", __FILE__)
|
|
11
13
|
|
|
12
14
|
desc "Generates a notification with the given NAME."
|
|
13
15
|
|
|
16
|
+
def generate_abstract_class
|
|
17
|
+
return if File.exist?("app/notifiers/application_notifier.rb")
|
|
18
|
+
template "application_notifier.rb", "app/notifiers/application_notifier.rb"
|
|
19
|
+
end
|
|
20
|
+
|
|
14
21
|
def generate_notification
|
|
15
|
-
template "notifier.rb", "app/notifiers/#{file_path}.rb"
|
|
22
|
+
template "notifier.rb", "app/notifiers/#{file_path}_notifier.rb"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def file_name # :doc:
|
|
28
|
+
@_file_name ||= super.sub(/_notifier\z/i, "")
|
|
16
29
|
end
|
|
17
30
|
end
|
|
18
31
|
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
class BulkDeliveryMethods::<%= class_name %> < ApplicationBulkDeliveryMethod
|
|
2
|
+
# To use this delivery method, specify the class option in your notifier.
|
|
3
|
+
#
|
|
4
|
+
# class MyNotifer < ApplicationNotifier
|
|
5
|
+
# bulk_deliver_by :<%= file_path %>, class: "<%= class_name %>"
|
|
6
|
+
# end
|
|
7
|
+
|
|
8
|
+
# Specify required options for the deliver_by config block
|
|
9
|
+
# required_options :foo, :bar
|
|
10
|
+
|
|
11
|
+
def deliver
|
|
12
|
+
# Logic for sending the notification
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
class DeliveryMethods::<%= class_name %> <
|
|
1
|
+
class DeliveryMethods::<%= class_name %> < ApplicationDeliveryMethod
|
|
2
|
+
# To use this delivery method, specify the class option in your notifier.
|
|
3
|
+
#
|
|
4
|
+
# class MyNotifer < ApplicationNotifier
|
|
5
|
+
# deliver_by :<%= file_path %>, class: "<%= class_name %>"
|
|
6
|
+
# end
|
|
7
|
+
|
|
8
|
+
# Specify required options for the deliver_by config block
|
|
9
|
+
# required_options :foo, :bar
|
|
10
|
+
|
|
2
11
|
def deliver
|
|
3
12
|
# Logic for sending the notification
|
|
4
13
|
end
|
|
5
|
-
|
|
6
|
-
# You may override this method to validate options for the delivery method
|
|
7
|
-
# Invalid options should raise a ValidationError
|
|
8
|
-
#
|
|
9
|
-
# def self.validate!(options)
|
|
10
|
-
# raise ValidationError, "required_option missing" unless options[:required_option]
|
|
11
|
-
# end
|
|
12
14
|
end
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# To deliver this notification:
|
|
2
2
|
#
|
|
3
|
-
# <%= class_name
|
|
3
|
+
# <%= class_name %>Notifier.with(record: @post, message: "New post").deliver(User.all)
|
|
4
4
|
|
|
5
|
-
class <%= class_name %> <
|
|
5
|
+
class <%= class_name %>Notifier < ApplicationNotifier
|
|
6
6
|
# Add your delivery methods
|
|
7
7
|
#
|
|
8
8
|
# deliver_by :email do |config|
|
|
@@ -21,4 +21,10 @@ class <%= class_name %> < Noticed::Event
|
|
|
21
21
|
# Add required params
|
|
22
22
|
#
|
|
23
23
|
# required_param :message
|
|
24
|
+
|
|
25
|
+
# Compute recipients without having to pass them in
|
|
26
|
+
#
|
|
27
|
+
# recipients do
|
|
28
|
+
# params[:record].thread.all_authors
|
|
29
|
+
# end
|
|
24
30
|
end
|
data/lib/noticed/api_client.rb
CHANGED
|
@@ -28,7 +28,9 @@ module Noticed
|
|
|
28
28
|
if (json = args.delete(:json))
|
|
29
29
|
request.body = json.to_json
|
|
30
30
|
elsif (form = args.delete(:form))
|
|
31
|
-
request.
|
|
31
|
+
request.form_data = form
|
|
32
|
+
elsif (body = args.delete(:body))
|
|
33
|
+
request.body = body
|
|
32
34
|
end
|
|
33
35
|
|
|
34
36
|
logger.debug("POST #{url}")
|
|
@@ -1,20 +1,32 @@
|
|
|
1
1
|
module Noticed
|
|
2
|
-
class BulkDeliveryMethod <
|
|
2
|
+
class BulkDeliveryMethod < Noticed.parent_class.constantize
|
|
3
3
|
include ApiClient
|
|
4
4
|
include RequiredOptions
|
|
5
5
|
|
|
6
|
+
extend ActiveModel::Callbacks
|
|
7
|
+
|
|
8
|
+
define_model_callbacks :deliver
|
|
9
|
+
|
|
6
10
|
class_attribute :logger, default: Rails.logger
|
|
7
11
|
|
|
8
12
|
attr_reader :config, :event
|
|
9
13
|
|
|
10
|
-
def perform(delivery_method_name, event)
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
def perform(delivery_method_name, event, recipient: nil, params: {}, overrides: {})
|
|
15
|
+
# Ephemeral notifications
|
|
16
|
+
if event.is_a? String
|
|
17
|
+
@event = event.constantize.new_with_params(recipient, params)
|
|
18
|
+
@config = overrides
|
|
19
|
+
else
|
|
20
|
+
@event = event
|
|
21
|
+
@config = event.bulk_delivery_methods.fetch(delivery_method_name).config.merge(overrides)
|
|
22
|
+
end
|
|
13
23
|
|
|
14
24
|
return false if config.has_key?(:if) && !evaluate_option(:if)
|
|
15
25
|
return false if config.has_key?(:unless) && evaluate_option(:unless)
|
|
16
26
|
|
|
17
|
-
deliver
|
|
27
|
+
run_callbacks :deliver do
|
|
28
|
+
deliver
|
|
29
|
+
end
|
|
18
30
|
end
|
|
19
31
|
|
|
20
32
|
def deliver
|
|
@@ -23,7 +35,7 @@ module Noticed
|
|
|
23
35
|
|
|
24
36
|
def fetch_constant(name)
|
|
25
37
|
option = config[name]
|
|
26
|
-
option.is_a?(String) ? option.constantize : option
|
|
38
|
+
option.is_a?(String) ? option.constantize : evaluate_option(option)
|
|
27
39
|
end
|
|
28
40
|
|
|
29
41
|
def evaluate_option(name)
|
|
@@ -34,7 +46,7 @@ module Noticed
|
|
|
34
46
|
event.instance_exec(&option)
|
|
35
47
|
|
|
36
48
|
# Call method if symbol and matching method
|
|
37
|
-
elsif option.is_a?(Symbol) && event.respond_to?(option)
|
|
49
|
+
elsif option.is_a?(Symbol) && event.respond_to?(option, true)
|
|
38
50
|
event.send(option)
|
|
39
51
|
|
|
40
52
|
# Return the value
|