activity_notification 2.0.0 → 2.1.4

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.
Files changed (202) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +22 -0
  3. data/.github/ISSUE_TEMPLATE/feature_request.md +17 -0
  4. data/.github/pull_request_template.md +13 -0
  5. data/.gitignore +10 -3
  6. data/.travis.yml +6 -5
  7. data/CHANGELOG.md +60 -0
  8. data/Gemfile +8 -3
  9. data/Procfile +1 -1
  10. data/README.md +153 -1510
  11. data/activity_notification.gemspec +4 -1
  12. data/app/channels/activity_notification/notification_api_channel.rb +12 -0
  13. data/app/channels/activity_notification/notification_api_with_devise_channel.rb +46 -0
  14. data/app/channels/activity_notification/notification_channel.rb +2 -2
  15. data/app/channels/activity_notification/notification_with_devise_channel.rb +2 -2
  16. data/app/controllers/activity_notification/apidocs_controller.rb +75 -0
  17. data/app/controllers/activity_notification/notifications_api_controller.rb +143 -0
  18. data/app/controllers/activity_notification/notifications_api_with_devise_controller.rb +7 -0
  19. data/app/controllers/activity_notification/notifications_controller.rb +79 -53
  20. data/app/controllers/activity_notification/subscriptions_api_controller.rb +197 -0
  21. data/app/controllers/activity_notification/subscriptions_api_with_devise_controller.rb +7 -0
  22. data/app/controllers/activity_notification/subscriptions_controller.rb +78 -69
  23. data/app/views/activity_notification/notifications/default/_default.html.erb +18 -18
  24. data/app/views/activity_notification/notifications/default/_default_without_grouping.html.erb +14 -14
  25. data/app/views/activity_notification/notifications/default/index.html.erb +6 -6
  26. data/app/views/activity_notification/optional_targets/default/action_cable_channel/_default.html.erb +176 -0
  27. data/app/views/activity_notification/subscriptions/default/_form.html.erb +1 -1
  28. data/app/views/activity_notification/subscriptions/default/_notification_keys.html.erb +3 -31
  29. data/app/views/activity_notification/subscriptions/default/_subscription.html.erb +7 -7
  30. data/app/views/activity_notification/subscriptions/default/index.html.erb +11 -7
  31. data/bin/deploy_on_heroku.sh +3 -1
  32. data/docs/CODE_OF_CONDUCT.md +76 -0
  33. data/docs/CONTRIBUTING.md +36 -0
  34. data/docs/Functions.md +1130 -0
  35. data/docs/Setup.md +801 -0
  36. data/docs/Testing.md +148 -0
  37. data/gemfiles/Gemfile.rails-4.2 +5 -1
  38. data/gemfiles/Gemfile.rails-5.0 +6 -1
  39. data/gemfiles/Gemfile.rails-5.1 +6 -1
  40. data/gemfiles/Gemfile.rails-5.2 +6 -1
  41. data/gemfiles/{Gemfile.rails-6.0.rc → Gemfile.rails-6.0} +6 -5
  42. data/lib/activity_notification.rb +13 -0
  43. data/lib/activity_notification/apis/notification_api.rb +37 -93
  44. data/lib/activity_notification/apis/subscription_api.rb +20 -8
  45. data/lib/activity_notification/apis/swagger.rb +6 -0
  46. data/lib/activity_notification/common.rb +4 -1
  47. data/lib/activity_notification/config.rb +41 -21
  48. data/lib/activity_notification/controllers/common_api_controller.rb +30 -0
  49. data/lib/activity_notification/controllers/common_controller.rb +45 -21
  50. data/lib/activity_notification/controllers/concerns/swagger/error_responses.rb +55 -0
  51. data/lib/activity_notification/controllers/concerns/swagger/notifications_api.rb +273 -0
  52. data/lib/activity_notification/controllers/concerns/swagger/notifications_parameters.rb +92 -0
  53. data/lib/activity_notification/controllers/concerns/swagger/subscriptions_api.rb +405 -0
  54. data/lib/activity_notification/controllers/concerns/swagger/subscriptions_parameters.rb +50 -0
  55. data/lib/activity_notification/controllers/devise_authentication_controller.rb +7 -6
  56. data/lib/activity_notification/gem_version.rb +14 -0
  57. data/lib/activity_notification/helpers/errors.rb +2 -0
  58. data/lib/activity_notification/helpers/view_helpers.rb +4 -0
  59. data/lib/activity_notification/mailers/helpers.rb +17 -10
  60. data/lib/activity_notification/models/concerns/notifiable.rb +31 -15
  61. data/lib/activity_notification/models/concerns/subscriber.rb +12 -1
  62. data/lib/activity_notification/models/concerns/swagger/error_schema.rb +36 -0
  63. data/lib/activity_notification/models/concerns/swagger/notification_schema.rb +209 -0
  64. data/lib/activity_notification/models/concerns/swagger/subscription_schema.rb +162 -0
  65. data/lib/activity_notification/models/concerns/target.rb +36 -10
  66. data/lib/activity_notification/models/notification.rb +1 -0
  67. data/lib/activity_notification/models/subscription.rb +1 -0
  68. data/lib/activity_notification/optional_targets/action_cable_api_channel.rb +69 -0
  69. data/lib/activity_notification/optional_targets/action_cable_channel.rb +68 -0
  70. data/lib/activity_notification/optional_targets/base.rb +7 -13
  71. data/lib/activity_notification/orm/active_record/notification.rb +17 -1
  72. data/lib/activity_notification/orm/active_record/subscription.rb +1 -1
  73. data/lib/activity_notification/orm/dynamoid.rb +38 -3
  74. data/lib/activity_notification/orm/dynamoid/extension.rb +79 -1
  75. data/lib/activity_notification/orm/dynamoid/notification.rb +49 -14
  76. data/lib/activity_notification/orm/dynamoid/subscription.rb +2 -2
  77. data/lib/activity_notification/orm/mongoid.rb +32 -3
  78. data/lib/activity_notification/orm/mongoid/notification.rb +24 -6
  79. data/lib/activity_notification/orm/mongoid/subscription.rb +1 -1
  80. data/lib/activity_notification/rails/routes.rb +132 -48
  81. data/lib/activity_notification/renderable.rb +13 -2
  82. data/lib/activity_notification/roles/acts_as_notifiable.rb +39 -20
  83. data/lib/activity_notification/version.rb +1 -1
  84. data/lib/generators/activity_notification/controllers_generator.rb +2 -1
  85. data/lib/generators/templates/activity_notification.rb +8 -0
  86. data/lib/generators/templates/controllers/notifications_api_controller.rb +31 -0
  87. data/lib/generators/templates/controllers/notifications_api_with_devise_controller.rb +31 -0
  88. data/lib/generators/templates/controllers/notifications_controller.rb +1 -37
  89. data/lib/generators/templates/controllers/notifications_with_devise_controller.rb +1 -45
  90. data/lib/generators/templates/controllers/subscriptions_api_controller.rb +61 -0
  91. data/lib/generators/templates/controllers/subscriptions_api_with_devise_controller.rb +61 -0
  92. data/lib/generators/templates/controllers/subscriptions_controller.rb +14 -37
  93. data/lib/generators/templates/controllers/subscriptions_with_devise_controller.rb +14 -45
  94. data/lib/generators/templates/models/README +8 -4
  95. data/lib/generators/templates/models/notification.rb +1 -1
  96. data/lib/generators/templates/models/subscription.rb +1 -1
  97. data/package.json +8 -0
  98. data/spec/channels/notification_api_channel_shared_examples.rb +59 -0
  99. data/spec/channels/notification_api_channel_spec.rb +51 -0
  100. data/spec/channels/notification_api_with_devise_channel_spec.rb +78 -0
  101. data/spec/concerns/apis/notification_api_spec.rb +38 -3
  102. data/spec/concerns/models/notifiable_spec.rb +82 -18
  103. data/spec/concerns/models/subscriber_spec.rb +13 -16
  104. data/spec/concerns/models/target_spec.rb +32 -0
  105. data/spec/concerns/renderable_spec.rb +2 -2
  106. data/spec/config_spec.rb +26 -15
  107. data/spec/controllers/controller_spec_utility.rb +136 -0
  108. data/spec/controllers/notifications_api_controller_shared_examples.rb +506 -0
  109. data/spec/controllers/notifications_api_controller_spec.rb +19 -0
  110. data/spec/controllers/notifications_api_with_devise_controller_spec.rb +60 -0
  111. data/spec/controllers/notifications_controller_shared_examples.rb +54 -79
  112. data/spec/controllers/notifications_controller_spec.rb +1 -2
  113. data/spec/controllers/notifications_with_devise_controller_spec.rb +3 -12
  114. data/spec/controllers/subscriptions_api_controller_shared_examples.rb +750 -0
  115. data/spec/controllers/subscriptions_api_controller_spec.rb +19 -0
  116. data/spec/controllers/subscriptions_api_with_devise_controller_spec.rb +60 -0
  117. data/spec/controllers/subscriptions_controller_shared_examples.rb +94 -121
  118. data/spec/controllers/subscriptions_controller_spec.rb +1 -2
  119. data/spec/controllers/subscriptions_with_devise_controller_spec.rb +3 -12
  120. data/spec/helpers/view_helpers_spec.rb +4 -11
  121. data/spec/mailers/mailer_spec.rb +41 -0
  122. data/spec/models/notification_spec.rb +17 -0
  123. data/spec/models/subscription_spec.rb +8 -13
  124. data/spec/optional_targets/action_cable_api_channel_spec.rb +37 -0
  125. data/spec/optional_targets/action_cable_channel_spec.rb +44 -0
  126. data/spec/optional_targets/amazon_sns_spec.rb +0 -2
  127. data/spec/optional_targets/slack_spec.rb +0 -2
  128. data/spec/rails_app/Rakefile +9 -0
  129. data/spec/rails_app/app/assets/config/manifest.js +3 -0
  130. data/spec/rails_app/app/assets/images/.keep +0 -0
  131. data/spec/rails_app/app/controllers/admins_controller.rb +21 -0
  132. data/spec/rails_app/app/controllers/application_controller.rb +1 -1
  133. data/spec/rails_app/app/controllers/articles_controller.rb +6 -3
  134. data/spec/rails_app/app/controllers/spa_controller.rb +7 -0
  135. data/spec/rails_app/app/controllers/users/notifications_controller.rb +0 -65
  136. data/spec/rails_app/app/controllers/users/notifications_with_devise_controller.rb +0 -73
  137. data/spec/rails_app/app/controllers/users/subscriptions_controller.rb +0 -77
  138. data/spec/rails_app/app/controllers/users/subscriptions_with_devise_controller.rb +0 -85
  139. data/spec/rails_app/app/controllers/users_controller.rb +26 -0
  140. data/spec/rails_app/app/javascript/App.vue +40 -0
  141. data/spec/rails_app/app/javascript/components/DeviseTokenAuth.vue +82 -0
  142. data/spec/rails_app/app/javascript/components/Top.vue +98 -0
  143. data/spec/rails_app/app/javascript/components/notifications/Index.vue +200 -0
  144. data/spec/rails_app/app/javascript/components/notifications/Notification.vue +133 -0
  145. data/spec/rails_app/app/javascript/components/notifications/NotificationContent.vue +122 -0
  146. data/spec/rails_app/app/javascript/components/subscriptions/Index.vue +279 -0
  147. data/spec/rails_app/app/javascript/components/subscriptions/NewSubscription.vue +112 -0
  148. data/spec/rails_app/app/javascript/components/subscriptions/NotificationKey.vue +141 -0
  149. data/spec/rails_app/app/javascript/components/subscriptions/Subscription.vue +226 -0
  150. data/spec/rails_app/app/javascript/config/development.js +5 -0
  151. data/spec/rails_app/app/javascript/config/environment.js +7 -0
  152. data/spec/rails_app/app/javascript/config/production.js +5 -0
  153. data/spec/rails_app/app/javascript/config/test.js +5 -0
  154. data/spec/rails_app/app/javascript/packs/application.js +18 -0
  155. data/spec/rails_app/app/javascript/packs/spa.js +14 -0
  156. data/spec/rails_app/app/javascript/router/index.js +73 -0
  157. data/spec/rails_app/app/javascript/store/index.js +37 -0
  158. data/spec/rails_app/app/models/admin.rb +16 -15
  159. data/spec/rails_app/app/models/article.rb +26 -21
  160. data/spec/rails_app/app/models/comment.rb +24 -71
  161. data/spec/rails_app/app/models/dummy/dummy_group.rb +8 -0
  162. data/spec/rails_app/app/models/dummy/dummy_notifiable_target.rb +8 -0
  163. data/spec/rails_app/app/models/user.rb +44 -20
  164. data/spec/rails_app/app/views/activity_notification/notifications/default/article/_update.html.erb +146 -0
  165. data/spec/rails_app/app/views/articles/index.html.erb +51 -7
  166. data/spec/rails_app/app/views/articles/show.html.erb +1 -1
  167. data/spec/rails_app/app/views/layouts/_header.html.erb +8 -10
  168. data/spec/rails_app/app/views/spa/index.html.erb +2 -0
  169. data/spec/rails_app/babel.config.js +72 -0
  170. data/spec/rails_app/bin/webpack +18 -0
  171. data/spec/rails_app/bin/webpack-dev-server +18 -0
  172. data/spec/rails_app/config/application.rb +18 -2
  173. data/spec/rails_app/config/dynamoid.rb +11 -3
  174. data/spec/rails_app/config/environment.rb +2 -1
  175. data/spec/rails_app/config/environments/development.rb +5 -0
  176. data/spec/rails_app/config/environments/production.rb +6 -0
  177. data/spec/rails_app/config/environments/test.rb +5 -0
  178. data/spec/rails_app/config/initializers/activity_notification.rb +11 -3
  179. data/spec/rails_app/config/initializers/copy_it.aws.rb.template +6 -0
  180. data/spec/rails_app/config/initializers/devise_token_auth.rb +55 -0
  181. data/spec/rails_app/config/initializers/mysql.rb +9 -0
  182. data/spec/rails_app/config/locales/activity_notification.en.yml +2 -2
  183. data/spec/rails_app/config/routes.rb +37 -1
  184. data/spec/rails_app/config/webpack/development.js +5 -0
  185. data/spec/rails_app/config/webpack/environment.js +7 -0
  186. data/spec/rails_app/config/webpack/loaders/vue.js +6 -0
  187. data/spec/rails_app/config/webpack/production.js +5 -0
  188. data/spec/rails_app/config/webpack/test.js +5 -0
  189. data/spec/rails_app/config/webpacker.yml +97 -0
  190. data/spec/rails_app/db/migrate/20191201000000_add_tokens_to_users.rb +10 -0
  191. data/spec/rails_app/db/schema.rb +4 -1
  192. data/spec/rails_app/db/seeds.rb +10 -2
  193. data/spec/rails_app/lib/custom_optional_targets/raise_error.rb +14 -0
  194. data/spec/rails_app/package.json +23 -0
  195. data/spec/rails_app/postcss.config.js +12 -0
  196. data/spec/roles/acts_as_group_spec.rb +0 -2
  197. data/spec/roles/acts_as_notifiable_spec.rb +6 -8
  198. data/spec/roles/acts_as_notifier_spec.rb +0 -2
  199. data/spec/roles/acts_as_target_spec.rb +0 -4
  200. data/spec/spec_helper.rb +7 -15
  201. data/spec/version_spec.rb +31 -0
  202. metadata +191 -13
