noticed 1.2.11 → 1.2.16

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: f215fc7642db8db6a38ba3354c4d58ad1621c6d6af5c4ee479a519fdab1fae8d
4
- data.tar.gz: 874dc986fa682f54eaee86f0e8e638049cb8d4f310a2e4d906e76ba11b5d7405
3
+ metadata.gz: 3b37e7d17da790342493c2ffc575cc5d013ac156b7ac600fb0022c79bcb034de
4
+ data.tar.gz: 87fc46cbf6829e174b0dc6df1751187965e645f7461848469e48a2ea7bcb6a46
5
5
  SHA512:
6
- metadata.gz: '039b85fe5977ecf3d3353ba275f0913f03a325a3affc913a5edc05f07e5555b38deff9fd23b492d16fbdaa58c0c5e3cf281267288c3ff69697d07e0ff840ded8'
7
- data.tar.gz: 7a49698a38596e35382fffc86d12857414f9f8ecdbc68f2c66fd24e124e6b893f62f442e736d004c5fad0403aa55eecc30a749843c6a61b5f0fc45d1b9da84c2
6
+ metadata.gz: b9b4db6825f88670f27d768f40724fbd22c2f8e92fc6ce5f3bc32650cc9e77475d3c6eecb51fd7f59b10d70e735f648c92ecdae6f6d4b8ff61ff4b5c39e501d3
7
+ data.tar.gz: f474ad70283d4faa9b33bd51346acb64b29a4076b9c9c0ffcff58e60f75d331bc54b162a8e3d77310153d39caf898ac2924b234389b1089b3262b35fa7b48ac3
data/README.md CHANGED
@@ -78,7 +78,7 @@ To add delivery methods, simply `include` the module for the delivery methods yo
78
78
  class CommentNotification < Noticed::Base
79
79
  deliver_by :database
80
80
  deliver_by :action_cable
81
- deliver_by :email, if: :email_notifications?
81
+ deliver_by :email, mailer: 'CommentMailer', if: :email_notifications?
82
82
 
83
83
  # I18n helpers
84
84
  def message
@@ -86,6 +86,7 @@ class CommentNotification < Noticed::Base
86
86
  end
87
87
 
88
88
  # URL helpers are accessible in notifications
89
+ # Don't forget to set your default_url_options so Rails knows how to generate urls
89
90
  def url
90
91
  post_path(params[:post])
91
92
  end
@@ -113,6 +114,12 @@ You can define helper methods inside your Notification object to make it easier
113
114
 
114
115
  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.
115
116
 
117
+ Don't forget, you'll need to configure `default_url_options` in order for Rails to know what host and port to use when generating URLs.
118
+
119
+ ```ruby
120
+ Rails.application.routes.default_url_options[:host] = 'localhost:3000'
121
+ ```
122
+
116
123
  **Callbacks**
117
124
 
118
125
  Like ActiveRecord, notifications have several different types of callbacks.
@@ -120,7 +127,7 @@ Like ActiveRecord, notifications have several different types of callbacks.
120
127
  ```ruby
121
128
  class CommentNotification < Noticed::Base
122
129
  deliver_by :database
123
- deliver_by :email
130
+ deliver_by :email, mailer: 'CommentMailer'
124
131
 
125
132
  # Callbacks for the entire delivery
126
133
  before_deliver :whatever
@@ -158,7 +165,7 @@ For example:
158
165
 
159
166
  ```ruby
160
167
  class CommentNotification < Noticed::Base
161
- deliver_by :email, if: :email_notifications?
168
+ deliver_by :email, mailer: 'CommentMailer', if: :email_notifications?
162
169
 
163
170
  def email_notifications?
164
171
  recipient.email_notifications?
@@ -311,22 +318,28 @@ Sends an SMS notification via Vonage / Nexmo.
311
318
 
312
319
  ### 🚚 Custom Delivery Methods
313
320
 
314
- 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`.
321
+ To generate a custom delivery method, simply run
315
322
 
316
- ```ruby
317
- class MyNotification < Noticed::Base
318
- deliver_by :discord, class: "DiscordNotification"
319
- end
320
- ```
323
+ `rails generate noticed:delivery_method Discord`
324
+
325
+ This will generate a new `DeliveryMethods::Discord` class inside the `app/notifications/delivery_methods` folder, which can be used to deliver notifications to Discord.
321
326
 
322
327
  ```ruby
323
- class DiscordNotification < Noticed::DeliveryMethods::Base
328
+ class DeliveryMethods::Discord < Noticed::DeliveryMethods::Base
324
329
  def deliver
