noticed 2.0.0 → 3.0.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 +624 -185
- data/app/jobs/noticed/event_job.rb +5 -7
- data/app/models/concerns/noticed/deliverable.rb +60 -18
- data/app/models/concerns/noticed/notification_methods.rb +1 -1
- data/app/models/concerns/noticed/readable.rb +32 -8
- data/app/models/noticed/deliverable/deliver_by.rb +28 -7
- data/app/models/noticed/ephemeral.rb +63 -0
- data/app/models/noticed/event.rb +13 -0
- data/app/models/noticed/notification.rb +3 -3
- data/db/migrate/20231215190233_create_noticed_tables.rb +16 -5
- data/db/migrate/20240129184740_add_notifications_count_to_noticed_event.rb +5 -0
- data/lib/generators/noticed/delivery_method_generator.rb +9 -1
- data/lib/generators/noticed/notifier_generator.rb +14 -1
- data/lib/generators/noticed/templates/application_bulk_delivery_method.rb.tt +2 -0
- data/lib/generators/noticed/templates/application_delivery_method.rb.tt +2 -0
- data/lib/generators/noticed/templates/application_notifier.rb.tt +2 -0
- data/lib/generators/noticed/templates/bulk_delivery_method.rb.tt +14 -0
- data/lib/generators/noticed/templates/delivery_method.rb.tt +10 -8
- data/lib/generators/noticed/templates/notifier.rb.tt +8 -2
- data/lib/noticed/api_client.rb +3 -1
- data/lib/noticed/bulk_delivery_method.rb +19 -7
- data/lib/noticed/bulk_delivery_methods/bluesky.rb +51 -0
- data/lib/noticed/bulk_delivery_methods/discord.rb +2 -0
- data/lib/noticed/bulk_delivery_methods/slack.rb +25 -1
- data/lib/noticed/bulk_delivery_methods/test.rb +13 -0
- data/lib/noticed/bulk_delivery_methods/webhook.rb +4 -1
- data/lib/noticed/coder.rb +5 -1
- data/lib/noticed/delivery_method.rb +21 -8
- data/lib/noticed/delivery_methods/action_cable.rb +11 -5
- data/lib/noticed/delivery_methods/action_push_native.rb +24 -0
- data/lib/noticed/delivery_methods/discord.rb +2 -0
- data/lib/noticed/delivery_methods/email.rb +13 -5
- data/lib/noticed/delivery_methods/fcm.rb +19 -2
- data/lib/noticed/delivery_methods/ios.rb +15 -4
- data/lib/noticed/delivery_methods/microsoft_teams.rb +2 -0
- data/lib/noticed/delivery_methods/slack.rb +25 -1
- data/lib/noticed/delivery_methods/test.rb +2 -0
- data/lib/noticed/delivery_methods/twilio_messaging.rb +9 -1
- data/lib/noticed/delivery_methods/vonage_sms.rb +2 -0
- data/lib/noticed/delivery_methods/webhook.rb +4 -1
- data/lib/noticed/engine.rb +10 -0
- data/lib/noticed/has_notifications.rb +49 -0
- data/lib/noticed/notification_channel.rb +19 -0
- data/lib/noticed/version.rb +1 -1
- data/lib/noticed.rb +15 -27
- metadata +14 -6
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module Noticed
|
|
2
|
+
module BulkDeliveryMethods
|
|
3
|
+
class Bluesky < BulkDeliveryMethod
|
|
4
|
+
required_options :identifier, :password, :json
|
|
5
|
+
|
|
6
|
+
# bulk_deliver_by :bluesky do |config|
|
|
7
|
+
# config.identifier = ENV["BLUESKY_ID"]
|
|
8
|
+
# config.password = ENV["BLUESKY_PASSWORD"]
|
|
9
|
+
# config.json = {text: "...", createdAt: "..."}
|
|
10
|
+
# end
|
|
11
|
+
|
|
12
|
+
def deliver
|
|
13
|
+
Rails.logger.debug(evaluate_option(:json))
|
|
14
|
+
post_request(
|
|
15
|
+
"https://#{host}/xrpc/com.atproto.repo.createRecord",
|
|
16
|
+
headers: {"Authorization" => "Bearer #{token}"},
|
|
17
|
+
json: {
|
|
18
|
+
repo: identifier,
|
|
19
|
+
collection: "app.bsky.feed.post",
|
|
20
|
+
record: evaluate_option(:json)
|
|
21
|
+
}
|
|
22
|
+
)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def token
|
|
26
|
+
start_session.dig("accessJwt")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def start_session
|
|
30
|
+
response = post_request(
|
|
31
|
+
"https://#{host}/xrpc/com.atproto.server.createSession",
|
|
32
|
+
json: {
|
|
33
|
+
identifier: identifier,
|
|
34
|
+
password: evaluate_option(:password)
|
|
35
|
+
}
|
|
36
|
+
)
|
|
37
|
+
JSON.parse(response.body)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def host
|
|
41
|
+
@host ||= evaluate_option(:host) || "bsky.social"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def identifier
|
|
45
|
+
@identifier ||= evaluate_option(:identifier)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
ActiveSupport.run_load_hooks :noticed_bulk_delivery_methods_bluesky, Noticed::BulkDeliveryMethods::Bluesky
|
|
@@ -6,12 +6,36 @@ module Noticed
|
|
|
6
6
|
required_options :json
|
|
7
7
|
|
|
8
8
|
def deliver
|
|
9
|
-
|
|
9
|
+
headers = evaluate_option(:headers)
|
|
10
|
+
json = evaluate_option(:json)
|
|
11
|
+
response = post_request url, headers: headers, json: json
|
|
12
|
+
|
|
13
|
+
if raise_if_not_ok? && !success?(response)
|
|
14
|
+
raise ResponseUnsuccessful.new(response, url, {headers: headers, json: json})
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
response
|
|
10
18
|
end
|
|
11
19
|
|
|
12
20
|
def url
|
|
13
21
|
evaluate_option(:url) || DEFAULT_URL
|
|
14
22
|
end
|
|
23
|
+
|
|
24
|
+
def raise_if_not_ok?
|
|
25
|
+
value = evaluate_option(:raise_if_not_ok)
|
|
26
|
+
value.nil? || value
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def success?(response)
|
|
30
|
+
if response.content_type == "application/json"
|
|
31
|
+
JSON.parse(response.body).dig("ok")
|
|
32
|
+
else
|
|
33
|
+
# https://api.slack.com/changelog/2016-05-17-changes-to-errors-for-incoming-webhooks
|
|
34
|
+
response.is_a?(Net::HTTPSuccess)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
15
37
|
end
|
|
16
38
|
end
|
|
17
39
|
end
|
|
40
|
+
|
|
41
|
+
ActiveSupport.run_load_hooks :noticed_bulk_delivery_methods_slack, Noticed::BulkDeliveryMethods::Slack
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module Noticed
|
|
2
|
+
module BulkDeliveryMethods
|
|
3
|
+
class Test < BulkDeliveryMethod
|
|
4
|
+
class_attribute :delivered, default: []
|
|
5
|
+
|
|
6
|
+
def deliver
|
|
7
|
+
delivered << event
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
ActiveSupport.run_load_hooks :noticed_bulk_delivery_methods_test, Noticed::BulkDeliveryMethods::Test
|
|
@@ -10,9 +10,12 @@ module Noticed
|
|
|
10
10
|
basic_auth: evaluate_option(:basic_auth),
|
|
11
11
|
headers: evaluate_option(:headers),
|
|
12
12
|
json: evaluate_option(:json),
|
|
13
|
-
form: evaluate_option(:form)
|
|
13
|
+
form: evaluate_option(:form),
|
|
14
|
+
body: evaluate_option(:body)
|
|
14
15
|
)
|
|
15
16
|
end
|
|
16
17
|
end
|
|
17
18
|
end
|
|
18
19
|
end
|
|
20
|
+
|
|
21
|
+
ActiveSupport.run_load_hooks :noticed_bulk_delivery_methods_webhook, Noticed::BulkDeliveryMethods::Webhook
|
data/lib/noticed/coder.rb
CHANGED
|
@@ -11,7 +11,11 @@ module Noticed
|
|
|
11
11
|
|
|
12
12
|
def self.dump(data)
|
|
13
13
|
return if data.nil?
|
|
14
|
-
ActiveJob::Arguments.
|
|
14
|
+
if ActiveJob::Arguments.respond_to?(:serialize_argument, true)
|
|
15
|
+
ActiveJob::Arguments.send(:serialize_argument, data)
|
|
16
|
+
else
|
|
17
|
+
ActiveJob::Arguments.serialize(data)
|
|
18
|
+
end
|
|
15
19
|
end
|
|
16
20
|
end
|
|
17
21
|
end
|
|
@@ -1,16 +1,27 @@
|
|
|
1
1
|
module Noticed
|
|
2
|
-
class DeliveryMethod <
|
|
2
|
+
class DeliveryMethod < Noticed.parent_class.constantize
|
|
3
3
|
include ApiClient
|
|
4
4
|
include RequiredOptions
|
|
5
5
|
|
|
6
|
+
extend ActiveModel::Callbacks
|
|
7
|
+
|
|
8
|
+
define_model_callbacks :deliver
|
|
9
|
+
|
|
6
10
|
class_attribute :logger, default: Rails.logger
|
|
7
11
|
|
|
8
12
|
attr_reader :config, :event, :notification
|
|
9
13
|
delegate :recipient, to: :notification
|
|
14
|
+
delegate :record, :params, to: :event
|
|
10
15
|
|
|
11
|
-
def perform(delivery_method_name, notification, overrides: {})
|
|
12
|
-
|
|
13
|
-
|
|
16
|
+
def perform(delivery_method_name, notification, recipient: nil, params: {}, overrides: {})
|
|
17
|
+
# Ephemeral notifications
|
|
18
|
+
if notification.is_a? String
|
|
19
|
+
@notification = notification.constantize.new_with_params(recipient, params)
|
|
20
|
+
@event = @notification.event
|
|
21
|
+
else
|
|
22
|
+
@notification = notification
|
|
23
|
+
@event = notification.event
|
|
24
|
+
end
|
|
14
25
|
|
|
15
26
|
# Look up config from Notifier and merge overrides
|
|
16
27
|
@config = event.delivery_methods.fetch(delivery_method_name).config.merge(overrides)
|
|
@@ -18,7 +29,9 @@ module Noticed
|
|
|
18
29
|
return false if config.has_key?(:if) && !evaluate_option(:if)
|
|
19
30
|
return false if config.has_key?(:unless) && evaluate_option(:unless)
|
|
20
31
|
|
|
21
|
-
deliver
|
|
32
|
+
run_callbacks :deliver do
|
|
33
|
+
deliver
|
|
34
|
+
end
|
|
22
35
|
end
|
|
23
36
|
|
|
24
37
|
def deliver
|
|
@@ -26,7 +39,7 @@ module Noticed
|
|
|
26
39
|
end
|
|
27
40
|
|
|
28
41
|
def fetch_constant(name)
|
|
29
|
-
option =
|
|
42
|
+
option = evaluate_option(name)
|
|
30
43
|
option.is_a?(String) ? option.constantize : option
|
|
31
44
|
end
|
|
32
45
|
|
|
@@ -38,8 +51,8 @@ module Noticed
|
|
|
38
51
|
notification.instance_exec(&option)
|
|
39
52
|
|
|
40
53
|
# Call method if symbol and matching method on Notifier
|
|
41
|
-
elsif option.is_a?(Symbol) && event.respond_to?(option)
|
|
42
|
-
event.send(option,
|
|
54
|
+
elsif option.is_a?(Symbol) && event.respond_to?(option, true)
|
|
55
|
+
event.send(option, notification)
|
|
43
56
|
|
|
44
57
|
# Return the value
|
|
45
58
|
else
|
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
module Noticed
|
|
2
2
|
module DeliveryMethods
|
|
3
3
|
class ActionCable < DeliveryMethod
|
|
4
|
-
required_options :
|
|
4
|
+
required_options :message
|
|
5
5
|
|
|
6
6
|
def deliver
|
|
7
|
-
channel
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
channel.broadcast_to stream, evaluate_option(:message)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def channel
|
|
11
|
+
fetch_constant(:channel) || Noticed::NotificationChannel
|
|
12
|
+
end
|
|
10
13
|
|
|
11
|
-
|
|
14
|
+
def stream
|
|
15
|
+
evaluate_option(:stream) || recipient
|
|
12
16
|
end
|
|
13
17
|
end
|
|
14
18
|
end
|
|
15
19
|
end
|
|
20
|
+
|
|
21
|
+
ActiveSupport.run_load_hooks :noticed_delivery_methods_action_cable, Noticed::DeliveryMethods::ActionCable
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Noticed
|
|
2
|
+
module DeliveryMethods
|
|
3
|
+
class ActionPushNative < DeliveryMethod
|
|
4
|
+
required_options :devices, :format
|
|
5
|
+
|
|
6
|
+
def deliver
|
|
7
|
+
notification = (!!evaluate_option(:silent)) ? notification_class.silent : notification_class
|
|
8
|
+
|
|
9
|
+
notification
|
|
10
|
+
.with_apple(evaluate_option(:with_apple))
|
|
11
|
+
.with_google(evaluate_option(:with_google))
|
|
12
|
+
.with_data(evaluate_option(:with_data))
|
|
13
|
+
.new(**evaluate_option(:format))
|
|
14
|
+
.deliver_later_to(evaluate_option(:devices))
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def notification_class
|
|
18
|
+
fetch_constant(:class) || ApplicationPushNotification
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
ActiveSupport.run_load_hooks :noticed_delivery_methods_action_push_native, Noticed::DeliveryMethods::ActionPushNative
|
|
@@ -6,14 +6,22 @@ module Noticed
|
|
|
6
6
|
def deliver
|
|
7
7
|
mailer = fetch_constant(:mailer)
|
|
8
8
|
email = evaluate_option(:method)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
mail = mailer.with(params)
|
|
13
|
-
mail = args.present? ? mail.send(email, *args) : mail.send(email)
|
|
9
|
+
args = evaluate_option(:args) || []
|
|
10
|
+
kwargs = evaluate_option(:kwargs) || {}
|
|
11
|
+
mail = mailer.with(params).public_send(email, *args, **kwargs)
|
|
14
12
|
|
|
15
13
|
(!!evaluate_option(:enqueue)) ? mail.deliver_later : mail.deliver_now
|
|
16
14
|
end
|
|
15
|
+
|
|
16
|
+
def params
|
|
17
|
+
(evaluate_option(:params) || notification&.params || {}).merge(
|
|
18
|
+
notification: notification,
|
|
19
|
+
record: notification&.record,
|
|
20
|
+
recipient: notification&.recipient
|
|
21
|
+
)
|
|
22
|
+
end
|
|
17
23
|
end
|
|
18
24
|
end
|
|
19
25
|
end
|
|
26
|
+
|
|
27
|
+
ActiveSupport.run_load_hooks :noticed_delivery_methods_email, Noticed::DeliveryMethods::Email
|
|
@@ -14,15 +14,30 @@ module Noticed
|
|
|
14
14
|
def send_notification(device_token)
|
|
15
15
|
post_request("https://fcm.googleapis.com/v1/projects/#{credentials[:project_id]}/messages:send",
|
|
16
16
|
headers: {authorization: "Bearer #{access_token}"},
|
|
17
|
-
json:
|
|
17
|
+
json: format_notification(device_token))
|
|
18
18
|
rescue Noticed::ResponseUnsuccessful => exception
|
|
19
|
-
if exception.response
|
|
19
|
+
if bad_token?(exception.response) && config[:invalid_token]
|
|
20
20
|
notification.instance_exec(device_token, &config[:invalid_token])
|
|
21
|
+
elsif config[:error_handler]
|
|
22
|
+
notification.instance_exec(exception.response, &config[:error_handler])
|
|
21
23
|
else
|
|
22
24
|
raise
|
|
23
25
|
end
|
|
24
26
|
end
|
|
25
27
|
|
|
28
|
+
def format_notification(device_token)
|
|
29
|
+
method = config[:json]
|
|
30
|
+
if method.is_a?(Symbol) && event.respond_to?(method, true)
|
|
31
|
+
event.send(method, device_token)
|
|
32
|
+
else
|
|
33
|
+
notification.instance_exec(device_token, &method)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def bad_token?(response)
|
|
38
|
+
response.code == "404" || response.code == "400"
|
|
39
|
+
end
|
|
40
|
+
|
|
26
41
|
def credentials
|
|
27
42
|
@credentials ||= begin
|
|
28
43
|
value = evaluate_option(:credentials)
|
|
@@ -53,3 +68,5 @@ module Noticed
|
|
|
53
68
|
end
|
|
54
69
|
end
|
|
55
70
|
end
|
|
71
|
+
|
|
72
|
+
ActiveSupport.run_load_hooks :noticed_delivery_methods_fcm, Noticed::DeliveryMethods::Fcm
|
|
@@ -16,6 +16,7 @@ module Noticed
|
|
|
16
16
|
connection_pool.with do |connection|
|
|
17
17
|
response = connection.push(apn)
|
|
18
18
|
raise "Timeout sending iOS push notification" unless response
|
|
19
|
+
connection.close
|
|
19
20
|
|
|
20
21
|
if bad_token?(response) && config[:invalid_token]
|
|
21
22
|
# Allow notification to cleanup invalid iOS device tokens
|
|
@@ -32,7 +33,12 @@ module Noticed
|
|
|
32
33
|
def format_notification(apn)
|
|
33
34
|
apn.topic = evaluate_option(:bundle_identifier)
|
|
34
35
|
|
|
35
|
-
|
|
36
|
+
method = config[:format]
|
|
37
|
+
# Call method on Notifier if defined
|
|
38
|
+
if method&.is_a?(Symbol) && event.respond_to?(method, true)
|
|
39
|
+
event.send(method, notification, apn)
|
|
40
|
+
# If Proc, evaluate it on the Notification
|
|
41
|
+
elsif method&.respond_to?(:call)
|
|
36
42
|
notification.instance_exec(apn, &method)
|
|
37
43
|
elsif notification.params.try(:has_key?, :message)
|
|
38
44
|
apn.alert = notification.params[:message]
|
|
@@ -57,6 +63,9 @@ module Noticed
|
|
|
57
63
|
handler = proc do |connection|
|
|
58
64
|
connection.on(:error) do |exception|
|
|
59
65
|
Rails.logger.info "Apnotic exception raised: #{exception}"
|
|
66
|
+
if config[:error_handler].respond_to?(:call)
|
|
67
|
+
notification.instance_exec(exception, &config[:error_handler])
|
|
68
|
+
end
|
|
60
69
|
end
|
|
61
70
|
end
|
|
62
71
|
|
|
@@ -70,9 +79,9 @@ module Noticed
|
|
|
70
79
|
def connection_pool_options
|
|
71
80
|
{
|
|
72
81
|
auth_method: :token,
|
|
73
|
-
cert_path: StringIO.new(
|
|
74
|
-
key_id:
|
|
75
|
-
team_id:
|
|
82
|
+
cert_path: StringIO.new(evaluate_option(:apns_key)),
|
|
83
|
+
key_id: evaluate_option(:key_id),
|
|
84
|
+
team_id: evaluate_option(:team_id)
|
|
76
85
|
}
|
|
77
86
|
end
|
|
78
87
|
|
|
@@ -82,3 +91,5 @@ module Noticed
|
|
|
82
91
|
end
|
|
83
92
|
end
|
|
84
93
|
end
|
|
94
|
+
|
|
95
|
+
ActiveSupport.run_load_hooks :noticed_delivery_methods_ios, Noticed::DeliveryMethods::Ios
|
|
@@ -6,12 +6,36 @@ module Noticed
|
|
|
6
6
|
required_options :json
|
|
7
7
|
|
|
8
8
|
def deliver
|
|
9
|
-
|
|
9
|
+
headers = evaluate_option(:headers)
|
|
10
|
+
json = evaluate_option(:json)
|
|
11
|
+
response = post_request url, headers: headers, json: json
|
|
12
|
+
|
|
13
|
+
if raise_if_not_ok? && !success?(response)
|
|
14
|
+
raise ResponseUnsuccessful.new(response, url, {headers: headers, json: json})
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
response
|
|
10
18
|
end
|
|
11
19
|
|
|
12
20
|
def url
|
|
13
21
|
evaluate_option(:url) || DEFAULT_URL
|
|
14
22
|
end
|
|
23
|
+
|
|
24
|
+
def raise_if_not_ok?
|
|
25
|
+
value = evaluate_option(:raise_if_not_ok)
|
|
26
|
+
value.nil? || value
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def success?(response)
|
|
30
|
+
if response.content_type == "application/json"
|
|
31
|
+
JSON.parse(response.body).dig("ok")
|
|
32
|
+
else
|
|
33
|
+
# https://api.slack.com/changelog/2016-05-17-changes-to-errors-for-incoming-webhooks
|
|
34
|
+
response.is_a?(Net::HTTPSuccess)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
15
37
|
end
|
|
16
38
|
end
|
|
17
39
|
end
|
|
40
|
+
|
|
41
|
+
ActiveSupport.run_load_hooks :noticed_delivery_methods_slack, Noticed::DeliveryMethods::Slack
|
|
@@ -2,7 +2,13 @@ module Noticed
|
|
|
2
2
|
module DeliveryMethods
|
|
3
3
|
class TwilioMessaging < DeliveryMethod
|
|
4
4
|
def deliver
|
|
5
|
-
post_request url, basic_auth: {user: account_sid, pass: auth_token}, form: json
|
|
5
|
+
post_request url, basic_auth: {user: account_sid, pass: auth_token}, form: json.stringify_keys
|
|
6
|
+
rescue Noticed::ResponseUnsuccessful => exception
|
|
7
|
+
if exception.response.code.start_with?("4") && config[:error_handler]
|
|
8
|
+
notification.instance_exec(exception.response, &config[:error_handler])
|
|
9
|
+
else
|
|
10
|
+
raise
|
|
11
|
+
end
|
|
6
12
|
end
|
|
7
13
|
|
|
8
14
|
def json
|
|
@@ -35,3 +41,5 @@ module Noticed
|
|
|
35
41
|
end
|
|
36
42
|
end
|
|
37
43
|
end
|
|
44
|
+
|
|
45
|
+
ActiveSupport.run_load_hooks :noticed_delivery_methods_twilio_messaging, Noticed::DeliveryMethods::TwilioMessaging
|
|
@@ -9,9 +9,12 @@ module Noticed
|
|
|
9
9
|
basic_auth: evaluate_option(:basic_auth),
|
|
10
10
|
headers: evaluate_option(:headers),
|
|
11
11
|
json: evaluate_option(:json),
|
|
12
|
-
form: evaluate_option(:form)
|
|
12
|
+
form: evaluate_option(:form),
|
|
13
|
+
body: evaluate_option(:body)
|
|
13
14
|
)
|
|
14
15
|
end
|
|
15
16
|
end
|
|
16
17
|
end
|
|
17
18
|
end
|
|
19
|
+
|
|
20
|
+
ActiveSupport.run_load_hooks :noticed_delivery_methods_webhook, Noticed::DeliveryMethods::Webhook
|
data/lib/noticed/engine.rb
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
module Noticed
|
|
2
2
|
class Engine < ::Rails::Engine
|
|
3
3
|
isolate_namespace Noticed
|
|
4
|
+
|
|
5
|
+
initializer "noticed.deprecator" do |app|
|
|
6
|
+
app.deprecators[:noticed] = Noticed.deprecator if app.respond_to?(:deprecators)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
initializer "noticed.has_notifications" do
|
|
10
|
+
ActiveSupport.on_load(:active_record) do
|
|
11
|
+
include Noticed::HasNotifications
|
|
12
|
+
end
|
|
13
|
+
end
|
|
4
14
|
end
|
|
5
15
|
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
module Noticed
|
|
2
|
+
module HasNotifications
|
|
3
|
+
# Defines a method for the association and a before_destroy callback to remove notifications
|
|
4
|
+
# where this record is a param
|
|
5
|
+
#
|
|
6
|
+
# class User < ApplicationRecord
|
|
7
|
+
# has_noticed_notifications
|
|
8
|
+
# has_noticed_notifications param_name: :owner, destroy: false, model: "Notification"
|
|
9
|
+
# end
|
|
10
|
+
#
|
|
11
|
+
# @user.notifications_as_user
|
|
12
|
+
# @user.notifications_as_owner
|
|
13
|
+
|
|
14
|
+
extend ActiveSupport::Concern
|
|
15
|
+
|
|
16
|
+
class_methods do
|
|
17
|
+
def has_noticed_notifications(param_name: model_name.singular, **options)
|
|
18
|
+
define_method :"notifications_as_#{param_name}" do
|
|
19
|
+
model = options.fetch(:model_name, "Noticed::Event").constantize
|
|
20
|
+
case current_adapter
|
|
21
|
+
when "postgresql", "postgis"
|
|
22
|
+
model.where("params @> ?", Noticed::Coder.dump(param_name.to_sym => self).to_json)
|
|
23
|
+
when "mysql2", "trilogy"
|
|
24
|
+
model.where("JSON_CONTAINS(params, ?)", Noticed::Coder.dump(param_name.to_sym => self).to_json)
|
|
25
|
+
when "sqlite3"
|
|
26
|
+
model.where("json_extract(params, ?) = ?", "$.#{param_name}", Noticed::Coder.dump(self).to_json)
|
|
27
|
+
else
|
|
28
|
+
# This will perform an exact match which isn't ideal
|
|
29
|
+
model.where(params: {param_name.to_sym => self})
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
if options.fetch(:destroy, true)
|
|
34
|
+
before_destroy do
|
|
35
|
+
send(:"notifications_as_#{param_name}").destroy_all
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def current_adapter
|
|
42
|
+
if ActiveRecord::Base.respond_to?(:connection_db_config)
|
|
43
|
+
ActiveRecord::Base.connection_db_config.adapter
|
|
44
|
+
else
|
|
45
|
+
ActiveRecord::Base.connection_config[:adapter]
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Noticed
|
|
2
|
+
class NotificationChannel < ApplicationCable::Channel
|
|
3
|
+
def subscribed
|
|
4
|
+
stream_for current_user
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def unsubscribed
|
|
8
|
+
stop_all_streams
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def mark_as_seen(data)
|
|
12
|
+
current_user.notifications.where(id: data["ids"]).mark_as_seen
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def mark_as_read(data)
|
|
16
|
+
current_user.notifications.where(id: data["ids"]).mark_as_read
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
data/lib/noticed/version.rb
CHANGED
data/lib/noticed.rb
CHANGED
|
@@ -1,46 +1,34 @@
|
|
|
1
1
|
require "noticed/version"
|
|
2
2
|
require "noticed/engine"
|
|
3
3
|
|
|
4
|
+
require "zeitwerk"
|
|
5
|
+
|
|
6
|
+
loader = Zeitwerk::Loader.for_gem(warn_on_extra_files: false)
|
|
7
|
+
loader.ignore("#{__dir__}/generators")
|
|
8
|
+
loader.do_not_eager_load("#{__dir__}/noticed/bulk_delivery_methods")
|
|
9
|
+
loader.do_not_eager_load("#{__dir__}/noticed/delivery_methods")
|
|
10
|
+
loader.do_not_eager_load("#{__dir__}/noticed/notification_channel.rb")
|
|
11
|
+
loader.setup
|
|
12
|
+
|
|
4
13
|
module Noticed
|
|
5
14
|
include ActiveSupport::Deprecation::DeprecatedConstantAccessor
|
|
6
15
|
|
|
7
16
|
def self.deprecator # :nodoc:
|
|
8
|
-
@deprecator ||= ActiveSupport::Deprecation.new
|
|
17
|
+
@deprecator ||= ActiveSupport::Deprecation.new("3.0", "Noticed")
|
|
9
18
|
end
|
|
10
19
|
|
|
11
20
|
deprecate_constant :Base, "Noticed::Event", deprecator: deprecator
|
|
12
21
|
|
|
13
|
-
autoload :ApiClient, "noticed/api_client"
|
|
14
|
-
autoload :BulkDeliveryMethod, "noticed/bulk_delivery_method"
|
|
15
|
-
autoload :Coder, "noticed/coder"
|
|
16
|
-
autoload :DeliveryMethod, "noticed/delivery_method"
|
|
17
|
-
autoload :RequiredOptions, "noticed/required_options"
|
|
18
|
-
autoload :Translation, "noticed/translation"
|
|
19
|
-
|
|
20
|
-
module BulkDeliveryMethods
|
|
21
|
-
autoload :Discord, "noticed/bulk_delivery_methods/discord"
|
|
22
|
-
autoload :Slack, "noticed/bulk_delivery_methods/slack"
|
|
23
|
-
autoload :Webhook, "noticed/bulk_delivery_methods/webhook"
|
|
24
|
-
end
|
|
25
|
-
|
|
26
22
|
module DeliveryMethods
|
|
27
23
|
include ActiveSupport::Deprecation::DeprecatedConstantAccessor
|
|
28
|
-
deprecate_constant :Base, "Noticed::DeliveryMethod", deprecator: Noticed.deprecator
|
|
29
24
|
|
|
30
|
-
|
|
31
|
-
autoload :Email, "noticed/delivery_methods/email"
|
|
32
|
-
autoload :Fcm, "noticed/delivery_methods/fcm"
|
|
33
|
-
autoload :Ios, "noticed/delivery_methods/ios"
|
|
34
|
-
autoload :MicrosoftTeams, "noticed/delivery_methods/microsoft_teams"
|
|
35
|
-
autoload :Slack, "noticed/delivery_methods/slack"
|
|
36
|
-
autoload :Test, "noticed/delivery_methods/test"
|
|
37
|
-
autoload :TwilioMessaging, "noticed/delivery_methods/twilio_messaging"
|
|
38
|
-
autoload :VonageSms, "noticed/delivery_methods/vonage_sms"
|
|
39
|
-
autoload :Webhook, "noticed/delivery_methods/webhook"
|
|
25
|
+
deprecate_constant :Base, "Noticed::DeliveryMethod", deprecator: Noticed.deprecator
|
|
40
26
|
end
|
|
41
27
|
|
|
42
|
-
|
|
43
|
-
|
|
28
|
+
mattr_accessor :parent_class
|
|
29
|
+
@@parent_class = "Noticed::ApplicationJob"
|
|
30
|
+
|
|
31
|
+
class ValidationError < StandardError; end
|
|
44
32
|
|
|
45
33
|
class ResponseUnsuccessful < StandardError
|
|
46
34
|
attr_reader :response
|