activity_notification 1.7.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +3 -0
  3. data/.travis.yml +16 -2
  4. data/CHANGELOG.md +22 -2
  5. data/Gemfile +7 -0
  6. data/Procfile +2 -0
  7. data/README.md +366 -32
  8. data/Rakefile +19 -10
  9. data/activity_notification.gemspec +5 -3
  10. data/app/channels/activity_notification/notification_channel.rb +37 -0
  11. data/app/channels/activity_notification/notification_with_devise_channel.rb +51 -0
  12. data/app/controllers/activity_notification/notifications_controller.rb +1 -1
  13. data/app/controllers/activity_notification/subscriptions_controller.rb +1 -1
  14. data/app/jobs/activity_notification/notify_all_job.rb +16 -0
  15. data/app/jobs/activity_notification/notify_job.rb +17 -0
  16. data/app/jobs/activity_notification/notify_to_job.rb +16 -0
  17. data/app/views/activity_notification/notifications/default/_default_without_grouping.html.erb +1 -1
  18. data/app/views/activity_notification/notifications/default/index.html.erb +55 -2
  19. data/bin/_dynamodblocal +4 -0
  20. data/{scripts → bin}/bundle_update.sh +1 -0
  21. data/bin/deploy_on_heroku.sh +14 -0
  22. data/bin/install_dynamodblocal.sh +5 -0
  23. data/bin/start_dynamodblocal.sh +47 -0
  24. data/bin/stop_dynamodblocal.sh +34 -0
  25. data/gemfiles/Gemfile.rails-4.2 +1 -0
  26. data/gemfiles/Gemfile.rails-5.0 +2 -0
  27. data/gemfiles/Gemfile.rails-5.1 +1 -0
  28. data/gemfiles/Gemfile.rails-5.2 +1 -0
  29. data/gemfiles/Gemfile.rails-6.0.rc +21 -0
  30. data/lib/activity_notification.rb +1 -0
  31. data/lib/activity_notification/apis/notification_api.rb +289 -136
  32. data/lib/activity_notification/apis/subscription_api.rb +80 -53
  33. data/lib/activity_notification/common.rb +3 -3
  34. data/lib/activity_notification/config.rb +89 -33
  35. data/lib/activity_notification/controllers/common_controller.rb +19 -7
  36. data/lib/activity_notification/helpers/errors.rb +4 -0
  37. data/lib/activity_notification/helpers/view_helpers.rb +1 -1
  38. data/lib/activity_notification/models/concerns/notifiable.rb +61 -53
  39. data/lib/activity_notification/models/concerns/subscriber.rb +7 -6
  40. data/lib/activity_notification/models/concerns/target.rb +73 -28
  41. data/lib/activity_notification/optional_targets/base.rb +2 -2
  42. data/lib/activity_notification/orm/active_record/notification.rb +4 -23
  43. data/lib/activity_notification/orm/dynamoid.rb +495 -0
  44. data/lib/activity_notification/orm/dynamoid/extension.rb +184 -0
  45. data/lib/activity_notification/orm/dynamoid/notification.rb +189 -0
  46. data/lib/activity_notification/orm/dynamoid/subscription.rb +82 -0
  47. data/lib/activity_notification/orm/mongoid.rb +4 -1
  48. data/lib/activity_notification/orm/mongoid/notification.rb +8 -25
  49. data/lib/activity_notification/orm/mongoid/subscription.rb +1 -1
  50. data/lib/activity_notification/roles/acts_as_notifiable.rb +33 -5
  51. data/lib/activity_notification/roles/acts_as_target.rb +62 -9
  52. data/lib/activity_notification/version.rb +1 -1
  53. data/lib/generators/templates/activity_notification.rb +30 -7
  54. data/lib/tasks/activity_notification_tasks.rake +14 -4
  55. data/spec/channels/notification_channel_shared_examples.rb +59 -0
  56. data/spec/channels/notification_channel_spec.rb +50 -0
  57. data/spec/channels/notification_with_devise_channel_spec.rb +99 -0
  58. data/spec/concerns/apis/notification_api_spec.rb +2 -2
  59. data/spec/concerns/apis/subscription_api_spec.rb +2 -2
  60. data/spec/concerns/models/notifiable_spec.rb +72 -7
  61. data/spec/concerns/models/subscriber_spec.rb +53 -49
  62. data/spec/concerns/models/target_spec.rb +135 -13
  63. data/spec/config_spec.rb +41 -1
  64. data/spec/controllers/notifications_controller_shared_examples.rb +7 -3
  65. data/spec/controllers/subscriptions_controller_shared_examples.rb +7 -3
  66. data/spec/helpers/view_helpers_spec.rb +12 -10
  67. data/spec/models/dummy/dummy_group_spec.rb +4 -0
  68. data/spec/models/dummy/dummy_notifiable_spec.rb +4 -0
  69. data/spec/models/dummy/dummy_notifier_spec.rb +4 -0
  70. data/spec/models/dummy/dummy_subscriber_spec.rb +3 -0
  71. data/spec/models/dummy/dummy_target_spec.rb +4 -0
  72. data/spec/models/notification_spec.rb +164 -45
  73. data/spec/models/subscription_spec.rb +69 -14
  74. data/spec/orm/dynamoid_spec.rb +115 -0
  75. data/spec/rails_app/app/assets/javascripts/application.js +2 -1
  76. data/spec/rails_app/app/assets/javascripts/cable.js +12 -0
  77. data/spec/rails_app/app/controllers/comments_controller.rb +3 -4
  78. data/spec/rails_app/app/models/admin.rb +6 -4
  79. data/spec/rails_app/app/models/article.rb +2 -2
  80. data/spec/rails_app/app/models/comment.rb +17 -5
  81. data/spec/rails_app/app/models/user.rb +5 -3
  82. data/spec/rails_app/app/views/activity_notification/notifications/users/overridden/custom/_test.html.erb +1 -0
  83. data/spec/rails_app/config/application.rb +6 -1
  84. data/spec/rails_app/config/cable.yml +8 -0
  85. data/spec/rails_app/config/dynamoid.rb +5 -0
  86. data/spec/rails_app/config/environment.rb +4 -1
  87. data/spec/rails_app/config/environments/production.rb +1 -1
  88. data/spec/rails_app/config/initializers/activity_notification.rb +30 -7
  89. data/spec/rails_app/config/locales/activity_notification.en.yml +2 -0
  90. data/spec/rails_app/db/seeds.rb +21 -5
  91. data/spec/rails_app/lib/mailer_previews/mailer_preview.rb +12 -4
  92. data/spec/roles/acts_as_notifiable_spec.rb +2 -2
  93. data/spec/roles/acts_as_target_spec.rb +1 -1
  94. data/spec/spec_helper.rb +15 -8
  95. metadata +67 -20
  96. data/spec/rails_app/app/models/.keep +0 -0
  97. data/spec/rails_app/app/views/activity_notification/notifications/users/overriden/custom/_test.html.erb +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: f16ad8322faabd5fec778b470437863df703dcf1