@@ -0,0 +1,162 @@
1
+ module ActivityNotification
2
+ module Swagger::SubscriptionSchema #:nodoc:
3
+ extend ActiveSupport::Concern
4
+ include ::Swagger::Blocks
5
+
6
+ included do
7
+ swagger_component do
8
+ schema :SubscriptionAttributes do
9
+ key :type, :object
10
+ property :key do
11
+ key :type, :string
12
+ key :example, "comment.default"
13
+ end
14
+ property :subscribing do
15
+ key :type, :boolean
16
+ key :default, true
17
+ key :example, true
18
+ end
19
+ property :subscribing_to_email do
20
+ key :type, :boolean
21
+ key :default, true
22
+ key :example, true
23
+ end
24
+ end
25
+
26
+ schema :Subscription do
27
+ key :type, :object
28
+ key :required, [ :id, :target_type, :target_id, :key, :subscribing, :subscribing_to_email, :created_at, :updated_at, :target ]
29
+ allOf do
30
+ schema do
31
+ key :type, :object
32
+ property :id do
33
+ key :oneOf, [
34
+ { type: :integer },
35
+ { type: :string }
36
+ ]
37
+ key :description, "This parameter type is integer with ActiveRecord, but will be string with Mongoid or Dynamoid ORMs."
38
+ key :example, 321
39
+ end
40
+ property :target_type do
41
+ key :type, :string
42
+ key :example, "User"
43
+ end
44
+ property :target_id do
45
+ key :oneOf, [
46
+ { type: :integer },
47
+ { type: :string }
48
+ ]
49
+ key :description, "This parameter type is integer with ActiveRecord, but will be string with Mongoid or Dynamoid ORMs."
50
+ key :example, 1
51
+ end
52
+ end
53
+ schema do
54
+ key :'$ref', :SubscriptionAttributes
55
+ end
56
+ schema do
57
+ key :type, :object
58
+ property :subscribed_at do
59
+ key :type, :string
60
+ key :format, :'date-time'
61
+ key :nullable, true
62
+ end
63
+ property :unsubscribed_at do
64
+ key :type, :string
65
+ key :format, :'date-time'
66
+ key :nullable, true
67
+ end
68
+ property :subscribed_to_email_at do
69
+ key :type, :string
70
+ key :format, :'date-time'
71
+ key :nullable, true
72
+ end
73
+ property :unsubscribed_to_email_at do
74
+ key :type, :string
75
+ key :format, :'date-time'
76
+ key :nullable, true
77
+ end
78
+ property :optional_targets do
79
+ key :type, :object
80
+ key :additionalProperties, {
81
+ type: "object",
82
+ properties: {
83
+ subscribing: {
84
+ type: "boolean"
85
+ },
86
+ subscribed_at: {
87
+ type: "string",
88
+ format: "date-time"
89
+ }
90
+ }
91
+ }
92
+ key :example, {
93
+ action_cable_channel: {
94
+ subscribing: true,
95
+ subscribed_at: Time.current,
96
+ unsubscribed_at: nil
97
+ },
98
+ slack: {
99
+ subscribing: false,
100
+ subscribed_at: nil,
101
+ unsubscribed_at: Time.current
102
+ }
103
+ }
104
+ end
105
+ property :created_at do
106
+ key :type, :string
107
+ key :format, :'date-time'
108
+ end
109
+ property :updated_at do
110
+ key :type, :string
111
+ key :format, :'date-time'
112
+ end
113
+ property :target do
114
+ key :type, :object
115
+ key :description, "Associated target model in your application"
116
+ key :example, {
117
+ id: 1,
118
+ email: "ichiro@example.com",
119
+ name: "Ichiro",
120
+ created_at: Time.current,
121
+ updated_at: Time.current
122
+ }
123
+ end
124
+ end
125
+ end
126
+ end
127
+
128
+ schema :SubscriptionInput do
129
+ key :type, :object
130
+ key :required, [ :key ]
131
+ allOf do
132
+ schema do
133
+ key :'$ref', :SubscriptionAttributes
134
+ end
135
+ schema do
136
+ key :type, :object
137
+ property :optional_targets do
138
+ key :type, :object
139
+ key :additionalProperties, {
140
+ type: "object",
141
+ properties: {
142
+ subscribing: {
143
+ type: "boolean"
144
+ }
145
+ }
146
+ }
147
+ key :example, {
148
+ action_cable_channel: {
149
+ subscribing: true
150
+ },
151
+ slack: {
152
+ subscribing: false
153
+ }
154
+ }
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end
@@ -41,7 +41,7 @@ module ActivityNotification
41
41
  self._notification_email_allowed = ActivityNotification.config.email_enabled
