activity_notification 2.5.1 → 2.6.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 +2 -0
- data/app/channels/activity_notification/notification_api_channel.rb +5 -5
- data/app/channels/activity_notification/notification_api_with_devise_channel.rb +4 -4
- data/app/channels/activity_notification/notification_channel.rb +4 -0
- data/app/channels/activity_notification/notification_with_devise_channel.rb +4 -4
- data/app/controllers/activity_notification/notifications_controller.rb +1 -2
- data/app/controllers/activity_notification/subscriptions_controller.rb +2 -3
- data/app/jobs/activity_notification/notify_all_job.rb +2 -2
- data/app/jobs/activity_notification/notify_job.rb +2 -2
- data/app/jobs/activity_notification/notify_to_job.rb +1 -1
- data/app/mailers/activity_notification/mailer.rb +1 -1
- data/app/views/activity_notification/mailer/default/batch_default.text.erb +1 -1
- data/app/views/activity_notification/notifications/default/index.html.erb +1 -1
- data/app/views/activity_notification/subscriptions/default/_notification_keys.html.erb +1 -1
- data/app/views/activity_notification/subscriptions/default/_subscription.html.erb +1 -1
- data/docs/Functions.md +93 -9
- data/docs/Setup.md +7 -7
- data/docs/Testing.md +1 -1
- data/docs/Upgrade-to-2.6.md +108 -0
- data/lib/activity_notification/apis/notification_api.rb +55 -40
- data/lib/activity_notification/apis/subscription_api.rb +10 -10
- data/lib/activity_notification/common.rb +5 -5
- data/lib/activity_notification/config.rb +15 -5
- data/lib/activity_notification/controllers/common_controller.rb +2 -4
- data/lib/activity_notification/controllers/devise_authentication_controller.rb +2 -2
- data/lib/activity_notification/helpers/polymorphic_helpers.rb +6 -6
- data/lib/activity_notification/helpers/view_helpers.rb +3 -3
- data/lib/activity_notification/mailers/helpers.rb +88 -2
- data/lib/activity_notification/models/concerns/notifiable.rb +60 -30
- data/lib/activity_notification/models/concerns/notifier.rb +1 -1
- data/lib/activity_notification/models/concerns/subscriber.rb +72 -15
- data/lib/activity_notification/models/concerns/target.rb +38 -35
- data/lib/activity_notification/optional_targets/action_cable_api_channel.rb +1 -1
- data/lib/activity_notification/optional_targets/slack.rb +2 -2
- data/lib/activity_notification/orm/active_record/notification.rb +25 -25
- data/lib/activity_notification/orm/active_record/subscription.rb +21 -1
- data/lib/activity_notification/orm/dynamoid/extension.rb +3 -3
- data/lib/activity_notification/orm/dynamoid/subscription.rb +8 -1
- data/lib/activity_notification/orm/dynamoid.rb +18 -18
- data/lib/activity_notification/orm/mongoid/notification.rb +26 -28
- data/lib/activity_notification/orm/mongoid/subscription.rb +21 -1
- data/lib/activity_notification/orm/mongoid.rb +1 -1
- data/lib/activity_notification/rails/routes.rb +11 -11
- data/lib/activity_notification/roles/acts_as_group.rb +1 -1
- data/lib/activity_notification/roles/acts_as_notifiable.rb +5 -5
- data/lib/activity_notification/roles/acts_as_notifier.rb +1 -1
- data/lib/activity_notification/roles/acts_as_target.rb +1 -1
- data/lib/activity_notification/version.rb +1 -1
- data/lib/generators/activity_notification/add_notifiable_to_subscriptions/add_notifiable_to_subscriptions_generator.rb +23 -0
- data/lib/generators/activity_notification/add_notifiable_to_subscriptions/templates/add_notifiable_to_subscriptions.rb +13 -0
- data/lib/generators/templates/activity_notification.rb +14 -2
- data/lib/generators/templates/migrations/migration.rb +4 -2
- metadata +5 -2
|
@@ -94,6 +94,11 @@ module ActivityNotification
|
|
|
94
94
|
headers[header_name] = header_value if header_value
|
|
95
95
|
end
|
|
96
96
|
@email = headers[:to]
|
|
97
|
+
|
|
98
|
+
# Resolve attachments
|
|
99
|
+
attachment_specs = resolve_attachments(key)
|
|
100
|
+
headers[:attachment_specs] = attachment_specs if attachment_specs.present?
|
|
101
|
+
|
|
97
102
|
headers
|
|
98
103
|
end
|
|
99
104
|
|
|
@@ -125,6 +130,58 @@ module ActivityNotification
|
|
|
125
130
|
end
|
|
126
131
|
end
|
|
127
132
|
|
|
133
|
+
# Returns attachment specification(s) for notification email.
|
|
134
|
+
# Checks target method first, then falls back to global configuration.
|
|
135
|
+
#
|
|
136
|
+
# @param [Object] target Target instance to notify
|
|
137
|
+
# @return [Hash, Array<Hash>, nil] Attachment specification(s) or nil
|
|
138
|
+
def mailer_attachments(target)
|
|
139
|
+
if target.respond_to?(:mailer_attachments)
|
|
140
|
+
target.mailer_attachments
|
|
141
|
+
elsif ActivityNotification.config.mailer_attachments.present?
|
|
142
|
+
if ActivityNotification.config.mailer_attachments.is_a?(Proc)
|
|
143
|
+
key = @notification ? @notification.key : nil
|
|
144
|
+
ActivityNotification.config.mailer_attachments.call(key)
|
|
145
|
+
else
|
|
146
|
+
ActivityNotification.config.mailer_attachments
|
|
147
|
+
end
|
|
148
|
+
else
|
|
149
|
+
nil
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# Resolves attachment specifications with priority:
|
|
154
|
+
# notifiable override > target method > global configuration.
|
|
155
|
+
#
|
|
156
|
+
# @param [String] key Key of the notification
|
|
157
|
+
# @return [Hash, Array<Hash>, nil] Resolved attachment specification(s) or nil
|
|
158
|
+
def resolve_attachments(key)
|
|
159
|
+
if @notification&.notifiable&.respond_to?(:overriding_notification_email_attachments) &&
|
|
160
|
+
@notification.notifiable.overriding_notification_email_attachments(@target, key).present?
|
|
161
|
+
@notification.notifiable.overriding_notification_email_attachments(@target, key)
|
|
162
|
+
else
|
|
163
|
+
mailer_attachments(@target)
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# Processes attachment specifications and adds them to the mail object.
|
|
168
|
+
#
|
|
169
|
+
# @param [Mail::Message] mail_obj The mail object to add attachments to
|
|
170
|
+
# @param [Hash, Array<Hash>, nil] specs Attachment specification(s)
|
|
171
|
+
# @return [void]
|
|
172
|
+
def process_attachments(mail_obj, specs)
|
|
173
|
+
return if specs.blank?
|
|
174
|
+
specs_array = specs.is_a?(Array) ? specs : [specs]
|
|
175
|
+
specs_array.each do |spec|
|
|
176
|
+
next if spec.blank?
|
|
177
|
+
validate_attachment_spec!(spec)
|
|
178
|
+
content = spec[:content] || File.read(spec[:path])
|
|
179
|
+
options = { content: content }
|
|
180
|
+
options[:mime_type] = spec[:mime_type] if spec[:mime_type]
|
|
181
|
+
mail_obj.attachments[spec[:filename]] = options
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
128
185
|
# Returns sender email address as 'reply_to'.
|
|
129
186
|
#
|
|
130
187
|
# @param [String] key Key of the notification or batch notification email
|
|
@@ -204,17 +261,46 @@ module ActivityNotification
|
|
|
204
261
|
# @param [Hash] headers Prepared email header
|
|
205
262
|
# @param [String, Symbol] fallback Fallback option
|
|
206
263
|
def send_mail(headers, fallback = nil)
|
|
264
|
+
attachment_specs = headers.delete(:attachment_specs)
|
|
207
265
|
begin
|
|
208
|
-
mail headers
|
|
266
|
+
mail_obj = mail headers
|
|
267
|
+
process_attachments(mail_obj, attachment_specs)
|
|
268
|
+
mail_obj
|
|
209
269
|
rescue ActionView::MissingTemplate => e
|
|
210
270
|
if fallback.present?
|
|
211
|
-
mail headers.merge(template_name: fallback)
|
|
271
|
+
mail_obj = mail headers.merge(template_name: fallback)
|
|
272
|
+
process_attachments(mail_obj, attachment_specs)
|
|
273
|
+
mail_obj
|
|
212
274
|
else
|
|
213
275
|
raise e
|
|
214
276
|
end
|
|
215
277
|
end
|
|
216
278
|
end
|
|
217
279
|
|
|
280
|
+
# Validates an attachment specification hash.
|
|
281
|
+
#
|
|
282
|
+
# @param [Hash] spec Attachment specification
|
|
283
|
+
# @raise [ArgumentError] If specification is invalid
|
|
284
|
+
# @return [void]
|
|
285
|
+
def validate_attachment_spec!(spec)
|
|
286
|
+
unless spec.is_a?(Hash)
|
|
287
|
+
raise ArgumentError, "Attachment specification must be a Hash, got #{spec.class}"
|
|
288
|
+
end
|
|
289
|
+
unless spec[:filename].present?
|
|
290
|
+
raise ArgumentError, "Attachment specification must include :filename"
|
|
291
|
+
end
|
|
292
|
+
content_sources = [spec[:content], spec[:path]].compact
|
|
293
|
+
if content_sources.empty?
|
|
294
|
+
raise ArgumentError, "Attachment specification must include :content or :path"
|
|
295
|
+
end
|
|
296
|
+
if content_sources.size > 1
|
|
297
|
+
raise ArgumentError, "Attachment specification must include only one of :content or :path"
|
|
298
|
+
end
|
|
299
|
+
if spec[:path].present? && !File.exist?(spec[:path])
|
|
300
|
+
raise ArgumentError, "Attachment file not found: #{spec[:path]}"
|
|
301
|
+
end
|
|
302
|
+
end
|
|
303
|
+
|
|
218
304
|
end
|
|
219
305
|
end
|
|
220
306
|
end
|
|
@@ -14,7 +14,7 @@ module ActivityNotification
|
|
|
14
14
|
# Has many notification instances for this notifiable.
|
|
15
15
|
# Dependency for these notifications can be overridden from acts_as_notifiable.
|
|
16
16
|
# @scope instance
|
|
17
|
-
# @return [Array<
|
|
17
|
+
# @return [Array<Notification>, Mongoid::Criteria<Notification>] Array or database query of notifications for this notifiable
|
|
18
18
|
has_many_records :generated_notifications_as_notifiable,
|
|
19
19
|
class_name: "::ActivityNotification::Notification",
|
|
20
20
|
as: :notifiable
|
|
@@ -65,13 +65,13 @@ module ActivityNotification
|
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
# Returns notification targets from configured field or overridden method.
|
|
68
|
-
# This method
|
|
68
|
+
# This method can be overridden.
|
|
69
69
|
#
|
|
70
70
|
# @param [String] target_type Target type to notify
|
|
71
71
|
# @param [Hash] options Options for notifications
|
|
72
72
|
# @option options [String] :key (notifiable.default_notification_key) Key of the notification
|
|
73
73
|
# @option options [Hash] :parameters ({}) Additional parameters of the notifications
|
|
74
|
-
# @return [Array<
|
|
74
|
+
# @return [Array<Notification> | ActiveRecord_AssociationRelation<Notification>] Array or database query of the notification targets
|
|
75
75
|
def notification_targets(target_type, options = {})
|
|
76
76
|
target_typed_method_name = "notification_#{cast_to_resources_name(target_type)}"
|
|
77
77
|
resolved_parameter = resolve_parameter(
|
|
@@ -86,8 +86,40 @@ module ActivityNotification
|
|
|
86
86
|
resolved_parameter
|
|
87
87
|
end
|
|
88
88
|
|
|
89
|
+
# Returns targets that have instance-level subscriptions for this notifiable.
|
|
90
|
+
# This method finds all active instance-level subscriptions for this specific notifiable
|
|
91
|
+
# instance and returns their target objects.
|
|
92
|
+
#
|
|
93
|
+
# @param [String] target_type Target type to notify
|
|
94
|
+
# @param [String] key Key of the notification (defaults to default_notification_key)
|
|
95
|
+
# @return [Array<Object>] Array of target instances with active instance-level subscriptions
|
|
96
|
+
def instance_subscription_targets(target_type, key = nil)
|
|
97
|
+
key ||= default_notification_key
|
|
98
|
+
target_class_name = target_type.to_s.to_model_name
|
|
99
|
+
if ActivityNotification.config.orm == :dynamoid
|
|
100
|
+
# :nocov:
|
|
101
|
+
delimiter = ActivityNotification.config.composite_key_delimiter
|
|
102
|
+
Subscription.where(
|
|
103
|
+
notifiable_key: "#{self.class.name}#{delimiter}#{self.id}",
|
|
104
|
+
key: key,
|
|
105
|
+
subscribing: true
|
|
106
|
+
).select { |s| s.target_type == target_class_name }.map(&:target).compact
|
|
107
|
+
# :nocov:
|
|
108
|
+
else
|
|
109
|
+
# :nocov:
|
|
110
|
+
Subscription.where(
|
|
111
|
+
notifiable_type: self.class.name,
|
|
112
|
+
notifiable_id: self.id,
|
|
113
|
+
key: key,
|
|
114
|
+
subscribing: true,
|
|
115
|
+
target_type: target_class_name
|
|
116
|
+
).map(&:target).compact
|
|
117
|
+
# :nocov:
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
89
121
|
# Returns group unit of the notifications from configured field or overridden method.
|
|
90
|
-
# This method
|
|
122
|
+
# This method can be overridden.
|
|
91
123
|
#
|
|
92
124
|
# @param [String] target_type Target type to notify
|
|
93
125
|
# @param [String] key Key of the notification
|
|
@@ -101,7 +133,7 @@ module ActivityNotification
|
|
|
101
133
|
end
|
|
102
134
|
|
|
103
135
|
# Returns group expiry period of the notifications from configured field or overridden method.
|
|
104
|
-
# This method
|
|
136
|
+
# This method can be overridden.
|
|
105
137
|
#
|
|
106
138
|
# @param [String] target_type Target type to notify
|
|
107
139
|
# @param [String] key Key of the notification
|
|
@@ -115,7 +147,7 @@ module ActivityNotification
|
|
|
115
147
|
end
|
|
116
148
|
|
|
117
149
|
# Returns additional notification parameters from configured field or overridden method.
|
|
118
|
-
# This method
|
|
150
|
+
# This method can be overridden.
|
|
119
151
|
#
|
|
120
152
|
# @param [String] target_type Target type to notify
|
|
121
153
|
# @param [String] key Key of the notification
|
|
@@ -129,7 +161,7 @@ module ActivityNotification
|
|
|
129
161
|
end
|
|
130
162
|
|
|
131
163
|
# Returns notifier of the notification from configured field or overridden method.
|
|
132
|
-
# This method
|
|
164
|
+
# This method can be overridden.
|
|
133
165
|
#
|
|
134
166
|
# @param [String] target_type Target type to notify
|
|
135
167
|
# @param [String] key Key of the notification
|
|
@@ -143,7 +175,7 @@ module ActivityNotification
|
|
|
143
175
|
end
|
|
144
176
|
|
|
145
177
|
# Returns if sending notification email is allowed for the notifiable from configured field or overridden method.
|
|
146
|
-
# This method
|
|
178
|
+
# This method can be overridden.
|
|
147
179
|
#
|
|
148
180
|
# @param [Object] target Target instance to notify
|
|
149
181
|
# @param [String] key Key of the notification
|
|
@@ -157,7 +189,7 @@ module ActivityNotification
|
|
|
157
189
|
end
|
|
158
190
|
|
|
159
191
|
# Returns if publishing WebSocket using ActionCable is allowed for the notifiable from configured field or overridden method.
|
|
160
|
-
# This method
|
|
192
|
+
# This method can be overridden.
|
|
161
193
|
#
|
|
162
194
|
# @param [Object] target Target instance to notify
|
|
163
195
|
# @param [String] key Key of the notification
|
|
@@ -171,7 +203,7 @@ module ActivityNotification
|
|
|
171
203
|
end
|
|
172
204
|
|
|
173
205
|
# Returns if publishing WebSocket API using ActionCable is allowed for the notifiable from configured field or overridden method.
|
|
174
|
-
# This method
|
|
206
|
+
# This method can be overridden.
|
|
175
207
|
#
|
|
176
208
|
# @param [Object] target Target instance to notify
|
|
177
209
|
# @param [String] key Key of the notification
|
|
@@ -185,7 +217,7 @@ module ActivityNotification
|
|
|
185
217
|
end
|
|
186
218
|
|
|
187
219
|
# Returns notifiable_path to move after opening notification from configured field or overridden method.
|
|
188
|
-
# This method
|
|
220
|
+
# This method can be overridden.
|
|
189
221
|
#
|
|
190
222
|
# @param [String] target_type Target type to notify
|
|
191
223
|
# @param [String] key Key of the notification
|
|
@@ -219,7 +251,7 @@ module ActivityNotification
|
|
|
219
251
|
end
|
|
220
252
|
|
|
221
253
|
# Returns optional_targets of the notification from configured field or overridden method.
|
|
222
|
-
# This method
|
|
254
|
+
# This method can be overridden.
|
|
223
255
|
#
|
|
224
256
|
# @param [String] target_type Target type to notify
|
|
225
257
|
# @param [String] key Key of the notification
|
|
@@ -233,7 +265,7 @@ module ActivityNotification
|
|
|
233
265
|
end
|
|
234
266
|
|
|
235
267
|
# Returns optional_target names of the notification from configured field or overridden method.
|
|
236
|
-
# This method
|
|
268
|
+
# This method can be overridden.
|
|
237
269
|
#
|
|
238
270
|
# @param [String] target_type Target type to notify
|
|
239
271
|
# @param [String] key Key of the notification
|
|
@@ -275,8 +307,8 @@ module ActivityNotification
|
|
|
275
307
|
# @option options [Boolean] :send_email (true) Whether it sends notification email
|
|
276
308
|
# @option options [Boolean] :send_later (true) Whether it sends notification email asynchronously
|
|
277
309
|
# @option options [Boolean] :publish_optional_targets (true) Whether it publishes notification to optional targets
|
|
278
|
-
# @option options [Hash<String, Hash>] :optional_targets ({}) Options for optional targets, keys are optional target name (:amazon_sns or :slack etc) and values are options
|
|
279
|
-
# @return [Array<
|
|
310
|
+
# @option options [Hash<String, Hash>] :optional_targets ({}) Options for optional targets, keys are optional target name (:amazon_sns or :slack etc.) and values are options
|
|
311
|
+
# @return [Array<Notification>] Array of generated notifications
|
|
280
312
|
def notify(target_type, options = {})
|
|
281
313
|
Notification.notify(target_type, self, options)
|
|
282
314
|
end
|
|
@@ -295,8 +327,8 @@ module ActivityNotification
|
|
|
295
327
|
# @option options [Boolean] :send_email (true) Whether it sends notification email
|
|
296
328
|
# @option options [Boolean] :send_later (true) Whether it sends notification email asynchronously
|
|
297
329
|
# @option options [Boolean] :publish_optional_targets (true) Whether it publishes notification to optional targets
|
|
298
|
-
# @option options [Hash<String, Hash>] :optional_targets ({}) Options for optional targets, keys are optional target name (:amazon_sns or :slack etc) and values are options
|
|
299
|
-
# @return [Array<
|
|
330
|
+
# @option options [Hash<String, Hash>] :optional_targets ({}) Options for optional targets, keys are optional target name (:amazon_sns or :slack etc.) and values are options
|
|
331
|
+
# @return [Array<Notification>] Array of generated notifications
|
|
300
332
|
def notify_later(target_type, options = {})
|
|
301
333
|
Notification.notify_later(target_type, self, options)
|
|
302
334
|
end
|
|
@@ -316,8 +348,8 @@ module ActivityNotification
|
|
|
316
348
|
# @option options [Boolean] :send_email (true) Whether it sends notification email
|
|
317
349
|
# @option options [Boolean] :send_later (true) Whether it sends notification email asynchronously
|
|
318
350
|
# @option options [Boolean] :publish_optional_targets (true) Whether it publishes notification to optional targets
|
|
319
|
-
# @option options [Hash<String, Hash>] :optional_targets ({}) Options for optional targets, keys are optional target name (:amazon_sns or :slack etc) and values are options
|
|
320
|
-
# @return [Array<
|
|
351
|
+
# @option options [Hash<String, Hash>] :optional_targets ({}) Options for optional targets, keys are optional target name (:amazon_sns or :slack etc.) and values are options
|
|
352
|
+
# @return [Array<Notification>] Array of generated notifications
|
|
321
353
|
def notify_all(targets, options = {})
|
|
322
354
|
Notification.notify_all(targets, self, options)
|
|
323
355
|
end
|
|
@@ -337,8 +369,8 @@ module ActivityNotification
|
|
|
337
369
|
# @option options [Boolean] :send_email (true) Whether it sends notification email
|
|
338
370
|
# @option options [Boolean] :send_later (true) Whether it sends notification email asynchronously
|
|
339
371
|
# @option options [Boolean] :publish_optional_targets (true) Whether it publishes notification to optional targets
|
|
340
|
-
# @option options [Hash<String, Hash>] :optional_targets ({}) Options for optional targets, keys are optional target name (:amazon_sns or :slack etc) and values are options
|
|
341
|
-
# @return [Array<
|
|
372
|
+
# @option options [Hash<String, Hash>] :optional_targets ({}) Options for optional targets, keys are optional target name (:amazon_sns or :slack etc.) and values are options
|
|
373
|
+
# @return [Array<Notification>] Array of generated notifications
|
|
342
374
|
def notify_all_later(targets, options = {})
|
|
343
375
|
Notification.notify_all_later(targets, self, options)
|
|
344
376
|
end
|
|
@@ -357,7 +389,7 @@ module ActivityNotification
|
|
|
357
389
|
# @option options [Boolean] :send_email (true) Whether it sends notification email
|
|
358
390
|
# @option options [Boolean] :send_later (true) Whether it sends notification email asynchronously
|
|
359
391
|
# @option options [Boolean] :publish_optional_targets (true) Whether it publishes notification to optional targets
|
|
360
|
-
# @option options [Hash<String, Hash>] :optional_targets ({}) Options for optional targets, keys are optional target name (:amazon_sns or :slack etc) and values are options
|
|
392
|
+
# @option options [Hash<String, Hash>] :optional_targets ({}) Options for optional targets, keys are optional target name (:amazon_sns or :slack etc.) and values are options
|
|
361
393
|
# @return [Notification] Generated notification instance
|
|
362
394
|
def notify_to(target, options = {})
|
|
363
395
|
Notification.notify_to(target, self, options)
|
|
@@ -378,14 +410,14 @@ module ActivityNotification
|
|
|
378
410
|
# @option options [Boolean] :send_email (true) Whether it sends notification email
|
|
379
411
|
# @option options [Boolean] :send_later (true) Whether it sends notification email asynchronously
|
|
380
412
|
# @option options [Boolean] :publish_optional_targets (true) Whether it publishes notification to optional targets
|
|
381
|
-
# @option options [Hash<String, Hash>] :optional_targets ({}) Options for optional targets, keys are optional target name (:amazon_sns or :slack etc) and values are options
|
|
413
|
+
# @option options [Hash<String, Hash>] :optional_targets ({}) Options for optional targets, keys are optional target name (:amazon_sns or :slack etc.) and values are options
|
|
382
414
|
# @return [Notification] Generated notification instance
|
|
383
415
|
def notify_later_to(target, options = {})
|
|
384
416
|
Notification.notify_later_to(target, self, options)
|
|
385
417
|
end
|
|
386
418
|
|
|
387
419
|
# Returns default key of the notification.
|
|
388
|
-
# This method
|
|
420
|
+
# This method can be overridden.
|
|
389
421
|
# "#{to_resource_name}.default" is defined as default key.
|
|
390
422
|
#
|
|
391
423
|
# @return [String] Default key of the notification
|
|
@@ -394,7 +426,7 @@ module ActivityNotification
|
|
|
394
426
|
end
|
|
395
427
|
|
|
396
428
|
# Returns key of the notification for tracked notifiable creation.
|
|
397
|
-
# This method
|
|
429
|
+
# This method can be overridden.
|
|
398
430
|
# "#{to_resource_name}.create" is defined as default creation key.
|
|
399
431
|
#
|
|
400
432
|
# @return [String] Key of the notification for tracked notifiable creation
|
|
@@ -403,7 +435,7 @@ module ActivityNotification
|
|
|
403
435
|
end
|
|
404
436
|
|
|
405
437
|
# Returns key of the notification for tracked notifiable update.
|
|
406
|
-
# This method
|
|
438
|
+
# This method can be overridden.
|
|
407
439
|
# "#{to_resource_name}.update" is defined as default update key.
|
|
408
440
|
#
|
|
409
441
|
# @return [String] Key of the notification for tracked notifiable update
|
|
@@ -435,12 +467,10 @@ module ActivityNotification
|
|
|
435
467
|
# @api private
|
|
436
468
|
# @param [String] target_type Target type of generated notifications
|
|
437
469
|
def generated_notifications_as_notifiable_for(target_type = nil)
|
|
438
|
-
target_type.nil? ?
|
|
439
|
-
generated_notifications_as_notifiable.all :
|
|
440
|
-
generated_notifications_as_notifiable.filtered_by_target_type(target_type.to_s.to_model_name)
|
|
470
|
+
target_type.nil? ? generated_notifications_as_notifiable.all : generated_notifications_as_notifiable.filtered_by_target_type(target_type.to_s.to_model_name)
|
|
441
471
|
end
|
|
442
472
|
|
|
443
|
-
#
|
|
473
|
+
# Destroys generated notifications for specified target type with dependency.
|
|
444
474
|
# This method is intended to be called before destroy this notifiable as dependent configuration.
|
|
445
475
|
# @api private
|
|
446
476
|
# @param [Symbol] dependent Has_many dependency, [:delete_all, :destroy, :restrict_with_error, :restrict_with_exception] are available
|
|
@@ -9,7 +9,7 @@ module ActivityNotification
|
|
|
9
9
|
|
|
10
10
|
# Has many sent notification instances from this notifier.
|
|
11
11
|
# @scope instance
|
|
12
|
-
# @return [Array<
|
|
12
|
+
# @return [Array<Notification>, Mongoid::Criteria<Notification>] Array or database query of sent notifications from this notifier
|
|
13
13
|
has_many_records :sent_notifications,
|
|
14
14
|
class_name: "::ActivityNotification::Notification",
|
|
15
15
|
as: :notifier
|
|
@@ -27,20 +27,48 @@ module ActivityNotification
|
|
|
27
27
|
|
|
28
28
|
# Gets subscription of the target and notification key.
|
|
29
29
|
#
|
|
30
|
-
# @param [
|
|
30
|
+
# @param [String] key Key of the notification for subscription
|
|
31
|
+
# @param [Object] notifiable Optional notifiable instance for instance-level subscription lookup
|
|
31
32
|
# @return [Subscription] Configured subscription instance
|
|
32
|
-
def find_subscription(key)
|
|
33
|
-
|
|
33
|
+
def find_subscription(key, notifiable: nil)
|
|
34
|
+
if notifiable
|
|
35
|
+
if ActivityNotification.config.orm == :dynamoid
|
|
36
|
+
# :nocov:
|
|
37
|
+
delimiter = ActivityNotification.config.composite_key_delimiter
|
|
38
|
+
subscriptions.where(key: key, notifiable_key: "#{notifiable.class.name}#{delimiter}#{notifiable.id}").first
|
|
39
|
+
# :nocov:
|
|
40
|
+
else
|
|
41
|
+
# :nocov:
|
|
42
|
+
subscriptions.where(key: key, notifiable_type: notifiable.class.name, notifiable_id: notifiable.id).first
|
|
43
|
+
# :nocov:
|
|
44
|
+
end
|
|
45
|
+
else
|
|
46
|
+
if ActivityNotification.config.orm == :dynamoid
|
|
47
|
+
# :nocov:
|
|
48
|
+
subscriptions.where(key: key).select { |s| s.notifiable_type.nil? }.first
|
|
49
|
+
# :nocov:
|
|
50
|
+
else
|
|
51
|
+
# :nocov:
|
|
52
|
+
subscriptions.where(key: key, notifiable_type: nil).first
|
|
53
|
+
# :nocov:
|
|
54
|
+
end
|
|
55
|
+
end
|
|
34
56
|
end
|
|
35
57
|
|
|
36
58
|
# Gets subscription of the target and notification key.
|
|
37
59
|
#
|
|
38
|
-
# @param [
|
|
60
|
+
# @param [String] key Key of the notification for subscription
|
|
39
61
|
# @param [Hash] subscription_params Parameters to create subscription record
|
|
40
62
|
# @return [Subscription] Found or created subscription instance
|
|
41
63
|
def find_or_create_subscription(key, subscription_params = {})
|
|
42
|
-
|
|
43
|
-
subscription
|
|
64
|
+
notifiable = subscription_params.delete(:notifiable)
|
|
65
|
+
subscription = find_subscription(key, notifiable: notifiable)
|
|
66
|
+
merge_params = { key: key }
|
|
67
|
+
if notifiable
|
|
68
|
+
merge_params[:notifiable_type] = notifiable.class.name
|
|
69
|
+
merge_params[:notifiable_id] = notifiable.id
|
|
70
|
+
end
|
|
71
|
+
subscription || create_subscription(subscription_params.merge(merge_params))
|
|
44
72
|
end
|
|
45
73
|
|
|
46
74
|
# Creates new subscription of the target.
|
|
@@ -65,6 +93,13 @@ module ActivityNotification
|
|
|
65
93
|
elsif subscription_params[:subscribing_to_email].nil?
|
|
66
94
|
subscription_params[:subscribing_to_email] = ActivityNotification.config.subscribe_to_email_as_default
|
|
67
95
|
end
|
|
96
|
+
# :nocov:
|
|
97
|
+
# Convert notifiable_type/notifiable_id to notifiable_key for Dynamoid
|
|
98
|
+
if ActivityNotification.config.orm == :dynamoid && subscription_params[:notifiable_type].present? && subscription_params[:notifiable_id].present?
|
|
99
|
+
delimiter = ActivityNotification.config.composite_key_delimiter
|
|
100
|
+
subscription_params[:notifiable_key] = "#{subscription_params.delete(:notifiable_type)}#{delimiter}#{subscription_params.delete(:notifiable_id)}"
|
|
101
|
+
end
|
|
102
|
+
# :nocov:
|
|
68
103
|
subscription = Subscription.new(subscription_params)
|
|
69
104
|
subscription.assign_attributes(target: self)
|
|
70
105
|
subscription.subscribing? ?
|
|
@@ -101,7 +136,7 @@ module ActivityNotification
|
|
|
101
136
|
# @option options [String] :filtered_by_key (nil) Key of the notification for filter
|
|
102
137
|
# @option options [Array|Hash] :custom_filter (nil) Custom subscription filter (e.g. ["created_at >= ?", time.hour.ago])
|
|
103
138
|
# @option options [Boolean] :with_target (false) If it includes target with subscriptions
|
|
104
|
-
# @return [Array<
|
|
139
|
+
# @return [Array<Notification>] Configured subscription index of the target
|
|
105
140
|
def subscription_index(options = {})
|
|
106
141
|
target_index = subscriptions.filtered_by_options(options)
|
|
107
142
|
target_index = options[:reverse] ? target_index.earliest_order : target_index.latest_order
|
|
@@ -120,7 +155,7 @@ module ActivityNotification
|
|
|
120
155
|
# @option options [Symbol|String] :filter (nil) Filter option to load notification keys (Nothing as all, 'configured' with configured subscriptions or 'unconfigured' without subscriptions)
|
|
121
156
|
# @option options [String] :filtered_by_key (nil) Key of the notification for filter
|
|
122
157
|
# @option options [Array|Hash] :custom_filter (nil) Custom subscription filter (e.g. ["created_at >= ?", time.hour.ago])
|
|
123
|
-
# @return [Array<
|
|
158
|
+
# @return [Array<Notification>] Unconfigured notification keys of the target
|
|
124
159
|
def notification_keys(options = {})
|
|
125
160
|
subscription_keys = subscriptions.uniq_keys
|
|
126
161
|
target_notifications = notifications.filtered_by_options(options.select { |k, _| [:filtered_by_key, :custom_filter].include?(k) })
|
|
@@ -146,10 +181,22 @@ module ActivityNotification
|
|
|
146
181
|
# @api protected
|
|
147
182
|
#
|
|
148
183
|
# @param [String] key Key of the notification
|
|
149
|
-
# @param [Boolean] subscribe_as_default Default subscription value to use when the subscription record
|
|
184
|
+
# @param [Boolean] subscribe_as_default Default subscription value to use when the subscription record is not configured
|
|
150
185
|
# @return [Boolean] If the target subscribes to the notification
|
|
151
186
|
def _subscribes_to_notification?(key, subscribe_as_default = ActivityNotification.config.subscribe_as_default)
|
|
152
|
-
|
|
187
|
+
subscription = _find_key_level_subscription(key)
|
|
188
|
+
evaluate_subscription(subscription, :subscribing?, subscribe_as_default)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# Returns if the target subscribes to the notification for a specific notifiable instance.
|
|
192
|
+
# @api protected
|
|
193
|
+
#
|
|
194
|
+
# @param [String] key Key of the notification
|
|
195
|
+
# @param [Object] notifiable Notifiable instance to check subscription for
|
|
196
|
+
# @return [Boolean] If the target has an active instance-level subscription for this notifiable
|
|
197
|
+
def _subscribes_to_notification_for_instance?(key, notifiable)
|
|
198
|
+
instance_sub = find_subscription(key, notifiable: notifiable)
|
|
199
|
+
instance_sub.present? && instance_sub.subscribing?
|
|
153
200
|
end
|
|
154
201
|
|
|
155
202
|
# Returns if the target subscribes to the notification email.
|
|
@@ -157,10 +204,11 @@ module ActivityNotification
|
|
|
157
204
|
# @api protected
|
|
158
205
|
#
|
|
159
206
|
# @param [String] key Key of the notification
|
|
160
|
-
# @param [Boolean] subscribe_as_default Default subscription value to use when the subscription record
|
|
207
|
+
# @param [Boolean] subscribe_as_default Default subscription value to use when the subscription record is not configured
|
|
161
208
|
# @return [Boolean] If the target subscribes to the notification
|
|
162
209
|
def _subscribes_to_notification_email?(key, subscribe_as_default = ActivityNotification.config.subscribe_to_email_as_default)
|
|
163
|
-
|
|
210
|
+
subscription = _find_key_level_subscription(key)
|
|
211
|
+
evaluate_subscription(subscription, :subscribing_to_email?, subscribe_as_default)
|
|
164
212
|
end
|
|
165
213
|
alias_method :_subscribes_to_email?, :_subscribes_to_notification_email?
|
|
166
214
|
|
|
@@ -170,20 +218,29 @@ module ActivityNotification
|
|
|
170
218
|
#
|
|
171
219
|
# @param [String] key Key of the notification
|
|
172
220
|
# @param [String, Symbol] optional_target_name Class name of the optional target implementation (e.g. :amazon_sns, :slack)
|
|
173
|
-
# @param [Boolean] subscribe_as_default Default subscription value to use when the subscription record
|
|
221
|
+
# @param [Boolean] subscribe_as_default Default subscription value to use when the subscription record is not configured
|
|
174
222
|
# @return [Boolean] If the target subscribes to the specified optional target
|
|
175
223
|
def _subscribes_to_optional_target?(key, optional_target_name, subscribe_as_default = ActivityNotification.config.subscribe_to_optional_targets_as_default)
|
|
224
|
+
subscription = _find_key_level_subscription(key)
|
|
176
225
|
_subscribes_to_notification?(key, subscribe_as_default) &&
|
|
177
|
-
evaluate_subscription(
|
|
226
|
+
evaluate_subscription(subscription, :subscribing_to_optional_target?, subscribe_as_default, optional_target_name, subscribe_as_default)
|
|
178
227
|
end
|
|
179
228
|
|
|
180
229
|
private
|
|
181
230
|
|
|
231
|
+
# Finds a key-level subscription (where notifiable is nil) for the given key.
|
|
232
|
+
# @api private
|
|
233
|
+
# @param [String] key Key of the notification
|
|
234
|
+
# @return [Subscription, nil] Key-level subscription record or nil
|
|
235
|
+
def _find_key_level_subscription(key)
|
|
236
|
+
find_subscription(key, notifiable: nil)
|
|
237
|
+
end
|
|
238
|
+
|
|
182
239
|
# Returns if the target subscribes.
|
|
183
240
|
# @api private
|
|
184
241
|
# @param [Boolean] record Subscription record
|
|
185
242
|
# @param [Symbol] field Evaluating subscription field or method of the record
|
|
186
|
-
# @param [Boolean] default Default subscription value to use when the subscription record
|
|
243
|
+
# @param [Boolean] default Default subscription value to use when the subscription record is not configured
|
|
187
244
|
# @param [Array] args Arguments of evaluating subscription method
|
|
188
245
|
# @return [Boolean] If the target subscribes
|
|
189
246
|
def evaluate_subscription(record, field, default, *args)
|