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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3b37e7d17da790342493c2ffc575cc5d013ac156b7ac600fb0022c79bcb034de
4
- data.tar.gz: 87fc46cbf6829e174b0dc6df1751187965e645f7461848469e48a2ea7bcb6a46
3
+ metadata.gz: e648889dba7414cf25efd56b6b39aeeef03c44febfd7bbfccf47151cb940736e
4
+ data.tar.gz: 0ecb213d7913181f686bbd5cd716e617f0cb6da58a87a4c3185d8e69dcf114c0
5
5
  SHA512:
6
- metadata.gz: b9b4db6825f88670f27d768f40724fbd22c2f8e92fc6ce5f3bc32650cc9e77475d3c6eecb51fd7f59b10d70e735f648c92ecdae6f6d4b8ff61ff4b5c39e501d3
7
- data.tar.gz: f474ad70283d4faa9b33bd51346acb64b29a4076b9c9c0ffcff58e60f75d331bc54b162a8e3d77310153d39caf898ac2924b234389b1089b3262b35fa7b48ac3
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
- Marking all notifications as read:
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 Assocation
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
 
@@ -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"
@@ -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
- enqueue ? method.perform_later(args) : method.perform_now(args)
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.classify}".constantize
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).deliver_later
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.merge(
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
@@ -7,6 +7,8 @@ module Noticed
7
7
  if !options[:ignore_failure] && status != "0"
8
8
  raise ResponseUnsuccessful.new(response)
9
9
  end
10
+
11
+ response
10
12
  end
11
13
 
12
14
  private
@@ -14,11 +14,15 @@ module Noticed
14
14
  scope :read, -> { where.not(read_at: nil) }
15
15
  end
16
16
 
17
- module ClassMethods
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
@@ -1,3 +1,3 @@
1
1
  module Noticed
2
- VERSION = "1.2.16"
2
+ VERSION = "1.2.21"
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.16
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-10-16 00:00:00.000000000 Z
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: mocha
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