42
42
  self._batch_notification_email_allowed = ActivityNotification.config.email_enabled
43
43
  self._notification_subscription_allowed = ActivityNotification.config.subscription_enabled
44
- self._notification_action_cable_allowed = ActivityNotification.config.action_cable_enabled
44
+ self._notification_action_cable_allowed = ActivityNotification.config.action_cable_enabled || ActivityNotification.config.action_cable_api_enabled
45
45
  self._notification_action_cable_with_devise = ActivityNotification.config.action_cable_with_devise
46
46
  self._notification_devise_resource = ->(model) { model }
47
47
  self._notification_current_devise_target = ->(current_resource) { current_resource }
@@ -61,6 +61,8 @@ module ActivityNotification
61
61
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
62
62
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
63
63
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
64
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
65
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
64
66
  # @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
65
67
  # @return [Array<Notificaion>] All notifications for this target type
66
68
  def all_notifications(options = {})
@@ -101,6 +103,8 @@ module ActivityNotification
101
103
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
102
104
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
103
105
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
106
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
107
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
104
108
  # @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
105
109
  # @return [Hash<Target, Notificaion>] All notifications for this target type grouped by targets
106
110
  def notification_index_map(options = {})
@@ -123,6 +127,8 @@ module ActivityNotification
123
127
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
124
128
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
125
129
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
130
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
131
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
126
132
  # @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