325
330
  # Logic for sending a Discord notification
326
331
  end
327
332
  end
328
333
  ```
329
334
 
335
+ You can use the custom delivery method thus created by adding a `deliver_by` line with a unique name and `class` option in your notification class.
336
+
337
+ ```ruby
338
+ class MyNotification < Noticed::Base
339
+ deliver_by :discord, class: "DeliveryMethods::Discord"
340
+ end
341
+ ```
342
+
330
343
  Delivery methods have access to the following methods and attributes:
331
344
 
332
345
  * `notification` - The instance of the Notification. You can call methods on the notification to let the user easily override formatting and other functionality of the delivery method.
@@ -334,12 +347,51 @@ Delivery methods have access to the following methods and attributes:
334
347
  * `recipient` - The object who should receive the notification. This is typically a User, Account, or other ActiveRecord model.
335
348
  * `params` - The params passed into the notification. This is details about the event that happened. For example, a user commenting on a post would have params of `{ user: User.first }`
336
349
 
350
+ #### Validating options passed to Custom Delivery methods
351
+
352
+ The presence of the delivery method options is automatically validated if using the `option(s)` method.
353
+
354
+ If you want to validate that the passed options contain valid values, or to add any custom validations, override the `self.validate!(delivery_method_options)` method from the `Noticed::DeliveryMethods::Base` class.
355
+
356
+ ```ruby
357
+ class DeliveryMethods::Discord < Noticed::DeliveryMethods::Base
358
+ option :username # Requires the username option to be passed
359
+
360
+ def deliver
361
+ # Logic for sending a Discord notification
362
+ end
363
+
364
+ def self.validate!(delivery_method_options)
365
+ super # Don't forget to call super, otherwise option presence won't be validated
366
+
367
+   # Custom validations
368
+ if delivery_method_options[:username].blank?
369
+ raise Noticed::ValidationError, 'the `username` option must be present'
370
+ end
371
+ end
372
+ end
373
+
374
+ class CommentNotification < Noticed::Base
375
+ deliver_by :discord, class: 'DeliveryMethods::Discord'
376
+ end
377
+ ```
378
+
379
+ Now it will raise an error because a required argument is missing.
380
+
381
+ To fix the error, the argument has to be passed correctly. For example:
382
+
383
+ ```ruby
384
+ class CommentNotification < Noticed::Base
385
+ deliver_by :discord, class: 'DeliveryMethods::Discord', username: User.admin.username
386
+ end
387
+ ```
388
+
337
389
  #### Callbacks
338
390
 
339
391
  Callbacks for delivery methods wrap the *actual* delivery of the notification. You can use `before_deliver`, `around_deliver` and `after_deliver` in your custom delivery methods.
340
392
 
341
393
  ```ruby
342
- class DiscordNotification < Noticed::DeliveryMethods::Base
394
+ class DeliveryMethods::Discord < Noticed::DeliveryMethods::Base
343
395
  after_deliver do
344
396
  # Do whatever you want
345
397
  end
@@ -351,13 +403,13 @@ end
351
403
  Rails 6.1+ can serialize Class and Module objects as arguments to ActiveJob. The following syntax should work for Rails 6.1+:
352
404
 
353
405
  ```ruby
354
- deliver_by DiscordNotification
406
+ deliver_by DeliveryMethods::Discord
355
407
  ```
356
408
 
357
- For Rails 6.0 and earlier, you must pass strings of the class names in the `deliver_by` options.
409
+ For Rails 6.0, you must pass strings of the class names in the `deliver_by` options.
358
410
 
359
411
  ```ruby
360
- deliver_by :discord, class: "DiscordNotification"
412
+ deliver_by :discord, class: "DeliveryMethods::Discord"
361
413
  ```
362
414
 
363
415
  We recommend the Rails 6.0 compatible options to prevent confusion.
@@ -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 DeliveryMethodGenerator < Rails::Generators::NamedBase
8
+ include Rails::Generators::ResourceHelpers
9
+
10
+ source_root File.expand_path("../templates", __FILE__)
11
+
12
+ desc "Generates a class for a custom delivery method with the given NAME."
13
+
14
+ def generate_notification
15
+ template "delivery_method.rb", "app/notifications/delivery_methods/#{singular_name}.rb"
16
+ end
17
+ end
18
+ end
19
+ end
@@ -15,13 +15,22 @@ module Noticed
15
15
  argument :attributes, type: :array, default: [], banner: "field:type field:type"
16
16
 
17
17
  def generate_notification
