noticed 1.2.16 → 1.2.21
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +79 -4
- data/lib/noticed.rb +1 -0
- data/lib/noticed/base.rb +12 -5
- data/lib/noticed/delivery_methods/base.rb +3 -0
- data/lib/noticed/delivery_methods/database.rb +7 -0
- data/lib/noticed/delivery_methods/email.rb +4 -6
- data/lib/noticed/delivery_methods/microsoft_teams.rb +32 -0
- data/lib/noticed/delivery_methods/vonage.rb +2 -0
- data/lib/noticed/model.rb +9 -1
- data/lib/noticed/version.rb +1 -1
- metadata +18 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e648889dba7414cf25efd56b6b39aeeef03c44febfd7bbfccf47151cb940736e
|
4
|
+
data.tar.gz: 0ecb213d7913181f686bbd5cd716e617f0cb6da58a87a4c3185d8e69dcf114c0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 65a6fdd5fa8ea6cea59201358b62a93c5b98af509d8edd0694afda809887367baf973173ecc1bf401e54cb9dc0700989cb7e6e8ff56aa0978b130a8c10b2250b
|
7
|
+
data.tar.gz: e873f202212c36f16b2a97ab7fc678498ded0383bc2ac0ca1af9c647806c0c827be8c85833199af34823202bb8b029fffd66d60903928377890bbcd1e0b4209f
|
data/README.md
CHANGED
@@ -12,6 +12,7 @@ Currently, we support these notification delivery methods out of the box:
|
|
12
12
|
* Email
|
13
13
|
* ActionCable channels
|
14
14
|
* Slack
|
15
|
+
* Microsoft Teams
|
15
16
|
* Twilio (SMS)
|
16
17
|
* Vonage / Nexmo (SMS)
|
17
18
|
|
@@ -105,6 +106,7 @@ end
|
|
105
106
|
|
106
107
|
* `if: :method_name` - Calls `method_name`and cancels delivery method if `false` is returned
|
107
108
|
* `unless: :method_name` - Calls `method_name`and cancels delivery method if `true` is returned
|
109
|
+
* `delay: ActiveSupport::Duration` - Delays the delivery for the given duration of time
|
108
110
|
|
109
111
|
##### Helper Methods
|
110
112
|
|
@@ -185,7 +187,7 @@ Writes notification to the database.
|
|
185
187
|
|
186
188
|
`deliver_by :database`
|
187
189
|
|
188
|
-
**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.
|
190
|
+
**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. For that same reason, the delivery can't be delayed (via the `delay` option) or an error will be raised.
|
189
191
|
|
190
192
|
##### Options
|
191
193
|
|
@@ -253,6 +255,42 @@ Sends a Slack notification via webhook.
|
|
253
255
|
|
254
256
|
Defaults to `Rails.application.credentials.slack[:notification_url]`
|
255
257
|
|
258
|
+
### Microsoft Teams
|
259
|
+
|
260
|
+
Sends a Teams notification via webhook.
|
261
|
+
|
262
|
+
`deliver_by :microsoft_teams`
|
263
|
+
|
264
|
+
#### Options
|
265
|
+
|
266
|
+
* `format: :format_for_teams` - *Optional*
|
267
|
+
|
268
|
+
Use a custom method to define the payload sent to slack. Method should return a Hash.
|
269
|
+
Documentation for posting via Webhooks available at: https://docs.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook
|
270
|
+
|
271
|
+
```ruby
|
272
|
+
{
|
273
|
+
title: "This is the title for the card",
|
274
|
+
text: "This is the body text for the card",
|
275
|
+
sections: [{activityTitle: "Section Title", activityText: "Section Text"}],
|
276
|
+
"potentialAction": [{
|
277
|
+
"@type": "OpenUri",
|
278
|
+
name: "Button Text",
|
279
|
+
targets: [{
|
280
|
+
os: "default",
|
281
|
+
uri: "https://example.com/foo/action"
|
282
|
+
}]
|
283
|
+
}]
|
284
|
+
|
285
|
+
}
|
286
|
+
```
|
287
|
+
|
288
|
+
* `url: :url_for_teams_channel`: - *Optional*
|
289
|
+
|
290
|
+
Use a custom method to retrieve the MS Teams Webhook URL. Method should return a string.
|
291
|
+
|
292
|
+
Defaults to `Rails.application.credentials.microsoft_teams[:notification_url]`
|
293
|
+
|
256
294
|
### Twilio SMS
|
257
295
|
|
258
296
|
Sends an SMS notification via Twilio.
|
@@ -316,6 +354,33 @@ Sends an SMS notification via Vonage / Nexmo.
|
|
316
354
|
}
|
317
355
|
```
|
318
356
|
|
357
|
+
### Fallback Notifications
|
358
|
+
|
359
|
+
A common pattern is to deliver a notification via the database and 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 `delay` option, and the conditional `if` / `unless` option.
|
360
|
+
|
361
|
+
```ruby
|
362
|
+
class CommentNotification < Noticed::Base
|
363
|
+
deliver_by :database
|
364
|
+
deliver_by :email, mailer: 'CommentMailer', delay: 15.minutes, unless: :read?
|
365
|
+
end
|
366
|
+
```
|
367
|
+
|
368
|
+
Here a notification will be created immediately in the database (for display directly in your app). If the notification has not been read after 15 minutes, the email notification will be sent. If the notification has already been read in the app, the email will be skipped.
|
369
|
+
|
370
|
+
You can also configure multiple fallback options:
|
371
|
+
|
372
|
+
```ruby
|
373
|
+
class CriticalSystemNotification < Noticed::Base
|
374
|
+
deliver_by :slack
|
375
|
+
deliver_by :email, mailer: 'CriticalSystemMailer', delay: 10.minutes, unless: :read?
|
376
|
+
deliver_by :twilio, delay: 20.minutes, unless: :read?
|
377
|
+
end
|
378
|
+
```
|
379
|
+
|
380
|
+
In this scenario, you can create an escalating notification that starts with a ping in Slack, then emails the team, and then finally sends an SMS to the on-call phone.
|
381
|
+
|
382
|
+
You can mix and match the options and delivery methods to suit your application specific needs.
|
383
|
+
|
319
384
|
### 🚚 Custom Delivery Methods
|
320
385
|
|
321
386
|
To generate a custom delivery method, simply run
|
@@ -426,10 +491,19 @@ Sorting notifications by newest first:
|
|
426
491
|
user.notifications.newest_first
|
427
492
|
```
|
428
493
|
|
429
|
-
|
494
|
+
Query for read or unread notifications:
|
495
|
+
|
496
|
+
```ruby
|
497
|
+
user.notifications.read
|
498
|
+
user.notifications.unread
|
499
|
+
```
|
500
|
+
|
501
|
+
|
502
|
+
Marking all notifications as read or unread:
|
430
503
|
|
431
504
|
```ruby
|
432
505
|
user.notifications.mark_as_read!
|
506
|
+
user.notifications.mark_as_unread!
|
433
507
|
```
|
434
508
|
|
435
509
|
#### Instance methods
|
@@ -440,10 +514,11 @@ Convert back into a Noticed notification object:
|
|
440
514
|
@notification.to_notification
|
441
515
|
```
|
442
516
|
|
443
|
-
Mark notification as read:
|
517
|
+
Mark notification as read / unread:
|
444
518
|
|
445
519
|
```ruby
|
446
520
|
@notification.mark_as_read!
|
521
|
+
@notification.mark_as_unread!
|
447
522
|
```
|
448
523
|
|
449
524
|
Check if read / unread:
|
@@ -483,7 +558,7 @@ class Post < ApplicationRecord
|
|
483
558
|
end
|
484
559
|
```
|
485
560
|
|
486
|
-
##### Polymorphic
|
561
|
+
##### Polymorphic Association
|
487
562
|
|
488
563
|
If your notification is only associated with one model or you're using a `text` column for your params column , then a polymorphic association is what you'll want to use.
|
489
564
|
|
data/lib/noticed.rb
CHANGED
@@ -16,6 +16,7 @@ module Noticed
|
|
16
16
|
autoload :Database, "noticed/delivery_methods/database"
|
17
17
|
autoload :Email, "noticed/delivery_methods/email"
|
18
18
|
autoload :Slack, "noticed/delivery_methods/slack"
|
19
|
+
autoload :MicrosoftTeams, "noticed/delivery_methods/microsoft_teams"
|
19
20
|
autoload :Test, "noticed/delivery_methods/test"
|
20
21
|
autoload :Twilio, "noticed/delivery_methods/twilio"
|
21
22
|
autoload :Vonage, "noticed/delivery_methods/vonage"
|
data/lib/noticed/base.rb
CHANGED
@@ -12,6 +12,8 @@ module Noticed
|
|
12
12
|
# Gives notifications access to the record and recipient when formatting for delivery
|
13
13
|
attr_accessor :record, :recipient
|
14
14
|
|
15
|
+
delegate :read?, :unread?, to: :record
|
16
|
+
|
15
17
|
class << self
|
16
18
|
def deliver_by(name, options = {})
|
17
19
|
delivery_methods.push(name: name, options: options)
|
@@ -85,9 +87,6 @@ module Noticed
|
|
85
87
|
|
86
88
|
# Actually runs an individual delivery
|
87
89
|
def run_delivery_method(delivery_method, recipient:, enqueue:)
|
88
|
-
return if (delivery_method_name = delivery_method.dig(:options, :if)) && !send(delivery_method_name)
|
89
|
-
return if (delivery_method_name = delivery_method.dig(:options, :unless)) && send(delivery_method_name)
|
90
|
-
|
91
90
|
args = {
|
92
91
|
notification_class: self.class.name,
|
93
92
|
options: delivery_method[:options],
|
@@ -98,7 +97,15 @@ module Noticed
|
|
98
97
|
|
99
98
|
run_callbacks delivery_method[:name] do
|
100
99
|
method = delivery_method_for(delivery_method[:name], delivery_method[:options])
|
101
|
-
|
100
|
+
|
101
|
+
# Always perfrom later if a delay is present
|
102
|
+
if (delay = delivery_method.dig(:options, :delay))
|
103
|
+
method.set(wait: delay).perform_later(args)
|
104
|
+
elsif enqueue
|
105
|
+
method.perform_later(args)
|
106
|
+
else
|
107
|
+
method.perform_now(args)
|
108
|
+
end
|
102
109
|
end
|
103
110
|
end
|
104
111
|
|
@@ -106,7 +113,7 @@ module Noticed
|
|
106
113
|
if options[:class]
|
107
114
|
options[:class].constantize
|
108
115
|
else
|
109
|
-
"Noticed::DeliveryMethods::#{name.to_s.
|
116
|
+
"Noticed::DeliveryMethods::#{name.to_s.camelize}".constantize
|
110
117
|
end
|
111
118
|
end
|
112
119
|
|
@@ -40,6 +40,9 @@ module Noticed
|
|
40
40
|
@notification.record = args[:record]
|
41
41
|
@notification.recipient = args[:recipient]
|
42
42
|
|
43
|
+
return if (condition = @options[:if]) && !@notification.send(condition)
|
44
|
+
return if (condition = @options[:unless]) && @notification.send(condition)
|
45
|
+
|
43
46
|
run_callbacks :deliver do
|
44
47
|
deliver
|
45
48
|
end
|
@@ -6,6 +6,13 @@ module Noticed
|
|
6
6
|
recipient.send(association_name).create!(attributes)
|
7
7
|
end
|
8
8
|
|
9
|
+
def self.validate!(options)
|
10
|
+
super
|
11
|
+
|
12
|
+
# Must be executed right away so the other deliveries can access the db record
|
13
|
+
raise ArgumentError, "database delivery cannot be delayed" if options.key?(:delay)
|
14
|
+
end
|
15
|
+
|
9
16
|
private
|
10
17
|
|
11
18
|
def association_name
|
@@ -4,7 +4,7 @@ module Noticed
|
|
4
4
|
option :mailer
|
5
5
|
|
6
6
|
def deliver
|
7
|
-
mailer.with(format).send(method.to_sym).
|
7
|
+
mailer.with(format).send(method.to_sym).deliver_now
|
8
8
|
end
|
9
9
|
|
10
10
|
private
|
@@ -18,14 +18,12 @@ module Noticed
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def format
|
21
|
-
if (method = options[:format])
|
21
|
+
params = if (method = options[:format])
|
22
22
|
notification.send(method)
|
23
23
|
else
|
24
|
-
notification.params
|
25
|
-
recipient: recipient,
|
26
|
-
record: record
|
27
|
-
)
|
24
|
+
notification.params
|
28
25
|
end
|
26
|
+
params.merge(recipient: recipient, record: record)
|
29
27
|
end
|
30
28
|
end
|
31
29
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Noticed
|
2
|
+
module DeliveryMethods
|
3
|
+
class MicrosoftTeams < Base
|
4
|
+
def deliver
|
5
|
+
post(url, json: format)
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def format
|
11
|
+
if (method = options[:format])
|
12
|
+
notification.send(method)
|
13
|
+
else
|
14
|
+
{
|
15
|
+
title: notification.params[:title],
|
16
|
+
text: notification.params[:text],
|
17
|
+
sections: notification.params[:sections],
|
18
|
+
potentialAction: notification.params[:notification_action]
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def url
|
24
|
+
if (method = options[:url])
|
25
|
+
notification.send(method)
|
26
|
+
else
|
27
|
+
Rails.application.credentials.microsoft_teams[:notification_url]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/noticed/model.rb
CHANGED
@@ -14,11 +14,15 @@ module Noticed
|
|
14
14
|
scope :read, -> { where.not(read_at: nil) }
|
15
15
|
end
|
16
16
|
|
17
|
-
|
17
|
+
class_methods do
|
18
18
|
def mark_as_read!
|
19
19
|
update_all(read_at: Time.current, updated_at: Time.current)
|
20
20
|
end
|
21
21
|
|
22
|
+
def mark_as_unread!
|
23
|
+
update_all(read_at: nil, updated_at: Time.current)
|
24
|
+
end
|
25
|
+
|
22
26
|
def noticed_coder
|
23
27
|
case attribute_types["params"].type
|
24
28
|
when :json, :jsonb
|
@@ -42,6 +46,10 @@ module Noticed
|
|
42
46
|
update(read_at: Time.current)
|
43
47
|
end
|
44
48
|
|
49
|
+
def mark_as_unread!
|
50
|
+
update(read_at: nil)
|
51
|
+
end
|
52
|
+
|
45
53
|
def unread?
|
46
54
|
!read?
|
47
55
|
end
|
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: 1.2.
|
4
|
+
version: 1.2.21
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Oliver
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -67,7 +67,21 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: webmock
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: mysql2
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
87
|
- - ">="
|
@@ -104,6 +118,7 @@ files:
|
|
104
118
|
- lib/noticed/delivery_methods/base.rb
|
105
119
|
- lib/noticed/delivery_methods/database.rb
|
106
120
|
- lib/noticed/delivery_methods/email.rb
|
121
|
+
- lib/noticed/delivery_methods/microsoft_teams.rb
|
107
122
|
- lib/noticed/delivery_methods/slack.rb
|
108
123
|
- lib/noticed/delivery_methods/test.rb
|
109
124
|
- lib/noticed/delivery_methods/twilio.rb
|