activity_notification 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (195) 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 +22 -0
  8. data/Gemfile +8 -2
  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 +1 -1
  15. data/app/channels/activity_notification/notification_with_devise_channel.rb +1 -1
  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 +674 -0
  36. data/docs/Testing.md +148 -0
  37. data/gemfiles/Gemfile.rails-4.2 +3 -0
  38. data/gemfiles/Gemfile.rails-5.0 +3 -0
  39. data/gemfiles/Gemfile.rails-5.1 +3 -0
  40. data/gemfiles/Gemfile.rails-5.2 +3 -0
  41. data/gemfiles/{Gemfile.rails-6.0.rc → Gemfile.rails-6.0} +5 -3
  42. data/lib/activity_notification.rb +13 -1
  43. data/lib/activity_notification/apis/notification_api.rb +29 -92
  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/config.rb +41 -21
  47. data/lib/activity_notification/controllers/common_api_controller.rb +30 -0
  48. data/lib/activity_notification/controllers/common_controller.rb +44 -20
  49. data/lib/activity_notification/controllers/concerns/swagger/error_responses.rb +55 -0
  50. data/lib/activity_notification/controllers/concerns/swagger/notifications_api.rb +273 -0
  51. data/lib/activity_notification/controllers/concerns/swagger/notifications_parameters.rb +92 -0
  52. data/lib/activity_notification/controllers/concerns/swagger/subscriptions_api.rb +405 -0
  53. data/lib/activity_notification/controllers/concerns/swagger/subscriptions_parameters.rb +50 -0
  54. data/lib/activity_notification/controllers/devise_authentication_controller.rb +7 -6
  55. data/lib/activity_notification/gem_version.rb +14 -0
  56. data/lib/activity_notification/helpers/errors.rb +2 -0
  57. data/lib/activity_notification/helpers/view_helpers.rb +4 -0
  58. data/lib/activity_notification/mailers/helpers.rb +17 -10
  59. data/lib/activity_notification/models/concerns/notifiable.rb +26 -10
  60. data/lib/activity_notification/models/concerns/subscriber.rb +12 -1
  61. data/lib/activity_notification/models/concerns/swagger/error_schema.rb +36 -0
  62. data/lib/activity_notification/models/concerns/swagger/notification_schema.rb +209 -0
  63. data/lib/activity_notification/models/concerns/swagger/subscription_schema.rb +162 -0
  64. data/lib/activity_notification/models/concerns/target.rb +36 -10
  65. data/lib/activity_notification/models/notification.rb +1 -0
  66. data/lib/activity_notification/models/subscription.rb +1 -0
  67. data/lib/activity_notification/optional_targets/action_cable_api_channel.rb +69 -0
  68. data/lib/activity_notification/optional_targets/action_cable_channel.rb +68 -0
  69. data/lib/activity_notification/optional_targets/base.rb +7 -13
  70. data/lib/activity_notification/orm/active_record/notification.rb +17 -1
  71. data/lib/activity_notification/orm/active_record/subscription.rb +1 -1
  72. data/lib/activity_notification/orm/dynamoid.rb +28 -0
  73. data/lib/activity_notification/orm/dynamoid/extension.rb +79 -1
  74. data/lib/activity_notification/orm/dynamoid/notification.rb +1 -1
  75. data/lib/activity_notification/orm/dynamoid/subscription.rb +1 -1
  76. data/lib/activity_notification/orm/mongoid.rb +22 -0
  77. data/lib/activity_notification/orm/mongoid/notification.rb +17 -1
  78. data/lib/activity_notification/orm/mongoid/subscription.rb +1 -1
  79. data/lib/activity_notification/rails/routes.rb +132 -48
  80. data/lib/activity_notification/renderable.rb +13 -2
  81. data/lib/activity_notification/roles/acts_as_notifiable.rb +38 -20
  82. data/lib/activity_notification/version.rb +1 -1
  83. data/lib/generators/activity_notification/controllers_generator.rb +2 -1
  84. data/lib/generators/templates/activity_notification.rb +8 -0
  85. data/lib/generators/templates/controllers/notifications_api_controller.rb +31 -0
  86. data/lib/generators/templates/controllers/notifications_api_with_devise_controller.rb +31 -0
  87. data/lib/generators/templates/controllers/notifications_controller.rb +1 -37
  88. data/lib/generators/templates/controllers/notifications_with_devise_controller.rb +1 -45
  89. data/lib/generators/templates/controllers/subscriptions_api_controller.rb +61 -0
  90. data/lib/generators/templates/controllers/subscriptions_api_with_devise_controller.rb +61 -0
  91. data/lib/generators/templates/controllers/subscriptions_controller.rb +14 -37
  92. data/lib/generators/templates/controllers/subscriptions_with_devise_controller.rb +14 -45
  93. data/lib/generators/templates/models/README +8 -4
  94. data/lib/generators/templates/models/notification.rb +1 -1
  95. data/lib/generators/templates/models/subscription.rb +1 -1
  96. data/package.json +8 -0
  97. data/spec/channels/notification_api_channel_shared_examples.rb +59 -0
  98. data/spec/channels/notification_api_channel_spec.rb +51 -0
  99. data/spec/channels/notification_api_with_devise_channel_spec.rb +78 -0
  100. data/spec/concerns/apis/notification_api_spec.rb +37 -2
  101. data/spec/concerns/models/notifiable_spec.rb +64 -0
  102. data/spec/concerns/models/subscriber_spec.rb +13 -16
  103. data/spec/concerns/models/target_spec.rb +32 -0
  104. data/spec/concerns/renderable_spec.rb +2 -2
  105. data/spec/controllers/controller_spec_utility.rb +136 -0
  106. data/spec/controllers/notifications_api_controller_shared_examples.rb +506 -0
  107. data/spec/controllers/notifications_api_controller_spec.rb +19 -0
  108. data/spec/controllers/notifications_api_with_devise_controller_spec.rb +60 -0
  109. data/spec/controllers/notifications_controller_shared_examples.rb +54 -79
  110. data/spec/controllers/notifications_controller_spec.rb +1 -2
  111. data/spec/controllers/notifications_with_devise_controller_spec.rb +3 -12
  112. data/spec/controllers/subscriptions_api_controller_shared_examples.rb +750 -0
  113. data/spec/controllers/subscriptions_api_controller_spec.rb +19 -0
  114. data/spec/controllers/subscriptions_api_with_devise_controller_spec.rb +60 -0
  115. data/spec/controllers/subscriptions_controller_shared_examples.rb +94 -121
  116. data/spec/controllers/subscriptions_controller_spec.rb +1 -2
  117. data/spec/controllers/subscriptions_with_devise_controller_spec.rb +3 -12
  118. data/spec/helpers/view_helpers_spec.rb +4 -11
  119. data/spec/mailers/mailer_spec.rb +41 -0
  120. data/spec/models/notification_spec.rb +17 -0
  121. data/spec/models/subscription_spec.rb +0 -13
  122. data/spec/optional_targets/action_cable_api_channel_spec.rb +37 -0
  123. data/spec/optional_targets/action_cable_channel_spec.rb +44 -0
  124. data/spec/optional_targets/amazon_sns_spec.rb +0 -2
  125. data/spec/optional_targets/slack_spec.rb +0 -2
  126. data/spec/rails_app/Rakefile +9 -0
  127. data/spec/rails_app/app/assets/config/manifest.js +3 -0
  128. data/spec/rails_app/app/assets/images/.keep +0 -0
  129. data/spec/rails_app/app/controllers/admins_controller.rb +21 -0
  130. data/spec/rails_app/app/controllers/application_controller.rb +1 -1
  131. data/spec/rails_app/app/controllers/articles_controller.rb +6 -3
  132. data/spec/rails_app/app/controllers/spa_controller.rb +7 -0
  133. data/spec/rails_app/app/controllers/users/notifications_controller.rb +0 -65
  134. data/spec/rails_app/app/controllers/users/notifications_with_devise_controller.rb +0 -73
  135. data/spec/rails_app/app/controllers/users/subscriptions_controller.rb +0 -77
  136. data/spec/rails_app/app/controllers/users/subscriptions_with_devise_controller.rb +0 -85
  137. data/spec/rails_app/app/controllers/users_controller.rb +21 -0
  138. data/spec/rails_app/app/javascript/App.vue +104 -0
  139. data/spec/rails_app/app/javascript/components/DeviseTokenAuth.vue +83 -0
  140. data/spec/rails_app/app/javascript/components/Top.vue +99 -0
  141. data/spec/rails_app/app/javascript/components/notifications/Index.vue +200 -0
  142. data/spec/rails_app/app/javascript/components/notifications/Notification.vue +133 -0
  143. data/spec/rails_app/app/javascript/components/notifications/NotificationContent.vue +122 -0
  144. data/spec/rails_app/app/javascript/components/subscriptions/Index.vue +279 -0
  145. data/spec/rails_app/app/javascript/components/subscriptions/NewSubscription.vue +112 -0
  146. data/spec/rails_app/app/javascript/components/subscriptions/NotificationKey.vue +141 -0
  147. data/spec/rails_app/app/javascript/components/subscriptions/Subscription.vue +226 -0
  148. data/spec/rails_app/app/javascript/config/development.js +5 -0
  149. data/spec/rails_app/app/javascript/config/environment.js +7 -0
  150. data/spec/rails_app/app/javascript/config/production.js +5 -0
  151. data/spec/rails_app/app/javascript/config/test.js +5 -0
  152. data/spec/rails_app/app/javascript/packs/application.js +18 -0
  153. data/spec/rails_app/app/javascript/packs/spa.js +11 -0
  154. data/spec/rails_app/app/javascript/store/auth.js +37 -0
  155. data/spec/rails_app/app/models/admin.rb +16 -15
  156. data/spec/rails_app/app/models/article.rb +26 -21
  157. data/spec/rails_app/app/models/comment.rb +24 -71
  158. data/spec/rails_app/app/models/user.rb +43 -20
  159. data/spec/rails_app/app/views/activity_notification/notifications/default/article/_update.html.erb +146 -0
  160. data/spec/rails_app/app/views/articles/index.html.erb +51 -7
  161. data/spec/rails_app/app/views/articles/show.html.erb +1 -1
  162. data/spec/rails_app/app/views/layouts/_header.html.erb +8 -10
  163. data/spec/rails_app/app/views/spa/index.html.erb +2 -0
  164. data/spec/rails_app/babel.config.js +72 -0
  165. data/spec/rails_app/bin/webpack +18 -0
  166. data/spec/rails_app/bin/webpack-dev-server +18 -0
  167. data/spec/rails_app/config/application.rb +15 -2
  168. data/spec/rails_app/config/environment.rb +2 -1
  169. data/spec/rails_app/config/environments/development.rb +5 -0
  170. data/spec/rails_app/config/environments/production.rb +3 -0
  171. data/spec/rails_app/config/environments/test.rb +5 -0
  172. data/spec/rails_app/config/initializers/activity_notification.rb +8 -0
  173. data/spec/rails_app/config/initializers/devise_token_auth.rb +55 -0
  174. data/spec/rails_app/config/initializers/mysql.rb +9 -0
  175. data/spec/rails_app/config/locales/activity_notification.en.yml +2 -2
  176. data/spec/rails_app/config/routes.rb +33 -1
  177. data/spec/rails_app/config/webpack/development.js +5 -0
  178. data/spec/rails_app/config/webpack/environment.js +7 -0
  179. data/spec/rails_app/config/webpack/loaders/vue.js +6 -0
  180. data/spec/rails_app/config/webpack/production.js +5 -0
  181. data/spec/rails_app/config/webpack/test.js +5 -0
  182. data/spec/rails_app/config/webpacker.yml +97 -0
  183. data/spec/rails_app/db/migrate/20191201000000_add_tokens_to_users.rb +10 -0
  184. data/spec/rails_app/db/schema.rb +4 -1
  185. data/spec/rails_app/db/seeds.rb +1 -0
  186. data/spec/rails_app/lib/custom_optional_targets/raise_error.rb +14 -0
  187. data/spec/rails_app/package.json +23 -0
  188. data/spec/rails_app/postcss.config.js +12 -0
  189. data/spec/roles/acts_as_group_spec.rb +0 -2
  190. data/spec/roles/acts_as_notifiable_spec.rb +1 -3
  191. data/spec/roles/acts_as_notifier_spec.rb +0 -2
  192. data/spec/roles/acts_as_target_spec.rb +0 -4
  193. data/spec/spec_helper.rb +7 -15
  194. data/spec/version_spec.rb +31 -0
  195. metadata +187 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2a31c915030fbad2174abd43cd1e64656cbc609e7fdd2521b06bccdfa46ea69e
4
- data.tar.gz: 4d24557f5a670b094be8d5bb5ab8c07763d7944c7fb1de550c5f4dc956d50906
3
+ metadata.gz: b1f6ad3e3fe40d4841cde7931cdc67065c87fd948db1674a1cbc3016f1338aba
4
+ data.tar.gz: 0b15bf8fe764df0d3431543d29ec08b3f95548faf337a14b3c30f98379688742
5
5
  SHA512:
6
- metadata.gz: 156543325a87e170ebe74d1a2dbc2bcf8c9870bb69c86ef8689f5634a564ed84f286c6965baf79ac84b8bd82dbbdd7bceb522faeeef09e028cfdc038c3284008
7
- data.tar.gz: a911a86c566b7d3c7bbeeacbc78f9db7ca9dfff4f2496544d4c3190076cfd742ead7902e077af3cffb041532557c19f3ab3fd687f9ccf79fca9f951ff957c337
6
+ metadata.gz: 56c6fe87c9ab5444d02969775ca91d1c3054d1c63ff0e12f1308984b0b5c8f06c48f3dea8cd9bfa333f79f72f3951de99d028a1f586d2f485537104300346c07
7
+ data.tar.gz: 309085505f26839eefdfed6a34a9d950af85013a1c161d384206e3c4a31e3156b80c1d37097d8c56dced7b10fea83715daaa10abf85e70185029e7df76fcc9d6
@@ -0,0 +1,22 @@
1
+ ---
2
+ name: Bug report
3
+ about: Create a report to help us improve
4
+ title: ''
5
+ labels: ''
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ ### Steps to reproduce
11
+ <!-- Tell us how to reproduce the issue -->
12
+
13
+ ### Expected behavior
14
+ <!-- Tell us what should happen -->
15
+
16
+ ### Actual behavior
17
+ <!-- Tell us what happens instead -->
18
+
19
+ ### System configuration
20
+ **activity_notification gem version**:
21
+ **Rails version**:
22
+ **ORM (ActiveRecord, Mongoid or Dynamoid)**:
@@ -0,0 +1,17 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest an idea for this project
4
+ title: ''
5
+ labels: ''
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ ### Problem or use case
11
+ <!-- Tell us what the problem is if your feature request is related to a problem -->
12
+
13
+ ### Expected solution
14
+ <!-- Tell us what you want to happen -->
15
+
16
+ ### Alternatives
17
+ <!-- Tell us any alternative solutions or features you've considered -->
@@ -0,0 +1,13 @@
1
+ **Issue #, if available**:
2
+
3
+ ### Summary
4
+
5
+ <!-- Provide a general description of the code changes in your pull request.
6
+ Were there any bugs you had fixed? If so, mention them.
7
+ If these bugs have open GitHub issues, be sure to tag them here as well, to keep the conversation linked together. -->
8
+
9
+ ### Other Information
10
+
11
+ <!-- If there's anything else that's important and relevant to your pull request, mention that information here.
12
+
13
+ Thank you for contributing to activity_notification! -->
data/.gitignore CHANGED
@@ -7,6 +7,7 @@
7
7
  /InstalledFiles
8
8
  /pkg/
9
9
  /spec/reports/
10
+ /spec/openapi.json
10
11
  /spec/examples.txt
