noticed 2.1.3 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4481f215fcf7bde433f273ff7e3b7df9a0af5971eae6827e108f667fb21e57f4
4
- data.tar.gz: 67360b14ce530e2ad2433ee8271c8c0e231220908d8c4014b817517eb3d9185a
3
+ metadata.gz: 7df6a0c9d61e67b03bdb4fa83ac6cf3ef46b1b79b23ac98f1b0acdf1b02b336a
4
+ data.tar.gz: f457d0616b83add859fb1660cc53f2bf321f3631c25e6d9403bf52d84246be43
5
5
  SHA512:
6
- metadata.gz: a9a5d6e6b500e8e4ce297951058f46abf4e3b5c23f42b5e904cfd3a2a7dce6b4f4d933e12731fbde524e70d2339d1a698375eabdd4ba6fd26898e0a0910d2ac8
7
- data.tar.gz: 9b4b44dcb8d1fe3fc540e2cdea0ff039846ce56b3b0e1bf709b98f484ee58e7f4ab0ad6566fdbccf2eec1a28297ad511db00ed87b3825a5eaac0d1e532086173
6
+ metadata.gz: cc114600b94adafc1fb4c01034cfd31e70acda183e5734a31f5ea1d5408272b93b5545dad3861394e0af2944aa2f95765a14689130d8f49479925e3a17f35c2b
7
+ data.tar.gz: a5e8cc9353874c01f45c286ced403446196be57d241ca1c534b365df1869a560fe08e6c65655e8bb246e672728dd2edb8a394de68111c94b0446513e93b52f9c
data/README.md CHANGED
@@ -71,7 +71,7 @@ Noticed operates with a few constructs: Notifiers, delivery methods, and Notific
71
71
 
72
72
  To start, generate a Notifier:
73
73
 
74
- ```sh
74
+ ```bash
75
75
  rails generate noticed:notifier NewCommentNotifier
76
76
  ```
77
77
 
@@ -202,12 +202,12 @@ class CommentNotifier < Noticed::Event
202
202
  end
203
203
  end
204
204
 
205
- class Recipent < ApplicationRecord # or whatever your recipient model is
205
+ class Recipient < ApplicationRecord # or whatever your recipient model is
206
206
  has_many :ios_device_tokens
207
207
 
208
- def send_ios_notification?
209
- # some logic
210
- end
208
+ def send_ios_notification?
209
+ # some logic
210
+ end
211
211
  end
212
212
  ```
213
213
  </details>
@@ -297,16 +297,16 @@ Will look for the following translation path:
297
297
 
298
298
  en:
299
299
  notifiers:
300
- new_comment_notifier:
301
- notification:
302
- message: "Someone posted a new comment!"
300
+ new_comment_notifier:
301
+ notification:
302
+ message: "Someone posted a new comment!"
303
303
  ```
304
304
 
305
305
  Or, if you have your Notifier within another module, such as `Admin::NewCommentNotifier`, the resulting lookup path will be `en.notifiers.admin.new_comment_notifier.notification.message` (modules become nesting steps).
306
306
 
307
307
  #### Tip: Capture User Preferences
308
308
 
309
- 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.
309
+ 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.
310
310
 
311
311
  For example:
312
312
 
@@ -319,6 +319,19 @@ class CommentNotifier < Noticed::Event
319
319
  end
320
320
  end
321
321
  ```
322
+
323
+ If you would like to skip the delivery job altogether, for example if you know that a user doesn't support the platform and you would like to save resources by not enqueuing the job, you can use `before_enqueue`.
324
+
325
+ For example:
326
+
327
+ ```ruby
328
+ class IosNotifier < Noticed::Event
329
+ deliver_by :ios do |config|
330
+ # ...
331
+ config.before_enqueue = ->{ throw(:abort) unless recipient.registered_ios? }
332
+ end
333
+ end
334
+
322
335
  #### Tip: Extracting Delivery Method Configurations
323
336
 
324
337
  If you want to reuse delivery method configurations across multiple Notifiers, you can extract them into a module and include them in your Notifiers.
@@ -348,7 +361,7 @@ module IosNotifier
348
361
  config.key_id = Rails.application.credentials.dig(:ios, :key_id)
349
362
  config.team_id = Rails.application.credentials.dig(:ios, :team_id)
350
363
  config.apns_key = Rails.application.credentials.dig(:ios, :apns_key)
351
- config.if = ->(recipient) { recipient.ios_notifications? }
364
+ config.if = -> { recipient.ios_notifications? }
352
365
  end
353
366
  end
354
367
  end
@@ -361,8 +374,8 @@ Each of these options are available for every delivery method (individual or bul
361
374
  * `config.if` — Intended for a lambda or method; runs after the `wait` if configured; cancels the delivery method if returns falsey
362
375
  * `config.unless` — Intended for a lambda or method; runs after the `wait` if configured; cancels the delivery method if returns truthy
363
376
  * `config.wait` — (Should yield an `ActiveSupport::Duration`) Delays the job that runs this delivery method for the given duration of time
364
- * `config.wait_until` — (Should yield a specific time object) Delays the job that runs this delivery method until the specific time specified
365
- * `config.queue` — Sets the ActiveJob queue name to be used for the job that runs this delivery method
377
+ * `config.wait_until` — (Should yield a specific time object) Delays the job that runs this delivery method until the specific time specified
378
+ * `config.queue` — Sets the ActiveJob queue name to be used for the job that runs this delivery method
366
379
 
367
380
  ### 📨 Sending Notifications
368
381
 
@@ -387,7 +400,7 @@ This invocation will create a single `Noticed::Event` record and a `Noticed::Not
387
400
 