4
- data.tar.gz: 87eb45c1c03c92836aa5a72b7b1e07cf2fb8548b
2
+ SHA256:
3
+ metadata.gz: 2a31c915030fbad2174abd43cd1e64656cbc609e7fdd2521b06bccdfa46ea69e
4
+ data.tar.gz: 4d24557f5a670b094be8d5bb5ab8c07763d7944c7fb1de550c5f4dc956d50906
5
5
  SHA512:
6
- metadata.gz: 8a34fa413bd90c2fb8228115bc7f76f12ddb0ca8c7d981f761b10692ec3aa1bd4239781bdd3001c33aa5ed4497e4b7f842d05a77fe3e86ccddaa347df9e8d05f
7
- data.tar.gz: ae29b5111bbef97182cd0fdbeab616c332a53779e19cb940afe2300e7672591a7ebb490044b006f97447cdb662371aff46311b7274eefd0ab9923476a7414c87
6
+ metadata.gz: 156543325a87e170ebe74d1a2dbc2bcf8c9870bb69c86ef8689f5634a564ed84f286c6965baf79ac84b8bd82dbbdd7bceb522faeeef09e028cfdc038c3284008
7
+ data.tar.gz: a911a86c566b7d3c7bbeeacbc78f9db7ca9dfff4f2496544d4c3190076cfd742ead7902e077af3cffb041532557c19f3ab3fd687f9ccf79fca9f951ff957c337
data/.gitignore CHANGED
@@ -10,6 +10,8 @@
10
10
  /spec/examples.txt