11
12
  /spec/rails_app/log/*
12
13
  /spec/rails_app/tmp/*
@@ -54,11 +55,17 @@ build-iPhoneSimulator/
54
55
  /gemfiles/vendor/bundle
55
56
  /lib/bundler/man/
56
57
 
58
+ # Ignore webpacker files
59
+ /spec/rails_app/node_modules
60
+ /spec/rails_app/yarn.lock
61
+ /spec/rails_app/yarn-error.log
62
+ /spec/rails_app/public/packs
63
+ /spec/rails_app/public/packs-test
64
+
57
65
  # for a library or gem, you might want to ignore these files since the code is
58
66
  # intended to run in multiple environments; otherwise, check them in:
59
- # Gemfile.lock
60
- # .ruby-version
61
- # .ruby-gemset
67
+ .ruby-version
68
+ .ruby-gemset
62
69
 
63
70
  # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
64
71
  .rvmrc
@@ -5,17 +5,18 @@ branches:
5
5
  - images
6
6
 
7
7
  rvm:
8
- - 2.6.3
9
- # - 2.5.5
10
- # - 2.4.6
11
- # - 2.3.8
8
+ # - 2.7.0 # Need to respond to warnings for Ruby 3.0
9
+ - 2.6.5
10
+ # - 2.5.7
11
+ # - 2.4.9
12
+ # - 2.3.8 #EOL
12
13
 
13
14
  gemfile:
14
15
  - gemfiles/Gemfile.rails-4.2
15
16
  - gemfiles/Gemfile.rails-5.0
16
17
  - gemfiles/Gemfile.rails-5.1
17
18
  - gemfiles/Gemfile.rails-5.2
18
- - gemfiles/Gemfile.rails-6.0.rc
19
+ - gemfiles/Gemfile.rails-6.0
19
20
 
20
21
  env:
21
22
  - AN_ORM=active_record
@@ -1,3 +1,25 @@
1
+ ## 2.1.0 / 2020-02-04
2
+ [Full Changelog](http://github.com/simukappu/activity_notification/compare/v2.0.0...v2.1.0)
3
+
4
+ Enhancements:
5
+
6
+ * Add API mode using notification and subscription API controllers - [#108](https://github.com/simukappu/activity_notification/issues/108) [#113](https://github.com/simukappu/activity_notification/issues/113)
7
+ * Add API controllers integrated with Devise Token Auth - [#108](https://github.com/simukappu/activity_notification/issues/108) [#113](https://github.com/simukappu/activity_notification/issues/113)
8
+ * Add sample single page application working with REST API backend - [#108](https://github.com/simukappu/activity_notification/issues/108) [#113](https://github.com/simukappu/activity_notification/issues/113)
9
+ * Move Action Cable broadcasting to optional targets - [#111](https://github.com/simukappu/activity_notification/issues/111)
10
+ * Add Action Cable API channels publishing formatted JSON - [#111](https://github.com/simukappu/activity_notification/issues/111)
11
+ * Rescue and skip error in optional_targets - [#103](https://github.com/simukappu/activity_notification/issues/103)
12
+ * Add *later_than* and *earlier_than* filter options to notification index API - [#108](https://github.com/simukappu/activity_notification/issues/108)
13
+ * Add key uniqueness validation to subscription model - [#119](https://github.com/simukappu/activity_notification/issues/119)
14
+ * Make mailer headers more configurable to set custom *from*, *reply_to* and *message_id* - [#116](https://github.com/simukappu/activity_notification/pull/116)
15
+ * Allow use and test with Rails 6.0 release - [#102](https://github.com/simukappu/activity_notification/issues/102)
16
+
17
+ Breaking Changes:
18
+
19
+ * Change HTTP POST method of open notification and subscription methods into PUT method
20
+ * Make *Target#open_all_notifications* return opened notification records instead of their count
21
+ * Make *Subscriber#create_subscription* raise *ActivityNotification::RecordInvalidError* when the request is invalid - [#119](https://github.com/simukappu/activity_notification/pull/119)
22
+
1
23
  ## 2.0.0 / 2019-08-09
2
24
  [Full Changelog](http://github.com/simukappu/activity_notification/compare/v1.7.1...v2.0.0)
3
25
 
data/Gemfile CHANGED
@@ -2,12 +2,13 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'rails', '~> 5.2'
5
+ gem 'rails', '~> 6.0.0'
6
6
 
7
7
  group :production do
8
8
  gem 'puma'
9
9
  gem 'pg'
10
10
  gem 'devise'
11
+ gem 'devise_token_auth'
11
12
  end
12
13
 
13
14
  group :development do
@@ -15,11 +16,16 @@ group :development do
15
16
  end
16
17
 
17
18
  group :test do
19
+ #TODO https://github.com/rails/rails/issues/35417
20
+ gem 'rspec-rails', '4.0.0.beta4'
18
21
  gem 'rails-controller-testing'
19
- gem 'action-cable-testing'
20
22
  gem 'ammeter'
21
23
  gem 'timecop'
24
+ gem 'committee'
25
+ gem 'committee-rails'
22
26
  gem 'coveralls', require: false
23
27
  end
24
28
 
29
+ gem 'webpacker', groups: [:production, :development]
30
+ gem 'rack-cors', groups: [:production, :development]
25
31
  gem 'dotenv-rails', groups: [:development, :test]
data/Procfile CHANGED
@@ -1,2 +1,2 @@
1
- web: cd spec/rails_app; bin/rails server Puma -p $PORT -e $RAILS_ENV; cd -
1
+ web: cd spec/rails_app; bin/rails server -u Puma -p $PORT -e $RAILS_ENV; cd -
2
2
  console: cd spec/rails_app; bin/rails console -e $RAILS_ENV; cd -
data/README.md CHANGED
@@ -16,7 +16,7 @@
16
16
  ## About
17
17
 
18
18
  *activity_notification* provides following functions:
19
- * Notification API (creating notifications, query for notifications and managing notification parameters)
19
+ * Notification API for your Rails application (creating and managing notifications, query for notifications)
20
20
  * Notification models (stored with ActiveRecord, Mongoid or Dynamoid ORM)
21
21
  * Notification controllers (managing open/unopen of notifications, providing link to notifiable activity page)
22
22
  * Notification views (presentation of notifications)
@@ -26,13 +26,15 @@
26
26
  * Batch email notification (event driven or periodical email notification, daily or weekly etc)
27
27
  * Push notification with [Action Cable](https://guides.rubyonrails.org/action_cable_overview.html)
28
28
  * Subscription management (subscribing and unsubscribing for each target and notification type)
29
+ * REST API backend and [OpenAPI Specification](https://github.com/OAI/OpenAPI-Specification)
29
30
  * Integration with [Devise](https://github.com/plataformatec/devise) authentication
30
31
  * Activity notifications stream integrated into cloud computing using [Amazon DynamoDB Streams](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html)
31
32
  * Optional notification targets (Configurable optional notification targets like [Amazon SNS](https://aws.amazon.com/sns), [Slack](https://slack.com), SMS and so on)
32
33
 
33
- ### Online demo
34
+ ### Online Demo
34
35
 
35
- You can see an actual application using this gem here: **https://activity-notification-example.herokuapp.com/**
36
+ You can see an actual application using this gem here:
37
+ * **https://activity-notification-example.herokuapp.com/**
36
38
 
37
39
  Login as the following test users to experience user activity notifications:
38
40
 
@@ -43,93 +45,121 @@ Login as the following test users to experience user activity notifications:
43
45
  | klay@example.com | changeit | |
44
46
  | kevin@example.com | changeit | |
45
47
 
46
- The deployed demo application is included in this gem's source code as a test application here: **[/spec/rails_app](/spec/rails_app/)**
48
+ The deployed demo application is included in this gem's source code as a test application here: *[/spec/rails_app](/spec/rails_app/)*
47
49
 
48
50
  ### Notification index and plugin notifications
51
+
49
52
  <kbd>![plugin-notifications-image](https://raw.githubusercontent.com/simukappu/activity_notification/images/activity_notification_plugin_focus_with_subscription.png)</kbd>
50
53
 
51
54
  *activity_notification* deeply uses [PublicActivity](https://github.com/pokonski/public_activity) as reference in presentation layer.
52
55
 
53
56
  ### Subscription management of notifications
57
+
54
58
  <kbd>![subscription-management-image](https://raw.githubusercontent.com/simukappu/activity_notification/images/activity_notification_subscription_management_with_optional_targets.png)</kbd>
55
59
 
56
60
  ### Amazon SNS as optional notification target
61
+
57
62
  <kbd>![optional-target-amazon-sns-email-image](https://raw.githubusercontent.com/simukappu/activity_notification/images/activity_notification_optional_target_amazon_sns.png)</kbd>
58
63
 
59
64
  ### Slack as optional notification target
65
+
60
66
  <kbd>![optional-target-slack-image](https://raw.githubusercontent.com/simukappu/activity_notification/images/activity_notification_optional_target_slack.png)</kbd>
61
67
 
68
+ ### Public REST API reference as OpenAPI Specification
69
+
70
+ REST API reference as OpenAPI Specification is published in SwaggerHub here:
71
+ * **https://app.swaggerhub.com/apis/simukappu/activity-notification/**
72
+
73
+ You can see sample single page application using [Vue.js](https://vuejs.org) as a part of example Rails application here:
74
+ * **https://activity-notification-example.herokuapp.com/spa/**
75
+
76
+ This sample application works with *activity_notification* REST API backend.
77
+
62
78
 
63
- ## Table of contents
79
+ ## Table of Contents
64
80
 
65
81
  - [About](#about)
66
- - [Setup](#setup)
67
- - [Gem installation](#gem-installation)
68
- - [Database setup](#database-setup)
69
- - [Using ActiveRecord ORM](#using-activerecord-orm)
70
- - [Using Mongoid ORM](#using-mongoid-orm)
71
- - [Using Dynamoid ORM](#using-dynamoid-orm)
72
- - [Integration with DynamoDB Streams](#integration-with-dynamodb-streams)
73
- - [Configuring models](#configuring-models)
74
- - [Configuring target models](#configuring-target-models)
75
- - [Configuring notifiable models](#configuring-notifiable-models)
76
- - [Advanced notifiable path](#advanced-notifiable-path)
77
- - [Configuring views](#configuring-views)
78
- - [Configuring routes](#configuring-routes)
79
- - [Routes with scope](#routes-with-scope)
80
- - [Creating notifications](#creating-notifications)
81
- - [Notification API](#notification-api)
82
- - [Asynchronous notification API with ActiveJob](#asynchronous-notification-api-with-activejob)
83
- - [Automatic tracked notifications](#automatic-tracked-notifications)
84
- - [Displaying notifications](#displaying-notifications)
85
- - [Preparing target notifications](#preparing-target-notifications)
86
- - [Rendering notifications](#rendering-notifications)
87
- - [Notification views](#notification-views)
88
- - [i18n for notifications](#i18n-for-notifications)
89
- - [Customizing controllers (optional)](#customizing-controllers-optional)
90
- - [Functions](#functions)
91
- - [Email notification](#email-notification)
92
- - [Mailer setup](#mailer-setup)
93
- - [Sender configuration](#sender-configuration)
94
- - [Email templates](#email-templates)
95
- - [Email subject](#email-subject)
96
- - [i18n for email](#i18n-for-email)
97
- - [Batch email notification](#batch-email-notification)
98
- - [Batch mailer setup](#batch-mailer-setup)
99
- - [Batch sender configuration](#batch-sender-configuration)
100
- - [Batch email templates](#batch-email-templates)
101
- - [Batch email subject](#batch-email-subject)
102
- - [i18n for batch email](#i18n-for-batch-email)
103
- - [Grouping notifications](#grouping-notifications)
104
- - [Subscription management](#subscription-management)
105
- - [Configuring subscriptions](#configuring-subscriptions)
106
- - [Managing subscriptions](#managing-subscriptions)
107
- - [Customizing subscriptions](#customizing-subscriptions)
108
- - [Integration with Devise](#integration-with-devise)
109
- - [Configuring integration with Devise authentication](#configuring-integration-with-devise-authentication)
110
- - [Using different model as target](#using-different-model-as-target)
111
- - [Configuring simple default routes](#configuring-simple-default-routes)
112
- - [Push notification with Action Cable](#push-notification-with-action-cable)
113
- - [Enabling broadcasting notifications to channels](#enabling-broadcasting-notifications-to-channels)
114
- - [Subscribing notifications from channels](#subscribing-notifications-from-channels)
115
- - [Subscribing notifications with Devise authentication](#subscribing-notifications-with-devise-authentication)
116
- - [Optional notification targets](#optional-notification-targets)
117
- - [Configuring optional targets](#configuring-optional-targets)
118
- - [Customizing message format](#customizing-message-format)
119
- - [Amazon SNS as optional target](#amazon-sns-as-optional-target)
120
- - [Slack as optional target](#slack-as-optional-target)
121
- - [Developing custom optional targets](#developing-custom-optional-targets)
122
- - [Testing](#testing)
123
- - [Testing your application](#testing-your-application)
124
- - [Testing gem alone](#testing-gem-alone)
82
+ - [Online Demo](#online-demo)
83
+ - [Public REST API reference as OpenAPI Specification](#public-rest-apu-reference-as-openapi-specification)
84
+ - [Getting Started](#getting-started)
85
+ - [Setup](/docs/Setup.md#Setup)
86
+ - [Gem installation](/docs/Setup.md#gem-installation)
87
+ - [Database setup](/docs/Setup.md#database-setup)
88
+ - [Using ActiveRecord ORM](/docs/Setup.md#using-activerecord-orm)
89
+ - [Using Mongoid ORM](/docs/Setup.md#using-mongoid-orm)
90
+ - [Using Dynamoid ORM](/docs/Setup.md#using-dynamoid-orm)
91
+ - [Integration with DynamoDB Streams](/docs/Setup.md#integration-with-dynamodb-streams)
92
+ - [Configuring models](/docs/Setup.md#configuring-models)
93
+ - [Configuring target models](/docs/Setup.md#configuring-target-models)
94
+ - [Configuring notifiable models](/docs/Setup.md#configuring-notifiable-models)
95
+ - [Advanced notifiable path](/docs/Setup.md#advanced-notifiable-path)
96
+ - [Configuring views](/docs/Setup.md#configuring-views)
97
+ - [Configuring routes](/docs/Setup.md#configuring-routes)
98
+ - [Routes with scope](/docs/Setup.md#routes-with-scope)
99
+ - [Routes as REST API backend](/docs/Setup.md#routes-as-rest-api-backend)
100
+ - [Creating notifications](/docs/Setup.md#creating-notifications)
101
+ - [Notification API](/docs/Setup.md#notification-api)
102
+ - [Asynchronous notification API with ActiveJob](/docs/Setup.md#asynchronous-notification-api-with-activejob)
103
+ - [Automatic tracked notifications](/docs/Setup.md#automatic-tracked-notifications)
104
+ - [Displaying notifications](/docs/Setup.md#displaying-notifications)
105
+ - [Preparing target notifications](/docs/Setup.md#preparing-target-notifications)
106
+ - [Rendering notifications](/docs/Setup.md#rendering-notifications)
107
+ - [Notification views](/docs/Setup.md#notification-views)
108
+ - [i18n for notifications](/docs/Setup.md#i18n-for-notifications)
109
+ - [Customizing controllers (optional)](/docs/Setup.md#customizing-controllers-optional)
110
+ - [Functions](/docs/Functions.md#Functions)
111
+ - [Email notification](/docs/Functions.md#email-notification)
112
+ - [Mailer setup](/docs/Functions.md#mailer-setup)
113
+ - [Sender configuration](/docs/Functions.md#sender-configuration)
114
+ - [Email templates](/docs/Functions.md#email-templates)
115
+ - [Email subject](/docs/Functions.md#email-subject)
116
+ - [Other header fields](/docs/Functions.md#other-header-fields)
117
+ - [i18n for email](/docs/Functions.md#i18n-for-email)
118
+ - [Batch email notification](/docs/Functions.md#batch-email-notification)
119
+ - [Batch mailer setup](/docs/Functions.md#batch-mailer-setup)
120
+ - [Batch sender configuration](/docs/Functions.md#batch-sender-configuration)
121
+ - [Batch email templates](/docs/Functions.md#batch-email-templates)
122
+ - [Batch email subject](/docs/Functions.md#batch-email-subject)
123
+ - [i18n for batch email](/docs/Functions.md#i18n-for-batch-email)
124
+ - [Grouping notifications](/docs/Functions.md#grouping-notifications)
125
+ - [Subscription management](/docs/Functions.md#subscription-management)
126
+ - [Configuring subscriptions](/docs/Functions.md#configuring-subscriptions)
127
+ - [Managing subscriptions](/docs/Functions.md#managing-subscriptions)
128
+ - [Customizing subscriptions](/docs/Functions.md#customizing-subscriptions)
129
+ - [REST API backend](/docs/Functions.md#rest-api-backend)
130
+ - [Configuring REST API backend](/docs/Functions.md#configuring-rest-api-backend)
131
+ - [API reference as OpenAPI Specification](/docs/Functions.md#api-reference-as-openapi-specification)
132
+ - [Integration with Devise](/docs/Functions.md#integration-with-devise)
133
+ - [Configuring integration with Devise authentication](/docs/Functions.md#configuring-integration-with-devise-authentication)
134
+ - [Using different model as target](/docs/Functions.md#using-different-model-as-target)
135
+ - [Configuring simple default routes](/docs/Functions.md#configuring-simple-default-routes)
136
+ - [REST API backend with Devise Token Auth](/docs/Functions.md#rest-api-backend-with-devise-token-auth)
137
+ - [Push notification with Action Cable](/docs/Functions.md#push-notification-with-action-cable)
138
+ - [Enabling broadcasting notifications to channels](/docs/Functions.md#enabling-broadcasting-notifications-to-channels)
139
+ - [Subscribing notifications from channels](/docs/Functions.md#subscribing-notifications-from-channels)
140
+ - [Subscribing notifications with Devise authentication](/docs/Functions.md#subscribing-notifications-with-devise-authentication)
141
+ - [Subscribing notifications API with Devise Token Auth](/docs/Functions.md#subscribing-notifications-api-with-devise-token-auth)
142
+ - [Subscription management of Action Cable channels](/docs/Functions.md#subscription-management-of-action-cable-channels)
143
+ - [Optional notification targets](/docs/Functions.md#optional-notification-targets)
144
+ - [Configuring optional targets](/docs/Functions.md#configuring-optional-targets)
145
+ - [Customizing message format](/docs/Functions.md#customizing-message-format)
146
+ - [Action Cable channels as optional target](/docs/Functions.md#action-cable-channels-as-optional-target)
147
+ - [Amazon SNS as optional target](/docs/Functions.md#amazon-sns-as-optional-target)
148
+ - [Slack as optional target](/docs/Functions.md#slack-as-optional-target)
149
+ - [Developing custom optional targets](/docs/Functions.md#developing-custom-optional-targets)
150
+ - [Subscription management of optional targets](/docs/Functions.md#subscription-management-of-optional-targets)
151
+ - [Testing](/docs/Testing.md#Testing)
152
+ - [Testing your application](/docs/Testing.md#testing-your-application)
153
+ - [Testing gem alone](/docs/Testing.md#testing-gem-alone)
125
154
  - [Documentation](#documentation)
126
- - **[Common examples](#common-examples)**
127
- - [Help](#help)
155
+ - [Common Examples](#common-examples)
128
156
  - [Contributing](#contributing)
129
157
  - [License](#license)
130
158
 
131
159
 
132
- ## Setup
160
+ ## Getting Started
161
+
162
+ This getting started shows easy setup description of *activity_notification*. See [Setup](/docs/Setup.md#Setup) for more details.
133
163
 
134
164
  ### Gem installation
135
165
 
@@ -151,12 +181,9 @@ $ bin/rails generate activity_notification:install
151
181
  ```
152
182
 
153
183
  The generator will install an initializer which describes all configuration options of *activity_notification*.
154
- It also generates a i18n based translation file which we can configure the presentation of notifications.
155
184
 
156
185
  ### Database setup
157
186
 
158
- #### Using ActiveRecord ORM
159
-
160
187
  When you use *activity_notification* with ActiveRecord ORM as default configuration,
161
188
  create migration for notifications and migrate the database in your Rails project:
162
189
 
@@ -165,194 +192,22 @@ $ bin/rails generate activity_notification:migration
165
192
  $ bin/rake db:migrate
166
193
  ```
167
194
 
168
- If you are using a different table name from *"notifications"*, change the settings in your *config/initializers/activity_notification.rb* file, e.g., if you're using the table name *"activity_notifications"* instead of the default *"notifications"*:
169
-
170
- ```ruby
171
- config.notification_table_name = "activity_notifications"
172
- ```
173
-
174
- The same can be done for the subscription table name, e.g., if you're using the table name *"notifications_subscriptions"* instead of the default *"subscriptions"*:
175
-
176
- ```ruby
177
- config.subscription_table_name = "notifications_subscriptions"
178
- ```
179
-
180
- #### Using Mongoid ORM
181
-
182
- When you use *activity_notification* with [Mongoid](http://mongoid.org) ORM, set **AN_ORM** environment variable to **mongoid**:
183
-
184
- ```console
185
- $ export AN_ORM=mongoid
186
- ```
187
-
188
- You can also configure ORM in initializer **activity_notification.rb**:
189
-
190
- ```ruby
191
- config.orm = :mongoid
192
- ```
193
-
194
- You need to configure Mongoid in your Rails application for your MongoDB environment. Then, your notifications and subscriptions will be stored in your MongoDB.
195
-
196
- #### Using Dynamoid ORM
197
-
198
- When you use *activity_notification* with [Dynamoid](https://github.com/Dynamoid/dynamoid) ORM, set **AN_ORM** environment variable to **dynamoid**:
199
-
200
- ```console
201
- $ export AN_ORM=dynamoid
202
- ```
203
-
204
- You can also configure ORM in initializer **activity_notification.rb**:
205
-
206
- ```ruby
207
- config.orm = :dynamoid
208
- ```
209
-
210
- You need to configure Dynamoid in your Rails application for your Amazon DynamoDB environment.
211
- Then, you can use this rake task to create DynamoDB tables used by *activity_notification* with Dynamoid:
212
-
213
- ```console
214
- $ bin/rake activity_notification:create_dynamodb_tables
215
- ```
216
-
217
- After these configurations, your notifications and subscriptions will be stored in your Amazon DynamoDB.
218
-
219
- Note: Amazon DynamoDB integration using Dynamoid ORM is only supported with Rails 5.0+.
220
-
221
- ##### Integration with DynamoDB Streams
222
-
223
- You can capture *activity_notification*'s table activity with [DynamoDB Streams](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html).
224
- Using DynamoDB Streams, activity notifications in your Rails application will be integrated into cloud computing and available as event stream processed by [DynamoDB Streams Kinesis Adapter](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.KCLAdapter.html) or [AWS Lambda](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.Lambda.html).
225
-
226
- When you consume your activity notifications from DynamoDB Streams, sometimes you need to process notification records with associated target, notifiable or notifier record which is stored in database of your Rails application.
227
- In such cases, you can use **store_with_associated_records** option in initializer **activity_notification.rb**:
228
-
229
- ```ruby
230
- config.store_with_associated_records = true
231
- ```
232
-
233
- When **store_with_associated_records** is set to *false* as default, *activity_notification* stores notificaion records with association like this:
234
-
235
- ```json
236
- {
237
- "id": {
238
- "S": "f05756ef-661e-4ef5-9e99-5af51243125c"
239
- },
240
- "target_key": {
241
- "S": "User#1"
242
- },
243
- "notifiable_key": {
244
- "S": "Comment#2"
245
- },
246
- "key": {
247
- "S": "comment.default"
248
- },
249
- "group_key": {
250
- "S": "Article#1"
251
- },
252
- "notifier_key": {
253
- "S": "User#2"
254
- },
255
- "created_at": {
256
- "N": "1560085332.689929"
257
- },
258
- "updated_at": {
259
- "N": "1560085332.695515"
260
- },
261
- "parameters": {
262
- "M": {}
263
- }
264
- }
265
- ```
266
-
267
- When you set **store_with_associated_records** to *true*, *activity_notification* stores notificaion records including associated target, notifiable and notifier like this:
268
-
269
- ```json
270
- {
271
- "id": {
272
- "S": "f05756ef-661e-4ef5-9e99-5af51243125c"
273
- },
274
- "target_key": {
275
- "S": "User#1"
276
- },
277
- "target_record": {
278
- "S": "{\"id\":1,\"email\":\"ichiro@example.com\",\"name\":\"Ichiro\",\"created_at\":\"2019-06-09T13:10:44.853Z\",\"updated_at\":\"2019-06-09T13:10:44.853Z\"}"
279
- },
280
- "notifiable_key": {
281
- "S": "Comment#2"
282
- },
283
- "notifiable_record": {
284
- "S": "{\"id\":2,\"user_id\":2,\"article_id\":1,\"body\":\"This is the first Stephen's comment to Ichiro's article.\",\"created_at\":\"2019-06-09T13:10:45.677Z\",\"updated_at\":\"2019-06-09T13:10:45.677Z\"}"
285
- },
286
- "key": {
287
- "S": "comment.default"
288
- },
289
- "group_key": {
290
- "S": "Article#1"
291
- },
292
- "notifier_key": {
293
- "S": "User#2"
294
- },
295
- "notifier_record": {
296
- "S": "{\"id\":2,\"email\":\"stephen@example.com\",\"name\":\"Stephen\",\"created_at\":\"2019-06-09T13:10:45.006Z\",\"updated_at\":\"2019-06-09T13:10:45.006Z\"}"
297
- },
298
- "created_at": {
299
- "N": "1560085332.689929"
300
- },
301
- "updated_at": {
302
- "N": "1560085332.695515"
303
- },
304
- "parameters": {
305
- "M": {}
306
- }
307
- }
308
- ```
309
-
310
- Then, you can process notification records with associated records in your DynamoDB Streams.
311
-
312
- Note: This **store_with_associated_records** option can be set true only when you use mongoid or dynamoid ORM.
195
+ See [Database setup](/docs/Setup.md#database-setup) for other ORMs.
313
196
 
314
197
  ### Configuring models
315
198
 
316
- #### Configuring target models
317
-
318
199
  Configure your target model (e.g. *app/models/user.rb*).
319
200
  Add **acts_as_target** configuration to your target model to get notifications.
320
201
 
321
- ##### Target as an ActiveRecord model
322
-
323
202
  ```ruby
324
203
  class User < ActiveRecord::Base
325
- # acts_as_target configures your model as ActivityNotification::Target
326
- # with parameters as value or custom methods defined in your model as lambda or symbol.
327
- # This is an example without any options (default configuration) as the target.
328
- acts_as_target
329
- end
330
- ```
331
-
332
- ##### Target as a Mongoid model
333
-
334
- ```ruby
335
- require 'mongoid'
336
- class User
337
- include Mongoid::Document
338
- include Mongoid::Timestamps
339
- include GlobalID::Identification
340
-
341
- # You need include ActivityNotification::Models except models which extend ActiveRecord::Base
342
- include ActivityNotification::Models
343
204
  acts_as_target
344
205
  end
345
206
  ```
346
207
 
347
- *Note*: *acts_as_notification_target* is an alias for *acts_as_target* and does the same.
348
-
349
- #### Configuring notifiable models
350
-
351
- Configure your notifiable model (e.g. *app/models/comment.rb*).
208
+ Then, configure your notifiable model (e.g. *app/models/comment.rb*).
352
209
  Add **acts_as_notifiable** configuration to your notifiable model representing activity to notify for each of your target model.
353
- You have to define notification targets for all notifications from this notifiable model by *:targets* option. Other configurations are options. *:notifiable_path* option is a path to move when the notification is opened by the target user.
354
-
355
- ##### Notifiable as an ActiveRecord model
210
+ You have to define notification targets for all notifications from this notifiable model by *:targets* option. Other configurations are optional. *:notifiable_path* option is a path to move when the notification is opened by the target user.
356
211
 
357
212
  ```ruby
358
213
  class Article < ActiveRecord::Base
@@ -365,52 +220,9 @@ class Comment < ActiveRecord::Base
365
220
  belongs_to :article
366
221
  belongs_to :user
367
222
 
368
- # acts_as_notifiable configures your model as ActivityNotification::Notifiable
369
- # with parameters as value or custom methods defined in your model as lambda or symbol.
370
- # The first argument is the plural symbol name of your target model.
371
- acts_as_notifiable :users,
372
- # Notification targets as :targets is a necessary option
373
- # Set to notify to author and users commented to the article, except comment owner self
374
- targets: ->(comment, key) {
375
- ([comment.article.user] + comment.article.commented_users.to_a - [comment.user]).uniq
376
- },
377
- # Path to move when the notification is opened by the target user
378
- # This is an optional configuration since activity_notification uses polymorphic_path as default
379
- notifiable_path: :article_notifiable_path
380
-
381
- def article_notifiable_path
382
- article_path(article)
383
- end
384
- end
385
- ```
386
-
387
- ##### Notifiable as a Mongoid model
388
-
389
- ```ruby
390
- require 'mongoid'
391
- class Article
392
- include Mongoid::Document
393
- include Mongoid::Timestamps
394
-
395
- belongs_to :user
396
- has_many :comments, dependent: :destroy
397
-
398
- def commented_users
399
- User.where(:id.in => comments.pluck(:user_id))
400
- end
401
- end
402
-
403
- require 'mongoid'
404
- class Comment
405
- include Mongoid::Document
406
- include Mongoid::Timestamps
407
- include GlobalID::Identification
408
-
409
- # You need include ActivityNotification::Models except models which extend ActiveRecord::Base
410
- include ActivityNotification::Models
411
223
  acts_as_notifiable :users,
412
224
  targets: ->(comment, key) {
413
- ([comment.article.user] + comment.article.commented_users.to_a - [comment.user]).uniq
225
+ ([comment.article.user] + comment.article.reload.commented_users.to_a - [comment.user]).uniq
414
226
  },
415
227
  notifiable_path: :article_notifiable_path
416
228
 
@@ -420,40 +232,12 @@ class Comment
420
232
  end
421
233
  ```
422
234
 
423
- ##### Advanced notifiable path
424
-
425
- Sometimes it might be necessary to provide extra information in the *notifiable_path*. In those cases, passing a lambda function to the *notifiable_path* will give you the notifiable object and the notifiable key to play around with:
426
-
427
- ```ruby
428
- acts_as_notifiable :users,
429
- targets: ->(comment, key) {
430
- ([comment.article.user] + comment.article.commented_users.to_a - [comment.user]).uniq
431
- },
432
-  notifiable_path: ->(comment, key) { "#{comment.article_notifiable_path}##{key}" }
433
- ```
434
-
435
- This will attach the key of the notification to the notifiable path.
235
+ See [Configuring models](/docs/Setup.md#configuring-models) for more details.
436
236
 
437
237
  ### Configuring views
438
238
 
439
- *activity_notification* provides view templates to customize your notification views. The view generator can generate default views for all targets.
440
-
441
- ```console
442
- $ bin/rails generate activity_notification:views
443
- ```
444
-
445
- If you have multiple target models in your application, such as *User* and *Admin*, you will be able to have views based on the target like *notifications/users/index* and *notifications/admins/index*. If no view is found for the target, *activity_notification* will use the default view at *notifications/default/index*. You can also use the generator to generate views for the specified target:
446
-
447
- ```console
448
- $ bin/rails generate activity_notification:views users
449
- ```
450
-
451
- If you would like to generate only a few sets of views, like the ones for the *notifications* (for notification views) and *mailer* (for notification email views),
452
- you can pass a list of modules to the generator with the *-v* flag.
453
-
454
- ```console
455
- $ bin/rails generate activity_notification:views -v notifications
456
- ```
239
+ *activity_notification* provides view templates to customize your notification views.
240
+ See [Configuring views](/docs/Setup.md#configuring-views) for more details.
457
241
 
458
242
  ### Configuring routes
459
243
 
@@ -465,1248 +249,107 @@ Rails.application.routes.draw do
465
249
  end
466
250
  ```
467
251
 
468
- Then, you can access several pages like */users/1/notifications* and manage open/unopen of notifications using *[ActivityNotification::NotificationsController](/app/controllers/activity_notification/notifications_controller.rb)*.
469
- If you use Devise integration and you want to configure simple default routes for authenticated users, see [Configuring simple default routes](#configuring-simple-default-routes).
252
+ See [Configuring routes](/docs/Setup.md#configuring-routes) for more details.
470
253
 
471
- #### Routes with scope
472
-
473
- You can also configure *activity_notification* routes with scope like this:
254
+ You can also configure *activity_notification* routes as REST API backend with *api_mode* option like this:
474
255
 
475
256
  ```ruby
476
257
  Rails.application.routes.draw do
477
- scope :myscope, as: :myscope do
478
- notify_to :users, routing_scope: :myscope
258
+ scope :api do
259
+ scope :"v2" do
260
+ notify_to :users, api_mode: true
261
+ end
479
262
  end
480
263
  end
481
264
  ```
482
265
 
483
- Then, pages are shown as */myscope/users/1/notifications*.
266
+ See [Routes as REST API backend](/docs/Setup.md#configuring-routes) and [REST API backend](/docs/Functions.md#rest-api-backend) for more details.
484
267
 
485
268
  ### Creating notifications
486
269
 
487
- #### Notification API
488
-
489
270
  You can trigger notifications by setting all your required parameters and triggering **notify** on the notifiable model, like this:
490
271
 
491
272
  ```ruby
492
273
  @comment.notify :users, key: "comment.reply"
493
274
  ```
494
275
 
495
- Or, you can call public API as **ActivityNotification::Notification.notify**
496
-
497
- ```ruby
498
- ActivityNotification::Notification.notify :users, @comment, key: "comment.reply"
499
- ```
500
-
501
276
  The first argument is the plural symbol name of your target model, which is configured in notifiable model by *acts_as_notifiable*.
502
277
  The new instances of **ActivityNotification::Notification** model will be generated for the specified targets.
503
278
 
504
- *Hint*: *:key* is a option. Default key `#{notifiable_type}.default` which means *comment.default* will be used without specified key.
505
- You can override it by *Notifiable#default_notification_key*.
506
-
507
- #### Asynchronous notification API with ActiveJob
508
-
509
- Using Notification API with default configurations, the notifications will be generated synchronously. *activity_notification* also supports **asynchronous notification API** with ActiveJob to improve application performance. You can use **notify_later** method on the notifiable model, like this:
510
-
511
- ```ruby
512
- @comment.notify_later :users, key: "comment.reply"
513
- ```
514
-
515
- You can also use *:notify_later* option in *notify* method. This is the same operation as calling *notify_later* method.
516
-
517
- ```ruby
518
- @comment.notify :users, key: "comment.reply", notify_later: true
519
- ```
520
-
521
- *Note*: *notify_now* is an alias for *notify* and does the same.
522
-
523
- When you use asynchronous notification API, you should setup ActiveJob with background queuing service such as Sidekiq.
524
- You can set *config.active_job_queue* in your initializer to specify a queue name *activity_notification* will use.
525
- The default queue name is *:activity_notification*.
526
-
527
- ```ruby
528
- # Configure ActiveJob queue name for delayed notifications.
529
- config.active_job_queue = :my_notification_queue
530
- ```
531
-
532
- #### Automatic tracked notifications
533
-
534
- You can also generate automatic tracked notifications by **:tracked** option in *acts_as_notifiable*.
535
- *:tracked* option adds required callbacks to generate notifications for creation and update of the notifiable model.
536
- Set true to *:tracked* option to generate all tracked notifications, like this:
537
-
538
- ```ruby
539
- class Comment < ActiveRecord::Base
540
- acts_as_notifiable :users,
541
- targets: ->(comment, key) {
542
- ([comment.article.user] + comment.article.commented_users.to_a - [comment.user]).uniq
543
- },
544
- # Set true to :tracked option to generate automatic tracked notifications.
545
- # It adds required callbacks to generate notifications for creation and update of the notifiable model.
546
- tracked: true
547
- end
548
- ```
549
-
550
- Or, set *:only* or *:except* option to generate specified tracked notifications, like this:
551
-
552
- ```ruby
553
- class Comment < ActiveRecord::Base
554
- acts_as_notifiable :users,
555
- targets: ->(comment, key) {
556
- ([comment.article.user] + comment.article.commented_users.to_a - [comment.user]).uniq
557
- },
558
- # Set { only: [:create] } to :tracked option to generate tracked notifications for creation only.
559
- # It adds required callbacks to generate notifications for creation of the notifiable model.
560
- tracked: { only: [:create] }
561
- end
562
- ```
563
-
564
- ```ruby
565
- class Comment < ActiveRecord::Base
566
- acts_as_notifiable :users,
567
- targets: ->(comment, key) {
568
- ([comment.article.user] + comment.article.commented_users.to_a - [comment.user]).uniq
569
- },
570
- # Set { except: [:update] } to :tracked option to generate tracked notifications except update (creation only).
571
- # It adds required callbacks to generate notifications for creation of the notifiable model.
572
- tracked: { except: [:update], key: 'comment.create.now', send_later: false }
573
- end
574
- ```
575
-
576
- *Hint*: `#{notifiable_type}.create` and `#{notifiable_type}.update` will be used as the key of tracked notifications.
577
- You can override them by *Notifiable#notification_key_for_tracked_creation* and *Notifiable#notification_key_for_tracked_update*.
578
- You can also specify key option in the *:tracked* statement.
579
-
580
- As a default, the notifications will be generated synchronously along with model creation or update. If you want to generate notifications asynchronously, use *:notify_later* option with the *:tracked* option, like this:
581
-
582
- ```ruby
583
- class Comment < ActiveRecord::Base
584
- acts_as_notifiable :users,
585
- targets: ->(comment, key) {
586
- ([comment.article.user] + comment.article.commented_users.to_a - [comment.user]).uniq
587
- },
588
- # It adds required callbacks to generate notifications asynchronously for creation of the notifiable model.
589
- tracked: { only: [:create], key: 'comment.create.later', notify_later: true }
590
- end
591
- ```
279
+ See [Creating notifications](/docs/Setup.md#creating-notifications) for more details.
592
280
 
593
281
  ### Displaying notifications
594
282
 
595
- #### Preparing target notifications
596
-
597
- To display notifications, you can use **notifications** association of the target model:
598
-
599
- ```ruby
600
- # custom_notifications_controller.rb
601
- def index
602
- @notifications = @target.notifications
603
- end
604
- ```
605
-
606
- You can also use several scope to filter notifications. For example, **unopened_only** to filter them unopened notifications only.
607
-
608
- ```ruby
609
- # custom_notifications_controller.rb
610
- def index
611
- @notifications = @target.notifications.unopened_only
612
- end
613
- ```
614
-
615
- Moreover, you can use **notification_index** or **notification_index_with_attributes** methods to automatically prepare notification index for the target.
616
-
617
- ```ruby
618
- # custom_notifications_controller.rb
619
- def index
620
- @notifications = @target.notification_index_with_attributes
621
- end
622
- ```
623
-
624
- #### Rendering notifications
625
-
626
- You can use **render_notifications** helper in your views to show the notification index:
627
-
628
- ```erb
629
- <%= render_notifications(@notifications) %>
630
- ```
631
-
632
- We can set *:target* option to specify the target type of notifications:
633
-
634
- ```erb
635
- <%= render_notifications(@notifications, target: :users) %>
636
- ```
637
-
638
- *Note*: *render_notifications* is an alias for *render_notification* and does the same.
639
-
640
- If you want to set notification index in the common layout, such as common header, you can use **render_notifications_of** helper like this:
641
-
642
- ```shared/_header.html.erb
643
- <%= render_notifications_of current_user, index_content: :with_attributes %>
644
- ```
283
+ *activity_notification* also provides notification views. You can prepare target notifications, render them in your controller, and show them provided or custom notification views.
645
284
 
646
- Then, content named **:notification_index** will be prepared and you can use it in your partial template.
285
+ See [Displaying notifications](/docs/Setup.md#displaying-notifications) for more details.
647
286
 
648
- ```activity_notifications/notifications/users/_index.html.erb
649
- ...
650
- <%= yield :notification_index %>
651
- ...
652
- ```
287
+ ### Run example Rails application
653
288
 
654
- Sometimes, it's desirable to pass additional local variables to partials. It can be done this way:
289
+ Test module includes example Rails application in *[spec/rails_app](/spec/rails_app)*.
290
+ Pull git repository and you can run the example application as common Rails application.
655
291
 
656
- ```erb
657
- <%= render_notification(@notification, locals: { friends: current_user.friends }) %>
292
+ ```console
293
+ $ git pull https://github.com/simukappu/activity_notification.git
294
+ $ cd activity_notification
295
+ $ bundle install —path vendor/bundle
296
+ $ cd spec/rails_app
297
+ $ bin/rake db:migrate
298
+ $ bin/rake db:seed
299
+ $ bin/rails server
658
300
  ```
301
+ Then, you can access <http://localhost:3000> for the example application.
659
302
 
660
- #### Notification views
661
-
662
- *activity_notification* looks for views in *app/views/activity_notification/notifications/:target* with **:key** of the notifications.
663
-
664
- For example, if you have a notification with *:key* set to *"notification.comment.reply"* and rendered it with *:target* set to *:users*, the gem will look for a partial in *app/views/activity_notification/notifications/users/comment/_reply.html.(|erb|haml|slim|something_else)*.
665
303
 
666
- *Hint*: the *"notification."* prefix in *:key* is completely optional, you can skip it in your projects or use this prefix only to make namespace.
304
+ ## Setup
667
305
 
668
- If you would like to fallback to a partial, you can utilize the **:fallback** parameter to specify the path of a partial to use when one is missing:
306
+ See [Setup](/docs/Setup.md#Setup).
669
307
 
670
- ```erb
671
- <%= render_notification(@notification, target: :users, fallback: :default) %>
672
- ```
673
308
 
674
- When used in this manner, if a partial with the specified *:key* cannot be located, it will use the partial defined in the *:fallback* instead. In the example above this would resolve to *activity_notification/notifications/users/_default.html.(|erb|haml|slim|something_else)*.
309
+ ## Functions
675
310
 
676
- If you do not specify *:target* option like this,
311
+ See [Functions](/docs/Functions.md#Functions).
677
312
 
678
- ```erb
679
- <%= render_notification(@notification, fallback: :default) %>
680
- ```
681
313
 
682
- the gem will look for a partial in *default* as the target type which means *activity_notification/notifications/default/_default.html.(|erb|haml|slim|something_else)*.
314
+ ## Testing
683
315
 
684
- If a view file does not exist then *ActionView::MisingTemplate* will be raised. If you wish to fallback to the old behaviour and use an i18n based translation in this situation you can specify a *:fallback* parameter of *:text* to fallback to this mechanism like such:
316
+ See [Testing](/docs/Testing.md#Testing).
685
317
 
686
- ```erb
687
- <%= render_notification(@notification, fallback: :text) %>
688
- ```
689
318
 
690
- Finally, default views of *activity_notification* depends on jQuery and you have to add requirements to *application.js* in your apps:
319
+ ## Documentation
691
320
 
692
- ```app/assets/javascripts/application.js
693
- //= require jquery
694
- //= require jquery_ujs
695
- ```
321
+ See [API Reference](http://www.rubydoc.info/github/simukappu/activity_notification/index) for more details.
696
322
 
697
- #### i18n for notifications
698
-
699
- Translations are used by the *#text* method, to which you can pass additional options in form of a hash. *#render* method uses translations when view templates have not been provided. You can render pure i18n strings by passing `{ i18n: true }` to *#render_notification* or *#render*.
700
-
701
- Translations should be put in your locale *.yml* files as **text** field. To render pure strings from I18n example structure:
702
-
703
- ```yaml
704
- notification:
705
- user:
706
- article:
707
- create:
708
- text: 'Article has been created'
709
- update:
710
- text: 'Article %{article_title} has been updated'
711
- destroy:
712
- text: 'Some user removed an article!'
713
- comment:
714
- create:
715
- text: '%{notifier_name} posted a comment on the article "%{article_title}"'
716
- post:
717
- text:
718
- one: "<p>%{notifier_name} posted a comment on your article %{article_title}</p>"
719
- other: "<p>%{notifier_name} posted %{count} comments on your article %{article_title}</p>"
720
- reply:
721
- text: "<p>%{notifier_name} and %{group_member_count} other people replied %{group_notification_count} times to your comment</p>"
722
- mail_subject: 'New comment on your article'
723
- admin:
724
- article:
725
- post:
726
- text: '[Admin] Article has been created'
323
+ RubyDoc.info does not support parsing methods in *included* and *class_methods* of *ActiveSupport::Concern* currently.
324
+ To read complete documents, please generate YARD documents on your local environment:
325
+ ```console
326
+ $ git pull https://github.com/simukappu/activity_notification.git
327
+ $ cd activity_notification
328
+ $ bundle install —path vendor/bundle
329
+ $ bundle exec yard doc
330
+ $ bundle exec yard server
727
331
  ```
332
+ Then you can see the documents at <http://localhost:8808/docs/index>.
728
333
 
729
- This structure is valid for notifications with keys *"notification.comment.reply"* or *"comment.reply"*. As mentioned before, *"notification."* part of the key is optional. In addition for above example, `%{notifier_name}` and `%{article_title}` are used from parameter field in the notification record. Pluralization is supported (but optional) for grouped notifications using the `%{group_notification_count}` value.
730
-
731
- ### Customizing controllers (optional)
732
-
733
- If the customization at the views level is not enough, you can customize each controller by following these steps:
734
-
735
- 1. Create your custom controllers using the generator with a target:
736
-
737
- ```console
738
- $ bin/rails generate activity_notification:controllers users
739
- ```
740
-
741
- If you specify *users* as the target, controllers will be created in *app/controllers/users*.
742
- And the notifications controller will look like this:
743
-
744
- ```ruby
745
- class Users::NotificationsController < ActivityNotification::NotificationsController
746
- # GET /:target_type/:target_id/notifications
747
- # def index
748
- # super
749
- # end
750
-
751
- # ...
752
-
753
- # POST /:target_type/:target_id/notifications/:id/open
754
- # def open
755
- # super
756
- # end
757
-
758
- # ...
759
- end
760
- ```
761
-
762
- 2. Tell the router to use this controller:
763
-
764
- ```ruby
765
- notify_to :users, controller: 'users/notifications'
766
- ```
767
-
768
- 3. Finally, change or extend the desired controller actions.
769
-
770
- You can completely override a controller action
771
- ```ruby
772
- class Users::NotificationsController < ActivityNotification::NotificationsController
773
- # ...
774
-
775
- # POST /:target_type/:target_id/notifications/:id/open
776
- def open
777
- # Custom code to open notification here
778
334
 
779
- # super
780
- end
335
+ ## Common Examples
781
336
 
782
- # ...
783
- end
784
- ```
337
+ See example Rails application in *[/spec/rails_app](/spec/rails_app)*.
785
338
 
339
+ You can also try this example Rails application as Online Demo here:
340
+ * **https://activity-notification-example.herokuapp.com/**
786
341
 
787
- ## Functions
342
+ You can login as test users to experience user activity notifications. For more details, see [Online Demo](#online-demo).
788
343
 
789
- ### Email notification
790
344
 
791
- *activity_notification* provides email notification to the notification targets.
345
+ ## Contributing
792
346
 
793
- #### Mailer setup
347
+ We encourage you to contribute to *activity_notification*!
348
+ Please check out the [Contributing to *activity_notification* guide](/docs/CONTRIBUTING.md#how-to-contribute-to-activity_notification) for guidelines about how to proceed.
794
349
 
795
- Set up SMTP server configuration for *ActionMailer*. Then, you need to set up the default URL options for the *activity_notification* mailer in each environment. Here is a possible configuration for *config/environments/development.rb*:
796
-
797
- ```ruby
798
- config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
799
- ```
800
-
801
- Email notification is disabled as default. You can configure it to enable email notification in initializer *activity_notification.rb*.
802
-
803
- ```ruby
804
- config.email_enabled = true
805
- ```
806
-
807
- You can also configure them for each model by *acts_as roles* like these:
808
-
809
- ```ruby
810
- class User < ActiveRecord::Base
811
- # Example using confirmed_at of devise field
812
- # to decide whether activity_notification sends notification email to this user
813
- acts_as_target email: :email, email_allowed: :confirmed_at
814
- end
815
- ```
816
-
817
- ```ruby
818
- class Comment < ActiveRecord::Base
819
- belongs_to :article
820
- belongs_to :user
821
-
822
- acts_as_notifiable :users,
823
- targets: ->(comment, key) {
824
- ([comment.article.user] + comment.article.commented_users.to_a - [comment.user]).uniq
825
- },
826
- # Allow notification email
827
- email_allowed: true,
828
- notifiable_path: :article_notifiable_path
829
-
830
- def article_notifiable_path
831
- article_path(article)
832
- end
833
- end
834
- ```
835
-
836
- #### Sender configuration
837
-
838
- You can configure the notification *"from"* address inside of *activity_notification.rb* in two ways.
839
-
840
- Using a simple email address as *String*:
841
-
842
- ```ruby
843
- config.mailer_sender = 'your_notification_sender@example.com'
844
- ```
845
-
846
- Using a *Proc* to configure the sender based on the *notification.key*:
847
-
848
- ```ruby
849
- config.mailer_sender = ->(key){ key == 'inquiry.post' ? 'support@example.com' : 'noreply@example.com' }
850
- ```
851
-
852
- #### Email templates
853
-
854
- *activity_notification* will look for email template in a similar way as notification views, but the view file name is not start with an underscore. For example, if you have a notification with *:key* set to *"notification.comment.reply"* and target_type *users*, the gem will look for a partial in *app/views/activity_notification/mailer/users/comment/reply.html.(|erb|haml|slim|something_else)*.
855
-
856
- If this template is missing, the gem will look for a partial in *default* as the target type which means *activity_notification/mailer/default/_default.html.(|erb|haml|slim|something_else)*.
857
-
858
- #### Email subject
859
-
860
- *activity_notification* will use `"Notification of #{@notification.notifiable.printable_type.downcase}"` as default email subject. If it is defined, *activity_notification* will resolve email subject from *overriding_notification_email_subject* method in notifiable models. You can customize email subject like this:
861
-
862
- ```
863
- class Comment < ActiveRecord::Base
864
- belongs_to :article
865
- belongs_to :user
866
-
867
- acts_as_notifiable :users,
868
- targets: ->(comment, key) {
869
- ([comment.article.user] + comment.article.commented_users.to_a - [comment.user]).uniq
870
- },
871
- notifiable_path: :article_notifiable_path
872
-
873
- def overriding_notification_email_subject(target, key)
874
- if key == "comment.create"
875
- "New comment to your article!"
876
- else
877
- "Notification for new comments!"
878
- end
879
- end
880
- end
881
-
882
- ```
883
-
884
- If you use i18n for email, you can configure email subject in your locale files. See [i18n for email](#i18n-for-email).
885
-
886
- #### i18n for email
887
-
888
- The subject of notification email can be put in your locale *.yml* files as **mail_subject** field:
889
-
890
- ```yaml
891
- notification:
892
- user:
893
- comment:
894
- post:
895
- text: "<p>Someone posted comments to your article</p>"
896
- mail_subject: 'New comment to your article'
897
- ```
898
-
899
- ### Batch email notification
900
-
901
- *activity_notification* provides batch email notification to the notification targets. You can send notification email daily, hourly or weekly and so on with a scheduler like *whenever*.
902
-
903
- #### Batch mailer setup
904
-
905
- Set up SMTP server configuration for *ActionMailer* and the default URL options for the *activity_notification* mailer in each environment.
906
-
907
- Batch email notification is disabled as default. You can configure it to enable email notification in initializer *activity_notification.rb* like single email notification.
908
-
909
- ```ruby
910
- config.email_enabled = true
911
- ```
912
-
913
- You can also configure them for each target model by *acts_as_target* role like this.
914
-
915
- ```ruby
916
- class User < ActiveRecord::Base
917
- # Example using confirmed_at of devise field
918
- # to decide whether activity_notification sends batch notification email to this user
919
- acts_as_target email: :email, batch_email_allowed: :confirmed_at
920
- end
921
- ```
922
-
923
- Then, you can send batch notification email for unopened notifications only to the all specified targets with *batch_key*.
924
-
925
- ```ruby
926
- # Send batch notification email to the users with unopened notifications
927
- User.send_batch_unopened_notification_email(batch_key: 'batch.comment.post')
928
- ```
929
-
930
- You can also add conditions to filter notifications, like this:
931
-
932
- ```ruby
933
- # Send batch notification email to the users with unopened notifications of specified key in 1 hour
934
- User.send_batch_unopened_notification_email(batch_key: 'batch.comment.post', filtered_by_key: 'comment.post', custom_filter: ["created_at >= ?", time.hour.ago])
935
- ```
936
-
937
- #### Batch sender configuration
938
-
939
- *activity_notification* uses same sender configuration of real-time email notification as batch email sender.
940
- You can configure *config.mailer_sender* as simply *String* or *Proc* based on the *batch_key*:
941
-
942
- ```ruby
943
- config.mailer_sender = ->(batch_key){ batch_key == 'batch.inquiry.post' ? 'support@example.com' : 'noreply@example.com' }
944
- ```
945
-
946
- *batch_key* is specified by **:batch_key** option. If this option is not specified, the key of the first notification will be used as *batch_key*.
947
-
948
- #### Batch email templates
949
-
950
- *activity_notification* will look for batch email template in the same way as email notification using *batch_key*.
951
-
952
- #### Batch email subject
953
-
954
- *activity_notification* will resolve batch email subject as the same way as [email subject](#email-subject) with *batch_key*.
955
-
956
- If you use i18n for batch email, you can configure batch email subject in your locale files. See [i18n for batch email](#i18n-for-batch-email).
957
-
958
- #### i18n for batch email
959
-
960
- The subject of batch notification email also can be put in your locale *.yml* files as **mail_subject** field for *batch_key*.
961
-
962
- ```yaml
963
- notification:
964
- user:
965
- batch:
966
- comment:
967
- post:
968
- mail_subject: 'New comments to your article'
969
- ```
970
-
971
- ### Grouping notifications
972
-
973
- *activity_notification* provides the function for automatically grouping notifications. When you created a notification like this, all *unopened* notifications to the same target will be grouped by *article* set as **:group** options:
974
-
975
- ```ruby
976
- @comment.notify :users key: 'comment.post', group: @comment.article
977
- ```
978
-
979
- When you use default notification view, it is helpful to configure **acts_as_notification_group** (or *acts_as_group*) with *:printable_name* option to render group instance.
980
-
981
- ```ruby
982
- class Article < ActiveRecord::Base
983
- belongs_to :user
984
- acts_as_notification_group printable_name: ->(article) { "article \"#{article.title}\"" }
985
- end
986
- ```
987
-
988
- You can use **group_owners_only** scope to filter owner notifications representing each group:
989
-
990
- ```ruby
991
- # custom_notifications_controller.rb
992
- def index
993
- @notifications = @target.notifications.group_owners_only
994
- end
995
- ```
996
- *notification_index* and *notification_index_with_attributes* methods also use *group_owners_only* scope internally.
997
-
998
- And you can render them in a view like this:
999
- ```erb
1000
- <% if notification.group_member_exists? %>
1001
- <%= "#{notification.notifier.name} and #{notification.group_member_count} other users" %>
1002
- <% else %>
1003
- <%= "#{notification.notifier.name}" %>
1004
- <% end %>
1005
- <%= "posted comments to your article \"#{notification.group.title}\"" %>
1006
- ```
1007
-
1008
- This presentation will be shown to target users as *Kevin and 7 other users posted comments to your article "Let's use Ruby"*.
1009
-
1010
- You can also use `%{group_member_count}`, `%{group_notification_count}`, `%{group_member_notifier_count}` and `%{group_notifier_count}` in i18n text as a field:
1011
-
1012
- ```yaml
1013
- notification:
1014
- user:
1015
- comment:
1016
- post:
1017
- text: "<p>%{notifier_name} and %{group_member_notifier_count} other users posted %{group_notification_count} comments to your article</p>"
1018
- mail_subject: 'New comment to your article'
1019
- ```
1020
-
1021
- Then, you will see *"Kevin and 7 other users posted 10 comments to your article"*.
1022
-
1023
-
1024
- ### Subscription management
1025
-
1026
- *activity_notification* provides the function for subscription management of notifications and notification email.
1027
-
1028
- #### Configuring subscriptions
1029
-
1030
- Subscription management is disabled as default. You can configure it to enable subscription management in initializer *activity_notification.rb*.
1031
-
1032
- ```ruby
1033
- config.subscription_enabled = true
1034
- ```
1035
-
1036
- This makes all target model subscribers. You can also configure them for each target model by *acts_as_target* role like this:
1037
-
1038
- ```ruby
1039
- class User < ActiveRecord::Base
1040
- # Example using confirmed_at of devise field
1041
- # to decide whether activity_notification manages subscriptions of this user
1042
- acts_as_target email: :email, email_allowed: :confirmed_at, subscription_allowed: :confirmed_at
1043
- end
1044
- ```
1045
-
1046
- If you do not have a subscriptions table in you database, create a migration for subscriptions and migrate the database in your Rails project:
1047
-
1048
- ```console
1049
- $ bin/rails generate activity_notification:migration CreateSubscriptions -t subscriptions
1050
- $ bin/rake db:migrate
1051
- ```
1052
- If you are using a different table name than the default "subscriptions", change the settings in your config/initializers/activity_notification.rb file, e.g, if you use the table name "notifications_subscription" instead:
1053
-
1054
- ```
1055
- config.subscription_table_name = "notifications_subscriptions"
1056
- ```
1057
-
1058
- #### Managing subscriptions
1059
-
1060
- Subscriptions are managed by instances of **ActivityNotification::Subscription** model which belongs to *target* and *key* of the notification.
1061
- *Subscription#subscribing* manages subscription of notifications.
1062
- *true* means the target will receive the notifications with this key.
1063
- *false* means the target will not receive these notifications.
1064
- *Subscription#subscribing_to_email* manages subscription of notification email.
1065
- *true* means the target will receive the notification email with this key including batch notification email with this *batch_key*.
1066
- *false* means the target will not receive these notification email.
1067
-
1068
- As default, all target subscribes to notification and notification email when subscription record does not exist in your database.
1069
- You can change this **subscribe_as_default** parameter in initializer *activity_notification.rb*.
1070
-
1071
- ```ruby
1072
- config.subscribe_as_default = false
1073
- ```
1074
-
1075
- Then, all target does not subscribe to notification and notification email and will not receive any notifications as default.
1076
-
1077
- You can create subscription record from subscription API in your target model like this:
1078
-
1079
- ```ruby
1080
- # Subscribe 'comment.reply' notifications and notification email
1081
- user.create_subscription(key: 'comment.reply')
1082
-
1083
- # Subscribe 'comment.reply' notifications but does not subscribe notification email
1084
- user.create_subscription(key: 'comment.reply', subscribing_to_email: false)
1085
-
1086
- # Unsubscribe 'comment.reply' notifications and notification email
1087
- user.create_subscription(key: 'comment.reply', subscribing: false)
1088
- ```
1089
-
1090
- You can also update subscriptions like this:
1091
-
1092
- ```ruby
1093
- # Subscribe 'comment.reply' notifications and notification email
1094
- user.find_or_create_subscription('comment.reply').subscribe
1095
-
1096
- # Unsubscribe 'comment.reply' notifications and notification email
1097
- user.find_or_create_subscription('comment.reply').unsubscribe
1098
-
1099
- # Unsubscribe 'comment.reply' notification email
1100
- user.find_or_create_subscription('comment.reply').unsubscribe_to_email
1101
- ```
1102
-
1103
- #### Customizing subscriptions
1104
-
1105
- *activity_notification* provides basic controllers and views to manage the subscriptions.
1106
-
1107
- Add subscription routing to *config/routes.rb* for the target (e.g. *:users*):
1108
-
1109
- ```ruby
1110
- Rails.application.routes.draw do
1111
- subscribed_by :users
1112
- end
1113
- ```
1114
-
1115
- or, you can also configure it with notifications like this:
1116
-
1117
- ```ruby
1118
- Rails.application.routes.draw do
1119
- notify_to :users, with_subscription: true
1120
- end
1121
- ```
1122
-
1123
- Then, you can access *users/1/subscriptions* and use *[ActivityNotification::SubscriptionsController](/app/controllers/activity_notification/subscriptions_controller.rb)* or *[ActivityNotification::SubscriptionsWithDeviseController](/app/controllers/activity_notification/subscriptions_with_devise_controller.rb)* to manage the subscriptions.
1124
-
1125
- If you would like to customize subscription controllers or views, you can use generators like notifications:
1126
-
1127
- * Customize subscription controllers
1128
-
1129
- 1. Create your custom controllers using controller generator with a target:
1130
-
1131
- ```console
1132
- $ bin/rails generate activity_notification:controllers users -c subscriptions subscriptions_with_devise
1133
- ```
1134
-
1135
- 2. Tell the router to use this controller:
1136
-
1137
- ```ruby
1138
- notify_to :users, with_subscription: { controller: 'users/subscriptions' }
1139
- ```
1140
-
1141
- * Customize subscription views
1142
-
1143
- ```console
1144
- $ bin/rails generate activity_notification:views users -v subscriptions
1145
- ```
1146
-
1147
-
1148
- ### Integration with Devise
1149
-
1150
- *activity_notification* supports to integrate with devise authentication.
1151
-
1152
- #### Configuring integration with Devise authentication
1153
-
1154
- Add **:with_devise** option in notification routing to *config/routes.rb* for the target:
1155
-
1156
- ```ruby
1157
- Rails.application.routes.draw do
1158
- devise_for :users
1159
- # Integrated with devise
1160
- notify_to :users, with_devise: :users
1161
- end
1162
- ```
1163
-
1164
- Then *activity_notification* will use *[ActivityNotification::NotificationsWithDeviseController](/app/controllers/activity_notification/notifications_with_devise_controller.rb)* as a notification controller. The controller actions automatically call *authenticate_user!* and the user will be restricted to access and operate own notifications only, not others'.
1165
-
1166
- *Hint*: HTTP 403 Forbidden will be returned for unauthorized notifications.
1167
-
1168
- #### Using different model as target
1169
-
1170
- You can also use different model from Devise resource as a target. When you will add this to *config/routes.rb*:
1171
-
1172
- ```ruby
1173
- Rails.application.routes.draw do
1174
- devise_for :users
1175
- # Integrated with devise for different model
1176
- notify_to :admins, with_devise: :users
1177
- end
1178
- ```
1179
-
1180
- and add **:devise_resource** option to *acts_as_target* in the target model:
1181
-
1182
- ```ruby
1183
- class Admin < ActiveRecord::Base
1184
- belongs_to :user
1185
- acts_as_target devise_resource: :user
1186
- end
1187
- ```
1188
-
1189
- *activity_notification* will authenticate *:admins* notifications with devise authentication for *:users*.
1190
- In this example, *activity_notification* will confirm *admin* belonging to authenticated *user* by Devise.
1191
-
1192
- #### Configuring simple default routes
1193
-
1194
- You can configure simple default routes for authenticated users, like */notifications* instead of */users/1/notifications*. Use *:devise_default_routes* option like this:
1195
-
1196
- ```ruby
1197
- Rails.application.routes.draw do
1198
- devise_for :users
1199
- notify_to :users, with_devise: :users, devise_default_routes: true
1200
- end
1201
- ```
1202
-
1203
- If you use multiple notification targets with Devise, you can also use this option with scope like this:
1204
-
1205
- ```ruby
1206
- Rails.application.routes.draw do
1207
- devise_for :users
1208
- # Integrated with devise for different model, and use with scope
1209
- scope :admins, as: :admins do
1210
- notify_to :admins, with_devise: :users, devise_default_routes: true, routing_scope: :admins
1211
- end
1212
- end
1213
- ```
1214
-
1215
- Then, you can access */admins/notifications* instead of */admins/1/notifications*.
1216
-
1217
-
1218
- ### Push notification with Action Cable
1219
-
1220
- *activity_notification* supports push notification with Action Cable by WebSocket.
1221
- *activity_notification* only provides Action Cable channels implementation, does not connections.
1222
- You can use default implementaion in Rails or your custom `ApplicationCable::Connection` for Action Cable connections.
1223
-
1224
- #### Enabling broadcasting notifications to channels
1225
-
1226
- Broadcasting notifications to Action Cable channels is disabled as default. You can configure it to enable Action Cable broadcasting in initializer *activity_notification.rb*.
1227
-
1228
- ```ruby
1229
- config.action_cable_enabled = true
1230
- ```
1231
-
1232
- You can also configure them for each model by *acts_as roles* like these:
1233
-
1234
- ```ruby
1235
- class User < ActiveRecord::Base
1236
- # Allow Action Cable broadcasting
1237
- acts_as_target action_cable_allowed: true
1238
- end
1239
- ```
1240
-
1241
- ```ruby
1242
- class Comment < ActiveRecord::Base
1243
- belongs_to :article
1244
- belongs_to :user
1245
-
1246
- acts_as_notifiable :users,
1247
- targets: ->(comment, key) {
1248
- ([comment.article.user] + comment.article.commented_users.to_a - [comment.user]).uniq
1249
- },
1250
- # Allow Action Cable broadcasting
1251
- action_cable_allowed: true
1252
- end
1253
- ```
1254
-
1255
- Then, *activity_notification* will broadcast configured notidications to target channels by *[ActivityNotification::NotificationApi](/lib/activity_notification/apis/notification_api.rb)#broadcast_to_action_cable_channel* method.
1256
-
1257
- #### Subscribing notifications from channels
1258
-
1259
- *activity_notification* provides *[ActivityNotification::NotificationChannel](/app/channels/activity_notification/notification_channel.rb)* to subscribe broadcasted notifications with Action Cable.
1260
-
1261
- You can simply create subscriptions for the specified target in your view like this:
1262
-
1263
- ```js
1264
- <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/push.js/1.0.9/push.min.js"></script>
1265
- <script>
1266
- App.activity_notification = App.cable.subscriptions.create(
1267
- {
1268
- channel: "ActivityNotification::NotificationChannel",
1269
- target_type: "<%= @target.to_class_name %>", target_id: "<%= @target.id %>"
1270
- },
1271
- {
1272
- connected: function() {
1273
- // Connected
1274
- },
1275
- disconnected: function() {
1276
- // Disconnected
1277
- },
1278
- rejected: function() {
1279
- // Rejected
1280
- },
1281
- received: function(notification) {
1282
- // Display notification
1283
-
1284
- // Push notificaion using Web Notification API by Push.js
1285
- Push.create('ActivityNotification', {
1286
- body: notification.text,
1287
- timeout: 5000,
1288
- onClick: function () {
1289
- location.href = notification.notifiable_path;
1290
- this.close();
1291
- }
1292
- });
1293
- }
1294
- }
1295
- );
1296
- </script>
1297
- ```
1298
-
1299
- Then, *activity_notification* will push desktop notification using Web Notification API.
1300
-
1301
- #### Subscribing notifications with Devise authentication
1302
-
1303
- To use Devise integration, enable subscribing notifications with Devise authentication in initializer *activity_notification.rb*.
1304
-
1305
- ```ruby
1306
- config.action_cable_with_devise = true
1307
- ```
1308
-
1309
- You can also configure them for each target model by *acts_as_target* like this:
1310
-
1311
- ```ruby
1312
- class User < ActiveRecord::Base
1313
- # Allow Action Cable broadcasting and enable subscribing notifications with Devise authentication
1314
- acts_as_target action_cable_allowed: true, action_cable_with_devise: true
1315
- end
1316
- ```
1317
-
1318
- When you set *action_cable_with_devise* option to *true*, `ActivityNotification::NotificationChannel` will reject your subscription requests for the target type.
1319
-
1320
- *activity_notification* also provides *[ActivityNotification::NotificationWithDeviseChannel](/app/channels/activity_notification/notification_with_devise_channel.rb)* to create subscriptions integrated with Devise authentication.
1321
- You can simply use `ActivityNotification::NotificationWithDeviseChannel` instead of `ActivityNotification::NotificationChannel`:
1322
-
1323
- ```js
1324
- App.activity_notification = App.cable.subscriptions.create(
1325
- {
1326
- channel: "ActivityNotification::NotificationWithDeviseChannel",
1327
- target_type: "<%= @target.to_class_name %>", target_id: "<%= @target.id %>"
1328
- },
1329
- {
1330
- // ...
1331
- }
1332
- );
1333
- ```
1334
-
1335
- You can also create these subscriptions with *devise_type* parameter instead of *target_id* parameter like this:
1336
-
1337
- ```js
1338
- App.activity_notification = App.cable.subscriptions.create(
1339
- {
1340
- channel: "ActivityNotification::NotificationWithDeviseChannel",
1341
- target_type: "users", devise_type: "users"
1342
- },
1343
- {
1344
- // ...
1345
- }
1346
- );
1347
- ```
1348
-
1349
- `ActivityNotification::NotificationWithDeviseChannel` will confirm subscription requests from authenticated cookies by Devise. If the user has not signed in, the subscription request will be rejected. If the user has signed in as unauthorized user, the subscription request will be also rejected.
1350
-
1351
- In addtion, you can use `Target#notification_action_cable_channel_class_name` method to select channel class depending on your *action_cable_with_devise* configuration for the target.
1352
-
1353
- ```js
1354
- App.activity_notification = App.cable.subscriptions.create(
1355
- {
1356
- channel: "<%= @target.notification_action_cable_channel_class_name %>",
1357
- target_type: "<%= @target.to_class_name %>", target_id: "<%= @target.id %>"
1358
- },
1359
- {
1360
- // ...
1361
- }
1362
- );
1363
- ```
1364
-
1365
- This script is also implemented in [default notifications index view](/app/views/activity_notification/notifications/default/index.html.erb) of *activity_notification*.
1366
-
1367
-
1368
- ### Optional notification targets
1369
-
1370
- *activity_notification* supports configurable optional notification targets like Amazon SNS, Slack, SMS and so on.
1371
-
1372
- #### Configuring optional targets
1373
-
1374
- *activity_notification* provides default optional target implementation for Amazon SNS and Slack.
1375
- You can develop any optional target classes which extends *ActivityNotification::OptionalTarget::Base*, and configure them to notifiable model by *acts_as_notifiable* like this:
1376
-
1377
- ```ruby
1378
- class Comment < ActiveRecord::Base
1379
- belongs_to :article
1380
- belongs_to :user
1381
-
1382
- require 'activity_notification/optional_targets/amazon_sns'
1383
- require 'activity_notification/optional_targets/slack'
1384
- require 'custom_optional_targets/console_output'
1385
- acts_as_notifiable :admins, targets: [Admin.first].compact,
1386
- notifiable_path: :article_notifiable_path,
1387
- # Set optional target implementation class and initializing parameters
1388
- optional_targets: {
1389
- ActivityNotification::OptionalTarget::AmazonSNS => { topic_arn: 'arn:aws:sns:XXXXX:XXXXXXXXXXXX:XXXXX' },
1390
- ActivityNotification::OptionalTarget::Slack => {
1391
- webhook_url: 'https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX',
1392
- slack_name: :slack_name, channel: 'activity_notification', username: 'ActivityNotification', icon_emoji: ":ghost:"
1393
- },
1394
- CustomOptionalTarget::ConsoleOutput => {}
1395
- }
1396
-
1397
- def article_notifiable_path
1398
- article_path(article)
1399
- end
1400
- end
1401
- ```
1402
-
1403
- Write *require* statement for optional target implementation classes and set them with initializing parameters to *acts_as_notifiable*.
1404
- *activity_notification* will publish all notifications of those targets and notifiables to optional targets.
1405
-
1406
- #### Customizing message format
1407
-
1408
- Optional targets prepare publishing messages from notification instance using view template like rendering notifications.
1409
- As default, all optional targets use *app/views/activity_notification/optional_targets/default/base/_default.text.erb*.
1410
- You can customize this template by creating *app/views/activity_notification/optional_targets/<target_class_name>/<optional_target_class_name>/<notification_key>.text.(|erb|haml|slim|something_else)*.
1411
- For example, if you have a notification for *:users* target with *:key* set to *"notification.comment.reply"* and *ActivityNotification::OptionalTarget::AmazonSNS* optional target is configured, the gem will look for a partial in *app/views/activity_notification/optional_targets/users/amazon_sns/comment/_reply.text.erb*.
1412
- The gem will also look for templates whose *<target_class_name>* is *default*, *<optional_target_class_name>* is *base* and *<notification_key>* is *default*, which means *app/views/activity_notification/optional_targets/users/amazon_sns/_default.text.erb*, *app/views/activity_notification/optional_targets/users/base/_default.text.erb*, *app/views/activity_notification/optional_targets/default/amazon_sns/_default.text.erb* and *app/views/activity_notification/optional_targets/default/base/_default.text.erb*.
1413
-
1414
- #### Amazon SNS as optional target
1415
-
1416
- *activity_notification* provides **ActivityNotification::OptionalTarget::AmazonSNS** as default optional target implementation for Amazon SNS.
1417
-
1418
- First, add **aws-sdk** or **aws-sdk-sns** (>= AWS SDK for Ruby v3) gem to your Gemfile and set AWS Credentials for SDK (See [Configuring the AWS SDK for Ruby](https://docs.aws.amazon.com/sdk-for-ruby/v3/developer-guide/setup-config.html)).
1419
-
1420
- ```ruby
1421
- gem 'aws-sdk', '~> 2'
1422
- # --- or ---
1423
- gem 'aws-sdk-sns', '~> 1'
1424
- ```
1425
-
1426
- ```ruby
1427
- require 'aws-sdk'
1428
- # --- or ---
1429
- require 'aws-sdk-sns'
1430
-
1431
- Aws.config.update(
1432
- region: 'your_region',
1433
- credentials: Aws::Credentials.new('your_access_key_id', 'your_secret_access_key')
1434
- )
1435
- ```
1436
-
1437
- Then, write `require 'activity_notification/optional_targets/amazon_sns'` statement in your notifiable model and set *ActivityNotification::OptionalTarget::AmazonSNS* to *acts_as_notifiable* with *:topic_arn*, *:target_arn* or *:phone_number* initializing parameters.
1438
- Any other options for `Aws::SNS::Client.new` are available as initializing parameters. See [API Reference of Class: Aws::SNS::Client](http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/SNS/Client.html) for more details.
1439
-
1440
- ```ruby
1441
- class Comment < ActiveRecord::Base
1442
- require 'activity_notification/optional_targets/amazon_sns'
1443
- acts_as_notifiable :admins, targets: [Admin.first].compact,
1444
- optional_targets: {
1445
- ActivityNotification::OptionalTarget::AmazonSNS => { topic_arn: 'arn:aws:sns:XXXXX:XXXXXXXXXXXX:XXXXX' }
1446
- }
1447
- end
1448
- ```
1449
-
1450
- #### Slack as optional target
1451
-
1452
- *activity_notification* provides **ActivityNotification::OptionalTarget::Slack** as default optional target implementation for Slack.
1453
-
1454
- First, add **slack-notifier** gem to your Gemfile and create Incoming WebHooks in Slack (See [Incoming WebHooks](https://wemakejp.slack.com/apps/A0F7XDUAZ-incoming-webhooks)).
1455
-
1456
- ```ruby
1457
- gem 'slack-notifier'
1458
- ```
1459
-
1460
- Then, write `require 'activity_notification/optional_targets/slack'` statement in your notifiable model and set *ActivityNotification::OptionalTarget::Slack* to *acts_as_notifiable* with *:webhook_url* and *:target_username* initializing parameters. *:webhook_url* is created WebHook URL and required, *:target_username* is target's slack user name as String value, symbol method name or lambda function and is optional.
1461
- Any other options for `Slack::Notifier.new` are available as initializing parameters. See [Github slack-notifier](https://github.com/stevenosloan/slack-notifier) and [API Reference of Class: Slack::Notifier](http://www.rubydoc.info/gems/slack-notifier/1.5.1/Slack/Notifier) for more details.
1462
-
1463
- ```ruby
1464
- class Comment < ActiveRecord::Base
1465
- require 'activity_notification/optional_targets/slack'
1466
- acts_as_notifiable :admins, targets: [Admin.first].compact,
1467
- optional_targets: {
1468
- ActivityNotification::OptionalTarget::Slack => {
1469
- webhook_url: 'https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX',
1470
- target_username: :slack_username, channel: 'activity_notification', username: 'ActivityNotification', icon_emoji: ":ghost:"
1471
- }
1472
- }
1473
- end
1474
- ```
1475
-
1476
- #### Developing custom optional targets
1477
-
1478
- You can develop any custom optional targets.
1479
- Custom optional target class must extend **ActivityNotification::OptionalTarget::Base** and override **initialize_target** and **notify** method.
1480
- You can use **render_notification_message** method to prepare message from notification instance using view template.
1481
-
1482
- For example, create *lib/custom_optional_targets/amazon_sns.rb* as follows:
1483
-
1484
- ```ruby
1485
- module CustomOptionalTarget
1486
- # Custom optional target implementation for mobile push notification or SMS using Amazon SNS.
1487
- class AmazonSNS < ActivityNotification::OptionalTarget::Base
1488
- require 'aws-sdk'
1489
-
1490
- # Initialize method to prepare Aws::SNS::Client
1491
- def initialize_target(options = {})
1492
- @topic_arn = options.delete(:topic_arn)
1493
- @target_arn = options.delete(:target_arn)
1494
- @phone_number = options.delete(:phone_number)
1495
- @sns_client = Aws::SNS::Client.new(options)
1496
- end
1497
-
1498
- # Publishes notification message to Amazon SNS
1499
- def notify(notification, options = {})
1500
- @sns_client.publish(
1501
- topic_arn: notification.target.resolve_value(options.delete(:topic_arn) || @topic_arn),
1502
- target_arn: notification.target.resolve_value(options.delete(:target_arn) || @target_arn),
1503
- phone_number: notification.target.resolve_value(options.delete(:phone_number) || @phone_number),
1504
- message: render_notification_message(notification, options)
1505
- )
1506
- end
1507
- end
1508
- end
1509
- ```
1510
-
1511
- Then, you can configure them to notifiable model by *acts_as_notifiable* like this:
1512
-
1513
- ```ruby
1514
- class Comment < ActiveRecord::Base
1515
- require 'custom_optional_targets/amazon_sns'
1516
- acts_as_notifiable :admins, targets: [Admin.first].compact,
1517
- optional_targets: {
1518
- CustomOptionalTarget::AmazonSNS => { topic_arn: 'arn:aws:sns:XXXXX:XXXXXXXXXXXX:XXXXX' }
1519
- }
1520
- end
1521
- ```
1522
-
1523
- *acts_as_notifiable* creates optional target instances and calls *initialize_target* method with initializing parameters.
1524
-
1525
-
1526
- ## Testing
1527
-
1528
- ### Testing your application
1529
-
1530
- First, you need to configure ActivityNotification as described above.
1531
-
1532
- #### Testing notifications with RSpec
1533
- Prepare target and notifiable model instances to test generating notifications (e.g. `@user` and `@comment`).
1534
- Then, you can call notify API and test if notifications of the target are generated.
1535
- ```ruby
1536
- # Prepare
1537
- @article_author = create(:user)
1538
- @comment = @article_author.articles.create.comments.create
1539
- expect(@article_author.notifications.unopened_only.count).to eq(0)
1540
-
1541
- # Call notify API
1542
- @comment.notify :users
1543
-
1544
- # Test generated notifications
1545
- expect(@article_author_user.notifications.unopened_only.count).to eq(1)
1546
- expect(@article_author_user.notifications.unopened_only.latest.notifiable).to eq(@comment)
1547
- ```
1548
-
1549
- #### Testing email notifications with RSpec
1550
- Prepare target and notifiable model instances to test sending notification email.
1551
- Then, you can call notify API and test if notification email is sent.
1552
- ```ruby
1553
- # Prepare
1554
- @article_author = create(:user)
1555
- @comment = @article_author.articles.create.comments.create
1556
- expect(ActivityNotification::Mailer.deliveries.size).to eq(0)
1557
-
1558
- # Call notify API and send email now
1559
- @comment.notify :users, send_later: false
1560
-
1561
- # Test sent notification email
1562
- expect(ActivityNotification::Mailer.deliveries.size).to eq(1)
1563
- expect(ActivityNotification::Mailer.deliveries.first.to[0]).to eq(@article_author.email)
1564
- ```
1565
- Note that notification email will be sent asynchronously without false as *:send_later* option.
1566
- ```ruby
1567
- # Prepare
1568
- include ActiveJob::TestHelper
1569
- @article_author = create(:user)
1570
- @comment = @article_author.articles.create.comments.create
1571
- expect(ActivityNotification::Mailer.deliveries.size).to eq(0)
1572
-
1573
- # Call notify API and send email asynchronously as default
1574
- # Test sent notification email with ActiveJob queue
1575
- expect {
1576
- perform_enqueued_jobs do
1577
- @comment.notify :users
1578
- end
1579
- }.to change { ActivityNotification::Mailer.deliveries.size }.by(1)
1580
- expect(ActivityNotification::Mailer.deliveries.first.to[0]).to eq(@article_author.email)
1581
- ```
1582
-
1583
- ### Testing gem alone
1584
-
1585
- #### Testing with RSpec
1586
- Pull git repository and execute RSpec.
1587
- ```console
1588
- $ git pull https://github.com/simukappu/activity_notification.git
1589
- $ cd activity_notification
1590
- $ bundle install —path vendor/bundle
1591
- $ bundle exec rspec
1592
- - or -
1593
- $ bundle exec rake
1594
- ```
1595
-
1596
- ##### Testing with DynamoDB Local
1597
- You can use [DynamoDB Local](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.html) to test Amazon DynamoDB integration in your local environment.
1598
-
1599
- At first, set up DynamoDB Local by install script:
1600
- ```console
1601
- $ bin/install_dynamodblocal.sh
1602
- ```
1603
- Then, start DynamoDB Local by start script:
1604
- ```console
1605
- $ bin/start_dynamodblocal.sh
1606
- ```
1607
- And you can stop DynamoDB Local by stop script:
1608
- ```console
1609
- $ bin/stop_dynamodblocal.sh
1610
- ```
1611
-
1612
- In short, you can test DynamoDB integration by the following step:
1613
- ```console
1614
- $ git pull https://github.com/simukappu/activity_notification.git
1615
- $ cd activity_notification
1616
- $ bundle install —path vendor/bundle
1617
- $ bin/install_dynamodblocal.sh
1618
- $ bin/start_dynamodblocal.sh
1619
- $ AN_ORM=dynamoid bundle exec rspec
1620
- ```
1621
-
1622
- #### Example Rails application
1623
- Test module includes example Rails application in **[spec/rails_app](/spec/rails_app)**. You can run the example application as common Rails application.
1624
- ```console
1625
- $ cd spec/rails_app
1626
- $ bin/rake db:migrate
1627
- $ bin/rake db:seed
1628
- $ bin/rails server
1629
- ```
1630
- Then, you can access <http://localhost:3000> for the example application.
1631
-
1632
- ##### Run with your local database
1633
- As default, example Rails application runs with local SQLite database in *spec/rails_app/db/development.sqlite3*.
1634
- This application supports to run with your local MySQL, PostgreSQL, MongoDB.
1635
- Set **AN_TEST_DB** environment variable as follows.
1636
-
1637
- To use MySQL:
1638
- ```console
1639
- $ export AN_TEST_DB=mysql
1640
- ```
1641
- To use PostgreSQL:
1642
- ```console
1643
- $ export AN_TEST_DB=postgresql
1644
- ```
1645
- To use MongoDB:
1646
- ```console
1647
- $ export AN_TEST_DB=mongodb
1648
- ```
1649
- When you set **mongodb** as *AN_TEST_DB*, you have to use *activity_notification* with MongoDB. Also set **AN_ORM** like:
1650
- ```console
1651
- $ export AN_ORM=mongoid
1652
- ```
1653
-
1654
- You can also run this Rails application in cross database environment like these:
1655
-
1656
- To use MySQL for your application and use MongoDB for *activity_notification*:
1657
- ```console
1658
- $ export AN_ORM=mongoid AN_TEST_DB=mysql
1659
- ```
1660
- To use PostgreSQL for your application and use Amazon DynamoDB for *activity_notification*:
1661
- ```console
1662
- $ export AN_ORM=dynamoid AN_TEST_DB=postgresql
1663
- ```
1664
-
1665
- Then, configure *spec/rails_app/config/database.yml* or *spec/rails_app/config/mongoid.yml*, *spec/rails_app/config/dynamoid.rb* as your local database.
1666
- Finally, run database migration, seed data script and the example appliation.
1667
- ```console
1668
- $ cd spec/rails_app
1669
- $ # You don't need migration when you use MongoDB only (AN_ORM=mongoid and AN_TEST_DB=mongodb)
1670
- $ bin/rake db:migrate
1671
- $ bin/rake db:seed
1672
- $ bin/rails server
1673
- ```
1674
-
1675
-
1676
- ## Documentation
1677
-
1678
- See [API Reference](http://www.rubydoc.info/github/simukappu/activity_notification/index) for more details.
1679
-
1680
- RubyDoc.info does not support parsing methods in *included* and *class_methods* of *ActiveSupport::Concern* currently.
1681
- To read complete documents, please generate YARD documents on your local environment:
1682
- ```console
1683
- $ git pull https://github.com/simukappu/activity_notification.git
1684
- $ cd activity_notification
1685
- $ bundle install —path vendor/bundle
1686
- $ bundle exec yard doc
1687
- $ bundle exec yard server
1688
- ```
1689
- Then you can see the documents at <http://localhost:8808/docs/index>.
1690
-
1691
-
1692
- ## Common examples
1693
-
1694
- See example Rails application in **[/spec/rails_app](/spec/rails_app)**.
1695
-
1696
- You can also try this example Rails application as a online demo here: **https://activity-notification-example.herokuapp.com/**
1697
- You can login as test users to experience user activity notifications. For more details, see [Online demo](#online-demo).
1698
-
1699
-
1700
- ## Help
1701
-
1702
- We are welcome your Github issues for gem problems or enhancement requests.
1703
-
1704
-
1705
- ## Contributing
350
+ Everyone interacting in *activity_notification* codebases, issue trackers, and pull requests is expected to follow the *activity_notification* [Code of Conduct](/docs/CODE_OF_CONDUCT.md#contributor-covenant-code-of-conduct).
1706
351
 
1707
- We are welcome all of your pull requests! Please check out the followings:
1708
- * Write tests with RSpec
1709
- * Write code docs and README if necessary
352
+ We appreciate any of your contribution!
1710
353
 
1711
354
 
1712
355
  ## License