noticed 1.2.12 → 1.2.17
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +89 -5
- data/lib/generators/noticed/model_generator.rb +11 -2
- data/lib/generators/noticed/templates/delivery_method.rb.tt +7 -0
- data/lib/noticed.rb +2 -0
- data/lib/noticed/base.rb +18 -7
- data/lib/noticed/delivery_methods/action_cable.rb +12 -12
- data/lib/noticed/delivery_methods/base.rb +25 -1
- data/lib/noticed/delivery_methods/email.rb +2 -0
- data/lib/noticed/delivery_methods/microsoft_teams.rb +32 -0
- data/lib/noticed/model.rb +8 -4
- data/{app/channels → lib}/noticed/notification_channel.rb +0 -0
- data/lib/noticed/translation.rb +1 -1
- data/lib/noticed/version.rb +1 -1
- metadata +8 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5dc2e5f50621a5b5da4f901c472621c2fce03d5f0f4db7c5a00a42de527e3128
|
4
|
+
data.tar.gz: 1e07d7ea3599b7999d9a252a062ab38641cf6553c8392bf54d70ec9fbc164050
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5f2dc0a1735bea8161241f7b384f722fd0a0d5bf1bac80424d63647d39cf9ef727839f3ba8320474c57da327e381daa46c533a788ca7d3ea1978c5eee10dcbfc
|
7
|
+
data.tar.gz: 44eb3c5472b947d416d6f14bb2fa1b6a6d9ed26e853eb5d5ca559c0467c0dea9b83634fb1aac72a691b8fbd7805103e3029562e0800d0f433d2ecd9ab5a4e4d1
|
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
|
|
@@ -78,7 +79,7 @@ To add delivery methods, simply `include` the module for the delivery methods yo
|
|
78
79
|
class CommentNotification < Noticed::Base
|
79
80
|
deliver_by :database
|
80
81
|
deliver_by :action_cable
|
81
|
-
deliver_by :email, if: :email_notifications?
|
82
|
+
deliver_by :email, mailer: 'CommentMailer', if: :email_notifications?
|
82
83
|
|
83
84
|
# I18n helpers
|
84
85
|
def message
|
@@ -86,6 +87,7 @@ class CommentNotification < Noticed::Base
|
|
86
87
|
end
|
87
88
|
|
88
89
|
# URL helpers are accessible in notifications
|
90
|
+
# Don't forget to set your default_url_options so Rails knows how to generate urls
|
89
91
|
def url
|
90
92
|
post_path(params[:post])
|
91
93
|
end
|
@@ -113,6 +115,12 @@ You can define helper methods inside your Notification object to make it easier
|
|
113
115
|
|
114
116
|
Rails url helpers are included in notification classes by default so you have full access to them just like you would in your controllers and views.
|
115
117
|
|
118
|
+
Don't forget, you'll need to configure `default_url_options` in order for Rails to know what host and port to use when generating URLs.
|
119
|
+
|
120
|
+
```ruby
|
121
|
+
Rails.application.routes.default_url_options[:host] = 'localhost:3000'
|
122
|
+
```
|
123
|
+
|
116
124
|
**Callbacks**
|
117
125
|
|
118
126
|
Like ActiveRecord, notifications have several different types of callbacks.
|
@@ -120,7 +128,7 @@ Like ActiveRecord, notifications have several different types of callbacks.
|
|
120
128
|
```ruby
|
121
129
|
class CommentNotification < Noticed::Base
|
122
130
|
deliver_by :database
|
123
|
-
deliver_by :email
|
131
|
+
deliver_by :email, mailer: 'CommentMailer'
|
124
132
|
|
125
133
|
# Callbacks for the entire delivery
|
126
134
|
before_deliver :whatever
|
@@ -158,7 +166,7 @@ For example:
|
|
158
166
|
|
159
167
|
```ruby
|
160
168
|
class CommentNotification < Noticed::Base
|
161
|
-
deliver_by :email, if: :email_notifications?
|
169
|
+
deliver_by :email, mailer: 'CommentMailer', if: :email_notifications?
|
162
170
|
|
163
171
|
def email_notifications?
|
164
172
|
recipient.email_notifications?
|
@@ -246,6 +254,42 @@ Sends a Slack notification via webhook.
|
|
246
254
|
|
247
255
|
Defaults to `Rails.application.credentials.slack[:notification_url]`
|
248
256
|
|
257
|
+
### Microsoft Teams
|
258
|
+
|
259
|
+
Sends a Teams notification via webhook.
|
260
|
+
|
261
|
+
`deliver_by :microsoft_teams`
|
262
|
+
|
263
|
+
#### Options
|
264
|
+
|
265
|
+
* `format: :format_for_teams` - *Optional*
|
266
|
+
|
267
|
+
Use a custom method to define the payload sent to slack. Method should return a Hash.
|
268
|
+
Documentation for posting via Webhooks available at: https://docs.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook
|
269
|
+
|
270
|
+
```ruby
|
271
|
+
{
|
272
|
+
title: "This is the title for the card",
|
273
|
+
text: "This is the body text for the card",
|
274
|
+
sections: [{activityTitle: "Section Title", activityText: "Section Text"}],
|
275
|
+
"potentialAction": [{
|
276
|
+
"@type": "OpenUri",
|
277
|
+
name: "Button Text",
|
278
|
+
targets: [{
|
279
|
+
os: "default",
|
280
|
+
uri: "https://example.com/foo/action"
|
281
|
+
}]
|
282
|
+
}]
|
283
|
+
|
284
|
+
}
|
285
|
+
```
|
286
|
+
|
287
|
+
* `url: :url_for_teams_channel`: - *Optional*
|
288
|
+
|
289
|
+
Use a custom method to retrieve the MS Teams Webhook URL. Method should return a string.
|
290
|
+
|
291
|
+
Defaults to `Rails.application.credentials.microsoft_teams[:notification_url]`
|
292
|
+
|
249
293
|
### Twilio SMS
|
250
294
|
|
251
295
|
Sends an SMS notification via Twilio.
|
@@ -340,6 +384,45 @@ Delivery methods have access to the following methods and attributes:
|
|
340
384
|
* `recipient` - The object who should receive the notification. This is typically a User, Account, or other ActiveRecord model.
|
341
385
|
* `params` - The params passed into the notification. This is details about the event that happened. For example, a user commenting on a post would have params of `{ user: User.first }`
|
342
386
|
|
387
|
+
#### Validating options passed to Custom Delivery methods
|
388
|
+
|
389
|
+
The presence of the delivery method options is automatically validated if using the `option(s)` method.
|
390
|
+
|
391
|
+
If you want to validate that the passed options contain valid values, or to add any custom validations, override the `self.validate!(delivery_method_options)` method from the `Noticed::DeliveryMethods::Base` class.
|
392
|
+
|
393
|
+
```ruby
|
394
|
+
class DeliveryMethods::Discord < Noticed::DeliveryMethods::Base
|
395
|
+
option :username # Requires the username option to be passed
|
396
|
+
|
397
|
+
def deliver
|
398
|
+
# Logic for sending a Discord notification
|
399
|
+
end
|
400
|
+
|
401
|
+
def self.validate!(delivery_method_options)
|
402
|
+
super # Don't forget to call super, otherwise option presence won't be validated
|
403
|
+
|
404
|
+
# Custom validations
|
405
|
+
if delivery_method_options[:username].blank?
|
406
|
+
raise Noticed::ValidationError, 'the `username` option must be present'
|
407
|
+
end
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
411
|
+
class CommentNotification < Noticed::Base
|
412
|
+
deliver_by :discord, class: 'DeliveryMethods::Discord'
|
413
|
+
end
|
414
|
+
```
|
415
|
+
|
416
|
+
Now it will raise an error because a required argument is missing.
|
417
|
+
|
418
|
+
To fix the error, the argument has to be passed correctly. For example:
|
419
|
+
|
420
|
+
```ruby
|
421
|
+
class CommentNotification < Noticed::Base
|
422
|
+
deliver_by :discord, class: 'DeliveryMethods::Discord', username: User.admin.username
|
423
|
+
end
|
424
|
+
```
|
425
|
+
|
343
426
|
#### Callbacks
|
344
427
|
|
345
428
|
Callbacks for delivery methods wrap the *actual* delivery of the notification. You can use `before_deliver`, `around_deliver` and `after_deliver` in your custom delivery methods.
|
@@ -360,7 +443,7 @@ Rails 6.1+ can serialize Class and Module objects as arguments to ActiveJob. The
|
|
360
443
|
deliver_by DeliveryMethods::Discord
|
361
444
|
```
|
362
445
|
|
363
|
-
For Rails 6.0
|
446
|
+
For Rails 6.0, you must pass strings of the class names in the `deliver_by` options.
|
364
447
|
|
365
448
|
```ruby
|
366
449
|
deliver_by :discord, class: "DeliveryMethods::Discord"
|
@@ -394,10 +477,11 @@ Convert back into a Noticed notification object:
|
|
394
477
|
@notification.to_notification
|
395
478
|
```
|
396
479
|
|
397
|
-
Mark notification as read:
|
480
|
+
Mark notification as read / unread:
|
398
481
|
|
399
482
|
```ruby
|
400
483
|
@notification.mark_as_read!
|
484
|
+
@notification.mark_as_unread!
|
401
485
|
```
|
402
486
|
|
403
487
|
Check if read / unread:
|
@@ -15,13 +15,22 @@ module Noticed
|
|
15
15
|
argument :attributes, type: :array, default: [], banner: "field:type field:type"
|
16
16
|
|
17
17
|
def generate_notification
|
18
|
-
generate :model, name, "recipient:references{polymorphic}", "type", params_column, "read_at:datetime", *attributes
|
18
|
+
generate :model, name, "recipient:references{polymorphic}", "type", params_column, "read_at:datetime:index", *attributes
|
19
19
|
end
|
20
20
|
|
21
21
|
def add_noticed_model
|
22
22
|
inject_into_class model_path, class_name, " include Noticed::Model\n"
|
23
23
|
end
|
24
24
|
|
25
|
+
def add_not_nullable
|
26
|
+
migration_path = Dir.glob(Rails.root.join("db/migrate/*")).max_by { |f| File.mtime(f) }
|
27
|
+
|
28
|
+
# Force is required because null: false already exists in the file and Thor isn't smart enough to tell the difference
|
29
|
+
insert_into_file migration_path, after: "t.string :type", force: true do
|
30
|
+
", null: false"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
25
34
|
def done
|
26
35
|
readme "README" if behavior == :invoke
|
27
36
|
end
|
@@ -34,7 +43,7 @@ module Noticed
|
|
34
43
|
|
35
44
|
def params_column
|
36
45
|
case ActiveRecord::Base.configurations.configs_for(spec_name: "primary").config["adapter"]
|
37
|
-
when "
|
46
|
+
when "mysql2"
|
38
47
|
"params:json"
|
39
48
|
when "postgresql"
|
40
49
|
"params:jsonb"
|
@@ -2,4 +2,11 @@ class DeliveryMethods::<%= class_name %> < Noticed::DeliveryMethods::Base
|
|
2
2
|
def deliver
|
3
3
|
# Logic for sending the notification
|
4
4
|
end
|
5
|
+
|
6
|
+
# You may override this method to validate options for the delivery method
|
7
|
+
# Invalid options should raise a ValidationError
|
8
|
+
#
|
9
|
+
# def self.validate!(options)
|
10
|
+
# raise ValidationError, "required_option missing" unless options[:required_option]
|
11
|
+
# end
|
5
12
|
end
|
data/lib/noticed.rb
CHANGED
@@ -8,6 +8,7 @@ module Noticed
|
|
8
8
|
autoload :Model, "noticed/model"
|
9
9
|
autoload :TextCoder, "noticed/text_coder"
|
10
10
|
autoload :Translation, "noticed/translation"
|
11
|
+
autoload :NotificationChannel, "noticed/notification_channel"
|
11
12
|
|
12
13
|
module DeliveryMethods
|
13
14
|
autoload :Base, "noticed/delivery_methods/base"
|
@@ -15,6 +16,7 @@ module Noticed
|
|
15
16
|
autoload :Database, "noticed/delivery_methods/database"
|
16
17
|
autoload :Email, "noticed/delivery_methods/email"
|
17
18
|
autoload :Slack, "noticed/delivery_methods/slack"
|
19
|
+
autoload :MicrosoftTeams, "noticed/delivery_methods/microsoft_teams"
|
18
20
|
autoload :Test, "noticed/delivery_methods/test"
|
19
21
|
autoload :Twilio, "noticed/delivery_methods/twilio"
|
20
22
|
autoload :Vonage, "noticed/delivery_methods/vonage"
|
data/lib/noticed/base.rb
CHANGED
@@ -32,7 +32,7 @@ module Noticed
|
|
32
32
|
def params(*names)
|
33
33
|
param_names.concat Array.wrap(names)
|
34
34
|
end
|
35
|
-
|
35
|
+
alias_method :param, :params
|
36
36
|
end
|
37
37
|
|
38
38
|
def initialize(params = {})
|
@@ -97,27 +97,38 @@ module Noticed
|
|
97
97
|
}
|
98
98
|
|
99
99
|
run_callbacks delivery_method[:name] do
|
100
|
-
|
101
|
-
enqueue ?
|
100
|
+
method = delivery_method_for(delivery_method[:name], delivery_method[:options])
|
101
|
+
enqueue ? method.perform_later(args) : method.perform_now(args)
|
102
102
|
end
|
103
103
|
end
|
104
104
|
|
105
|
-
|
106
|
-
def get_class(name, options)
|
105
|
+
def delivery_method_for(name, options)
|
107
106
|
if options[:class]
|
108
107
|
options[:class].constantize
|
109
108
|
else
|
110
|
-
"Noticed::DeliveryMethods::#{name.to_s.
|
109
|
+
"Noticed::DeliveryMethods::#{name.to_s.camelize}".constantize
|
111
110
|
end
|
112
111
|
end
|
113
112
|
|
114
|
-
# Validates that all params are present
|
115
113
|
def validate!
|
114
|
+
validate_params_present!
|
115
|
+
validate_options_of_delivery_methods!
|
116
|
+
end
|
117
|
+
|
118
|
+
# Validates that all params are present
|
119
|
+
def validate_params_present!
|
116
120
|
self.class.param_names.each do |param_name|
|
117
121
|
if params[param_name].nil?
|
118
122
|
raise ValidationError, "#{param_name} is missing."
|
119
123
|
end
|
120
124
|
end
|
121
125
|
end
|
126
|
+
|
127
|
+
def validate_options_of_delivery_methods!
|
128
|
+
delivery_methods.each do |delivery_method|
|
129
|
+
method = delivery_method_for(delivery_method[:name], delivery_method[:options])
|
130
|
+
method.validate!(delivery_method[:options])
|
131
|
+
end
|
132
|
+
end
|
122
133
|
end
|
123
134
|
end
|
@@ -17,18 +17,18 @@ module Noticed
|
|
17
17
|
|
18
18
|
def channel
|
19
19
|
@channel ||= begin
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
20
|
+
value = options[:channel]
|
21
|
+
case value
|
22
|
+
when String
|
23
|
+
value.constantize
|
24
|
+
when Symbol
|
25
|
+
notification.send(value)
|
26
|
+
when Class
|
27
|
+
value
|
28
|
+
else
|
29
|
+
Noticed::NotificationChannel
|
30
|
+
end
|
31
|
+
end
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
@@ -4,11 +4,35 @@ module Noticed
|
|
4
4
|
extend ActiveModel::Callbacks
|
5
5
|
define_model_callbacks :deliver
|
6
6
|
|
7
|
-
|
7
|
+
class_attribute :option_names, instance_writer: false, default: []
|
8
|
+
|
9
|
+
attr_reader :notification, :options, :params, :recipient, :record
|
10
|
+
|
11
|
+
class << self
|
12
|
+
# Copy option names from parent
|
13
|
+
def inherited(base) #:nodoc:
|
14
|
+
base.option_names = option_names.dup
|
15
|
+
super
|
16
|
+
end
|
17
|
+
|
18
|
+
def options(*names)
|
19
|
+
option_names.concat Array.wrap(names)
|
20
|
+
end
|
21
|
+
alias_method :option, :options
|
22
|
+
|
23
|
+
def validate!(delivery_method_options)
|
24
|
+
option_names.each do |option_name|
|
25
|
+
unless delivery_method_options.key? option_name
|
26
|
+
raise ValidationError, "option `#{option_name}` must be set for #{name}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
8
31
|
|
9
32
|
def perform(args)
|
10
33
|
@notification = args[:notification_class].constantize.new(args[:params])
|
11
34
|
@options = args[:options]
|
35
|
+
@params = args[:params]
|
12
36
|
@recipient = args[:recipient]
|
13
37
|
@record = args[:record]
|
14
38
|
|
@@ -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
@@ -32,16 +32,20 @@ module Noticed
|
|
32
32
|
# Rehydrate the database notification into the Notification object for rendering
|
33
33
|
def to_notification
|
34
34
|
@_notification ||= begin
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
35
|
+
instance = type.constantize.with(params)
|
36
|
+
instance.record = self
|
37
|
+
instance
|
38
|
+
end
|
39
39
|
end
|
40
40
|
|
41
41
|
def mark_as_read!
|
42
42
|
update(read_at: Time.current)
|
43
43
|
end
|
44
44
|
|
45
|
+
def mark_as_unread!
|
46
|
+
update(read_at: nil)
|
47
|
+
end
|
48
|
+
|
45
49
|
def unread?
|
46
50
|
!read?
|
47
51
|
end
|
File without changes
|
data/lib/noticed/translation.rb
CHANGED
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.17
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Oliver
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-10-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -91,7 +91,6 @@ files:
|
|
91
91
|
- MIT-LICENSE
|
92
92
|
- README.md
|
93
93
|
- Rakefile
|
94
|
-
- app/channels/noticed/notification_channel.rb
|
95
94
|
- lib/generators/noticed/delivery_method_generator.rb
|
96
95
|
- lib/generators/noticed/model_generator.rb
|
97
96
|
- lib/generators/noticed/notification_generator.rb
|
@@ -105,12 +104,14 @@ files:
|
|
105
104
|
- lib/noticed/delivery_methods/base.rb
|
106
105
|
- lib/noticed/delivery_methods/database.rb
|
107
106
|
- lib/noticed/delivery_methods/email.rb
|
107
|
+
- lib/noticed/delivery_methods/microsoft_teams.rb
|
108
108
|
- lib/noticed/delivery_methods/slack.rb
|
109
109
|
- lib/noticed/delivery_methods/test.rb
|
110
110
|
- lib/noticed/delivery_methods/twilio.rb
|
111
111
|
- lib/noticed/delivery_methods/vonage.rb
|
112
112
|
- lib/noticed/engine.rb
|
113
113
|
- lib/noticed/model.rb
|
114
|
+
- lib/noticed/notification_channel.rb
|
114
115
|
- lib/noticed/text_coder.rb
|
115
116
|
- lib/noticed/translation.rb
|
116
117
|
- lib/noticed/version.rb
|
@@ -119,7 +120,7 @@ homepage: https://github.com/excid3/noticed
|
|
119
120
|
licenses:
|
120
121
|
- MIT
|
121
122
|
metadata: {}
|
122
|
-
post_install_message:
|
123
|
+
post_install_message:
|
123
124
|
rdoc_options: []
|
124
125
|
require_paths:
|
125
126
|
- lib
|
@@ -134,8 +135,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
134
135
|
- !ruby/object:Gem::Version
|
135
136
|
version: '0'
|
136
137
|
requirements: []
|
137
|
-
rubygems_version: 3.1.
|
138
|
-
signing_key:
|
138
|
+
rubygems_version: 3.1.4
|
139
|
+
signing_key:
|
139
140
|
specification_version: 4
|
140
141
|
summary: Notifications for Ruby on Rails applications
|
141
142
|
test_files: []
|