11
11
  /spec/rails_app/log/*
12
12
  /spec/rails_app/tmp/*
13
+ /spec/rails_app/public/assets/
14
+ /spec/DynamoDBLocal-latest/
13
15
  /test/tmp/
14
16
  /test/version_tmp/
15
17
  /tmp/
@@ -17,6 +19,7 @@
17
19
  *~
18
20
  *.sqlite3
19
21
  .project
22
+ .DS_Store
20
23
 
21
24
  # Used by dotenv library to load environment variables.
22
25
  # .env
@@ -15,14 +15,20 @@ gemfile:
15
15
  - gemfiles/Gemfile.rails-5.0
16
16
  - gemfiles/Gemfile.rails-5.1
17
17
  - gemfiles/Gemfile.rails-5.2
18
+ - gemfiles/Gemfile.rails-6.0.rc
18
19
 
19
20
  env:
20
21
  - AN_ORM=active_record
21
22
  - AN_ORM=active_record AN_TEST_DB=mysql
22
23
  - AN_ORM=active_record AN_TEST_DB=postgresql
24
+ - AN_ORM=mongoid
23
25
  - AN_ORM=mongoid AN_TEST_DB=mongodb
26
+ - AN_ORM=dynamoid
24
27
 
25
28
  matrix:
29
+ exclude:
30
+ - gemfile: gemfiles/Gemfile.rails-4.2
31
+ env: AN_ORM=dynamoid
26
32
  include:
27
33
  - rvm: ruby-head
28
34
  gemfile: Gemfile
@@ -30,11 +36,16 @@ matrix:
30
36
  - rvm: ruby-head
31
37
  gemfile: Gemfile
32
38
  env: AN_ORM=mongoid
39
+ - rvm: ruby-head
40
+ gemfile: Gemfile
41
+ env: AN_ORM=dynamoid
33
42
  allow_failures:
34
43
  - rvm: ruby-head
35
44
  fast_finish: true
36
45
 
37
46
  services:
47
+ - mysql
48
+ - postgresql
38
49
  - mongodb
39
50
 
40
51
  sudo: false
@@ -48,12 +59,15 @@ before_install:
48
59
  install:
49
60
  # Specify bundler version as '< 2.0' for Rails 4.2
50
61
  - bundle _1.17.3_ install
62
+ - if [ "$AN_ORM" = "dynamoid" ]; then bin/install_dynamodblocal.sh; fi
51
63
 
52
64
  before_script:
53
65
  # Specify bundler version as '< 2.0' for Rails 4.2
54
66
  - bundle _1.17.3_ update
55
- - mysql -e 'create database activity_notification_test'
56
- - psql -c 'create database activity_notification_test' -U postgres
67
+ - if [ "$AN_TEST_DB" = "mysql" ]; then mysql -e 'create database activity_notification_test'; fi
68
+ - if [ "$AN_TEST_DB" = "postgresql" ]; then psql -c 'create database activity_notification_test' -U postgres; fi
69
+ - if [ "$AN_ORM" = "dynamoid" ]; then bin/start_dynamodblocal.sh; fi
70
+ - if [ "$AN_ORM" = "dynamoid" ]; then export AWS_DEFAULT_REGION=ap-northeast-1 AWS_ACCESS_KEY_ID=dummy AWS_SECRET_ACCESS_KEY=dummy; fi
57
71
 
58
72
  script: bundle exec rspec
59
73
 
@@ -1,4 +1,24 @@
1
- ## 1.7.0 / 2019-04-30
1
+ ## 2.0.0 / 2019-08-09
2
+ [Full Changelog](http://github.com/simukappu/activity_notification/compare/v1.7.1...v2.0.0)
3
+
4
+ Enhancements:
5
+
6
+ * Add push notification with Action Cable - [#101](https://github.com/simukappu/activity_notification/issues/101)
7
+ * Allow use with Rails 6.0 - [#102](https://github.com/simukappu/activity_notification/issues/102)
8
+ * Add Amazon DynamoDB support using Dynamoid
9
+ * Add *ActivityNotification.config.store_with_associated_records* option
10
+ * Add test case using Mongoid orm with ActiveRecord application
11
+ * Publish demo application on Heroku
12
+
13
+ Bug Fixes:
14
+
15
+ * Fix syntax error of a default view *_default_without_grouping.html.erb*
16
+
17
+ Deprecated:
18
+
19
+ * Remove deprecated *ActivityNotification.config.table_name* option
20
+
21
+ ## 1.7.1 / 2019-04-30
2
22
  [Full Changelog](http://github.com/simukappu/activity_notification/compare/v1.7.0...v1.7.1)
3
23
 
4
24
  Enhancements:
@@ -184,7 +204,7 @@ Bug Fixes:
184
204
 
185
205
  Breaking Changes:
186
206
 
187
- * Remove *notifiable_type* from the argument of overriden method or configured lambda function with *:batch_email_allowed* option in *acts_as_target* role
207
+ * Remove *notifiable_type* from the argument of overridden method or configured lambda function with *:batch_email_allowed* option in *acts_as_target* role
188
208
 
189
209
  ## 1.0.2 / 2016-11-14
190
210
  [Full Changelog](http://github.com/simukappu/activity_notification/compare/v1.0.1...v1.0.2)
data/Gemfile CHANGED
@@ -4,12 +4,19 @@ gemspec
4
4
 
5
5
  gem 'rails', '~> 5.2'
6
6
 
7
+ group :production do
8
+ gem 'puma'
9
+ gem 'pg'
10
+ gem 'devise'
11
+ end
12
+
7
13
  group :development do
8
14
  gem 'bullet'
9
15
  end
10
16
 
11
17
  group :test do
12
18
  gem 'rails-controller-testing'
19
+ gem 'action-cable-testing'
13
20
  gem 'ammeter'
14
21
  gem 'timecop'
15
22
  gem 'coveralls', require: false
@@ -0,0 +1,2 @@
1
+ web: cd spec/rails_app; bin/rails server Puma -p $PORT -e $RAILS_ENV; cd -
2
+ console: cd spec/rails_app; bin/rails console -e $RAILS_ENV; cd -
data/README.md CHANGED
@@ -8,25 +8,42 @@
8
8
  [![Gem Downloads](https://img.shields.io/gem/dt/activity_notification.svg)](https://rubygems.org/gems/activity_notification)
9
9
  [![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](MIT-LICENSE)
10
10
 
11
- *activity_notification* provides integrated user activity notifications for Ruby on Rails. You can easily use it to configure multiple notification targets and make activity notifications with notifiable models, like adding comments, responding etc.
11
+ *activity_notification* provides integrated user activity notifications for [Ruby on Rails](https://rubyonrails.org). You can easily use it to configure multiple notification targets and make activity notifications with notifiable models, like adding comments, responding etc.
12
12
 
13
- *activity_notification* supports Rails 4.2+ with ActiveRecord and [Mongoid](http://mongoid.org) ORM. It is tested for MySQL, PostgreSQL, SQLite3 with ActiveRecord and MongoDB with Mongoid.
13
+ *activity_notification* supports Rails 4.2+ with [ActiveRecord](https://guides.rubyonrails.org/active_record_basics.html), [Mongoid](https://mongoid.org) and [Dynamoid](https://github.com/Dynamoid/dynamoid) ORM. It is tested for [MySQL](https://www.mysql.com), [PostgreSQL](https://www.postgresql.org), [SQLite3](https://www.sqlite.org) with ActiveRecord, [MongoDB](https://www.mongodb.com) with Mongoid and [Amazon DynamoDB](https://aws.amazon.com/dynamodb) with Dynamoid. The latest *activity_notification* [v2](https://rubygems.org/gems/activity_notification) is almost compatible with [v1](https://rubygems.org/gems/activity_notification/versions/1.7.1).
14
14
 
15
15
 
16
16
  ## About
17
17
 
18
18
  *activity_notification* provides following functions:
19
19
  * Notification API (creating notifications, query for notifications and managing notification parameters)
20
- * Notification models (stored with ActiveRecord or Mongoid ORM)
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)
23
23
  * Automatic tracked notifications (generating notifications along with the lifecycle of notifiable models)
24
24
  * Grouping notifications (grouping like *"Kevin and 7 other users posted comments to this article"*)
25
25
  * Email notification
26
26
  * Batch email notification (event driven or periodical email notification, daily or weekly etc)
27
+ * Push notification with [Action Cable](https://guides.rubyonrails.org/action_cable_overview.html)
27
28
  * Subscription management (subscribing and unsubscribing for each target and notification type)
28
29
  * Integration with [Devise](https://github.com/plataformatec/devise) authentication
29
- * Optional notification targets (Configurable optional notification targets like Amazon SNS, Slack, SMS and so on)
30
+ * Activity notifications stream integrated into cloud computing using [Amazon DynamoDB Streams](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html)
31
+ * 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
+ ### Online demo
34
+
35
+ You can see an actual application using this gem here: **https://activity-notification-example.herokuapp.com/**
36
+
37
+ Login as the following test users to experience user activity notifications:
38
+
39
+ | Email | Password | Admin? |
40
+ |:---:|:---:|:---:|
41
+ | ichiro@example.com | changeit | Yes |
42
+ | stephen@example.com | changeit | |
43
+ | klay@example.com | changeit | |
44
+ | kevin@example.com | changeit | |
45
+
46
+ The deployed demo application is included in this gem's source code as a test application here: **[/spec/rails_app](/spec/rails_app/)**
30
47
 
31
48
  ### Notification index and plugin notifications
32
49
  <kbd>![plugin-notifications-image](https://raw.githubusercontent.com/simukappu/activity_notification/images/activity_notification_plugin_focus_with_subscription.png)</kbd>
@@ -51,6 +68,8 @@
51
68
  - [Database setup](#database-setup)
52
69
  - [Using ActiveRecord ORM](#using-activerecord-orm)
53
70
  - [Using Mongoid ORM](#using-mongoid-orm)
71
+ - [Using Dynamoid ORM](#using-dynamoid-orm)
72
+ - [Integration with DynamoDB Streams](#integration-with-dynamodb-streams)
54
73
  - [Configuring models](#configuring-models)
55
74
  - [Configuring target models](#configuring-target-models)
56
75
  - [Configuring notifiable models](#configuring-notifiable-models)
@@ -87,9 +106,13 @@
87
106
  - [Managing subscriptions](#managing-subscriptions)
88
107
  - [Customizing subscriptions](#customizing-subscriptions)
89
108
  - [Integration with Devise](#integration-with-devise)
90
- - [Configuring integration with Devise](#configuring-integration-with-devise)
109
+ - [Configuring integration with Devise authentication](#configuring-integration-with-devise-authentication)
91
110
  - [Using different model as target](#using-different-model-as-target)
92
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)
93
116
  - [Optional notification targets](#optional-notification-targets)
94
117
  - [Configuring optional targets](#configuring-optional-targets)
95
118
  - [Customizing message format](#customizing-message-format)
@@ -154,7 +177,6 @@ The same can be done for the subscription table name, e.g., if you're using the
154
177
  config.subscription_table_name = "notifications_subscriptions"
155
178
  ```
156
179
 
157
-
158
180
  #### Using Mongoid ORM
159
181
 
160
182
  When you use *activity_notification* with [Mongoid](http://mongoid.org) ORM, set **AN_ORM** environment variable to **mongoid**:
@@ -171,6 +193,124 @@ config.orm = :mongoid
171
193
 
172
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.
173
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.
313
+
174
314
  ### Configuring models
175
315
 
176
316
  #### Configuring target models
@@ -325,7 +465,7 @@ Rails.application.routes.draw do
325
465
  end
326
466
  ```
327
467
 
328
- Then, you can access several pages like */users/1/notifications* and manage open/unopen of notifications using **notifications_controller**.
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)*.
329
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).
330
470
 