18
- generate :model, name, "recipient:references{polymorphic}", "type", params_column, "read_at:datetime", *attributes
18
+ generate :model, name, "recipient:references{polymorphic}", "type", params_column, "read_at:datetime:index", *attributes
19
19
  end
20
20
 
21
21
  def add_noticed_model
22
22
  inject_into_class model_path, class_name, " include Noticed::Model\n"
23
23
  end
24
24
 
25
+ def add_not_nullable
26
+ migration_path = Dir.glob(Rails.root.join("db/migrate/*")).max_by { |f| File.mtime(f) }
27
+
28
+ # Force is required because null: false already exists in the file and Thor isn't smart enough to tell the difference
29
+ insert_into_file migration_path, after: "t.string :type", force: true do
30
+ ", null: false"
31
+ end
32
+ end
33
+
25
34
  def done
26
35
  readme "README" if behavior == :invoke
27
36
  end
@@ -34,7 +43,7 @@ module Noticed
34
43
 
35
44
  def params_column
36
45
  case ActiveRecord::Base.configurations.configs_for(spec_name: "primary").config["adapter"]
37
- when "mysql"
46
+ when "mysql2"
38
47
  "params:json"
39
48
  when "postgresql"
40
49
  "params:jsonb"
@@ -0,0 +1,12 @@
1
+ class DeliveryMethods::<%= class_name %> < Noticed::DeliveryMethods::Base
2
+ def deliver
3
+ # Logic for sending the notification
4
+ end
5
+
6
+ # You may override this method to validate options for the delivery method
7
+ # Invalid options should raise a ValidationError
8
+ #
9
+ # def self.validate!(options)
10
+ # raise ValidationError, "required_option missing" unless options[:required_option]
11
+ # end
12
+ end
@@ -8,6 +8,7 @@ module Noticed
8
8
  autoload :Model, "noticed/model"
9
9
  autoload :TextCoder, "noticed/text_coder"
10
10
  autoload :Translation, "noticed/translation"
11
+ autoload :NotificationChannel, "noticed/notification_channel"
11
12
 
12
13
  module DeliveryMethods
13
14
  autoload :Base, "noticed/delivery_methods/base"
@@ -32,7 +32,7 @@ module Noticed
32
32
  def params(*names)
33
33
  param_names.concat Array.wrap(names)
34
34
  end
35
- alias param params
35
+ alias_method :param, :params
36
36
  end
37
37
 
38
38
  def initialize(params = {})
@@ -97,13 +97,12 @@ module Noticed
97
97
  }
98
98
 
99
99
  run_callbacks delivery_method[:name] do
100
- klass = get_class(delivery_method[:name], delivery_method[:options])
101
- enqueue ? klass.perform_later(args) : klass.perform_now(args)
100
+ method = delivery_method_for(delivery_method[:name], delivery_method[:options])
101
+ enqueue ? method.perform_later(args) : method.perform_now(args)
102
102
  end
103
103
  end
104
104
 
105
- # Retrieves the correct class for a delivery method
106
- def get_class(name, options)
105
+ def delivery_method_for(name, options)
107
106
  if options[:class]
108
107
  options[:class].constantize
109
108
  else
@@ -111,13 +110,25 @@ module Noticed
111
110
  end
112
111
  end
113
112
 
114
- # Validates that all params are present
115
113
  def validate!
114
+ validate_params_present!
115
+ validate_options_of_delivery_methods!
116
+ end
117
+
118
+ # Validates that all params are present
119
+ def validate_params_present!
116
120
  self.class.param_names.each do |param_name|
117
121
  if params[param_name].nil?
118
122
  raise ValidationError, "#{param_name} is missing."
119
123
  end
120
124
  end
121
125
  end
126
+
127
+ def validate_options_of_delivery_methods!
128
+ delivery_methods.each do |delivery_method|
129
+ method = delivery_method_for(delivery_method[:name], delivery_method[:options])
130
+ method.validate!(delivery_method[:options])
131
+ end
132
+ end
122
133
  end
123
134
  end
@@ -17,18 +17,18 @@ module Noticed
17
17
 
18
18
  def channel
19
19
  @channel ||= begin
20
- value = options[:channel]
21
- case value
22
- when String
23
- value.constantize
24
- when Symbol
25
- notification.send(value)
26
- when Class
27
- value
28
- else
29
- Noticed::NotificationChannel
30
- end
31
- end
20
+ value = options[:channel]
21
+ case value
22
+ when String
23
+ value.constantize
24
+ when Symbol
25
+ notification.send(value)
26
+ when Class
27
+ value
28
+ else
29
+ Noticed::NotificationChannel
30
+ end
31
+ end
32
32
  end
