noticed 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +88 -41
- data/lib/generators/noticed/model_generator.rb +36 -0
- data/lib/generators/noticed/notification_generator.rb +19 -0
- data/lib/generators/noticed/templates/README +7 -0
- data/lib/generators/noticed/templates/notification.rb.tt +27 -0
- data/lib/noticed.rb +2 -0
- data/lib/noticed/base.rb +3 -0
- data/lib/noticed/delivery_methods/database.rb +5 -1
- data/lib/noticed/model.rb +42 -0
- data/lib/noticed/translation.rb +21 -0
- data/lib/noticed/version.rb +1 -1
- metadata +7 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5c8f1abe201518056e73f223b840bb30f44e173181116c632217f5f5a4a4b4d5
|
4
|
+
data.tar.gz: ba23af57eba01de7aecafd23c1ed00efacb8f354402592c68967f9f13c83a376
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 32fcb3681980b2e0ad9db0cbd26e47c8ff8c4b4524f5c1068da010b967c46524dcee78ec3809e622791768a1be08793fc7c159dae061e028ff3e707f89fe6f47
|
7
|
+
data.tar.gz: f1d9d8318f4acb4ea77c8940f4e71bd91dd3ea40b70873741246109c472fc5164a5aa6be67fb22089b2bc6868601497c417ffb88cdb2e6ab92d1c195ab69ee58
|
data/README.md
CHANGED
@@ -1,4 +1,8 @@
|
|
1
|
-
|
1
|
+
<p align="center">
|
2
|
+
<h1>Noticed</h1>
|
3
|
+
</p>
|
4
|
+
|
5
|
+
### 🎉 Notifications for your Ruby on Rails app.
|
2
6
|
|
3
7
|
[![Build Status](https://github.com/excid3/noticed/workflows/Tests/badge.svg)](https://github.com/excid3/noticed/actions)
|
4
8
|
|
@@ -6,32 +10,38 @@ Currently, we support these notification delivery methods out of the box:
|
|
6
10
|
|
7
11
|
* Database
|
8
12
|
* Email
|
9
|
-
*
|
13
|
+
* ActionCable channels
|
10
14
|
* Twilio (SMS)
|
11
15
|
* Vonage / Nexmo (SMS)
|
12
16
|
|
13
17
|
And you can easily add new notification types for any other delivery methods.
|
14
18
|
|
15
|
-
## Installation
|
16
|
-
|
19
|
+
## 🚀 Installation
|
20
|
+
Run the following command to add Noticed to your Gemfile
|
17
21
|
|
18
22
|
```ruby
|
19
|
-
|
23
|
+
bundle add "noticed"
|
20
24
|
```
|
21
25
|
|
22
|
-
|
23
|
-
```bash
|
24
|
-
$ bundle
|
25
|
-
```
|
26
|
+
To save notifications to your database, use the following command to generate a Notification model.
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
$ gem install noticed
|
28
|
+
```ruby
|
29
|
+
rails generate noticed:model
|
30
30
|
```
|
31
31
|
|
32
|
-
|
32
|
+
This will generate a Notification model and instructions for associating User models with the notifications table.
|
33
|
+
|
34
|
+
## 📝 Usage
|
35
|
+
|
36
|
+
To generate a notification object, simply run:
|
37
|
+
|
38
|
+
`rails generate noticed:notification CommentNotification`
|
39
|
+
|
40
|
+
#### Notification Objects
|
41
|
+
|
42
|
+
Notifications inherit from `Noticed::Base`. This provides all their functionality and allows them to be delivered.
|
33
43
|
|
34
|
-
|
44
|
+
To add delivery methods, simply `include` the module for the delivery methods you would like to use.
|
35
45
|
|
36
46
|
```ruby
|
37
47
|
class CommentNotification < Noticed::Base
|
@@ -42,13 +52,25 @@ class CommentNotification < Noticed::Base
|
|
42
52
|
def email_notifications?
|
43
53
|
!!recipient.preferences[:email]
|
44
54
|
end
|
45
|
-
|
55
|
+
|
56
|
+
# I18n helpers
|
57
|
+
def message
|
58
|
+
t(".message")
|
59
|
+
end
|
60
|
+
|
61
|
+
# URL helpers are accessible in notifications
|
62
|
+
def url
|
63
|
+
post_path(params[:post])
|
64
|
+
end
|
65
|
+
|
46
66
|
after_deliver do
|
47
67
|
# Anything you want
|
48
68
|
end
|
49
69
|
end
|
50
70
|
```
|
51
71
|
|
72
|
+
#### Sending Notifications
|
73
|
+
|
52
74
|
To send a notification to a user:
|
53
75
|
|
54
76
|
```ruby
|
@@ -61,15 +83,23 @@ notification.deliver_later(@comment.post.author)
|
|
61
83
|
notification.deliver(@comment.post.author)
|
62
84
|
```
|
63
85
|
|
64
|
-
This will instantiate a new notification with the `comment`
|
86
|
+
This will instantiate a new notification with the `comment` stored in the notification's params.
|
65
87
|
|
66
|
-
Each delivery method is able to
|
88
|
+
Each delivery method is able to transform this metadata that's best for the format. For example, the database may simply store the comment so it can be linked when rendering in the navbar. The websocket mechanism may transform this into a browser notification or insert it into the navbar.
|
67
89
|
|
68
90
|
**Shared Options**
|
69
91
|
|
70
92
|
* `if: :method_name` - Calls `method_name`and cancels delivery method if `false` is returned
|
71
93
|
* `unless: :method_name` - Calls `method_name`and cancels delivery method if `true` is returned
|
72
94
|
|
95
|
+
##### Helper Methods
|
96
|
+
|
97
|
+
You can define helper methods inside your Notification object to make it easier to render.
|
98
|
+
|
99
|
+
##### URL Helpers
|
100
|
+
|
101
|
+
Rails url helpers are included in notification classes by default so you have full access to them just like you would in your controllers and views.
|
102
|
+
|
73
103
|
**Callbacks**
|
74
104
|
|
75
105
|
Like ActiveRecord, notifications have several different types of callbacks.
|
@@ -78,11 +108,11 @@ Like ActiveRecord, notifications have several different types of callbacks.
|
|
78
108
|
class CommentNotification < Noticed::Base
|
79
109
|
deliver_by :database
|
80
110
|
deliver_by :email
|
81
|
-
|
111
|
+
|
82
112
|
# Callbacks for the entire delivery
|
83
113
|
before_deliver :whatever
|
84
114
|
around_deliver :whatever
|
85
|
-
after_deliver :whatever
|
115
|
+
after_deliver :whatever
|
86
116
|
|
87
117
|
# Callbacks for each delivery method
|
88
118
|
before_database :whatever
|
@@ -99,9 +129,35 @@ When using `deliver_later` callbacks will be run around queuing the delivery met
|
|
99
129
|
|
100
130
|
Defining custom delivery methods allows you to add callbacks that run inside the background job as each individual delivery is executed. See the Custom Delivery Methods section for more information.
|
101
131
|
|
102
|
-
|
132
|
+
##### Translations
|
133
|
+
|
134
|
+
We've added `translate` and `t` helpers like Rails has to provide an easy way of scoping translations. If the key starts with a period, it will automatically scope the key under `notifications` and the underscored name of the notification class it is used in.
|
135
|
+
|
136
|
+
For example:
|
137
|
+
|
138
|
+
`t(".message")` looks up `en.notifications.new_comment.message`
|
139
|
+
|
140
|
+
##### User Preferences
|
141
|
+
|
142
|
+
You can use the `if:` and `unless: ` options on your delivery methods to check the user's preferences and skip processing if they have disabled that type of notification.
|
143
|
+
|
144
|
+
For example:
|
145
|
+
|
146
|
+
```ruby
|
147
|
+
class CommentNotification < Noticed::Base
|
148
|
+
deliver_by :email, if: :email_notifications?
|
149
|
+
|
150
|
+
def email_notifications?
|
151
|
+
recipient.email_notifications?
|
152
|
+
end
|
153
|
+
end
|
154
|
+
```
|
103
155
|
|
104
|
-
|
156
|
+
###
|
157
|
+
|
158
|
+
## 🚛 Delivery Methods
|
159
|
+
|
160
|
+
The delivery methods are designed to be modular so you can customize the way each type gets delivered.
|
105
161
|
|
106
162
|
For example, emails will require a subject, body, and email address while an SMS requires a phone number and simple message. You can define the formats for each of these in your Notification and the delivery method will handle the processing of it.
|
107
163
|
|
@@ -113,6 +169,12 @@ Writes notification to the database.
|
|
113
169
|
|
114
170
|
**Note:** Database notifications are special in that they will run before the other delivery methods. We do this so you can reference the database record ID in other delivery methods.
|
115
171
|
|
172
|
+
##### Options
|
173
|
+
|
174
|
+
* `association` - *Optional*
|
175
|
+
|
176
|
+
The name of the database association to use. Defaults to `:notifications`
|
177
|
+
|
116
178
|
### Email
|
117
179
|
|
118
180
|
Sends an email notification. Emails will always be sent with `deliver_later`
|
@@ -228,23 +290,7 @@ Sends an SMS notification vai Vonage / Nexmo.
|
|
228
290
|
}
|
229
291
|
```
|
230
292
|
|
231
|
-
###
|
232
|
-
|
233
|
-
Each delivery method implements a `deliver_with_#{name}` method that receives the recipient as the first argument. You can override this method to check the user's preferences and skip processing if they have disabled that type of notification.
|
234
|
-
|
235
|
-
For example:
|
236
|
-
|
237
|
-
```ruby
|
238
|
-
class CommentNotification < Noticed::Base
|
239
|
-
deliver_by :email, if: :email_notifications?
|
240
|
-
|
241
|
-
def email_notifications?
|
242
|
-
recipient.email_notifications?
|
243
|
-
end
|
244
|
-
end
|
245
|
-
```
|
246
|
-
|
247
|
-
### Custom Delivery Methods
|
293
|
+
### 🚚 Custom Delivery Methods
|
248
294
|
|
249
295
|
You can define a custom delivery method easily by adding a `deliver_by` line with a unique name and class option. The class will be instantiated and should inherit from `Noticed::DeliveryMethods::Base`.
|
250
296
|
|
@@ -297,8 +343,9 @@ For Rails 6.0 and earlier, you must pass strings of the class names in the `deli
|
|
297
343
|
|
298
344
|
We recommend the Rails 6.0 compatible options to prevent confusion.
|
299
345
|
|
300
|
-
## Contributing
|
301
|
-
|
346
|
+
## 🙏 Contributing
|
347
|
+
|
348
|
+
This project uses [Standard](https://github.com/testdouble/standard) for formatting Ruby code. Please make sure to run `standardrb` before submitting pull requests.
|
302
349
|
|
303
|
-
## License
|
350
|
+
## 📝 License
|
304
351
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails/generators/named_base"
|
4
|
+
|
5
|
+
module Noticed
|
6
|
+
module Generators
|
7
|
+
class ModelGenerator < Rails::Generators::NamedBase
|
8
|
+
include Rails::Generators::ResourceHelpers
|
9
|
+
|
10
|
+
source_root File.expand_path("../templates", __FILE__)
|
11
|
+
|
12
|
+
desc "Generates a Notification model for storing notifications."
|
13
|
+
|
14
|
+
argument :name, type: :string, default: "Notification", banner: "Notification"
|
15
|
+
argument :attributes, type: :array, default: [], banner: "field:type field:type"
|
16
|
+
|
17
|
+
def generate_notification
|
18
|
+
generate :model, name, "recipient:references{polymorphic}", "type", "params:text", "read_at:datetime", *attributes
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_noticed_model
|
22
|
+
inject_into_class model_path, class_name, " include Noticed::Model\n"
|
23
|
+
end
|
24
|
+
|
25
|
+
def done
|
26
|
+
readme "README" if behavior == :invoke
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def model_path
|
32
|
+
@model_path ||= File.join("app", "models", "#{file_path}.rb")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails/generators/named_base"
|
4
|
+
|
5
|
+
module Noticed
|
6
|
+
module Generators
|
7
|
+
class NotificationGenerator < Rails::Generators::NamedBase
|
8
|
+
include Rails::Generators::ResourceHelpers
|
9
|
+
|
10
|
+
source_root File.expand_path("../templates", __FILE__)
|
11
|
+
|
12
|
+
desc "Generates a notification with the given NAME."
|
13
|
+
|
14
|
+
def generate_notification
|
15
|
+
template "notification.rb", "app/notifications/#{singular_name}.rb"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# To deliver this notification:
|
2
|
+
#
|
3
|
+
# <%= class_name %>.with(post: @post).deliver_later(current_user)
|
4
|
+
# <%= class_name %>.with(post: @post).deliver(current_user)
|
5
|
+
|
6
|
+
class <%= class_name %> < Noticed::Base
|
7
|
+
# Add your delivery methods
|
8
|
+
#
|
9
|
+
# deliver_by :database
|
10
|
+
# deliver_by :email, mailer: "UserMailer"
|
11
|
+
# deliver_by :slack
|
12
|
+
# deliver_by :custom, class: "MyDeliveryMethod"
|
13
|
+
|
14
|
+
# Add required params
|
15
|
+
#
|
16
|
+
# param :post
|
17
|
+
|
18
|
+
# Define helper methods to make rendering easier.
|
19
|
+
#
|
20
|
+
# def message
|
21
|
+
# t(".message")
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# def url
|
25
|
+
# posts_path(params[:post])
|
26
|
+
# end
|
27
|
+
end
|
data/lib/noticed.rb
CHANGED
@@ -4,6 +4,8 @@ require "noticed/engine"
|
|
4
4
|
module Noticed
|
5
5
|
autoload :Base, "noticed/base"
|
6
6
|
autoload :Coder, "noticed/coder"
|
7
|
+
autoload :Model, "noticed/model"
|
8
|
+
autoload :Translation, "noticed/translation"
|
7
9
|
|
8
10
|
module DeliveryMethods
|
9
11
|
autoload :Base, "noticed/delivery_methods/base"
|
data/lib/noticed/base.rb
CHANGED
@@ -3,11 +3,15 @@ module Noticed
|
|
3
3
|
class Database < Base
|
4
4
|
# Must return the database record
|
5
5
|
def deliver
|
6
|
-
recipient.
|
6
|
+
recipient.send(association_name).create!(attributes)
|
7
7
|
end
|
8
8
|
|
9
9
|
private
|
10
10
|
|
11
|
+
def association_name
|
12
|
+
options[:association] || :notifications
|
13
|
+
end
|
14
|
+
|
11
15
|
def attributes
|
12
16
|
if (method = options[:format])
|
13
17
|
notification.send(method)
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Noticed
|
2
|
+
module Model
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
self.inheritance_column = nil
|
7
|
+
|
8
|
+
serialize :params, Noticed::Coder
|
9
|
+
|
10
|
+
belongs_to :recipient, polymorphic: true
|
11
|
+
|
12
|
+
scope :newest_first, -> { order(created_at: :desc) }
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
def mark_as_read!
|
17
|
+
update_all(read_at: Time.current, updated_at: Time.current)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Rehydrate the database notification into the Notification object for rendering
|
22
|
+
def to_notification
|
23
|
+
@_notification ||= begin
|
24
|
+
instance = type.constantize.with(params)
|
25
|
+
instance.record = self
|
26
|
+
instance
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def mark_as_read!
|
31
|
+
update(read_at: Time.current)
|
32
|
+
end
|
33
|
+
|
34
|
+
def unread?
|
35
|
+
!read?
|
36
|
+
end
|
37
|
+
|
38
|
+
def read?
|
39
|
+
read_at?
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Translation
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
# Returns the +i18n_scope+ for the class. Overwrite if you want custom lookup.
|
5
|
+
def i18n_scope
|
6
|
+
:notifications
|
7
|
+
end
|
8
|
+
|
9
|
+
def translate(key, **options)
|
10
|
+
I18n.translate(scope_translation_key(key), **options)
|
11
|
+
end
|
12
|
+
alias t translate
|
13
|
+
|
14
|
+
def scope_translation_key(key)
|
15
|
+
if key.to_s.start_with?(".")
|
16
|
+
"notifications.#{self.class.name.underscore}#{key}"
|
17
|
+
else
|
18
|
+
key
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/noticed/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: noticed
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Oliver
|
@@ -92,6 +92,10 @@ files:
|
|
92
92
|
- README.md
|
93
93
|
- Rakefile
|
94
94
|
- app/channels/noticed/notification_channel.rb
|
95
|
+
- lib/generators/noticed/model_generator.rb
|
96
|
+
- lib/generators/noticed/notification_generator.rb
|
97
|
+
- lib/generators/noticed/templates/README
|
98
|
+
- lib/generators/noticed/templates/notification.rb.tt
|
95
99
|
- lib/noticed.rb
|
96
100
|
- lib/noticed/base.rb
|
97
101
|
- lib/noticed/coder.rb
|
@@ -104,6 +108,8 @@ files:
|
|
104
108
|
- lib/noticed/delivery_methods/twilio.rb
|
105
109
|
- lib/noticed/delivery_methods/vonage.rb
|
106
110
|
- lib/noticed/engine.rb
|
111
|
+
- lib/noticed/model.rb
|
112
|
+
- lib/noticed/translation.rb
|
107
113
|
- lib/noticed/version.rb
|
108
114
|
- lib/tasks/noticed_tasks.rake
|
109
115
|
homepage: https://github.com/excid3/noticed
|