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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6fca882449d4696c1551badc82383f789610f19898dec345a64f33a225ca9f81
4
- data.tar.gz: 8751afe5063970449573719d7bedb957d7c88e52f1efef96357d8754d48cec21
3
+ metadata.gz: 5dc2e5f50621a5b5da4f901c472621c2fce03d5f0f4db7c5a00a42de527e3128
4
+ data.tar.gz: 1e07d7ea3599b7999d9a252a062ab38641cf6553c8392bf54d70ec9fbc164050
5
5
  SHA512:
6
- metadata.gz: 8ab4f29e4611ee0e5c3f548562e0265dc991ca45cb4789fbf7eb780430b21eddaef3407fbc7946f21bbff411149dd8e796197d9d0b334d85d8085aaea7beb54a
7
- data.tar.gz: 7c6ce9b53092a182e405fc26274daae30e8ec6e2149c5f5794d3fa5c3728210f013f632c844dd00f9ad5f1d64cba12b09de6c311b9d367b580d91f899affb4c4
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 and earlier, you must pass strings of the class names in the `deliver_by` options.
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 "mysql"
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
@@ -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"
@@ -32,7 +32,7 @@ module Noticed
32
32
  def params(*names)
33
33
  param_names.concat Array.wrap(names)
34
34
  end
35
- alias param params
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
- klass = get_class(delivery_method[:name], delivery_method[:options])
101
- enqueue ? klass.perform_later(args) : klass.perform_now(args)
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
- # Retrieves the correct class for a delivery method
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.classify}".constantize
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
- 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
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
- attr_reader :notification, :options, :recipient, :record
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
 
@@ -1,6 +1,8 @@
1
1
  module Noticed
2
2
  module DeliveryMethods
3
3
  class Email < Base
4
+ option :mailer
5
+
4
6
  def deliver
5
7
  mailer.with(format).send(method.to_sym).deliver_later
6
8
  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
@@ -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
- instance = type.constantize.with(params)
36
- instance.record = self
37
- instance
38
- end
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
@@ -10,7 +10,7 @@ module Noticed
10
10
  def translate(key, **options)
11
11
  I18n.translate(scope_translation_key(key), **options)
12
12
  end
13
- alias t translate
13
+ alias_method :t, :translate
14
14
 
15
15
  def scope_translation_key(key)
16
16
  if key.to_s.start_with?(".")
@@ -1,3 +1,3 @@
1
1
  module Noticed
2
- VERSION = "1.2.12"
2
+ VERSION = "1.2.17"
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.12
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-08-24 00:00:00.000000000 Z
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.2
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: []