127
133
  # @option options [Boolean] :send_later (false) If it sends notification email asynchronously
128
134
  # @option options [String, Symbol] :fallback (:batch_default) Fallback template to use when MissingTemplate is raised
@@ -207,10 +213,7 @@ module ActivityNotification
207
213
  resolve_value(_notification_action_cable_with_devise)
208
214
  end
209
215
 
210
- # :only-rails5-plus#only-rails-with-callback-issue:
211
- # :only-rails5-plus#only-rails-without-callback-issue:
212
- # :only-rails5-plus#only-rails-with-callback-issue#except-dynamoid:
213
- # :only-rails5-plus#only-rails-without-callback-issue#except-dynamoid:
216
+ # :nocov:
214
217
  if Rails::VERSION::MAJOR >= 5
215
218
  # Returns notification ActionCable channel class name from action_cable_with_devise? configuration.
216
219
  #
@@ -219,10 +222,7 @@ module ActivityNotification
219
222
  notification_action_cable_with_devise? ? "ActivityNotification::NotificationWithDeviseChannel" : "ActivityNotification::NotificationChannel"
220
223
  end
221
224
  end
222
- # :only-rails5-plus#only-rails-with-callback-issue:
223
- # :only-rails5-plus#only-rails-without-callback-issue:
224
- # :only-rails5-plus#only-rails-with-callback-issue#except-dynamoid:
225
- # :only-rails5-plus#only-rails-without-callback-issue#except-dynamoid:
225
+ # :nocov:
226
226
 
