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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b8ce628657c8b6011616fbcf075869fe902ad33f19569acadf88e52aef89fb79
4
- data.tar.gz: f92330969818566ce0d4080341f19631be41fd5bb4c45f94dfb3ab5714c3c663
3
+ metadata.gz: 5c8f1abe201518056e73f223b840bb30f44e173181116c632217f5f5a4a4b4d5
4
+ data.tar.gz: ba23af57eba01de7aecafd23c1ed00efacb8f354402592c68967f9f13c83a376
5
5
  SHA512:
6
- metadata.gz: 8945414df8ed4cdf89bbf654171e686b8c655ae91542177207f134052d0d09794df146192694775f9e755a3b0a65fafbe180130d41590f186b53837c9f114961
7
- data.tar.gz: c78d5048f9fb95b6982dc44edd7fa03d8f2cf8cf093884d059668fb2aed3258d9f2992b84b2843ac61e39d3e3ce42818fc48c583520d2097cb89bf8260b1aa30
6
+ metadata.gz: 32fcb3681980b2e0ad9db0cbd26e47c8ff8c4b4524f5c1068da010b967c46524dcee78ec3809e622791768a1be08793fc7c159dae061e028ff3e707f89fe6f47
7
+ data.tar.gz: f1d9d8318f4acb4ea77c8940f4e71bd91dd3ea40b70873741246109c472fc5164a5aa6be67fb22089b2bc6868601497c417ffb88cdb2e6ab92d1c195ab69ee58
data/README.md CHANGED
@@ -1,4 +1,8 @@
1
- # Noticed - Notifications for your Ruby on Rails app.
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
- * Websocket (realtime)
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
- Add this line to your application's Gemfile:
19
+ ## 🚀 Installation
20
+ Run the following command to add Noticed to your Gemfile
17
21
 
18
22
  ```ruby
19
- gem 'noticed'
23
+ bundle add "noticed"
20
24
  ```
21
25
 
22
- And then execute:
23
- ```bash
24
- $ bundle
25
- ```
26
+ To save notifications to your database, use the following command to generate a Notification model.
26
27
 
27
- Or install it yourself as:
28
- ```bash
29
- $ gem install noticed
28
+ ```ruby
29
+ rails generate noticed:model
30
30
  ```
31
31
 
32
- ## Usage
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
- You can define a Notification as a class that inherits from Noticed::Base. To add delivery methods, simply `include` the module for the delivery methods you would like to use.
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` global ID stored in the metadata.
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 transfrom 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.
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
- ## Delivery Methods
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
- The delivery methods are designed to be overriden so that you can customi1ze the notification for each medium.
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
- ### User Preferences
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
- Contribution directions go here.
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,7 @@
1
+
2
+ 🚚 Your notifications database model has been generated!
3
+
4
+ Next steps:
5
+ 1. Run "rails db:migrate"
6
+ 2. Add "has_many :notifications, as: :recipient" to your User model(s).
7
+ 3. Generate notifications with "rails g noticed:notification"
@@ -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
@@ -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"
@@ -1,5 +1,8 @@
1
1
  module Noticed
2
2
  class Base
3
+ include Translation
4
+ include Rails.application.routes.url_helpers
5
+
3
6
  extend ActiveModel::Callbacks
4
7
  define_model_callbacks :deliver
5
8
 
@@ -3,11 +3,15 @@ module Noticed
3
3
  class Database < Base
4
4
  # Must return the database record
5
5
  def deliver
6
- recipient.notifications.create(attributes)
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
@@ -1,3 +1,3 @@
1
1
  module Noticed
2
- VERSION = "1.1.0"
2
+ VERSION = "1.2.0"
3
3
  end
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.1.0
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