331
471
  #### Routes with scope
@@ -571,6 +711,8 @@ notification:
571
711
  destroy:
572
712
  text: 'Some user removed an article!'
573
713
  comment:
714
+ create:
715
+ text: '%{notifier_name} posted a comment on the article "%{article_title}"'
574
716
  post:
575
717
  text:
576
718
  one: "<p>%{notifier_name} posted a comment on your article %{article_title}</p>"
@@ -656,13 +798,13 @@ Set up SMTP server configuration for *ActionMailer*. Then, you need to set up th
656
798
  config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
657
799
  ```
658
800
 
659
- Email notification is disabled as default. You can configure to enable email notification in initializer *activity_notification.rb*.
801
+ Email notification is disabled as default. You can configure it to enable email notification in initializer *activity_notification.rb*.
660
802
 
661
803
  ```ruby
662
804
  config.email_enabled = true
663
805
  ```
664
806
 
665
- You can also configure them for each model by *acts_as roles* like these.
807
+ You can also configure them for each model by *acts_as roles* like these:
666
808
 
667
809
  ```ruby
668
810
  class User < ActiveRecord::Base
@@ -709,7 +851,7 @@ config.mailer_sender = ->(key){ key == 'inquiry.post' ? 'support@example.com' :
709
851
 
710
852
  #### Email templates
711
853
 
712
- *activity_notification* will look for email template in the same way as notification views. 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)*.
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)*.
713
855
 
