activity_notification 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +23 -11
- data/Gemfile.lock +52 -40
- data/README.md +177 -14
- data/activity_notification.gemspec +3 -1
- data/app/controllers/activity_notification/subscriptions_controller.rb +48 -2
- data/app/views/activity_notification/optional_targets/default/base/_default.text.erb +10 -0
- data/app/views/activity_notification/optional_targets/default/slack/_default.text.erb +6 -0
- data/app/views/activity_notification/subscriptions/default/_notification_keys.html.erb +19 -0
- data/app/views/activity_notification/subscriptions/default/_subscription.html.erb +32 -3
- data/app/views/activity_notification/subscriptions/default/index.html.erb +4 -0
- data/app/views/activity_notification/subscriptions/default/show.html.erb +5 -0
- data/app/views/activity_notification/subscriptions/default/subscribe_to_optional_target.js.erb +6 -0
- data/app/views/activity_notification/subscriptions/default/unsubscribe_to_optional_target.js.erb +6 -0
- data/gemfiles/Gemfile.rails-4.2.lock +15 -3
- data/gemfiles/Gemfile.rails-5.0.lock +47 -35
- data/lib/activity_notification.rb +1 -0
- data/lib/activity_notification/apis/notification_api.rb +83 -26
- data/lib/activity_notification/apis/subscription_api.rb +93 -8
- data/lib/activity_notification/common.rb +6 -2
- data/lib/activity_notification/helpers/view_helpers.rb +43 -0
- data/lib/activity_notification/models/concerns/notifiable.rb +73 -28
- data/lib/activity_notification/models/concerns/subscriber.rb +34 -7
- data/lib/activity_notification/models/concerns/target.rb +25 -13
- data/lib/activity_notification/models/subscription.rb +13 -2
- data/lib/activity_notification/optional_targets/amazon_sns.rb +42 -0
- data/lib/activity_notification/optional_targets/base.rb +79 -0
- data/lib/activity_notification/optional_targets/slack.rb +33 -0
- data/lib/activity_notification/rails/routes.rb +30 -20
- data/lib/activity_notification/roles/acts_as_notifiable.rb +70 -11
- data/lib/activity_notification/version.rb +1 -1
- data/lib/generators/activity_notification/views_generator.rb +2 -2
- data/lib/generators/templates/migrations/migration.rb +2 -2
- data/spec/concerns/apis/notification_api_spec.rb +97 -0
- data/spec/concerns/apis/subscription_api_spec.rb +206 -41
- data/spec/concerns/common_spec.rb +7 -2
- data/spec/concerns/models/notifiable_spec.rb +88 -2
- data/spec/concerns/models/subscriber_spec.rb +114 -13
- data/spec/concerns/models/target_spec.rb +17 -0
- data/spec/controllers/subscriptions_controller_shared_examples.rb +251 -28
- data/spec/helpers/view_helpers_spec.rb +56 -0
- data/spec/optional_targets/amazon_sns_spec.rb +46 -0
- data/spec/optional_targets/base_spec.rb +43 -0
- data/spec/optional_targets/slack_spec.rb +46 -0
- data/spec/rails_app/app/controllers/comments_controller.rb +1 -0
- data/spec/rails_app/app/models/admin.rb +1 -2
- data/spec/rails_app/app/models/article.rb +2 -3
- data/spec/rails_app/app/models/comment.rb +19 -7
- data/spec/rails_app/app/views/activity_notification/optional_targets/admins/amazon_sns/comment/_default.text.erb +8 -0
- data/spec/rails_app/db/migrate/20160715050420_create_activity_notification_tables.rb +1 -1
- data/spec/rails_app/db/migrate/20160715050433_create_test_tables.rb +2 -0
- data/spec/rails_app/db/schema.rb +3 -1
- data/spec/rails_app/db/seeds.rb +1 -1
- data/spec/rails_app/lib/custom_optional_targets/console_output.rb +13 -0
- data/spec/rails_app/lib/custom_optional_targets/wrong_target.rb +10 -0
- data/spec/roles/acts_as_notifiable_spec.rb +124 -2
- metadata +49 -4
- data/spec/rails_app/app/models/notification.rb +0 -6
@@ -54,6 +54,7 @@ require 'activity_notification/helpers/view_helpers'
|
|
54
54
|
require 'activity_notification/controllers/common_controller'
|
55
55
|
require 'activity_notification/controllers/store_controller'
|
56
56
|
require 'activity_notification/controllers/devise_authentication_controller'
|
57
|
+
require 'activity_notification/optional_targets/base'
|
57
58
|
|
58
59
|
# Load role for models
|
59
60
|
require 'activity_notification/models'
|
@@ -24,13 +24,15 @@ module ActivityNotification
|
|
24
24
|
# @param [Symbol, String, Class] target_type Type of target
|
25
25
|
# @param [Object] notifiable Notifiable instance
|
26
26
|
# @param [Hash] options Options for notifications
|
27
|
-
# @option options [String] :key
|
28
|
-
# @option options [Object] :group
|
29
|
-
# @option options [ActiveSupport::Duration] :group_expiry_delay
|
30
|
-
# @option options [Object] :notifier
|
31
|
-
# @option options [Hash] :parameters
|
32
|
-
# @option options [Boolean] :send_email
|
33
|
-
# @option options [Boolean] :send_later
|
27
|
+
# @option options [String] :key (notifiable.default_notification_key) Key of the notification
|
28
|
+
# @option options [Object] :group (nil) Group unit of the notifications
|
29
|
+
# @option options [ActiveSupport::Duration] :group_expiry_delay (nil) Expiry period of a notification group
|
30
|
+
# @option options [Object] :notifier (nil) Notifier of the notifications
|
31
|
+
# @option options [Hash] :parameters ({}) Additional parameters of the notifications
|
32
|
+
# @option options [Boolean] :send_email (true) Whether it sends notification email
|
33
|
+
# @option options [Boolean] :send_later (true) Whether it sends notification email asynchronously
|
34
|
+
# @option options [Boolean] :publish_optional_targets (true) Whether it publishes notification to optional targets
|
35
|
+
# @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
|
34
36
|
# @return [Array<Notificaion>] Array of generated notifications
|
35
37
|
def notify(target_type, notifiable, options = {})
|
36
38
|
targets = notifiable.notification_targets(target_type, options[:key])
|
@@ -47,13 +49,15 @@ module ActivityNotification
|
|
47
49
|
# @param [Array<Object>] targets Targets to send notifications
|
48
50
|
# @param [Object] notifiable Notifiable instance
|
49
51
|
# @param [Hash] options Options for notifications
|
50
|
-
# @option options [String] :key
|
51
|
-
# @option options [Object] :group
|
52
|
-
# @option options [ActiveSupport::Duration] :group_expiry_delay
|
53
|
-
# @option options [Object] :notifier
|
54
|
-
# @option options [Hash] :parameters
|
55
|
-
# @option options [Boolean] :send_email
|
56
|
-
# @option options [Boolean] :send_later
|
52
|
+
# @option options [String] :key (notifiable.default_notification_key) Key of the notification
|
53
|
+
# @option options [Object] :group (nil) Group unit of the notifications
|
54
|
+
# @option options [ActiveSupport::Duration] :group_expiry_delay (nil) Expiry period of a notification group
|
55
|
+
# @option options [Object] :notifier (nil) Notifier of the notifications
|
56
|
+
# @option options [Hash] :parameters ({}) Additional parameters of the notifications
|
57
|
+
# @option options [Boolean] :send_email (true) Whether it sends notification email
|
58
|
+
# @option options [Boolean] :send_later (true) Whether it sends notification email asynchronously
|
59
|
+
# @option options [Boolean] :publish_optional_targets (true) Whether it publishes notification to optional targets
|
60
|
+
# @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
|
57
61
|
# @return [Array<Notificaion>] Array of generated notifications
|
58
62
|
def notify_all(targets, notifiable, options = {})
|
59
63
|
targets.map { |target| target.notify_to(notifiable, options) }
|
@@ -67,23 +71,30 @@ module ActivityNotification
|
|
67
71
|
# @param [Object] target Target to send notifications
|
68
72
|
# @param [Object] notifiable Notifiable instance
|
69
73
|
# @param [Hash] options Options for notifications
|
70
|
-
# @option options [String] :key
|
71
|
-
# @option options [Object] :group
|
72
|
-
# @option options [ActiveSupport::Duration] :group_expiry_delay
|
73
|
-
# @option options [Object] :notifier
|
74
|
-
# @option options [Hash] :parameters
|
75
|
-
# @option options [Boolean] :send_email
|
76
|
-
# @option options [Boolean] :send_later
|
74
|
+
# @option options [String] :key (notifiable.default_notification_key) Key of the notification
|
75
|
+
# @option options [Object] :group (nil) Group unit of the notifications
|
76
|
+
# @option options [ActiveSupport::Duration] :group_expiry_delay (nil) Expiry period of a notification group
|
77
|
+
# @option options [Object] :notifier (nil) Notifier of the notifications
|
78
|
+
# @option options [Hash] :parameters ({}) Additional parameters of the notifications
|
79
|
+
# @option options [Boolean] :send_email (true) Whether it sends notification email
|
80
|
+
# @option options [Boolean] :send_later (true) Whether it sends notification email asynchronously
|
81
|
+
# @option options [Boolean] :publish_optional_targets (true) Whether it publishes notification to optional targets
|
82
|
+
# @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
|
77
83
|
# @return [Notification] Generated notification instance
|
78
84
|
def notify_to(target, notifiable, options = {})
|
79
|
-
send_email
|
80
|
-
send_later
|
85
|
+
send_email = options.has_key?(:send_email) ? options[:send_email] : true
|
86
|
+
send_later = options.has_key?(:send_later) ? options[:send_later] : true
|
87
|
+
publish_optional_targets = options.has_key?(:publish_optional_targets) ? options[:publish_optional_targets] : true
|
81
88
|
# Generate notification
|
82
89
|
notification = generate_notification(target, notifiable, options)
|
83
90
|
# Send notification email
|
84
91
|
if notification.present? && send_email
|
85
92
|
notification.send_notification_email({ send_later: send_later })
|
86
93
|
end
|
94
|
+
# Publish to optional targets
|
95
|
+
if notification.present? && publish_optional_targets
|
96
|
+
notification.publish_to_optional_targets(options[:optional_targets] || {})
|
97
|
+
end
|
87
98
|
# Return generated notification
|
88
99
|
notification
|
89
100
|
end
|
@@ -192,8 +203,8 @@ module ActivityNotification
|
|
192
203
|
# @return [Mail::Message, ActionMailer::DeliveryJob] Email message or its delivery job
|
193
204
|
def send_notification_email(options = {})
|
194
205
|
if target.notification_email_allowed?(notifiable, key) &&
|
195
|
-
|
196
|
-
|
206
|
+
notifiable.notification_email_allowed?(target, key) &&
|
207
|
+
email_subscribed?
|
197
208
|
send_later = options.has_key?(:send_later) ? options[:send_later] : true
|
198
209
|
send_later ?
|
199
210
|
Mailer.send_notification_email(self, options).deliver_later :
|
@@ -201,6 +212,22 @@ module ActivityNotification
|
|
201
212
|
end
|
202
213
|
end
|
203
214
|
|
215
|
+
# Publishes notification to the optional targets.
|
216
|
+
#
|
217
|
+
# @param [Hash] options Options for optional targets
|
218
|
+
# @return [Hash] Result of publishing to optional target
|
219
|
+
def publish_to_optional_targets(options = {})
|
220
|
+
notifiable.optional_targets(target.to_resources_name, key).map { |optional_target|
|
221
|
+
optional_target_name = optional_target.to_optional_target_name
|
222
|
+
if optional_target_subscribed?(optional_target_name)
|
223
|
+
optional_target.notify(self, options[optional_target_name] || {})
|
224
|
+
[optional_target_name, true]
|
225
|
+
else
|
226
|
+
[optional_target_name, false]
|
227
|
+
end
|
228
|
+
}.to_h
|
229
|
+
end
|
230
|
+
|
204
231
|
# Opens the notification.
|
205
232
|
#
|
206
233
|
# @param [Hash] options Options for opening notifications
|
@@ -311,6 +338,18 @@ module ActivityNotification
|
|
311
338
|
notification.group_member_exists? ? notification.group_members.latest : self
|
312
339
|
end
|
313
340
|
|
341
|
+
# Remove from notification group and make a new group owner.
|
342
|
+
#
|
343
|
+
# @return [Notificaion] New group owner instance of the notification group
|
344
|
+
def remove_from_group
|
345
|
+
new_group_owner = group_members.earliest
|
346
|
+
if new_group_owner.present?
|
347
|
+
new_group_owner.update(group_owner_id: nil)
|
348
|
+
group_members.update_all(group_owner_id: new_group_owner)
|
349
|
+
end
|
350
|
+
new_group_owner
|
351
|
+
end
|
352
|
+
|
314
353
|
# Returns notifiable_path to move after opening notification with notifiable.notifiable_path.
|
315
354
|
#
|
316
355
|
# @return [String] Notifiable path URL to move after opening notification
|
@@ -327,10 +366,28 @@ module ActivityNotification
|
|
327
366
|
|
328
367
|
# Returns if the target subscribes this notification email.
|
329
368
|
# @return [Boolean] If the target subscribes the notification
|
330
|
-
def email_subscribed?
|
369
|
+
def email_subscribed?
|
331
370
|
target.subscribes_to_notification_email?(key)
|
332
371
|
end
|
333
372
|
|
373
|
+
# Returns if the target subscribes this notification email.
|
374
|
+
# @param [String, Symbol] optional_target_name Class name of the optional target implementation (e.g. :amazon_sns, :slack)
|
375
|
+
# @return [Boolean] If the target subscribes the specified optional target of the notification
|
376
|
+
def optional_target_subscribed?(optional_target_name)
|
377
|
+
target.subscribes_to_optional_target?(key, optional_target_name)
|
378
|
+
end
|
379
|
+
|
380
|
+
# Returns optional_targets of the notification from configured field or overriden method.
|
381
|
+
# @return [Array<ActivityNotification::OptionalTarget::Base>] Array of optional target instances
|
382
|
+
def optional_targets
|
383
|
+
notifiable.optional_targets(target.to_resources_name, key)
|
384
|
+
end
|
385
|
+
|
386
|
+
# Returns optional_target names of the notification from configured field or overriden method.
|
387
|
+
# @return [Array<Symbol>] Array of optional target names
|
388
|
+
def optional_target_names
|
389
|
+
notifiable.optional_target_names(target.to_resources_name, key)
|
390
|
+
end
|
334
391
|
|
335
392
|
protected
|
336
393
|
|
@@ -3,33 +3,73 @@ module ActivityNotification
|
|
3
3
|
module SubscriptionApi
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
|
+
class_methods do
|
7
|
+
# Returns key of optional_targets hash from symbol class name of the optional target implementation.
|
8
|
+
# @param [String, Symbol] optional_target_name Class name of the optional target implementation (e.g. :amazon_sns, :slack)
|
9
|
+
# @return [Symbol] Key of optional_targets hash
|
10
|
+
def to_optional_target_key(optional_target_name)
|
11
|
+
("subscribing_to_" + optional_target_name.to_s).to_sym
|
12
|
+
end
|
13
|
+
|
14
|
+
# Returns subscribed_at parameter key of optional_targets hash from symbol class name of the optional target implementation.
|
15
|
+
# @param [String, Symbol] optional_target_name Class name of the optional target implementation (e.g. :amazon_sns, :slack)
|
16
|
+
# @return [Symbol] Subscribed_at parameter key of optional_targets hash
|
17
|
+
def to_optional_target_subscribed_at_key(optional_target_name)
|
18
|
+
("subscribed_to_" + optional_target_name.to_s + "_at").to_sym
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns unsubscribed_at parameter key of optional_targets hash from symbol class name of the optional target implementation.
|
22
|
+
# @param [String, Symbol] optional_target_name Class name of the optional target implementation (e.g. :amazon_sns, :slack)
|
23
|
+
# @return [Symbol] Unsubscribed_at parameter key of optional_targets hash
|
24
|
+
def to_optional_target_unsubscribed_at_key(optional_target_name)
|
25
|
+
("unsubscribed_to_" + optional_target_name.to_s + "_at").to_sym
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
6
29
|
# Subscribes to the notification and notification email.
|
7
30
|
#
|
8
|
-
# @param [Hash] options Options for subscribing notification
|
31
|
+
# @param [Hash] options Options for subscribing to the notification
|
9
32
|
# @option options [DateTime] :subscribed_at (Time.current) Time to set to subscribed_at and subscribed_to_email_at of the subscription record
|
10
33
|
# @option options [Boolean] :with_email_subscription (true) If the subscriber also subscribes notification email
|
34
|
+
# @option options [Boolean] :with_optional_targets (true) If the subscriber also subscribes optional_targets
|
11
35
|
# @return [Boolean] If successfully updated subscription instance
|
12
36
|
def subscribe(options = {})
|
13
37
|
subscribed_at = options[:subscribed_at] || Time.current
|
14
38
|
with_email_subscription = options.has_key?(:with_email_subscription) ? options[:with_email_subscription] : true
|
15
|
-
|
16
|
-
|
17
|
-
|
39
|
+
with_optional_targets = options.has_key?(:with_optional_targets) ? options[:with_optional_targets] : true
|
40
|
+
new_attributes = { subscribing: true, subscribed_at: subscribed_at, optional_targets: optional_targets }
|
41
|
+
new_attributes = new_attributes.merge(subscribing_to_email: true, subscribed_to_email_at: subscribed_at) if with_email_subscription
|
42
|
+
if with_optional_targets
|
43
|
+
optional_target_names.each do |optional_target_name|
|
44
|
+
new_attributes[:optional_targets] = new_attributes[:optional_targets].merge(
|
45
|
+
Subscription.to_optional_target_key(optional_target_name) => true,
|
46
|
+
Subscription.to_optional_target_subscribed_at_key(optional_target_name) => subscribed_at)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
update(new_attributes)
|
18
50
|
end
|
19
51
|
|
20
52
|
# Unsubscribes to the notification and notification email.
|
21
53
|
#
|
22
|
-
# @param [Hash] options Options for unsubscribing notification
|
54
|
+
# @param [Hash] options Options for unsubscribing to the notification
|
23
55
|
# @option options [DateTime] :unsubscribed_at (Time.current) Time to set to unsubscribed_at and unsubscribed_to_email_at of the subscription record
|
24
56
|
# @return [Boolean] If successfully updated subscription instance
|
25
57
|
def unsubscribe(options = {})
|
26
58
|
unsubscribed_at = options[:unsubscribed_at] || Time.current
|
27
|
-
|
59
|
+
new_attributes = { subscribing: false, unsubscribed_at: unsubscribed_at,
|
60
|
+
subscribing_to_email: false, unsubscribed_to_email_at: unsubscribed_at,
|
61
|
+
optional_targets: optional_targets }
|
62
|
+
optional_target_names.each do |optional_target_name|
|
63
|
+
new_attributes[:optional_targets] = new_attributes[:optional_targets].merge(
|
64
|
+
Subscription.to_optional_target_key(optional_target_name) => false,
|
65
|
+
Subscription.to_optional_target_unsubscribed_at_key(optional_target_name) => subscribed_at)
|
66
|
+
end
|
67
|
+
update(new_attributes)
|
28
68
|
end
|
29
69
|
|
30
70
|
# Subscribes to the notification email.
|
31
71
|
#
|
32
|
-
# @param [Hash] options Options for subscribing notification email
|
72
|
+
# @param [Hash] options Options for subscribing to the notification email
|
33
73
|
# @option options [DateTime] :subscribed_to_email_at (Time.current) Time to set to subscribed_to_email_at of the subscription record
|
34
74
|
# @return [Boolean] If successfully updated subscription instance
|
35
75
|
def subscribe_to_email(options = {})
|
@@ -39,7 +79,7 @@ module ActivityNotification
|
|
39
79
|
|
40
80
|
# Unsubscribes to the notification email.
|
41
81
|
#
|
42
|
-
# @param [Hash] options Options for unsubscribing notification email
|
82
|
+
# @param [Hash] options Options for unsubscribing the notification email
|
43
83
|
# @option options [DateTime] :subscribed_to_email_at (Time.current) Time to set to subscribed_to_email_at of the subscription record
|
44
84
|
# @return [Boolean] If successfully updated subscription instance
|
45
85
|
def unsubscribe_to_email(options = {})
|
@@ -47,5 +87,50 @@ module ActivityNotification
|
|
47
87
|
update(subscribing_to_email: false, unsubscribed_to_email_at: unsubscribed_to_email_at)
|
48
88
|
end
|
49
89
|
|
90
|
+
# Returns if the target subscribes to the specified optional target.
|
91
|
+
#
|
92
|
+
# @param [Symbol] optional_target_name Symbol class name of the optional target implementation (e.g. :amazon_sns, :slack)
|
93
|
+
# @param [Boolean] subscribe_as_default Default subscription value to use when the subscription record does not configured
|
94
|
+
# @return [Boolean] If the target subscribes to the specified optional target
|
95
|
+
def subscribing_to_optional_target?(optional_target_name, subscribe_as_default = ActivityNotification.config.subscribe_as_default)
|
96
|
+
optional_target_key = Subscription.to_optional_target_key(optional_target_name)
|
97
|
+
subscribe_as_default ?
|
98
|
+
!optional_targets.has_key?(optional_target_key) || optional_targets[optional_target_key] :
|
99
|
+
optional_targets.has_key?(optional_target_key) && optional_targets[optional_target_key]
|
100
|
+
end
|
101
|
+
|
102
|
+
# Subscribes to the specified optional target.
|
103
|
+
#
|
104
|
+
# @param [String, Symbol] optional_target_name Symbol class name of the optional target implementation (e.g. :amazon_sns, :slack)
|
105
|
+
# @param [Hash] options Options for unsubscribing to the specified optional target
|
106
|
+
# @option options [DateTime] :subscribed_at (Time.current) Time to set to subscribed_[optional_target_name]_at in optional_targets hash of the subscription record
|
107
|
+
# @return [Boolean] If successfully updated subscription instance
|
108
|
+
def subscribe_to_optional_target(optional_target_name, options = {})
|
109
|
+
subscribed_at = options[:subscribed_at] || Time.current
|
110
|
+
update(optional_targets: optional_targets.merge(
|
111
|
+
Subscription.to_optional_target_key(optional_target_name) => true,
|
112
|
+
Subscription.to_optional_target_subscribed_at_key(optional_target_name) => subscribed_at)
|
113
|
+
)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Unsubscribes to the specified optional target.
|
117
|
+
#
|
118
|
+
# @param [String, Symbol] optional_target_name Class name of the optional target implementation (e.g. :amazon_sns, :slack)
|
119
|
+
# @param [Hash] options Options for unsubscribing to the specified optional target
|
120
|
+
# @option options [DateTime] :unsubscribed_at (Time.current) Time to set to unsubscribed_[optional_target_name]_at in optional_targets hash of the subscription record
|
121
|
+
# @return [Boolean] If successfully updated subscription instance
|
122
|
+
def unsubscribe_to_optional_target(optional_target_name, options = {})
|
123
|
+
unsubscribed_at = options[:unsubscribed_at] || Time.current
|
124
|
+
update(optional_targets: optional_targets.merge(
|
125
|
+
Subscription.to_optional_target_key(optional_target_name) => false,
|
126
|
+
Subscription.to_optional_target_unsubscribed_at_key(optional_target_name) => unsubscribed_at)
|
127
|
+
)
|
128
|
+
end
|
129
|
+
|
130
|
+
# Returns optional_target names of the subscription from optional_targets field.
|
131
|
+
# @return [Array<Symbol>] Array of optional target names
|
132
|
+
def optional_target_names
|
133
|
+
optional_targets.keys.select { |key| key.to_s.start_with?("subscribing_to_") }.map { |key| key.slice(15..-1) }
|
134
|
+
end
|
50
135
|
end
|
51
136
|
end
|
@@ -27,8 +27,10 @@ module ActivityNotification
|
|
27
27
|
thing.call(ActivityNotification.get_controller, context, *args)
|
28
28
|
elsif thing.arity > 1
|
29
29
|
thing.call(ActivityNotification.get_controller, context)
|
30
|
-
|
30
|
+
elsif thing.arity > 0
|
31
31
|
thing.call(context)
|
32
|
+
else
|
33
|
+
thing.call
|
32
34
|
end
|
33
35
|
when Hash
|
34
36
|
thing.dup.tap do |hash|
|
@@ -79,8 +81,10 @@ module ActivityNotification
|
|
79
81
|
when Proc
|
80
82
|
if thing.arity > 1
|
81
83
|
thing.call(self, *args)
|
82
|
-
|
84
|
+
elsif thing.arity > 0
|
83
85
|
thing.call(self)
|
86
|
+
else
|
87
|
+
thing.call
|
84
88
|
end
|
85
89
|
when Hash
|
86
90
|
thing.dup.tap do |hash|
|
@@ -243,6 +243,28 @@ module ActivityNotification
|
|
243
243
|
end
|
244
244
|
alias_method :unsubscribe_to_email_path_for, :unsubscribe_to_email_subscription_path_for
|
245
245
|
|
246
|
+
# Returns subscribe_to_optional_target_subscription_path for the target of specified subscription
|
247
|
+
#
|
248
|
+
# @param [Subscription] subscription Subscription instance
|
249
|
+
# @param [Hash] params Request parameters
|
250
|
+
# @return [String] subscription_path for the subscription
|
251
|
+
# @todo Needs any other better implementation
|
252
|
+
def subscribe_to_optional_target_subscription_path_for(subscription, params = {})
|
253
|
+
send("subscribe_to_optional_target_#{subscription.target.to_resource_name}_subscription_path", subscription.target, subscription, params)
|
254
|
+
end
|
255
|
+
alias_method :subscribe_to_optional_target_path_for, :subscribe_to_optional_target_subscription_path_for
|
256
|
+
|
257
|
+
# Returns unsubscribe_to_optional_target_subscription_path for the target of specified subscription
|
258
|
+
#
|
259
|
+
# @param [Subscription] subscription Subscription instance
|
260
|
+
# @param [Hash] params Request parameters
|
261
|
+
# @return [String] subscription_path for the subscription
|
262
|
+
# @todo Needs any other better implementation
|
263
|
+
def unsubscribe_to_optional_target_subscription_path_for(subscription, params = {})
|
264
|
+
send("unsubscribe_to_optional_target_#{subscription.target.to_resource_name}_subscription_path", subscription.target, subscription, params)
|
265
|
+
end
|
266
|
+
alias_method :unsubscribe_to_optional_target_path_for, :unsubscribe_to_optional_target_subscription_path_for
|
267
|
+
|
246
268
|
# Returns subscriptions_url for the target
|
247
269
|
#
|
248
270
|
# @param [Object] target Target instance
|
@@ -307,6 +329,27 @@ module ActivityNotification
|
|
307
329
|
end
|
308
330
|
alias_method :unsubscribe_to_email_url_for, :unsubscribe_to_email_subscription_url_for
|
309
331
|
|
332
|
+
# Returns subscribe_to_optional_target_subscription_url for the target of specified subscription
|
333
|
+
#
|
334
|
+
# @param [Subscription] subscription Subscription instance
|
335
|
+
# @param [Hash] params Request parameters
|
336
|
+
# @return [String] subscription_url for the subscription
|
337
|
+
# @todo Needs any other better implementation
|
338
|
+
def subscribe_to_optional_target_subscription_url_for(subscription, params = {})
|
339
|
+
send("subscribe_to_optional_target_#{subscription.target.to_resource_name}_subscription_url", subscription.target, subscription, params)
|
340
|
+
end
|
341
|
+
alias_method :subscribe_to_optional_target_url_for, :subscribe_to_optional_target_subscription_url_for
|
342
|
+
|
343
|
+
# Returns unsubscribe_to_optional_target_subscription_url for the target of specified subscription
|
344
|
+
#
|
345
|
+
# @param [Subscription] subscription Subscription instance
|
346
|
+
# @param [Hash] params Request parameters
|
347
|
+
# @return [String] subscription_url for the subscription
|
348
|
+
# @todo Needs any other better implementation
|
349
|
+
def unsubscribe_to_optional_target_subscription_url_for(subscription, params = {})
|
350
|
+
send("unsubscribe_to_optional_target_#{subscription.target.to_resource_name}_subscription_url", subscription.target, subscription, params)
|
351
|
+
end
|
352
|
+
alias_method :unsubscribe_to_optional_target_url_for, :unsubscribe_to_optional_target_subscription_url_for
|
310
353
|
|
311
354
|
private
|
312
355
|
|
@@ -25,7 +25,8 @@ module ActivityNotification
|
|
25
25
|
:_notification_parameters,
|
26
26
|
:_notification_email_allowed,
|
27
27
|
:_notifiable_path,
|
28
|
-
:_printable_notifiable_name
|
28
|
+
:_printable_notifiable_name,
|
29
|
+
:_optional_targets
|
29
30
|
set_notifiable_class_defaults
|
30
31
|
end
|
31
32
|
|
@@ -53,6 +54,7 @@ module ActivityNotification
|
|
53
54
|
self._notification_email_allowed = {}
|
54
55
|
self._notifiable_path = {}
|
55
56
|
self._printable_notifiable_name = {}
|
57
|
+
self._optional_targets = {}
|
56
58
|
nil
|
57
59
|
end
|
58
60
|
end
|
@@ -68,7 +70,8 @@ module ActivityNotification
|
|
68
70
|
resolved_parameter = resolve_parameter(
|
69
71
|
target_typed_method_name,
|
70
72
|
_notification_targets[cast_to_resources_sym(target_type)],
|
71
|
-
nil,
|
73
|
+
nil,
|
74
|
+
key)
|
72
75
|
unless resolved_parameter
|
73
76
|
raise NotImplementedError, "You have to implement #{self.class}##{target_typed_method_name} "\
|
74
77
|
"or set :targets in acts_as_notifiable"
|
@@ -86,7 +89,8 @@ module ActivityNotification
|
|
86
89
|
resolve_parameter(
|
87
90
|
"notification_group_for_#{cast_to_resources_name(target_type)}",
|
88
91
|
_notification_group[cast_to_resources_sym(target_type)],
|
89
|
-
nil,
|
92
|
+
nil,
|
93
|
+
key)
|
90
94
|
end
|
91
95
|
|
92
96
|
# Returns group expiry period of the notifications from configured field or overriden method.
|
@@ -99,7 +103,8 @@ module ActivityNotification
|
|
99
103
|
resolve_parameter(
|
100
104
|
"notification_group_expiry_delay_for_#{cast_to_resources_name(target_type)}",
|
101
105
|
_notification_group_expiry_delay[cast_to_resources_sym(target_type)],
|
102
|
-
nil,
|
106
|
+
nil,
|
107
|
+
key)
|
103
108
|
end
|
104
109
|
|
105
110
|
# Returns additional notification parameters from configured field or overriden method.
|
@@ -112,7 +117,8 @@ module ActivityNotification
|
|
112
117
|
resolve_parameter(
|
113
118
|
"notification_parameters_for_#{cast_to_resources_name(target_type)}",
|
114
119
|
_notification_parameters[cast_to_resources_sym(target_type)],
|
115
|
-
{},
|
120
|
+
{},
|
121
|
+
key)
|
116
122
|
end
|
117
123
|
|
118
124
|
# Returns notifier of the notification from configured field or overriden method.
|
@@ -125,7 +131,8 @@ module ActivityNotification
|
|
125
131
|
resolve_parameter(
|
126
132
|
"notifier_for_#{cast_to_resources_name(target_type)}",
|
127
133
|
_notifier[cast_to_resources_sym(target_type)],
|
128
|
-
nil,
|
134
|
+
nil,
|
135
|
+
key)
|
129
136
|
end
|
130
137
|
|
131
138
|
# Returns if sending notification email is allowed for the notifiable from configured field or overriden method.
|
@@ -152,7 +159,8 @@ module ActivityNotification
|
|
152
159
|
resolved_parameter = resolve_parameter(
|
153
160
|
"notifiable_path_for_#{cast_to_resources_name(target_type)}",
|
154
161
|
_notifiable_path[cast_to_resources_sym(target_type)],
|
155
|
-
nil,
|
162
|
+
nil,
|
163
|
+
key)
|
156
164
|
unless resolved_parameter
|
157
165
|
begin
|
158
166
|
resolved_parameter = polymorphic_path(self)
|
@@ -175,6 +183,30 @@ module ActivityNotification
|
|
175
183
|
target, key)
|
176
184
|
end
|
177
185
|
|
186
|
+
# Returns optional_targets of the notification from configured field or overriden method.
|
187
|
+
# This method is able to be overriden.
|
188
|
+
#
|
189
|
+
# @param [String] target_type Target type to notify
|
190
|
+
# @param [String] key Key of the notification
|
191
|
+
# @return [Array<ActivityNotification::OptionalTarget::Base>] Array of optional target instances
|
192
|
+
def optional_targets(target_type, key = nil)
|
193
|
+
resolve_parameter(
|
194
|
+
"optional_targets_for_#{cast_to_resources_name(target_type)}",
|
195
|
+
_optional_targets[cast_to_resources_sym(target_type)],
|
196
|
+
[],
|
197
|
+
key)
|
198
|
+
end
|
199
|
+
|
200
|
+
# Returns optional_target names of the notification from configured field or overriden method.
|
201
|
+
# This method is able to be overriden.
|
202
|
+
#
|
203
|
+
# @param [String] target_type Target type to notify
|
204
|
+
# @param [String] key Key of the notification
|
205
|
+
# @return [Array<Symbol>] Array of optional target names
|
206
|
+
def optional_target_names(target_type, key = nil)
|
207
|
+
optional_targets(target_type, key).map { |optional_target| optional_target.to_optional_target_name }
|
208
|
+
end
|
209
|
+
|
178
210
|
# overriding_notification_email_key is the method to override key definition for Mailer
|
179
211
|
# When respond_to?(overriding_notification_email_key) returns true,
|
180
212
|
# Mailer uses overriding_notification_email_key instead of original key.
|
@@ -188,13 +220,15 @@ module ActivityNotification
|
|
188
220
|
#
|
189
221
|
# @param [Symbol, String, Class] target_type Type of target
|
190
222
|
# @param [Hash] options Options for notifications
|
191
|
-
# @option options [String] :key
|
192
|
-
# @option options [Object] :group
|
193
|
-
# @option options [ActiveSupport::Duration] :group_expiry_delay
|
194
|
-
# @option options [Object] :notifier
|
195
|
-
# @option options [Hash] :parameters
|
196
|
-
# @option options [Boolean] :send_email
|
197
|
-
# @option options [Boolean] :send_later
|
223
|
+
# @option options [String] :key (notifiable.default_notification_key) Key of the notification
|
224
|
+
# @option options [Object] :group (nil) Group unit of the notifications
|
225
|
+
# @option options [ActiveSupport::Duration] :group_expiry_delay (nil) Expiry period of a notification group
|
226
|
+
# @option options [Object] :notifier (nil) Notifier of the notifications
|
227
|
+
# @option options [Hash] :parameters ({}) Additional parameters of the notifications
|
228
|
+
# @option options [Boolean] :send_email (true) Whether it sends notification email
|
229
|
+
# @option options [Boolean] :send_later (true) Whether it sends notification email asynchronously
|
230
|
+
# @option options [Boolean] :publish_optional_targets (true) Whether it publishes notification to optional targets
|
231
|
+
# @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
|
198
232
|
# @return [Array<Notificaion>] Array of generated notifications
|
199
233
|
def notify(target_type, options = {})
|
200
234
|
Notification.notify(target_type, self, options)
|
@@ -206,13 +240,15 @@ module ActivityNotification
|
|
206
240
|
#
|
207
241
|
# @param [Array<Object>] targets Targets to send notifications
|
208
242
|
# @param [Hash] options Options for notifications
|
209
|
-
# @option options [String] :key
|
210
|
-
# @option options [Object] :group
|
211
|
-
# @option options [ActiveSupport::Duration] :group_expiry_delay
|
212
|
-
# @option options [Object] :notifier
|
213
|
-
# @option options [Hash] :parameters
|
214
|
-
# @option options [Boolean] :send_email
|
215
|
-
# @option options [Boolean] :send_later
|
243
|
+
# @option options [String] :key (notifiable.default_notification_key) Key of the notification
|
244
|
+
# @option options [Object] :group (nil) Group unit of the notifications
|
245
|
+
# @option options [ActiveSupport::Duration] :group_expiry_delay (nil) Expiry period of a notification group
|
246
|
+
# @option options [Object] :notifier (nil) Notifier of the notifications
|
247
|
+
# @option options [Hash] :parameters ({}) Additional parameters of the notifications
|
248
|
+
# @option options [Boolean] :send_email (true) Whether it sends notification email
|
249
|
+
# @option options [Boolean] :send_later (true) Whether it sends notification email asynchronously
|
250
|
+
# @option options [Boolean] :publish_optional_targets (true) Whether it publishes notification to optional targets
|
251
|
+
# @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
|
216
252
|
# @return [Array<Notificaion>] Array of generated notifications
|
217
253
|
def notify_all(targets, options = {})
|
218
254
|
Notification.notify_all(targets, self, options)
|
@@ -224,13 +260,15 @@ module ActivityNotification
|
|
224
260
|
#
|
225
261
|
# @param [Object] target Target to send notifications
|
226
262
|
# @param [Hash] options Options for notifications
|
227
|
-
# @option options [String] :key
|
228
|
-
# @option options [Object] :group
|
229
|
-
# @option options [ActiveSupport::Duration] :group_expiry_delay
|
230
|
-
# @option options [Object] :notifier
|
231
|
-
# @option options [Hash] :parameters
|
232
|
-
# @option options [Boolean] :send_email
|
233
|
-
# @option options [Boolean] :send_later
|
263
|
+
# @option options [String] :key (notifiable.default_notification_key) Key of the notification
|
264
|
+
# @option options [Object] :group (nil) Group unit of the notifications
|
265
|
+
# @option options [ActiveSupport::Duration] :group_expiry_delay (nil) Expiry period of a notification group
|
266
|
+
# @option options [Object] :notifier (nil) Notifier of the notifications
|
267
|
+
# @option options [Hash] :parameters ({}) Additional parameters of the notifications
|
268
|
+
# @option options [Boolean] :send_email (true) Whether it sends notification email
|
269
|
+
# @option options [Boolean] :send_later (true) Whether it sends notification email asynchronously
|
270
|
+
# @option options [Boolean] :publish_optional_targets (true) Whether it publishes notification to optional targets
|
271
|
+
# @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
|
234
272
|
# @return [Notification] Generated notification instance
|
235
273
|
def notify_to(target, options = {})
|
236
274
|
Notification.notify_to(target, self, options)
|
@@ -265,6 +303,13 @@ module ActivityNotification
|
|
265
303
|
end
|
266
304
|
end
|
267
305
|
|
306
|
+
# Remove generated notifications from notification group to new group owner.
|
307
|
+
# This method is intended to be called before destroy this notifiable as dependent configuration.
|
308
|
+
# @api private
|
309
|
+
def remove_generated_notifications_from_group
|
310
|
+
generated_notifications_as_notifiable.group_owners_only.each { |n| n.remove_from_group }
|
311
|
+
end
|
312
|
+
|
268
313
|
# Casts to resources name.
|
269
314
|
# @api private
|
270
315
|
def cast_to_resources_name(target_type)
|