388
401
  ### Custom Noticed Model Methods
389
402
 
390
- In order to extend the Noticed models you'll need to use a concern an a to_prepare block:
403
+ In order to extend the Noticed models you'll need to use a concern and a to_prepare block:
391
404
 
392
405
  ```ruby
393
406
  # config/initializers/noticed.rb
@@ -395,7 +408,7 @@ module NotificationExtensions
395
408
  extend ActiveSupport::Concern
396
409
 
397
410
  included do
398
- belongs_to :organisation
411
+ belongs_to :organization
399
412
 
400
413
  scope :filter_by_type, ->(type) { where(type:) }
401
414
  scope :exclude_type, ->(type) { where.not(type:) }
@@ -489,7 +502,7 @@ Sending a notification is entirely an internal-to-your-app function. Delivery me
489
502
  A common pattern is to deliver a notification via a real (or real-ish)-time service, then, after some time has passed, email the user if they have not yet read the notification. You can implement this functionality by combining multiple delivery methods, the `wait` option, and the conditional `if` / `unless` option.
490
503
 
491
504
  ```ruby
492
- class NewCommentNotifier< Noticed::Event
505
+ class NewCommentNotifier < Noticed::Event
493
506
  deliver_by :action_cable
494
507
  deliver_by :email do |config|
495
508
  config.mailer = "CommentMailer"