714
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)*.
715
857
 
@@ -762,7 +904,7 @@ notification:
762
904
 
763
905
  Set up SMTP server configuration for *ActionMailer* and the default URL options for the *activity_notification* mailer in each environment.
764
906
 
765
- Batch email notification is disabled as default. You can configure to enable email notification in initializer *activity_notification.rb* like single email notification.
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.
766
908
 
767
909
  ```ruby
768
910
  config.email_enabled = true
@@ -885,13 +1027,13 @@ Then, you will see *"Kevin and 7 other users posted 10 comments to your article"
885
1027
 
886
1028
  #### Configuring subscriptions
887
1029
 
888
- Subscription management is disabled as default. You can configure to enable subscription management in initializer *activity_notification.rb*.
1030
+ Subscription management is disabled as default. You can configure it to enable subscription management in initializer *activity_notification.rb*.
889
1031
 
890
1032
  ```ruby
891
1033
  config.subscription_enabled = true
892
1034
  ```
893
1035
 
894
- This makes all target model subscribers. You can also configure them for each target model by *acts_as_target* role like this.
1036
+ This makes all target model subscribers. You can also configure them for each target model by *acts_as_target* role like this:
895
1037
 
896
1038
  ```ruby
897
1039
  class User < ActiveRecord::Base
@@ -978,7 +1120,7 @@ Rails.application.routes.draw do
978
1120
  end
979
1121
  ```
980
1122
 
981
- Then, you can access *users/1/subscriptions* and use **subscriptions_controller** or **subscriptions_with_devise_controller** to manage the subscriptions.
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.
982
1124
 
983
1125
  If you would like to customize subscription controllers or views, you can use generators like notifications:
984
1126
 
@@ -1007,7 +1149,7 @@ If you would like to customize subscription controllers or views, you can use ge
1007
1149
 
1008
1150
  *activity_notification* supports to integrate with devise authentication.
1009
1151
 
1010
- #### Configuring integration with Devise
1152
+ #### Configuring integration with Devise authentication
1011
1153
 
1012
1154
  Add **:with_devise** option in notification routing to *config/routes.rb* for the target:
1013
1155
 
@@ -1019,7 +1161,7 @@ Rails.application.routes.draw do
1019
1161
  end
1020
1162
  ```
1021
1163
 
1022
- Then *activity_notification* will use **notifications_with_devise_controller** 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'.
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'.
1023
1165
 
1024
1166
  *Hint*: HTTP 403 Forbidden will be returned for unauthorized notifications.
1025
1167
 
@@ -1073,6 +1215,156 @@ end
1073
1215
  Then, you can access */admins/notifications* instead of */admins/1/notifications*.
1074
1216
 
1075
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
+
1076
1368
  ### Optional notification targets
1077
1369
 
1078
1370
  *activity_notification* supports configurable optional notification targets like Amazon SNS, Slack, SMS and so on.
@@ -1080,7 +1372,7 @@ Then, you can access */admins/notifications* instead of */admins/1/notifications
1080
1372
  #### Configuring optional targets
1081
1373
 
1082
1374
  *activity_notification* provides default optional target implementation for Amazon SNS and Slack.
1083
- You can develop any optional target classes which extends *ActivityNotification::OptionalTarget::Base*, and configure them to notifiable model by *acts_as_notifiable* like this.
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:
1084
1376
 
1085
1377
  ```ruby
1086
1378
  class Comment < ActiveRecord::Base
@@ -1216,7 +1508,7 @@ module CustomOptionalTarget
1216
1508
  end
1217
1509
  ```
1218
1510
 
1219
- Then, you can configure them to notifiable model by *acts_as_notifiable* like this.
1511
+ Then, you can configure them to notifiable model by *acts_as_notifiable* like this:
1220
1512
 
1221
1513
  ```ruby
1222
1514
  class Comment < ActiveRecord::Base
@@ -1301,38 +1593,77 @@ $ bundle exec rspec
1301
1593
  $ bundle exec rake
1302
1594
  ```
1303
1595
 
1304
- #### Dummy Rails application
1305
- Test module includes dummy Rails application in **spec/rails_app**. You can run the dummy application as common Rails application.
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.
1306
1624
  ```console
1307
1625
  $ cd spec/rails_app
1308
1626
  $ bin/rake db:migrate
1309
1627
  $ bin/rake db:seed
1310
1628
  $ bin/rails server
1311
1629
  ```
1312
- Then, you can access <http://localhost:3000> for the dummy application.
1630
+ Then, you can access <http://localhost:3000> for the example application.
1313
1631
 
1314
1632
  ##### Run with your local database
1315
- As default, dummy Rails application runs with local SQLite database in *spec/rails_app/db/development.sqlite3*.
1316
- This application supports to run with your local MySQL, PostgreSQL and MongoDB.
1317
- Set **AN_TEST_DB** environment variable like:
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:
1318
1638
  ```console
1319
1639
  $ export AN_TEST_DB=mysql
1320
1640
  ```
1321
- for MySQL,
1641
+ To use PostgreSQL:
1322
1642
  ```console
1323
1643
  $ export AN_TEST_DB=postgresql
1324
1644
  ```
1325
- for PostgreSQL, and
1645
+ To use MongoDB:
1326
1646
  ```console
1327
1647
  $ export AN_TEST_DB=mongodb
1328
1648
  ```
1329
- for MongoDB. When you set **mongodb** as *AN_TEST_DB*, you have to use *activity_notification* with MongoDB. Also set **AN_ORM** like:
1649
+ When you set **mongodb** as *AN_TEST_DB*, you have to use *activity_notification* with MongoDB. Also set **AN_ORM** like:
1330
1650
  ```console
1331
1651
  $ export AN_ORM=mongoid
1332
1652
  ```
1333
1653
 
1334
- Then, configure *spec/rails_app/config/database.yml* or *spec/rails_app/config/mongoid.yml* as your local database.
1335
- Finally, run database migration, seed data script and the dummy appliation.
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.
1336
1667
  ```console
1337
1668
  $ cd spec/rails_app
1338
1669
  $ # You don't need migration when you use MongoDB only (AN_ORM=mongoid and AN_TEST_DB=mongodb)
@@ -1357,14 +1688,18 @@ $ bundle exec yard server
1357
1688
  ```
1358
1689
  Then you can see the documents at <http://localhost:8808/docs/index>.
1359
1690
 
1691
+
1360
1692
  ## Common examples
1361
1693
 
1362
- To be prepared. See dummy Rails application in *spec/rails_app*.
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).
1363
1698
 
1364
1699
 
1365
1700
  ## Help
1366
1701
 
1367
- We are welcome your Github issues for gem problems or enhancement requests. If you have any questions or problems for your own application environment, contact us by email of this repository.
1702
+ We are welcome your Github issues for gem problems or enhancement requests.
1368
1703
 
1369
1704
 
1370
1705
  ## Contributing
@@ -1372,7 +1707,6 @@ We are welcome your Github issues for gem problems or enhancement requests. If y
1372
1707
  We are welcome all of your pull requests! Please check out the followings:
1373
1708
  * Write tests with RSpec
1374
1709
  * Write code docs and README if necessary
1375
- * Send your pull request to *development* branch (Do NOT send to *master* branch)
1376
1710
 
1377
1711
 
1378
1712
  ## License