227
227
  # Returns Devise resource model associated with this target.
228
228
  #
@@ -263,6 +263,8 @@ module ActivityNotification
263
263
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
264
264
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
265
265
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
266
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
267
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
266
268
  # @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
267
269
  # @return [Integer] Count of unopened notifications of the target
268
270
  def unopened_notification_count(options = {})
@@ -279,6 +281,8 @@ module ActivityNotification
279
281
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
280
282
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
281
283
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
284
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
285
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
282
286
  # @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
283
287
  # @return [Boolean] If the target has unopened notifications
284
288
  def has_unopened_notifications?(options = {})
@@ -304,6 +308,8 @@ module ActivityNotification
304
308
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
305
309
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
306
310
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
311
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
312
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
307
313
  # @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
308
314
  # @return [Array<Notificaion>] Notification index of the target
309
315
  def notification_index(options = {})
@@ -327,6 +333,8 @@ module ActivityNotification
327
333
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
328
334
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
329
335
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
336
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
337
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
330
338
  # @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
331
339
  # @return [Array<Notificaion>] Unopened notification index of the target
332
340
  def unopened_notification_index(options = {})
@@ -348,6 +356,8 @@ module ActivityNotification
348
356
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
349
357
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
350
358
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
359
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
360
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
351
361
  # @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