@@ -544,6 +557,7 @@ See the [Custom Noticed Model Methods](#custom-noticed-model-methods) section fo
544
557
 
545
558
  ```ruby
546
559
  # app/notifiers/delivery_methods/turbo_stream.rb
560
+
547
561
  class DeliveryMethods::TurboStream < ApplicationDeliveryMethod
548
562
  def deliver
549
563
  return unless recipient.is_a?(User)
@@ -557,6 +571,7 @@ end
557
571
 
558
572
  ```ruby
559
573
  # app/models/concerns/noticed/notification_extensions.rb
574
+
560
575
  module Noticed::NotificationExtensions
561
576
  extend ActiveSupport::Concern
562
577
 
@@ -592,12 +607,12 @@ end
592
607
 
593
608
  Delivery methods have access to the following methods and attributes:
594
609
 
595
- * `event` — The `Noticed::Event` record that spawned the notification object currently being delivered
596
- * `record` — The object originally passed into the Notifier as the `record:` param (see the ✨ note above)
597
- * `notification` — The `Noticed::Notification` instance being delivered. All notification helper methods are available on this object
598
- * `recipient` — The individual recipient object being delivered to for this notification (remember that each recipient gets their own instance of the Delivery Method `#deliver`)
599
- * `config` — The hash of configuration options declared by the Notifier that generated this notification and delivery
600
- * `params` — The parameters given to the Notifier in the invocation (via `.with()`)
610
+ * `event` — The `Noticed::Event` record that spawned the notification object currently being delivered
611
+ * `record` — The object originally passed into the Notifier as the `record:` param (see the ✨ note above)
612
+ * `notification` — The `Noticed::Notification` instance being delivered. All notification helper methods are available on this object
613
+ * `recipient` — The individual recipient object being delivered to for this notification (remember that each recipient gets their own instance of the Delivery Method `#deliver`)
614
+ * `config` — The hash of configuration options declared by the Notifier that generated this notification and delivery
615
+ * `params` — The parameters given to the Notifier in the invocation (via `.with()`)
601
616
 
602
617
  #### Validating config options passed to Custom Delivery methods
603
618
 
@@ -628,7 +643,7 @@ class DeliveryMethods::WhatsApp < Noticed::DeliveryMethod
628
643
 
629
644
  def deliver
630
645
  # ...
631
- config.day #=> #<Proc:0x000f7c8 (lambda)>
646
+ config.day #=> #<Proc:0x000f7c8 (lambda)>
632
647
  evaluate_option(config.day) #=> "Tuesday"
633
648
  end
634
649
  end
@@ -766,7 +781,7 @@ class CreateNoticedTables < ActiveRecord::Migration[7.1]
766
781
  t.jsonb :params
767
782
 
768
783
  # Custom Fields
769
- t.string :organisation_id, type: :uuid, as: "((params ->> 'organisation_id')::uuid)", stored: true
784
+ t.string :organization_id, type: :uuid, as: "((params ->> 'organization_id')::uuid)", stored: true
770
785
  t.virtual :action_type, type: :string, as: "((params ->> 'action_type'))", stored: true
771
786
  t.virtual :url, type: :string, as: "((params ->> 'url'))", stored: true
772
787
 
@@ -803,4 +818,5 @@ DATABASE_URL=postgres://127.0.0.1/noticed_test rails test
803
818
  ```
804
819
 
805
820
  ## 📝 License
821
+
806
822
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -4,14 +4,14 @@ module Noticed
4
4
 
5
5
  def perform(event)
6
6
  # Enqueue bulk deliveries
7
- event.bulk_delivery_methods.each do |_, deliver_by|
7
+ event.bulk_delivery_methods.each_value do |deliver_by|
8
8
  deliver_by.perform_later(event)
9
9
  end
10
10
 
11
11
  # Enqueue individual deliveries
12
12
  event.notifications.each do |notification|
13
- event.delivery_methods.each do |_, deliver_by|
14
- deliver_by.perform_later(notification)
13
+ event.delivery_methods.each_value do |deliver_by|
14
+ deliver_by.perform_later(notification) if deliver_by.perform?(notification)
15
15
  end
16
16
  end
17
17
  end
@@ -138,5 +138,10 @@ module Noticed
138
138
  bulk_delivery_methods.values.each(&:validate!)
139
139
  delivery_methods.values.each(&:validate!)
140
140
  end
141
+
142
+ # If a GlobalID record in params is no longer found, the params will default with a noticed_error key
143
+ def deserialize_error?
144
+ !!params[:noticed_error]
145
+ end
141
146
  end
142
147
  end
@@ -19,27 +19,18 @@ module Noticed
19
19
  end
20
20
 
21
21
  def perform_later(event_or_notification, options = {})
22
- options[:wait] ||= evaluate_option(:wait, event_or_notification) if config.has_key?(:wait)
23
- options[:wait_until] ||= evaluate_option(:wait_until, event_or_notification) if config.has_key?(:wait_until)
24
- options[:queue] ||= evaluate_option(:queue, event_or_notification) if config.has_key?(:queue)
25
- options[:priority] ||= evaluate_option(:priority, event_or_notification) if config.has_key?(:priority)
26
-
27
- constant.set(options).perform_later(name, event_or_notification)
22
+ constant.set(computed_options(options, event_or_notification)).perform_later(name, event_or_notification)
28
23
  end
29
24
 
30
25
  def ephemeral_perform_later(notifier, recipient, params, options = {})
31
- options[:wait] ||= evaluate_option(:wait, recipient) if config.has_key?(:wait)
32
- options[:wait_until] ||= evaluate_option(:wait_until, recipient) if config.has_key?(:wait_until)
33
- options[:queue] ||= evaluate_option(:queue, recipient) if config.has_key?(:queue)
34
- options[:priority] ||= evaluate_option(:priority, recipient) if config.has_key?(:priority)
35
-
36
- constant.set(options).perform_later(name, "#{notifier}::Notification", recipient: recipient, params: params)
26
+ constant.set(computed_options(options, recipient))
27
+ .perform_later(name, "#{notifier}::Notification", recipient: recipient, params: params)
37
28
  end
38
29
 
39
30
  def evaluate_option(name, context)
40
31
  option = config[name]
41
32
 
42
- if option&.respond_to?(:call)
33
+ if option.respond_to?(:call)
43
34
  context.instance_exec(&option)
44
35
  elsif option.is_a?(Symbol) && context.respond_to?(option)
45
36
  context.send(option)
@@ -47,6 +38,27 @@ module Noticed
47
38
  option
48
39
  end
49
40
  end
41
+
42
+ def perform?(notification)
43
+ return true unless config.key?(:before_enqueue)
44
+
45
+ perform = false
46
+ catch(:abort) {
47
+ evaluate_option(:before_enqueue, notification)
48
+ perform = true
49
+ }
50
+ perform
51
+ end
52
+
53
+ private
54
+
55
+ def computed_options(options, recipient)
56
+ options[:wait] ||= evaluate_option(:wait, recipient) if config.has_key?(:wait)
57
+ options[:wait_until] ||= evaluate_option(:wait_until, recipient) if config.has_key?(:wait_until)
58
+ options[:queue] ||= evaluate_option(:queue, recipient) if config.has_key?(:queue)
59
+ options[:priority] ||= evaluate_option(:priority, recipient) if config.has_key?(:priority)
60
+ options
61
+ end
50
62
  end
51
63
  end
52
64
  end
@@ -29,6 +29,10 @@ module Noticed
29
29
  notifier.const_set :Notification, Class.new(Noticed::Ephemeral::Notification)
30
30
  end
31
31
 
32
+ def self.notification_methods(&block)
33
+ const_get(:Notification).class_eval(&block)
34
+ end
35
+
32
36
  def deliver(recipients)
33
37
  recipients = Array.wrap(recipients)
34
38
  bulk_delivery_methods.each do |_, deliver_by|
@@ -45,9 +49,5 @@ module Noticed
45
49
  def record
46
50
  params[:record]
47
51
  end
48
-
49
- def notification_methods(&block)
50
- const_get(:Notification).class_eval(&block)
51
- end
52
52
  end
53
53
  end
@@ -1,8 +1,9 @@
1
1
  class CreateNoticedTables < ActiveRecord::Migration[6.1]
2
2
  def change
3
- create_table :noticed_events do |t|
3
+ primary_key_type, foreign_key_type = primary_and_foreign_key_types
4
+ create_table :noticed_events, id: primary_key_type do |t|
4
5
  t.string :type
5
- t.belongs_to :record, polymorphic: true
6
+ t.belongs_to :record, polymorphic: true, type: foreign_key_type
6
7
  if t.respond_to?(:jsonb)
7
8
  t.jsonb :params
8
9
  else
@@ -12,14 +13,24 @@ class CreateNoticedTables < ActiveRecord::Migration[6.1]
12
13
  t.timestamps
13
14
  end
14
15
 
15
- create_table :noticed_notifications do |t|
16
+ create_table :noticed_notifications, id: primary_key_type do |t|
16
17
  t.string :type
17
- t.belongs_to :event, null: false
18
- t.belongs_to :recipient, polymorphic: true, null: false
18
+ t.belongs_to :event, null: false, type: foreign_key_type
19
+ t.belongs_to :recipient, polymorphic: true, null: false, type: foreign_key_type
19
20
  t.datetime :read_at
20
21
  t.datetime :seen_at
21
22
 
22
23
  t.timestamps
23
24
  end
24
25
  end
26
+
27
+ private
28
+
29
+ def primary_and_foreign_key_types
30
+ config = Rails.configuration.generators
31
+ setting = config.options[config.orm][:primary_key_type]
32
+ primary_key_type = setting || :primary_key
33
+ foreign_key_type = setting || :bigint
34
+ [primary_key_type, foreign_key_type]
35
+ end
25
36
  end
@@ -1,6 +1,6 @@
1
1
  # To deliver this notification:
2
2
  #
3
- # <%= class_name %>.with(record: @post, message: "New post").deliver(User.all)
3
+ # <%= class_name %>Notifier.with(record: @post, message: "New post").deliver(User.all)
4
4
 
5
5
  class <%= class_name %>Notifier < ApplicationNotifier
6
6
  # Add your delivery methods
@@ -28,7 +28,7 @@ module Noticed
28
28
  if (json = args.delete(:json))
29
29
  request.body = json.to_json
30
30
  elsif (form = args.delete(:form))
31
- request.set_form(form, "multipart/form-data")
31
+ request.form_data = form
32
32
  end
33
33
 
34
34
  logger.debug("POST #{url}")
@@ -35,7 +35,7 @@ module Noticed
35
35
  method = config[:format]
36
36
  # Call method on Notifier if defined
37
37
  if method&.is_a?(Symbol) && event.respond_to?(method)
38
- event.send(method, apn)
38
+ event.send(method, notification, apn)
39
39
  # If Proc, evaluate it on the Notification
40
40
  elsif method&.respond_to?(:call)
41
41
  notification.instance_exec(apn, &method)
@@ -1,3 +1,3 @@
1
1
  module Noticed
2
- VERSION = "2.1.3"
2
+ VERSION = "2.2.0"
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: 2.1.3
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Oliver
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-02-01 00:00:00.000000000 Z
11
+ date: 2024-03-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails