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 +4 -4
- data/README.md +39 -23
- data/app/jobs/noticed/event_job.rb +3 -3
- data/app/models/concerns/noticed/deliverable.rb +5 -0
- data/app/models/noticed/deliverable/deliver_by.rb +25 -13
- data/app/models/noticed/ephemeral.rb +4 -4
- data/db/migrate/20231215190233_create_noticed_tables.rb +16 -5
- data/lib/generators/noticed/templates/notifier.rb.tt +1 -1
- data/lib/noticed/api_client.rb +1 -1
- data/lib/noticed/delivery_methods/ios.rb +1 -1
- data/lib/noticed/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7df6a0c9d61e67b03bdb4fa83ac6cf3ef46b1b79b23ac98f1b0acdf1b02b336a
|
4
|
+
data.tar.gz: f457d0616b83add859fb1660cc53f2bf321f3631c25e6d9403bf52d84246be43
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
```
|
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
|
205
|
+
class Recipient < ApplicationRecord # or whatever your recipient model is
|
206
206
|
has_many :ios_device_tokens
|
207
207
|
|
208
|
-
|
209
|
-
|
210
|
-
|
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
|
-
|
301
|
-
|
302
|
-
|
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
|
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 = ->
|
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` —
|
365
|
-
* `config.queue`
|
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
|
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 :
|
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` —
|
596
|
-
* `record` —
|
597
|
-
* `notification` —
|
598
|
-
* `recipient` —
|
599
|
-
* `config` —
|
600
|
-
* `params` —
|
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
|
-
|
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 :
|
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.
|
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.
|
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
|
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
|
32
|
-
|
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
|
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
|
-
|
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
|
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
|
data/lib/noticed/api_client.rb
CHANGED
@@ -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)
|
data/lib/noticed/version.rb
CHANGED
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.
|
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-
|
11
|
+
date: 2024-03-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|