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
|
@@ -9,7 +9,7 @@ module ActivityNotification
|
|
|
9
9
|
|
|
10
10
|
# Has many notification instances of this target.
|
|
11
11
|
# @scope instance
|
|
12
|
-
# @return [Array<
|
|
12
|
+
# @return [Array<Notification>, Mongoid::Criteria<Notification>] Array or database query of notifications of this target
|
|
13
13
|
has_many_records :notifications,
|
|
14
14
|
class_name: "::ActivityNotification::Notification",
|
|
15
15
|
as: :target,
|
|
@@ -64,7 +64,7 @@ module ActivityNotification
|
|
|
64
64
|
# @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
|
|
65
65
|
# @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
|
|
66
66
|
# @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
|
|
67
|
-
# @return [Array<
|
|
67
|
+
# @return [Array<Notification>] All notifications for this target type
|
|
68
68
|
def all_notifications(options = {})
|
|
69
69
|
reverse = options[:reverse] || false
|
|
70
70
|
with_group_members = options[:with_group_members] || false
|
|
@@ -106,7 +106,7 @@ module ActivityNotification
|
|
|
106
106
|
# @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
|
|
107
107
|
# @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
|
|
108
108
|
# @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
|
|
109
|
-
# @return [Hash<Target,
|
|
109
|
+
# @return [Hash<Target, Notification>] All notifications for this target type grouped by targets
|
|
110
110
|
def notification_index_map(options = {})
|
|
111
111
|
all_notifications(options).group_by(&:target)
|
|
112
112
|
end
|
|
@@ -143,7 +143,7 @@ module ActivityNotification
|
|
|
143
143
|
end
|
|
144
144
|
|
|
145
145
|
# Resolves current authenticated target by devise authentication from current resource signed in with Devise.
|
|
146
|
-
# This method
|
|
146
|
+
# This method can be overridden.
|
|
147
147
|
#
|
|
148
148
|
# @param [Object] current_resource Current resource signed in with Devise
|
|
149
149
|
# @return [Object] Current authenticated target by devise authentication
|
|
@@ -160,7 +160,7 @@ module ActivityNotification
|
|
|
160
160
|
end
|
|
161
161
|
|
|
162
162
|
# Returns target email address for email notification.
|
|
163
|
-
# This method
|
|
163
|
+
# This method can be overridden.
|
|
164
164
|
#
|
|
165
165
|
# @return [String] Target email address
|
|
166
166
|
def mailer_to
|
|
@@ -168,7 +168,7 @@ module ActivityNotification
|
|
|
168
168
|
end
|
|
169
169
|
|
|
170
170
|
# Returns if sending notification email is allowed for the target from configured field or overridden method.
|
|
171
|
-
# This method
|
|
171
|
+
# This method can be overridden.
|
|
172
172
|
#
|
|
173
173
|
# @param [Object] notifiable Notifiable instance of the notification
|
|
174
174
|
# @param [String] key Key of the notification
|
|
@@ -178,7 +178,7 @@ module ActivityNotification
|
|
|
178
178
|
end
|
|
179
179
|
|
|
180
180
|
# Returns if sending batch notification email is allowed for the target from configured field or overridden method.
|
|
181
|
-
# This method
|
|
181
|
+
# This method can be overridden.
|
|
182
182
|
#
|
|
183
183
|
# @param [String] key Key of the notifications
|
|
184
184
|
# @return [Boolean] If sending batch notification email is allowed for the target
|
|
@@ -187,7 +187,7 @@ module ActivityNotification
|
|
|
187
187
|
end
|
|
188
188
|
|
|
189
189
|
# Returns if subscription management is allowed for the target from configured field or overridden method.
|
|
190
|
-
# This method
|
|
190
|
+
# This method can be overridden.
|
|
191
191
|
#
|
|
192
192
|
# @param [String] key Key of the notifications
|
|
193
193
|
# @return [Boolean] If subscription management is allowed for the target
|
|
@@ -197,7 +197,7 @@ module ActivityNotification
|
|
|
197
197
|
alias_method :notification_subscription_allowed?, :subscription_allowed?
|
|
198
198
|
|
|
199
199
|
# Returns if publishing WebSocket using ActionCable is allowed for the target from configured field or overridden method.
|
|
200
|
-
# This method
|
|
200
|
+
# This method can be overridden.
|
|
201
201
|
#
|
|
202
202
|
# @param [Object] notifiable Notifiable instance of the notification
|
|
203
203
|
# @param [String] key Key of the notification
|
|
@@ -228,7 +228,7 @@ module ActivityNotification
|
|
|
228
228
|
end
|
|
229
229
|
|
|
230
230
|
# Returns if current resource signed in with Devise is authenticated for the notification.
|
|
231
|
-
# This method
|
|
231
|
+
# This method can be overridden.
|
|
232
232
|
#
|
|
233
233
|
# @param [Object] current_resource Current resource signed in with Devise
|
|
234
234
|
# @return [Boolean] If current resource signed in with Devise is authenticated for the notification
|
|
@@ -288,8 +288,8 @@ module ActivityNotification
|
|
|
288
288
|
# Returns automatically arranged notification index of the target.
|
|
289
289
|
# This method is the typical way to get notification index from controller and view.
|
|
290
290
|
# When the target has unopened notifications, it returns unopened notifications first.
|
|
291
|
-
#
|
|
292
|
-
# @todo Is this
|
|
291
|
+
# Additionally, it returns opened notifications unless unopened index size overs the limit.
|
|
292
|
+
# @todo Is this combined array the best solution?
|
|
293
293
|
#
|
|
294
294
|
# @example Get automatically arranged notification index of @user
|
|
295
295
|
# @notifications = @user.notification_index
|
|
@@ -307,7 +307,7 @@ module ActivityNotification
|
|
|
307
307
|
# @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
|
|
308
308
|
# @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
|
|
309
309
|
# @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
|
|
310
|
-
# @return [Array<
|
|
310
|
+
# @return [Array<Notification>] Notification index of the target
|
|
311
311
|
def notification_index(options = {})
|
|
312
312
|
arrange_notification_index(method(:unopened_notification_index),
|
|
313
313
|
method(:opened_notification_index),
|
|
@@ -332,7 +332,7 @@ module ActivityNotification
|
|
|
332
332
|
# @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
|
|
333
333
|
# @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
|
|
334
334
|
# @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
|
|
335
|
-
# @return [Array<
|
|
335
|
+
# @return [Array<Notification>] Unopened notification index of the target
|
|
336
336
|
def unopened_notification_index(options = {})
|
|
337
337
|
arrange_single_notification_index(method(:_unopened_notification_index), options)
|
|
338
338
|
end
|
|
@@ -355,7 +355,7 @@ module ActivityNotification
|
|
|
355
355
|
# @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
|
|
356
356
|
# @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
|
|
357
357
|
# @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
|
|
358
|
-
# @return [Array<
|
|
358
|
+
# @return [Array<Notification>] Opened notification index of the target
|
|
359
359
|
def opened_notification_index(options = {})
|
|
360
360
|
arrange_single_notification_index(method(:_opened_notification_index), options)
|
|
361
361
|
end
|
|
@@ -374,7 +374,7 @@ module ActivityNotification
|
|
|
374
374
|
# @option options [Boolean] :send_email (true) Whether it sends notification email
|
|
375
375
|
# @option options [Boolean] :send_later (true) Whether it sends notification email asynchronously
|
|
376
376
|
# @option options [Boolean] :publish_optional_targets (true) Whether it publishes notification to optional targets
|
|
377
|
-
# @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
|
|
377
|
+
# @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
|
|
378
378
|
# @return [Notification] Generated notification instance
|
|
379
379
|
def receive_notification_of(notifiable, options = {})
|
|
380
380
|
Notification.notify_to(self, notifiable, options)
|
|
@@ -395,7 +395,7 @@ module ActivityNotification
|
|
|
395
395
|
# @option options [Boolean] :send_email (true) Whether it sends notification email
|
|
396
396
|
# @option options [Boolean] :send_later (true) Whether it sends notification email asynchronously
|
|
397
397
|
# @option options [Boolean] :publish_optional_targets (true) Whether it publishes notification to optional targets
|
|
398
|
-
# @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
|
|
398
|
+
# @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
|
|
399
399
|
# @return [Notification] Generated notification instance
|
|
400
400
|
def receive_notification_later_of(notifiable, options = {})
|
|
401
401
|
Notification.notify_later_to(self, notifiable, options)
|
|
@@ -439,7 +439,7 @@ module ActivityNotification
|
|
|
439
439
|
# Gets automatically arranged notification index of the target with included attributes like target, notifiable, group and notifier.
|
|
440
440
|
# This method is the typical way to get notifications index from controller of view.
|
|
441
441
|
# When the target have unopened notifications, it returns unopened notifications first.
|
|
442
|
-
#
|
|
442
|
+
# Additionally, it returns opened notifications unless unopened index size overs the limit.
|
|
443
443
|
# @todo Is this switching the best solution?
|
|
444
444
|
#
|
|
445
445
|
# @example Get automatically arranged notification index of the @user with included attributes
|
|
@@ -461,7 +461,7 @@ module ActivityNotification
|
|
|
461
461
|
# @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
|
|
462
462
|
# @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
|
|
463
463
|
# @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
|
|
464
|
-
# @return [Array<
|
|
464
|
+
# @return [Array<Notification>] Notification index of the target with attributes
|
|
465
465
|
def notification_index_with_attributes(options = {})
|
|
466
466
|
arrange_notification_index(method(:unopened_notification_index_with_attributes),
|
|
467
467
|
method(:opened_notification_index_with_attributes),
|
|
@@ -486,7 +486,7 @@ module ActivityNotification
|
|
|
486
486
|
# @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
|
|
487
487
|
# @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
|
|
488
488
|
# @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
|
|
489
|
-
# @return [Array<
|
|
489
|
+
# @return [Array<Notification>] Unopened notification index of the target with attributes
|
|
490
490
|
def unopened_notification_index_with_attributes(options = {})
|
|
491
491
|
include_attributes(_unopened_notification_index(options)).to_a
|
|
492
492
|
end
|
|
@@ -509,7 +509,7 @@ module ActivityNotification
|
|
|
509
509
|
# @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
|
|
510
510
|
# @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
|
|
511
511
|
# @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
|
|
512
|
-
# @return [Array<
|
|
512
|
+
# @return [Array<Notification>] Opened notification index of the target with attributes
|
|
513
513
|
def opened_notification_index_with_attributes(options = {})
|
|
514
514
|
include_attributes(_opened_notification_index(options)).to_a
|
|
515
515
|
end
|
|
@@ -545,17 +545,20 @@ module ActivityNotification
|
|
|
545
545
|
# It also returns true when the subscription management is not allowed for the target.
|
|
546
546
|
#
|
|
547
547
|
# @param [String] key Key of the notification
|
|
548
|
-
# @param [Boolean] subscribe_as_default Default subscription value to use when the subscription record
|
|
548
|
+
# @param [Boolean] subscribe_as_default Default subscription value to use when the subscription record is not configured
|
|
549
|
+
# @param [Object] notifiable Optional notifiable instance for instance-level subscription check
|
|
549
550
|
# @return [Boolean] If the target subscribes the notification or the subscription management is not allowed for the target
|
|
550
|
-
def subscribes_to_notification?(key, subscribe_as_default = ActivityNotification.config.subscribe_as_default)
|
|
551
|
-
|
|
551
|
+
def subscribes_to_notification?(key, subscribe_as_default = ActivityNotification.config.subscribe_as_default, notifiable: nil)
|
|
552
|
+
return true unless subscription_allowed?(key)
|
|
553
|
+
_subscribes_to_notification?(key, subscribe_as_default) ||
|
|
554
|
+
(notifiable.present? && _subscribes_to_notification_for_instance?(key, notifiable))
|
|
552
555
|
end
|
|
553
556
|
|
|
554
557
|
# Returns if the target subscribes to the notification email.
|
|
555
558
|
# It also returns true when the subscription management is not allowed for the target.
|
|
556
559
|
#
|
|
557
560
|
# @param [String] key Key of the notification
|
|
558
|
-
# @param [Boolean] subscribe_as_default Default subscription value to use when the subscription record
|
|
561
|
+
# @param [Boolean] subscribe_as_default Default subscription value to use when the subscription record is not configured
|
|
559
562
|
# @return [Boolean] If the target subscribes the notification email or the subscription management is not allowed for the target
|
|
560
563
|
def subscribes_to_notification_email?(key, subscribe_as_default = ActivityNotification.config.subscribe_to_email_as_default)
|
|
561
564
|
!subscription_allowed?(key) || _subscribes_to_notification_email?(key, subscribe_as_default)
|
|
@@ -567,7 +570,7 @@ module ActivityNotification
|
|
|
567
570
|
#
|
|
568
571
|
# @param [String] key Key of the notification
|
|
569
572
|
# @param [String, Symbol] optional_target_name Class name of the optional target implementation (e.g. :amazon_sns, :slack)
|
|
570
|
-
# @param [Boolean] subscribe_as_default Default subscription value to use when the subscription record
|
|
573
|
+
# @param [Boolean] subscribe_as_default Default subscription value to use when the subscription record is not configured
|
|
571
574
|
# @return [Boolean] If the target subscribes the notification email or the subscription management is not allowed for the target
|
|
572
575
|
def subscribes_to_optional_target?(key, optional_target_name, subscribe_as_default = ActivityNotification.config.subscribe_to_optional_targets_as_default)
|
|
573
576
|
!subscription_allowed?(key) || _subscribes_to_optional_target?(key, optional_target_name, subscribe_as_default)
|
|
@@ -590,7 +593,7 @@ module ActivityNotification
|
|
|
590
593
|
# @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
|
|
591
594
|
# @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
|
|
592
595
|
# @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
|
|
593
|
-
# @return [ActiveRecord_AssociationRelation<
|
|
596
|
+
# @return [ActiveRecord_AssociationRelation<Notification>|Mongoid::Criteria<Notification>|Dynamoid::Criteria::Chain] Unopened notification index of the target
|
|
594
597
|
def _unopened_notification_index(options = {})
|
|
595
598
|
reverse = options[:reverse] || false
|
|
596
599
|
with_group_members = options[:with_group_members] || false
|
|
@@ -612,7 +615,7 @@ module ActivityNotification
|
|
|
612
615
|
# @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
|
|
613
616
|
# @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
|
|
614
617
|
# @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
|
|
615
|
-
# @return [ActiveRecord_AssociationRelation<
|
|
618
|
+
# @return [ActiveRecord_AssociationRelation<Notification>|Mongoid::Criteria<Notification>|Dynamoid::Criteria::Chain] Opened notification index of the target
|
|
616
619
|
def _opened_notification_index(options = {})
|
|
617
620
|
limit = options[:limit] || ActivityNotification.config.opened_index_limit
|
|
618
621
|
reverse = options[:reverse] || false
|
|
@@ -622,11 +625,11 @@ module ActivityNotification
|
|
|
622
625
|
|
|
623
626
|
# Includes attributes like target, notifiable, group or notifier from the notification index.
|
|
624
627
|
# When group member exists in the notification index, group will be included in addition to target, notifiable and or notifier.
|
|
625
|
-
# Otherwise, target, notifiable and or notifier will be
|
|
628
|
+
# Otherwise, target, notifiable and or notifier will be included without group.
|
|
626
629
|
# @api private
|
|
627
630
|
#
|
|
628
|
-
# @param [ActiveRecord_AssociationRelation<
|
|
629
|
-
# @return [ActiveRecord_AssociationRelation<
|
|
631
|
+
# @param [ActiveRecord_AssociationRelation<Notification>|Mongoid::Criteria<Notification>|Dynamoid::Criteria::Chain] target_index Notification index
|
|
632
|
+
# @return [ActiveRecord_AssociationRelation<Notification>|Mongoid::Criteria<Notification>|Dynamoid::Criteria::Chain] Notification index with attributes
|
|
630
633
|
def include_attributes(target_index)
|
|
631
634
|
if target_index.present?
|
|
632
635
|
Notification.group_member_exists?(target_index.to_a) ?
|
|
@@ -654,7 +657,7 @@ module ActivityNotification
|
|
|
654
657
|
# @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
|
|
655
658
|
# @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
|
|
656
659
|
# @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
|
|
657
|
-
# @return [Array<
|
|
660
|
+
# @return [Array<Notification>] Notification index of the target
|
|
658
661
|
def arrange_single_notification_index(loading_index_method, options = {})
|
|
659
662
|
as_latest_group_member = options[:as_latest_group_member] || false
|
|
660
663
|
as_latest_group_member ?
|
|
@@ -664,7 +667,7 @@ module ActivityNotification
|
|
|
664
667
|
|
|
665
668
|
# Gets automatically arranged notification index of the target.
|
|
666
669
|
# When the target have unopened notifications, it returns unopened notifications first.
|
|
667
|
-
#
|
|
670
|
+
# Additionally, it returns opened notifications unless unopened index size overs the limit.
|
|
668
671
|
# @api private
|
|
669
672
|
# @todo Is this switching the best solution?
|
|
670
673
|
#
|
|
@@ -683,7 +686,7 @@ module ActivityNotification
|
|
|
683
686
|
# @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
|
|
684
687
|
# @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
|
|
685
688
|
# @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
|
|
686
|
-
# @return [Array<
|
|
689
|
+
# @return [Array<Notification>] Notification index of the target
|
|
687
690
|
def arrange_notification_index(loading_unopened_index_method, loading_opened_index_method, options = {})
|
|
688
691
|
# When the target have unopened notifications
|
|
689
692
|
if has_unopened_notifications?(options)
|
|
@@ -691,7 +694,7 @@ module ActivityNotification
|
|
|
691
694
|
target_unopened_index = arrange_single_notification_index(loading_unopened_index_method, options)
|
|
692
695
|
# Total limit of notification index
|
|
693
696
|
total_limit = options[:limit] || ActivityNotification.config.opened_index_limit
|
|
694
|
-
#
|
|
697
|
+
# Additionally, return opened notifications unless unopened index size overs the limit
|
|
695
698
|
if (opened_limit = total_limit - target_unopened_index.size) > 0
|
|
696
699
|
target_opened_index = arrange_single_notification_index(loading_opened_index_method, options.merge(limit: opened_limit))
|
|
697
700
|
target_unopened_index.concat(target_opened_index.to_a)
|
|
@@ -57,7 +57,7 @@ module ActivityNotification
|
|
|
57
57
|
}
|
|
58
58
|
end
|
|
59
59
|
|
|
60
|
-
#
|
|
60
|
+
# Overridden rendering notification message using format_message
|
|
61
61
|
# @param [Notification] notification Notification instance
|
|
62
62
|
# @param [Hash] options Options for rendering
|
|
63
63
|
# @return [String] Rendered json formatted message to broadcast
|
|
@@ -6,7 +6,7 @@ module ActivityNotification
|
|
|
6
6
|
|
|
7
7
|
# Initialize method to prepare Slack::Notifier
|
|
8
8
|
# @param [Hash] options Options for initializing
|
|
9
|
-
# @option options [String, Proc, Symbol] :target_username (nil) Target
|
|
9
|
+
# @option options [String, Proc, Symbol] :target_username (nil) Target username of Slack, it resolved by target instance like email_allowed?
|
|
10
10
|
# @option options [required, String] :webhook_url (nil) Webhook URL of Slack Incoming WebHooks integration
|
|
11
11
|
# @option options [Hash] others Other options to be set Slack::Notifier.new, like :channel, :username, :icon_emoji etc
|
|
12
12
|
def initialize_target(options = {})
|
|
@@ -17,7 +17,7 @@ module ActivityNotification
|
|
|
17
17
|
# Publishes notification message to Slack
|
|
18
18
|
# @param [Notification] notification Notification instance
|
|
19
19
|
# @param [Hash] options Options for publishing
|
|
20
|
-
# @option options [String, Proc, Symbol] :target_username (nil) Target
|
|
20
|
+
# @option options [String, Proc, Symbol] :target_username (nil) Target username of Slack, it resolved by target instance like email_allowed?
|
|
21
21
|
# @option options [String] :partial_root ("activity_notification/optional_targets/#{target}/#{optional_target_name}", "activity_notification/optional_targets/#{target}/base", "activity_notification/optional_targets/default/#{optional_target_name}", "activity_notification/optional_targets/default/base") Partial template name
|
|
22
22
|
# @option options [String] :partial (self.key.tr('.', '/')) Root path of partial template
|
|
23
23
|
# @option options [String] :layout (nil) Layout template name
|
|
@@ -36,7 +36,7 @@ module ActivityNotification
|
|
|
36
36
|
# Only group owner instance has :group_members value.
|
|
37
37
|
# Group member instance has nil as :group_members association.
|
|
38
38
|
# @scope instance
|
|
39
|
-
# @return [ActiveRecord_AssociationRelation<
|
|
39
|
+
# @return [ActiveRecord_AssociationRelation<Notification>] Database query of the group member notification instances of this notification
|
|
40
40
|
has_many :group_members, class_name: "ActivityNotification::Notification", foreign_key: :group_owner_id
|
|
41
41
|
|
|
42
42
|
# Belongs to :notifier instance of this notification.
|
|
@@ -59,52 +59,52 @@ module ActivityNotification
|
|
|
59
59
|
|
|
60
60
|
# Selects group owner notifications only.
|
|
61
61
|
# @scope class
|
|
62
|
-
# @return [ActiveRecord_AssociationRelation<
|
|
62
|
+
# @return [ActiveRecord_AssociationRelation<Notification>] Database query of filtered notifications
|
|
63
63
|
scope :group_owners_only, -> { where(group_owner_id: nil) }
|
|
64
64
|
|
|
65
65
|
# Selects group member notifications only.
|
|
66
66
|
# @scope class
|
|
67
|
-
# @return [ActiveRecord_AssociationRelation<
|
|
67
|
+
# @return [ActiveRecord_AssociationRelation<Notification>] Database query of filtered notifications
|
|
68
68
|
scope :group_members_only, -> { where.not(group_owner_id: nil) }
|
|
69
69
|
|
|
70
70
|
# Selects unopened notifications only.
|
|
71
71
|
# @scope class
|
|
72
|
-
# @return [ActiveRecord_AssociationRelation<
|
|
72
|
+
# @return [ActiveRecord_AssociationRelation<Notification>] Database query of filtered notifications
|
|
73
73
|
scope :unopened_only, -> { where(opened_at: nil) }
|
|
74
74
|
|
|
75
75
|
# Selects opened notifications only without limit.
|
|
76
76
|
# Be careful to get too many records with this method.
|
|
77
77
|
# @scope class
|
|
78
|
-
# @return [ActiveRecord_AssociationRelation<
|
|
78
|
+
# @return [ActiveRecord_AssociationRelation<Notification>] Database query of filtered notifications
|
|
79
79
|
scope :opened_only!, -> { where.not(opened_at: nil) }
|
|
80
80
|
|
|
81
81
|
# Selects opened notifications only with limit.
|
|
82
82
|
# @scope class
|
|
83
83
|
# @param [Integer] limit Limit to query for opened notifications
|
|
84
|
-
# @return [ActiveRecord_AssociationRelation<
|
|
84
|
+
# @return [ActiveRecord_AssociationRelation<Notification>] Database query of filtered notifications
|
|
85
85
|
scope :opened_only, ->(limit) { opened_only!.limit(limit) }
|
|
86
86
|
|
|
87
87
|
# Selects group member notifications in unopened_index.
|
|
88
88
|
# @scope class
|
|
89
|
-
# @return [ActiveRecord_AssociationRelation<
|
|
89
|
+
# @return [ActiveRecord_AssociationRelation<Notification>] Database query of filtered notifications
|
|
90
90
|
scope :unopened_index_group_members_only, -> { where(group_owner_id: unopened_index.map(&:id)) }
|
|
91
91
|
|
|
92
92
|
# Selects group member notifications in opened_index.
|
|
93
93
|
# @scope class
|
|
94
94
|
# @param [Integer] limit Limit to query for opened notifications
|
|
95
|
-
# @return [ActiveRecord_AssociationRelation<
|
|
95
|
+
# @return [ActiveRecord_AssociationRelation<Notification>] Database query of filtered notifications
|
|
96
96
|
scope :opened_index_group_members_only, ->(limit) { where(group_owner_id: opened_index(limit).map(&:id)) }
|
|
97
97
|
|
|
98
98
|
# Selects notifications within expiration.
|
|
99
99
|
# @scope class
|
|
100
100
|
# @param [ActiveSupport::Duration] expiry_delay Expiry period of notifications
|
|
101
|
-
# @return [ActiveRecord_AssociationRelation<
|
|
101
|
+
# @return [ActiveRecord_AssociationRelation<Notification>] Database query of filtered notifications
|
|
102
102
|
scope :within_expiration_only, ->(expiry_delay) { where("created_at > ?", expiry_delay.ago) }
|
|
103
103
|
|
|
104
104
|
# Selects group member notifications with specified group owner ids.
|
|
105
105
|
# @scope class
|
|
106
106
|
# @param [Array<String>] owner_ids Array of group owner ids
|
|
107
|
-
# @return [ActiveRecord_AssociationRelation<
|
|
107
|
+
# @return [ActiveRecord_AssociationRelation<Notification>] Database query of filtered notifications
|
|
108
108
|
scope :group_members_of_owner_ids_only, ->(owner_ids) { where(group_owner_id: owner_ids) }
|
|
109
109
|
|
|
110
110
|
# Selects filtered notifications by target instance.
|
|
@@ -113,63 +113,63 @@ module ActivityNotification
|
|
|
113
113
|
# @user.notifications
|
|
114
114
|
# @scope class
|
|
115
115
|
# @param [Object] target Target instance for filter
|
|
116
|
-
# @return [ActiveRecord_AssociationRelation<
|
|
116
|
+
# @return [ActiveRecord_AssociationRelation<Notification>] Database query of filtered notifications
|
|
117
117
|
scope :filtered_by_target, ->(target) { where(target: target) }
|
|
118
118
|
|
|
119
119
|
# Selects filtered notifications by notifiable instance.
|
|
120
|
-
# @example Get filtered unopened
|
|
120
|
+
# @example Get filtered unopened notifications of the @user for @comment as notifiable
|
|
121
121
|
# @notifications = @user.notifications.unopened_only.filtered_by_instance(@comment)
|
|
122
122
|
# @scope class
|
|
123
123
|
# @param [Object] notifiable Notifiable instance for filter
|
|
124
|
-
# @return [ActiveRecord_AssociationRelation<
|
|
124
|
+
# @return [ActiveRecord_AssociationRelation<Notification>] Database query of filtered notifications
|
|
125
125
|
scope :filtered_by_instance, ->(notifiable) { where(notifiable: notifiable) }
|
|
126
126
|
|
|
127
127
|
# Selects filtered notifications by group instance.
|
|
128
|
-
# @example Get filtered unopened
|
|
128
|
+
# @example Get filtered unopened notifications of the @user for @article as group
|
|
129
129
|
# @notifications = @user.notifications.unopened_only.filtered_by_group(@article)
|
|
130
130
|
# @scope class
|
|
131
131
|
# @param [Object] group Group instance for filter
|
|
132
|
-
# @return [ActiveRecord_AssociationRelation<
|
|
132
|
+
# @return [ActiveRecord_AssociationRelation<Notification>] Database query of filtered notifications
|
|
133
133
|
scope :filtered_by_group, ->(group) { where(group: group) }
|
|
134
134
|
|
|
135
135
|
# Selects filtered notifications later than specified time.
|
|
136
|
-
# @example Get filtered unopened
|
|
136
|
+
# @example Get filtered unopened notifications of the @user later than @notification
|
|
137
137
|
# @notifications = @user.notifications.unopened_only.later_than(@notification.created_at)
|
|
138
138
|
# @scope class
|
|
139
139
|
# @param [Time] Created time of the notifications for filter
|
|
140
|
-
# @return [ActiveRecord_AssociationRelation<
|
|
140
|
+
# @return [ActiveRecord_AssociationRelation<Notification>, Mongoid::Criteria<Notification>] Database query of filtered notifications
|
|
141
141
|
scope :later_than, ->(created_time) { where('created_at > ?', created_time) }
|
|
142
142
|
|
|
143
143
|
# Selects filtered notifications earlier than specified time.
|
|
144
|
-
# @example Get filtered unopened
|
|
144
|
+
# @example Get filtered unopened notifications of the @user earlier than @notification
|
|
145
145
|
# @notifications = @user.notifications.unopened_only.earlier_than(@notification.created_at)
|
|
146
146
|
# @scope class
|
|
147
147
|
# @param [Time] Created time of the notifications for filter
|
|
148
|
-
# @return [ActiveRecord_AssociationRelation<
|
|
148
|
+
# @return [ActiveRecord_AssociationRelation<Notification>, Mongoid::Criteria<Notification>] Database query of filtered notifications
|
|
149
149
|
scope :earlier_than, ->(created_time) { where('created_at < ?', created_time) }
|
|
150
150
|
|
|
151
151
|
# Includes target instance with query for notifications.
|
|
152
|
-
# @return [ActiveRecord_AssociationRelation<
|
|
152
|
+
# @return [ActiveRecord_AssociationRelation<Notification>] Database query of notifications with target
|
|
153
153
|
scope :with_target, -> { includes(:target) }
|
|
154
154
|
|
|
155
155
|
# Includes notifiable instance with query for notifications.
|
|
156
|
-
# @return [ActiveRecord_AssociationRelation<
|
|
156
|
+
# @return [ActiveRecord_AssociationRelation<Notification>] Database query of notifications with notifiable
|
|
157
157
|
scope :with_notifiable, -> { includes(:notifiable) }
|
|
158
158
|
|
|
159
159
|
# Includes group instance with query for notifications.
|
|
160
|
-
# @return [ActiveRecord_AssociationRelation<
|
|
160
|
+
# @return [ActiveRecord_AssociationRelation<Notification>] Database query of notifications with group
|
|
161
161
|
scope :with_group, -> { includes(:group) }
|
|
162
162
|
|
|
163
163
|
# Includes group owner instances with query for notifications.
|
|
164
|
-
# @return [ActiveRecord_AssociationRelation<
|
|
164
|
+
# @return [ActiveRecord_AssociationRelation<Notification>] Database query of notifications with group owner
|
|
165
165
|
scope :with_group_owner, -> { includes(:group_owner) }
|
|
166
166
|
|
|
167
167
|
# Includes group member instances with query for notifications.
|
|
168
|
-
# @return [ActiveRecord_AssociationRelation<
|
|
168
|
+
# @return [ActiveRecord_AssociationRelation<Notification>] Database query of notifications with group members
|
|
169
169
|
scope :with_group_members, -> { includes(:group_members) }
|
|
170
170
|
|
|
171
171
|
# Includes notifier instance with query for notifications.
|
|
172
|
-
# @return [ActiveRecord_AssociationRelation<
|
|
172
|
+
# @return [ActiveRecord_AssociationRelation<Notification>] Database query of notifications with notifier
|
|
173
173
|
scope :with_notifier, -> { includes(:notifier) }
|
|
174
174
|
|
|
175
175
|
# Raise DeleteRestrictionError for notifications.
|
|
@@ -13,6 +13,13 @@ module ActivityNotification
|
|
|
13
13
|
# @return [Object] Target instance of this subscription
|
|
14
14
|
belongs_to :target, polymorphic: true
|
|
15
15
|
|
|
16
|
+
# Belongs to notifiable instance of this subscription as polymorphic association (optional).
|
|
17
|
+
# When present, this subscription is scoped to a specific notifiable instance.
|
|
18
|
+
# When nil, this is a key-level subscription that applies globally.
|
|
19
|
+
# @scope instance
|
|
20
|
+
# @return [Object, nil] Notifiable instance of this subscription
|
|
21
|
+
belongs_to :notifiable, polymorphic: true, optional: true
|
|
22
|
+
|
|
16
23
|
# Serialize parameters Hash
|
|
17
24
|
# :nocov:
|
|
18
25
|
if Rails.gem_version >= Gem::Version.new('7.1')
|
|
@@ -23,7 +30,7 @@ module ActivityNotification
|
|
|
23
30
|
# :nocov:
|
|
24
31
|
|
|
25
32
|
validates :target, presence: true
|
|
26
|
-
validates :key, presence: true, uniqueness: { scope: :
|
|
33
|
+
validates :key, presence: true, uniqueness: { scope: [:target_type, :target_id, :notifiable_type, :notifiable_id] }
|
|
27
34
|
validates_inclusion_of :subscribing, in: [true, false]
|
|
28
35
|
validates_inclusion_of :subscribing_to_email, in: [true, false]
|
|
29
36
|
validate :subscribing_to_email_cannot_be_true_when_subscribing_is_false
|
|
@@ -46,6 +53,19 @@ module ActivityNotification
|
|
|
46
53
|
# @return [ActiveRecord_AssociationRelation<Subscription>] Database query of subscriptions with target
|
|
47
54
|
scope :with_target, -> { includes(:target) }
|
|
48
55
|
|
|
56
|
+
# Selects key-level subscriptions only (where notifiable is nil).
|
|
57
|
+
# @return [ActiveRecord_AssociationRelation<Subscription>] Database query of key-level subscriptions
|
|
58
|
+
scope :key_level_only, -> { where(notifiable_type: nil) }
|
|
59
|
+
|
|
60
|
+
# Selects instance-level subscriptions only (where notifiable is present).
|
|
61
|
+
# @return [ActiveRecord_AssociationRelation<Subscription>] Database query of instance-level subscriptions
|
|
62
|
+
scope :instance_level_only, -> { where.not(notifiable_type: nil) }
|
|
63
|
+
|
|
64
|
+
# Selects subscriptions for a specific notifiable instance.
|
|
65
|
+
# @param [Object] notifiable Notifiable instance for filter
|
|
66
|
+
# @return [ActiveRecord_AssociationRelation<Subscription>] Database query of filtered subscriptions
|
|
67
|
+
scope :for_notifiable, ->(notifiable) { where(notifiable_type: notifiable.class.name, notifiable_id: notifiable.id) }
|
|
68
|
+
|
|
49
69
|
# Selects unique keys from query for subscriptions.
|
|
50
70
|
# @return [Array<String>] Array of subscription unique keys
|
|
51
71
|
def self.uniq_keys
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require 'dynamoid/adapter_plugin/aws_sdk_v3'
|
|
2
2
|
|
|
3
|
-
#
|
|
3
|
+
# Extend Dynamoid v3.1.0 to support none, limit, exists?, update_all, serializable_hash in Dynamoid::Criteria::Chain.
|
|
4
4
|
# ActivityNotification project will try to contribute these fundamental functions to Dynamoid upstream.
|
|
5
5
|
# @private
|
|
6
6
|
module Dynamoid # :nodoc: all
|
|
@@ -83,13 +83,13 @@ module Dynamoid # :nodoc: all
|
|
|
83
83
|
end
|
|
84
84
|
end
|
|
85
85
|
|
|
86
|
-
#
|
|
86
|
+
# Extend Dynamoid to support uniqueness validator
|
|
87
87
|
# @private
|
|
88
88
|
module Dynamoid # :nodoc: all
|
|
89
89
|
# https://github.com/Dynamoid/dynamoid/blob/master/lib/dynamoid/validations.rb
|
|
90
90
|
# @private
|
|
91
91
|
module Validations
|
|
92
|
-
# Validates whether
|
|
92
|
+
# Validates whether a field is unique against the records in the database.
|
|
93
93
|
class UniquenessValidator < ActiveModel::EachValidator
|
|
94
94
|
# Validate the document for uniqueness violations.
|
|
95
95
|
# @param [Document] document The document to validate.
|
|
@@ -19,6 +19,13 @@ module ActivityNotification
|
|
|
19
19
|
# @return [Object] Target instance of this subscription
|
|
20
20
|
belongs_to_composite_xdb_record :target
|
|
21
21
|
|
|
22
|
+
# Belongs to notifiable instance of this subscription as polymorphic association using composite key (optional).
|
|
23
|
+
# When present, this subscription is scoped to a specific notifiable instance.
|
|
24
|
+
# When nil, this is a key-level subscription that applies globally.
|
|
25
|
+
# @scope instance
|
|
26
|
+
# @return [Object, nil] Notifiable instance of this subscription
|
|
27
|
+
belongs_to_composite_xdb_record :notifiable, optional: true
|
|
28
|
+
|
|
22
29
|
field :key, :string
|
|
23
30
|
field :subscribing, :boolean, default: ActivityNotification.config.subscribe_as_default
|
|
24
31
|
field :subscribing_to_email, :boolean, default: ActivityNotification.config.subscribe_to_email_as_default
|
|
@@ -31,7 +38,7 @@ module ActivityNotification
|
|
|
31
38
|
global_secondary_index name: :index_target_key_created_at, hash_key: :target_key, range_key: :created_at, projected_attributes: :all
|
|
32
39
|
|
|
33
40
|
validates :target, presence: true
|
|
34
|
-
validates :key, presence: true, uniqueness: { scope: :target_key }
|
|
41
|
+
validates :key, presence: true, uniqueness: { scope: [:target_key, :notifiable_key] }
|
|
35
42
|
validates_inclusion_of :subscribing, in: [true, false]
|
|
36
43
|
validates_inclusion_of :subscribing_to_email, in: [true, false]
|
|
37
44
|
validate :subscribing_to_email_cannot_be_true_when_subscribing_is_false
|