352
362
  # @return [Array<Notificaion>] Opened notification index of the target
353
363
  def opened_notification_index(options = {})
@@ -406,7 +416,9 @@ module ActivityNotification
406
416
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
407
417
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
408
418
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
409
- # @return [Integer] Number of opened notification records
419
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
420
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
421
+ # @return [Array<Notification>] Opened notification records
410
422
  def open_all_notifications(options = {})
411
423
  Notification.open_all_of(self, options)
412
424
  end
@@ -434,6 +446,8 @@ module ActivityNotification
434
446
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
435
447
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
436
448
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
449
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
450
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
437
451
  # @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
438
452
  # @return [Array<Notificaion>] Notification index of the target with attributes
439
453
  def notification_index_with_attributes(options = {})
@@ -457,6 +471,8 @@ module ActivityNotification
457
471
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
458
472
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
459
473
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
474
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
475
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
460
476
  # @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
461
477
  # @return [Array<Notificaion>] Unopened notification index of the target with attributes
462
478
  def unopened_notification_index_with_attributes(options = {})
@@ -478,6 +494,8 @@ module ActivityNotification
478
494
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
479
495
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
480
496
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
497
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
498
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
481
499
  # @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
482
500
  # @return [Array<Notificaion>] Opened notification index of the target with attributes
483
501
  def opened_notification_index_with_attributes(options = {})
@@ -557,6 +575,8 @@ module ActivityNotification
557
575
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
558
576
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
559
577
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
578
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
579
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
560
580
  # @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
561
581
  # @return [ActiveRecord_AssociationRelation<Notificaion>|Mongoid::Criteria<Notificaion>|Dynamoid::Criteria::Chain] Unopened notification index of the target
562
582
  def _unopened_notification_index(options = {})
@@ -577,6 +597,8 @@ module ActivityNotification
577
597
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
578
598
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
579
599
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
600
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
601
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
580
602
  # @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
581
603
  # @return [ActiveRecord_AssociationRelation<Notificaion>|Mongoid::Criteria<Notificaion>|Dynamoid::Criteria::Chain] Opened notification index of the target
582
604
  def _opened_notification_index(options = {})
@@ -617,6 +639,8 @@ module ActivityNotification
617
639
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
618
640
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
619
641
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
642
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
643
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
620
644
  # @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
621
645
  # @return [Array<Notificaion>] Notification index of the target
622
646
  def arrange_single_notification_index(loading_index_method, options = {})
@@ -644,6 +668,8 @@ module ActivityNotification
644
668
  # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
645
669
  # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