33
33
  end
34
34
  end
@@ -4,11 +4,35 @@ module Noticed
4
4
  extend ActiveModel::Callbacks
5
5
  define_model_callbacks :deliver
6
6
 
7
- attr_reader :notification, :options, :recipient, :record
7
+ class_attribute :option_names, instance_writer: false, default: []
8
+
9
+ attr_reader :notification, :options, :params, :recipient, :record
10
+
11
+ class << self
12
+ # Copy option names from parent
13
+ def inherited(base) #:nodoc:
14
+ base.option_names = option_names.dup
15
+ super
16
+ end
17
+
18
+ def options(*names)
19
+ option_names.concat Array.wrap(names)
20
+ end
21
+ alias_method :option, :options
22
+
23
+ def validate!(delivery_method_options)
24
+ option_names.each do |option_name|
25
+ unless delivery_method_options.key? option_name
26
+ raise ValidationError, "option `#{option_name}` must be set for #{name}"
27
+ end
28
+ end
29
+ end
30
+ end
8
31
 
9
32
  def perform(args)
10
33
  @notification = args[:notification_class].constantize.new(args[:params])
11
34
  @options = args[:options]
35
+ @params = args[:params]
12
36
  @recipient = args[:recipient]
13
37
  @record = args[:record]
14
38
 
@@ -1,6 +1,8 @@
1
1
  module Noticed
2
2
  module DeliveryMethods
3
3
  class Email < Base
4
+ option :mailer
5
+
4
6
  def deliver
5
7
  mailer.with(format).send(method.to_sym).deliver_later
6
8
  end
@@ -32,10 +32,10 @@ module Noticed
32
32
  # Rehydrate the database notification into the Notification object for rendering
33
33
  def to_notification
34
34
  @_notification ||= begin
35
- instance = type.constantize.with(params)
36
- instance.record = self
37
- instance
38
- end
35
+ instance = type.constantize.with(params)
36
+ instance.record = self
37
+ instance
38
+ end
39
39
  end
40
40
 
41
41
  def mark_as_read!
@@ -10,7 +10,7 @@ module Noticed
10
10
  def translate(key, **options)
11
11
  I18n.translate(scope_translation_key(key), **options)
12
12
  end
13
- alias t translate
13
+ alias_method :t, :translate
14
14
 
15
15
  def scope_translation_key(key)
16
16
  if key.to_s.start_with?(".")
@@ -1,3 +1,3 @@
1
1
  module Noticed
2
- VERSION = "1.2.11"
2
+ VERSION = "1.2.16"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: noticed
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.11
4
+ version: 1.2.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Oliver
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-08-20 00:00:00.000000000 Z
11
+ date: 2020-10-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -91,10 +91,11 @@ files:
91
91
  - MIT-LICENSE
92
92
  - README.md
93
93
  - Rakefile
94
- - app/channels/noticed/notification_channel.rb
94
+ - lib/generators/noticed/delivery_method_generator.rb
95
95
  - lib/generators/noticed/model_generator.rb
96
96
  - lib/generators/noticed/notification_generator.rb
97
97
  - lib/generators/noticed/templates/README
98
+ - lib/generators/noticed/templates/delivery_method.rb.tt
98
99
  - lib/generators/noticed/templates/notification.rb.tt
99
100
  - lib/noticed.rb
100
101
  - lib/noticed/base.rb
@@ -109,6 +110,7 @@ files:
109
110
  - lib/noticed/delivery_methods/vonage.rb
110
111
  - lib/noticed/engine.rb
111
112
  - lib/noticed/model.rb
113
+ - lib/noticed/notification_channel.rb
112
114
  - lib/noticed/text_coder.rb
113
115
  - lib/noticed/translation.rb
114
116
  - lib/noticed/version.rb
@@ -117,7 +119,7 @@ homepage: https://github.com/excid3/noticed
117
119
  licenses:
118
120
  - MIT
119
121
  metadata: {}
120
- post_install_message:
122
+ post_install_message:
121
123
  rdoc_options: []
122
124
  require_paths:
123
125
  - lib
@@ -132,8 +134,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
132
134
  - !ruby/object:Gem::Version
133
135
  version: '0'
134
136
  requirements: []
135
- rubygems_version: 3.1.2
136
- signing_key:
137
+ rubygems_version: 3.1.4
138
+ signing_key:
137
139
  specification_version: 4
138
140
  summary: Notifications for Ruby on Rails applications
139
141
  test_files: []