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.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/bug_report.md +22 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +17 -0
- data/.github/pull_request_template.md +13 -0
- data/.gitignore +10 -3
- data/.travis.yml +6 -5
- data/CHANGELOG.md +22 -0
- data/Gemfile +8 -2
- data/Procfile +1 -1
- data/README.md +153 -1510
- data/activity_notification.gemspec +4 -1
- data/app/channels/activity_notification/notification_api_channel.rb +12 -0
- data/app/channels/activity_notification/notification_api_with_devise_channel.rb +46 -0
- data/app/channels/activity_notification/notification_channel.rb +1 -1
- data/app/channels/activity_notification/notification_with_devise_channel.rb +1 -1
- data/app/controllers/activity_notification/apidocs_controller.rb +75 -0
- data/app/controllers/activity_notification/notifications_api_controller.rb +143 -0
- data/app/controllers/activity_notification/notifications_api_with_devise_controller.rb +7 -0
- data/app/controllers/activity_notification/notifications_controller.rb +79 -53
- data/app/controllers/activity_notification/subscriptions_api_controller.rb +197 -0
- data/app/controllers/activity_notification/subscriptions_api_with_devise_controller.rb +7 -0
- data/app/controllers/activity_notification/subscriptions_controller.rb +78 -69
- data/app/views/activity_notification/notifications/default/_default.html.erb +18 -18
- data/app/views/activity_notification/notifications/default/_default_without_grouping.html.erb +14 -14
- data/app/views/activity_notification/notifications/default/index.html.erb +6 -6
- data/app/views/activity_notification/optional_targets/default/action_cable_channel/_default.html.erb +176 -0
- data/app/views/activity_notification/subscriptions/default/_form.html.erb +1 -1
- data/app/views/activity_notification/subscriptions/default/_notification_keys.html.erb +3 -31
- data/app/views/activity_notification/subscriptions/default/_subscription.html.erb +7 -7
- data/app/views/activity_notification/subscriptions/default/index.html.erb +11 -7
- data/bin/deploy_on_heroku.sh +3 -1
- data/docs/CODE_OF_CONDUCT.md +76 -0
- data/docs/CONTRIBUTING.md +36 -0
- data/docs/Functions.md +1130 -0
- data/docs/Setup.md +674 -0
- data/docs/Testing.md +148 -0
- data/gemfiles/Gemfile.rails-4.2 +3 -0
- data/gemfiles/Gemfile.rails-5.0 +3 -0
- data/gemfiles/Gemfile.rails-5.1 +3 -0
- data/gemfiles/Gemfile.rails-5.2 +3 -0
- data/gemfiles/{Gemfile.rails-6.0.rc → Gemfile.rails-6.0} +5 -3
- data/lib/activity_notification.rb +13 -1
- data/lib/activity_notification/apis/notification_api.rb +29 -92
- data/lib/activity_notification/apis/subscription_api.rb +20 -8
- data/lib/activity_notification/apis/swagger.rb +6 -0
- data/lib/activity_notification/config.rb +41 -21
- data/lib/activity_notification/controllers/common_api_controller.rb +30 -0
- data/lib/activity_notification/controllers/common_controller.rb +44 -20
- data/lib/activity_notification/controllers/concerns/swagger/error_responses.rb +55 -0
- data/lib/activity_notification/controllers/concerns/swagger/notifications_api.rb +273 -0
- data/lib/activity_notification/controllers/concerns/swagger/notifications_parameters.rb +92 -0
- data/lib/activity_notification/controllers/concerns/swagger/subscriptions_api.rb +405 -0
- data/lib/activity_notification/controllers/concerns/swagger/subscriptions_parameters.rb +50 -0
- data/lib/activity_notification/controllers/devise_authentication_controller.rb +7 -6
- data/lib/activity_notification/gem_version.rb +14 -0
- data/lib/activity_notification/helpers/errors.rb +2 -0
- data/lib/activity_notification/helpers/view_helpers.rb +4 -0
- data/lib/activity_notification/mailers/helpers.rb +17 -10
- data/lib/activity_notification/models/concerns/notifiable.rb +26 -10
- data/lib/activity_notification/models/concerns/subscriber.rb +12 -1
- data/lib/activity_notification/models/concerns/swagger/error_schema.rb +36 -0
- data/lib/activity_notification/models/concerns/swagger/notification_schema.rb +209 -0
- data/lib/activity_notification/models/concerns/swagger/subscription_schema.rb +162 -0
- data/lib/activity_notification/models/concerns/target.rb +36 -10
- data/lib/activity_notification/models/notification.rb +1 -0
- data/lib/activity_notification/models/subscription.rb +1 -0
- data/lib/activity_notification/optional_targets/action_cable_api_channel.rb +69 -0
- data/lib/activity_notification/optional_targets/action_cable_channel.rb +68 -0
- data/lib/activity_notification/optional_targets/base.rb +7 -13
- data/lib/activity_notification/orm/active_record/notification.rb +17 -1
- data/lib/activity_notification/orm/active_record/subscription.rb +1 -1
- data/lib/activity_notification/orm/dynamoid.rb +28 -0
- data/lib/activity_notification/orm/dynamoid/extension.rb +79 -1
- data/lib/activity_notification/orm/dynamoid/notification.rb +1 -1
- data/lib/activity_notification/orm/dynamoid/subscription.rb +1 -1
- data/lib/activity_notification/orm/mongoid.rb +22 -0
- data/lib/activity_notification/orm/mongoid/notification.rb +17 -1
- data/lib/activity_notification/orm/mongoid/subscription.rb +1 -1
- data/lib/activity_notification/rails/routes.rb +132 -48
- data/lib/activity_notification/renderable.rb +13 -2
- data/lib/activity_notification/roles/acts_as_notifiable.rb +38 -20
- data/lib/activity_notification/version.rb +1 -1
- data/lib/generators/activity_notification/controllers_generator.rb +2 -1
- data/lib/generators/templates/activity_notification.rb +8 -0
- data/lib/generators/templates/controllers/notifications_api_controller.rb +31 -0
- data/lib/generators/templates/controllers/notifications_api_with_devise_controller.rb +31 -0
- data/lib/generators/templates/controllers/notifications_controller.rb +1 -37
- data/lib/generators/templates/controllers/notifications_with_devise_controller.rb +1 -45
- data/lib/generators/templates/controllers/subscriptions_api_controller.rb +61 -0
- data/lib/generators/templates/controllers/subscriptions_api_with_devise_controller.rb +61 -0
- data/lib/generators/templates/controllers/subscriptions_controller.rb +14 -37
- data/lib/generators/templates/controllers/subscriptions_with_devise_controller.rb +14 -45
- data/lib/generators/templates/models/README +8 -4
- data/lib/generators/templates/models/notification.rb +1 -1
- data/lib/generators/templates/models/subscription.rb +1 -1
- data/package.json +8 -0
- data/spec/channels/notification_api_channel_shared_examples.rb +59 -0
- data/spec/channels/notification_api_channel_spec.rb +51 -0
- data/spec/channels/notification_api_with_devise_channel_spec.rb +78 -0
- data/spec/concerns/apis/notification_api_spec.rb +37 -2
- data/spec/concerns/models/notifiable_spec.rb +64 -0
- data/spec/concerns/models/subscriber_spec.rb +13 -16
- data/spec/concerns/models/target_spec.rb +32 -0
- data/spec/concerns/renderable_spec.rb +2 -2
- data/spec/controllers/controller_spec_utility.rb +136 -0
- data/spec/controllers/notifications_api_controller_shared_examples.rb +506 -0
- data/spec/controllers/notifications_api_controller_spec.rb +19 -0
- data/spec/controllers/notifications_api_with_devise_controller_spec.rb +60 -0
- data/spec/controllers/notifications_controller_shared_examples.rb +54 -79
- data/spec/controllers/notifications_controller_spec.rb +1 -2
- data/spec/controllers/notifications_with_devise_controller_spec.rb +3 -12
- data/spec/controllers/subscriptions_api_controller_shared_examples.rb +750 -0
- data/spec/controllers/subscriptions_api_controller_spec.rb +19 -0
- data/spec/controllers/subscriptions_api_with_devise_controller_spec.rb +60 -0
- data/spec/controllers/subscriptions_controller_shared_examples.rb +94 -121
- data/spec/controllers/subscriptions_controller_spec.rb +1 -2
- data/spec/controllers/subscriptions_with_devise_controller_spec.rb +3 -12
- data/spec/helpers/view_helpers_spec.rb +4 -11
- data/spec/mailers/mailer_spec.rb +41 -0
- data/spec/models/notification_spec.rb +17 -0
- data/spec/models/subscription_spec.rb +0 -13
- data/spec/optional_targets/action_cable_api_channel_spec.rb +37 -0
- data/spec/optional_targets/action_cable_channel_spec.rb +44 -0
- data/spec/optional_targets/amazon_sns_spec.rb +0 -2
- data/spec/optional_targets/slack_spec.rb +0 -2
- data/spec/rails_app/Rakefile +9 -0
- data/spec/rails_app/app/assets/config/manifest.js +3 -0
- data/spec/rails_app/app/assets/images/.keep +0 -0
- data/spec/rails_app/app/controllers/admins_controller.rb +21 -0
- data/spec/rails_app/app/controllers/application_controller.rb +1 -1
- data/spec/rails_app/app/controllers/articles_controller.rb +6 -3
- data/spec/rails_app/app/controllers/spa_controller.rb +7 -0
- data/spec/rails_app/app/controllers/users/notifications_controller.rb +0 -65
- data/spec/rails_app/app/controllers/users/notifications_with_devise_controller.rb +0 -73
- data/spec/rails_app/app/controllers/users/subscriptions_controller.rb +0 -77
- data/spec/rails_app/app/controllers/users/subscriptions_with_devise_controller.rb +0 -85
- data/spec/rails_app/app/controllers/users_controller.rb +21 -0
- data/spec/rails_app/app/javascript/App.vue +104 -0
- data/spec/rails_app/app/javascript/components/DeviseTokenAuth.vue +83 -0
- data/spec/rails_app/app/javascript/components/Top.vue +99 -0
- data/spec/rails_app/app/javascript/components/notifications/Index.vue +200 -0
- data/spec/rails_app/app/javascript/components/notifications/Notification.vue +133 -0
- data/spec/rails_app/app/javascript/components/notifications/NotificationContent.vue +122 -0
- data/spec/rails_app/app/javascript/components/subscriptions/Index.vue +279 -0
- data/spec/rails_app/app/javascript/components/subscriptions/NewSubscription.vue +112 -0
- data/spec/rails_app/app/javascript/components/subscriptions/NotificationKey.vue +141 -0
- data/spec/rails_app/app/javascript/components/subscriptions/Subscription.vue +226 -0
- data/spec/rails_app/app/javascript/config/development.js +5 -0
- data/spec/rails_app/app/javascript/config/environment.js +7 -0
- data/spec/rails_app/app/javascript/config/production.js +5 -0
- data/spec/rails_app/app/javascript/config/test.js +5 -0
- data/spec/rails_app/app/javascript/packs/application.js +18 -0
- data/spec/rails_app/app/javascript/packs/spa.js +11 -0
- data/spec/rails_app/app/javascript/store/auth.js +37 -0
- data/spec/rails_app/app/models/admin.rb +16 -15
- data/spec/rails_app/app/models/article.rb +26 -21
- data/spec/rails_app/app/models/comment.rb +24 -71
- data/spec/rails_app/app/models/user.rb +43 -20
- data/spec/rails_app/app/views/activity_notification/notifications/default/article/_update.html.erb +146 -0
- data/spec/rails_app/app/views/articles/index.html.erb +51 -7
- data/spec/rails_app/app/views/articles/show.html.erb +1 -1
- data/spec/rails_app/app/views/layouts/_header.html.erb +8 -10
- data/spec/rails_app/app/views/spa/index.html.erb +2 -0
- data/spec/rails_app/babel.config.js +72 -0
- data/spec/rails_app/bin/webpack +18 -0
- data/spec/rails_app/bin/webpack-dev-server +18 -0
- data/spec/rails_app/config/application.rb +15 -2
- data/spec/rails_app/config/environment.rb +2 -1
- data/spec/rails_app/config/environments/development.rb +5 -0
- data/spec/rails_app/config/environments/production.rb +3 -0
- data/spec/rails_app/config/environments/test.rb +5 -0
- data/spec/rails_app/config/initializers/activity_notification.rb +8 -0
- data/spec/rails_app/config/initializers/devise_token_auth.rb +55 -0
- data/spec/rails_app/config/initializers/mysql.rb +9 -0
- data/spec/rails_app/config/locales/activity_notification.en.yml +2 -2
- data/spec/rails_app/config/routes.rb +33 -1
- data/spec/rails_app/config/webpack/development.js +5 -0
- data/spec/rails_app/config/webpack/environment.js +7 -0
- data/spec/rails_app/config/webpack/loaders/vue.js +6 -0
- data/spec/rails_app/config/webpack/production.js +5 -0
- data/spec/rails_app/config/webpack/test.js +5 -0
- data/spec/rails_app/config/webpacker.yml +97 -0
- data/spec/rails_app/db/migrate/20191201000000_add_tokens_to_users.rb +10 -0
- data/spec/rails_app/db/schema.rb +4 -1
- data/spec/rails_app/db/seeds.rb +1 -0
- data/spec/rails_app/lib/custom_optional_targets/raise_error.rb +14 -0
- data/spec/rails_app/package.json +23 -0
- data/spec/rails_app/postcss.config.js +12 -0
- data/spec/roles/acts_as_group_spec.rb +0 -2
- data/spec/roles/acts_as_notifiable_spec.rb +1 -3
- data/spec/roles/acts_as_notifier_spec.rb +0 -2
- data/spec/roles/acts_as_target_spec.rb +0 -4
- data/spec/spec_helper.rb +7 -15
- data/spec/version_spec.rb +31 -0
- metadata +187 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b1f6ad3e3fe40d4841cde7931cdc67065c87fd948db1674a1cbc3016f1338aba
|
4
|
+
data.tar.gz: 0b15bf8fe764df0d3431543d29ec08b3f95548faf337a14b3c30f98379688742
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
60
|
-
|
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
|
data/.travis.yml
CHANGED
@@ -5,17 +5,18 @@ branches:
|
|
5
5
|
- images
|
6
6
|
|
7
7
|
rvm:
|
8
|
-
- 2.
|
9
|
-
|
10
|
-
# - 2.
|
11
|
-
# - 2.
|
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
|
19
|
+
- gemfiles/Gemfile.rails-6.0
|
19
20
|
|
20
21
|
env:
|
21
22
|
- AN_ORM=active_record
|
data/CHANGELOG.md
CHANGED
@@ -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
|
+
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
|
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
|
34
|
+
### Online Demo
|
34
35
|
|
35
|
-
You can see an actual application using this gem here:
|
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:
|
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
|
79
|
+
## Table of Contents
|
64
80
|
|
65
81
|
- [About](#about)
|
66
|
-
- [
|
67
|
-
- [
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
- [
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
- [
|
81
|
-
|
82
|
-
- [
|
83
|
-
- [
|
84
|
-
- [
|
85
|
-
- [
|
86
|
-
- [
|
87
|
-
- [
|
88
|
-
|
89
|
-
|
90
|
-
- [
|
91
|
-
|
92
|
-
- [
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
- [
|
97
|
-
|
98
|
-
- [
|
99
|
-
- [
|
100
|
-
- [
|
101
|
-
- [
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
- [
|
106
|
-
- [
|
107
|
-
- [
|
108
|
-
- [
|
109
|
-
|
110
|
-
- [
|
111
|
-
- [
|
112
|
-
|
113
|
-
|
114
|
-
- [
|
115
|
-
- [
|
116
|
-
- [
|
117
|
-
- [Configuring
|
118
|
-
- [
|
119
|
-
- [
|
120
|
-
- [
|
121
|
-
|
122
|
-
- [
|
123
|
-
|
124
|
-
|
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
|
-
-
|
127
|
-
- [Help](#help)
|
155
|
+
- [Common Examples](#common-examples)
|
128
156
|
- [Contributing](#contributing)
|
129
157
|
- [License](#license)
|
130
158
|
|
131
159
|
|
132
|
-
##
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
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.
|
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
|
-
|
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
|
-
|
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 :
|
478
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
285
|
+
See [Displaying notifications](/docs/Setup.md#displaying-notifications) for more details.
|
647
286
|
|
648
|
-
|
649
|
-
...
|
650
|
-
<%= yield :notification_index %>
|
651
|
-
...
|
652
|
-
```
|
287
|
+
### Run example Rails application
|
653
288
|
|
654
|
-
|
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
|
-
```
|
657
|
-
|
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
|
-
|
304
|
+
## Setup
|
667
305
|
|
668
|
-
|
306
|
+
See [Setup](/docs/Setup.md#Setup).
|
669
307
|
|
670
|
-
```erb
|
671
|
-
<%= render_notification(@notification, target: :users, fallback: :default) %>
|
672
|
-
```
|
673
308
|
|
674
|
-
|
309
|
+
## Functions
|
675
310
|
|
676
|
-
|
311
|
+
See [Functions](/docs/Functions.md#Functions).
|
677
312
|
|
678
|
-
```erb
|
679
|
-
<%= render_notification(@notification, fallback: :default) %>
|
680
|
-
```
|
681
313
|
|
682
|
-
|
314
|
+
## Testing
|
683
315
|
|
684
|
-
|
316
|
+
See [Testing](/docs/Testing.md#Testing).
|
685
317
|
|
686
|
-
```erb
|
687
|
-
<%= render_notification(@notification, fallback: :text) %>
|
688
|
-
```
|
689
318
|
|
690
|
-
|
319
|
+
## Documentation
|
691
320
|
|
692
|
-
|
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
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
345
|
+
## Contributing
|
792
346
|
|
793
|
-
|
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
|
-
|
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
|
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
|