646
670
  # @option options [String] :filtered_by_key (nil) Key of the notification for filter
671
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notifications later than specified time
672
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notifications earlier than specified time
647
673
  # @option options [Array|Hash] :custom_filter (nil) Custom notification filter (e.g. ["created_at >= ?", time.hour.ago])
648
674
  # @return [Array<Notificaion>] Notification index of the target
649
675
  def arrange_notification_index(loading_unopened_index_method, loading_opened_index_method, options = {})
@@ -1,5 +1,6 @@
1
1
  module ActivityNotification
2
2
  # Notification model implementation with ORM.
3
3
  class Notification < inherit_orm("Notification")
4
+ include Swagger::NotificationSchema
4
5
  end
5
6
  end
@@ -1,6 +1,7 @@
1
1
  module ActivityNotification
2
2
  # Subscription model implementation with ORM.
3
3
  class Subscription < inherit_orm("Subscription")
4
+ include Swagger::SubscriptionSchema
4
5
  end
5
6
  end
6
7
 
@@ -0,0 +1,69 @@
1
+ module ActivityNotification
2
+ module OptionalTarget
3
+ # Optional target implementation to broadcast to Action Cable API channel
4
+ class ActionCableApiChannel < ActivityNotification::OptionalTarget::Base
5
+ # Initialize method to prepare Action Cable API channel
6
+ # @param [Hash] options Options for initializing
7
+ # @option options [String] :channel_prefix (ActivityNotification.config.notification_api_channel_prefix) Channel name prefix to broadcast notifications
8
+ # @option options [String] :composite_key_delimiter (ActivityNotification.config.composite_key_delimiter) Composite key delimiter for channel name
9
+ def initialize_target(options = {})
10
+ @channel_prefix = options.delete(:channel_prefix) || ActivityNotification.config.notification_api_channel_prefix
11
+ @composite_key_delimiter = options.delete(:composite_key_delimiter) || ActivityNotification.config.composite_key_delimiter
12
+ end
13
+
14
+ # Broadcast to ActionCable API subscribers
15
+ # @param [Notification] notification Notification instance
16
+ # @param [Hash] options Options for publishing
17
+ def notify(notification, options = {})
18
+ if notification_action_cable_api_allowed?(notification)
19
+ target_channel_name = "#{@channel_prefix}_#{notification.target_type}#{@composite_key_delimiter}#{notification.target_id}"
20
+ ActionCable.server.broadcast(target_channel_name, format_message(notification, options))
21
+ end
22
+ end
23
+
24
+ # Check if Action Cable notification API is allowed
25
+ # @param [Notification] notification Notification instance
26
+ # @return [Boolean] Whether Action Cable notification API is allowed
27
+ def notification_action_cable_api_allowed?(notification)
28
+ notification.target.notification_action_cable_allowed?(notification.notifiable, notification.key) &&
29
+ notification.notifiable.notifiable_action_cable_api_allowed?(notification.target, notification.key)
30
+ end
31
+
32
+ # Format message to broadcast
33
+ # @param [Notification] notification Notification instance
34
+ # @param [Hash] options Options for publishing
35
+ # @return [Hash] Formatted message to broadcast
36
+ def format_message(notification, options = {})
37
+ {
38
+ notification: notification.as_json(notification_json_options.merge(options)),
39
+ group_owner: notification.group_owner? ? nil : notification.group_owner.as_json(notification_json_options.merge(options))
40
+ }
41
+ end
42
+
43
+ protected
44
+
45
+ # Returns options for notification JSON
46
+ # @api protected
47
+ def notification_json_options
48
+ {
49
+ include: {
50
+ target: { methods: [:printable_type, :printable_target_name] },
51
+ notifiable: { methods: [:printable_type] },
52
+ group: { methods: [:printable_type, :printable_group_name] },
53
+ notifier: { methods: [:printable_type, :printable_notifier_name] },
54
+ group_members: {}
55
+ },
56
+ methods: [:notifiable_path, :printable_notifiable_name, :group_member_notifier_count, :group_notification_count, :text]
57
+ }
58
+ end
59
+
60
+ # Overriden rendering notification message using format_message
61
+ # @param [Notification] notification Notification instance
62
+ # @param [Hash] options Options for rendering
63
+ # @return [String] Rendered json formatted message to broadcast
64
+ def render_notification_message(notification, options = {})
65
+ format_message(notification, options)
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,68 @@
1
+ module ActivityNotification
2
+ module OptionalTarget
3
+ # Optional target implementation to broadcast to Action Cable channel
4
+ class ActionCableChannel < ActivityNotification::OptionalTarget::Base
5
+ # Initialize method to prepare Action Cable channel
6
+ # @param [Hash] options Options for initializing
7
+ # @option options [String] :channel_prefix (ActivityNotification.config.notification_channel_prefix) Channel name prefix to broadcast notifications
8
+ # @option options [String] :composite_key_delimiter (ActivityNotification.config.composite_key_delimiter) Composite key delimiter for channel name
9
+ def initialize_target(options = {})
10
+ @channel_prefix = options.delete(:channel_prefix) || ActivityNotification.config.notification_channel_prefix
11
+ @composite_key_delimiter = options.delete(:composite_key_delimiter) || ActivityNotification.config.composite_key_delimiter
12
+ end
13
+
14
+ # Broadcast to ActionCable subscribers
15
+ # @param [Notification] notification Notification instance
16
+ # @param [Hash] options Options for publishing
17
+ # @option options [String, Symbol] :target (nil) Target type name to find template or i18n text
18
+ # @option options [String] :partial_root ("activity_notification/notifications/#{target}", controller.target_view_path, 'activity_notification/notifications/default') Partial template name
19
+ # @option options [String] :partial (self.key.tr('.', '/')) Root path of partial template
20
+ # @option options [String] :layout (nil) Layout template name
21
+ # @option options [String] :layout_root ('layouts') Root path of layout template
22
+ # @option options [String, Symbol] :fallback (:default) Fallback template to use when MissingTemplate is raised. Set :text to use i18n text as fallback.
23
+ # @option options [String] :filter (nil) Filter option to load notification index (Nothing as auto, 'opened' or 'unopened')
24
+ # @option options [String] :limit (nil) Limit to query for notifications
25
+ # @option options [String] :without_grouping ('false') If notification index will include group members
26
+ # @option options [String] :with_group_members ('false') If notification index will include group members
27
+ # @option options [String] :filtered_by_type (nil) Notifiable type for filter
28
+ # @option options [String] :filtered_by_group_type (nil) Group type for filter, valid with :filtered_by_group_id
29
+ # @option options [String] :filtered_by_group_id (nil) Group instance id for filter, valid with :filtered_by_group_type
30
+ # @option options [String] :filtered_by_key (nil) Key of the notification for filter
31
+ # @option options [String] :later_than (nil) ISO 8601 format time to filter notification index later than specified time
32
+ # @option options [String] :earlier_than (nil) ISO 8601 format time to filter notification index earlier than specified time
33
+ # @option options [Hash] others Parameters to be set as locals
34
+ def notify(notification, options = {})
35
+ if notification_action_cable_allowed?(notification)
36
+ target_channel_name = "#{@channel_prefix}_#{notification.target_type}#{@composite_key_delimiter}#{notification.target_id}"
37
+ index_options = options.slice(:filter, :limit, :without_grouping, :with_group_members, :filtered_by_type, :filtered_by_group_type, :filtered_by_group_id, :filtered_by_key, :later_than, :earlier_than)
38
+ ActionCable.server.broadcast(target_channel_name, format_message(notification, options))
39
+ end
40
+ end
41
+
42
+ # Check if Action Cable notification is allowed
43
+ # @param [Notification] notification Notification instance
44
+ # @return [Boolean] Whether Action Cable notification is allowed
45
+ def notification_action_cable_allowed?(notification)
46
+ notification.target.notification_action_cable_allowed?(notification.notifiable, notification.key) &&
47
+ notification.notifiable.notifiable_action_cable_allowed?(notification.target, notification.key)
48
+ end
49
+
50
+ # Format message to broadcast
51
+ # @param [Notification] notification Notification instance
52
+ # @param [Hash] options Options for publishing
53
+ # @return [Hash] Formatted message to broadcast
54
+ def format_message(notification, options = {})
55
+ index_options = options.slice(:filter, :limit, :without_grouping, :with_group_members, :filtered_by_type, :filtered_by_group_type, :filtered_by_group_id, :filtered_by_key, :later_than, :earlier_than)
56
+ {
57
+ id: notification.id,
58
+ view: render_notification_message(notification, options),
59
+ text: notification.text(options),
60
+ notifiable_path: notification.notifiable_path,
61
+ group_owner_id: notification.group_owner_id,
62
+ group_owner_view: notification.group_owner? ? nil : render_notification_message(notification.group_owner, options),
63
+ unopened_notification_count: notification.target.unopened_notification_count(index_options)
64
+ }
65
+ end
66
+ end
67
+ end
68
+ end