noticed 2.1.3 → 2.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: 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