noticed 1.6.3 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +122 -147
  3. data/app/jobs/noticed/application_job.rb +9 -0
  4. data/app/jobs/noticed/event_job.rb +19 -0
  5. data/app/models/concerns/noticed/deliverable.rb +115 -0
  6. data/app/models/concerns/noticed/notification_methods.rb +17 -0
  7. data/app/models/concerns/noticed/readable.rb +62 -0
  8. data/app/models/noticed/application_record.rb +6 -0
  9. data/app/models/noticed/deliverable/deliver_by.rb +43 -0
  10. data/app/models/noticed/event.rb +15 -0
  11. data/app/models/noticed/notification.rb +16 -0
  12. data/db/migrate/20231215190233_create_noticed_tables.rb +25 -0
  13. data/lib/generators/noticed/delivery_method_generator.rb +1 -1
  14. data/lib/generators/noticed/install_generator.rb +19 -0
  15. data/lib/generators/noticed/{notification_generator.rb → notifier_generator.rb} +2 -2
  16. data/lib/generators/noticed/templates/README +5 -4
  17. data/lib/generators/noticed/templates/notifier.rb.tt +24 -0
  18. data/lib/noticed/api_client.rb +44 -0
  19. data/lib/noticed/bulk_delivery_method.rb +46 -0
  20. data/lib/noticed/bulk_delivery_methods/discord.rb +11 -0
  21. data/lib/noticed/bulk_delivery_methods/slack.rb +17 -0
  22. data/lib/noticed/bulk_delivery_methods/webhook.rb +18 -0
  23. data/lib/noticed/coder.rb +2 -0
  24. data/lib/noticed/delivery_method.rb +50 -0
  25. data/lib/noticed/delivery_methods/action_cable.rb +7 -39
  26. data/lib/noticed/delivery_methods/discord.rb +11 -0
  27. data/lib/noticed/delivery_methods/email.rb +9 -45
  28. data/lib/noticed/delivery_methods/fcm.rb +23 -64
  29. data/lib/noticed/delivery_methods/ios.rb +25 -112
  30. data/lib/noticed/delivery_methods/microsoft_teams.rb +5 -22
  31. data/lib/noticed/delivery_methods/slack.rb +6 -16
  32. data/lib/noticed/delivery_methods/test.rb +2 -12
  33. data/lib/noticed/delivery_methods/twilio_messaging.rb +37 -0
  34. data/lib/noticed/delivery_methods/vonage_sms.rb +20 -0
  35. data/lib/noticed/delivery_methods/webhook.rb +17 -0
  36. data/lib/noticed/engine.rb +1 -9
  37. data/lib/noticed/required_options.rb +21 -0
  38. data/lib/noticed/translation.rb +7 -3
  39. data/lib/noticed/version.rb +1 -1
  40. data/lib/noticed.rb +30 -15
  41. metadata +29 -40
  42. data/lib/generators/noticed/model/base_generator.rb +0 -47
  43. data/lib/generators/noticed/model/mysql_generator.rb +0 -18
  44. data/lib/generators/noticed/model/postgresql_generator.rb +0 -18
  45. data/lib/generators/noticed/model/sqlite3_generator.rb +0 -18
  46. data/lib/generators/noticed/model_generator.rb +0 -63
  47. data/lib/generators/noticed/templates/notification.rb.tt +0 -27
  48. data/lib/noticed/base.rb +0 -160
  49. data/lib/noticed/delivery_methods/base.rb +0 -95
  50. data/lib/noticed/delivery_methods/database.rb +0 -34
  51. data/lib/noticed/delivery_methods/twilio.rb +0 -51
  52. data/lib/noticed/delivery_methods/vonage.rb +0 -40
  53. data/lib/noticed/has_notifications.rb +0 -49
  54. data/lib/noticed/model.rb +0 -85
  55. data/lib/noticed/notification_channel.rb +0 -15
  56. data/lib/noticed/text_coder.rb +0 -16
  57. data/lib/rails_6_polyfills/actioncable/test_adapter.rb +0 -70
  58. data/lib/rails_6_polyfills/actioncable/test_helper.rb +0 -143
  59. data/lib/rails_6_polyfills/activejob/serializers.rb +0 -240
  60. data/lib/rails_6_polyfills/base.rb +0 -18
  61. data/lib/tasks/noticed_tasks.rake +0 -4
@@ -0,0 +1,6 @@
1
+ module Noticed
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ self.table_name_prefix = "noticed_"
5
+ end
6
+ end
@@ -0,0 +1,43 @@
1
+ module Noticed
2
+ module Deliverable
3
+ class DeliverBy
4
+ attr_reader :name, :config, :bulk
5
+
6
+ def initialize(name, config, bulk: false)
7
+ @name, @config, @bulk, = name, config, bulk
8
+ end
9
+
10
+ def constant
11
+ namespace = bulk ? "Noticed::BulkDeliveryMethods" : "Noticed::DeliveryMethods"
12
+ config.fetch(:class, [namespace, name.to_s.camelize].join("::")).constantize
13
+ end
14
+
15
+ def validate!
16
+ constant.required_option_names.each do |option|
17
+ raise ValidationError, "option `#{option}` must be set for `deliver_by :#{name}`" unless config[option].present?
18
+ end
19
+ end
20
+
21
+ def perform_later(event_or_notification, options = {})
22
+ options[:wait] = evaluate_option(:wait, event_or_notification) if config.has_key?(:wait)
23
+ options[:wait_until] = evaluate_option(:wait_until, event_or_notification) if config.has_key?(:wait_until)
24
+ options[:queue] = evaluate_option(:queue, event_or_notification) if config.has_key?(:queue)
25
+ options[:priority] = evaluate_option(:priority, event_or_notification) if config.has_key?(:priority)
26
+
27
+ constant.set(options).perform_later(name, event_or_notification)
28
+ end
29
+
30
+ def evaluate_option(name, context)
31
+ option = config[name]
32
+
33
+ if option&.respond_to?(:call)
34
+ context.instance_exec(&option)
35
+ elsif option.is_a?(Symbol) && context.respond_to?(option)
36
+ context.send(option)
37
+ else
38
+ option
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,15 @@
1
+ module Noticed
2
+ class Event < ApplicationRecord
3
+ include Deliverable
4
+ include NotificationMethods
5
+ include Translation
6
+ include Rails.application.routes.url_helpers
7
+
8
+ belongs_to :record, polymorphic: true, optional: true
9
+ has_many :notifications, dependent: :delete_all
10
+
11
+ accepts_nested_attributes_for :notifications
12
+
13
+ scope :newest_first, -> { order(created_at: :desc) }
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ module Noticed
2
+ class Notification < ApplicationRecord
3
+ include Rails.application.routes.url_helpers
4
+ include Readable
5
+ include Translation
6
+
7
+ belongs_to :event
8
+ belongs_to :recipient, polymorphic: true
9
+
10
+ scope :newest_first, -> { order(created_at: :desc) }
11
+
12
+ delegate :params, :record, to: :event
13
+
14
+ attribute :params, default: {}
15
+ end
16
+ end
@@ -0,0 +1,25 @@
1
+ class CreateNoticedTables < ActiveRecord::Migration[6.1]
2
+ def change
3
+ create_table :noticed_events do |t|
4
+ t.string :type
5
+ t.belongs_to :record, polymorphic: true
6
+ if t.respond_to?(:jsonb)
7
+ t.jsonb :params
8
+ else
9
+ t.json :params
10
+ end
11
+
12
+ t.timestamps
13
+ end
14
+
15
+ create_table :noticed_notifications do |t|
16
+ t.string :type
17
+ t.belongs_to :event, null: false
18
+ t.belongs_to :recipient, polymorphic: true, null: false
19
+ t.datetime :read_at
20
+ t.datetime :seen_at
21
+
22
+ t.timestamps
23
+ end
24
+ end
25
+ end
@@ -12,7 +12,7 @@ module Noticed
12
12
  desc "Generates a class for a custom delivery method with the given NAME."
13
13
 
14
14
  def generate_notification
15
- template "delivery_method.rb", "app/notifications/delivery_methods/#{singular_name}.rb"
15
+ template "delivery_method.rb", "app/notifiers/delivery_methods/#{singular_name}.rb"
16
16
  end
17
17
  end
18
18
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Noticed
4
+ module Generators
5
+ class ModelGenerator < Rails::Generators::Base
6
+ include Rails::Generators::ResourceHelpers
7
+
8
+ source_root File.expand_path("../templates", __FILE__)
9
+
10
+ def create_migrations
11
+ rails_command "railties:install:migrations FROM=noticed", inline: true
12
+ end
13
+
14
+ def done
15
+ readme "README" if behavior == :invoke
16
+ end
17
+ end
18
+ end
19
+ end
@@ -4,7 +4,7 @@ require "rails/generators/named_base"
4
4
 
5
5
  module Noticed
6
6
  module Generators
7
- class NotificationGenerator < Rails::Generators::NamedBase
7
+ class NotifierGenerator < Rails::Generators::NamedBase
8
8
  include Rails::Generators::ResourceHelpers
9
9
 
10
10
  source_root File.expand_path("../templates", __FILE__)
@@ -12,7 +12,7 @@ module Noticed
12
12
  desc "Generates a notification with the given NAME."
13
13
 
14
14
  def generate_notification
15
- template "notification.rb", "app/notifications/#{file_path}.rb"
15
+ template "notifier.rb", "app/notifiers/#{file_path}.rb"
16
16
  end
17
17
  end
18
18
  end
@@ -1,7 +1,8 @@
1
1
 
2
- 🚚 Your notifications database model has been generated!
2
+ 🚚 You're ready to start sending notifications!
3
3
 
4
4
  Next steps:
5
- 1. Run "rails db:migrate"
6
- 2. Add "has_many :notifications, as: :recipient, dependent: :destroy" to your User model(s).
7
- 3. Generate notifications with "rails g noticed:notification"
5
+ 1. Run `rails db:migrate`
6
+ 2. Add `has_many :notifications, as: :recipient, dependent: :destroy, class_name: "Noticed::Notification"` to your User model(s).
7
+ 2. Add `has_many :notifications, as: :record, dependent: :destroy, class_name: "Noticed::Event"` to your model(s) that notifications reference.
8
+ 3. Generate notifiers with "rails g noticed:notifier"
@@ -0,0 +1,24 @@
1
+ # To deliver this notification:
2
+ #
3
+ # <%= class_name %>.with(record: @post, message: "New post").deliver(User.all)
4
+
5
+ class <%= class_name %> < Noticed::Event
6
+ # Add your delivery methods
7
+ #
8
+ # deliver_by :email do |config|
9
+ # config.mailer = "UserMailer"
10
+ # config.method = "new_post"
11
+ # end
12
+ #
13
+ # bulk_deliver_by :slack do |config|
14
+ # config.url = -> { Rails.application.credentials.slack_webhook_url }
15
+ # end
16
+ #
17
+ # deliver_by :custom do |config|
18
+ # config.class = "MyDeliveryMethod"
19
+ # end
20
+
21
+ # Add required params
22
+ #
23
+ # required_param :message
24
+ end
@@ -0,0 +1,44 @@
1
+ require "net/http"
2
+
3
+ module Noticed
4
+ module ApiClient
5
+ extend ActiveSupport::Concern
6
+
7
+ # Helper method for making POST requests from delivery methods
8
+ #
9
+ # Usage:
10
+ # post_request("http://example.com", basic_auth: {user:, pass:}, headers: {}, json: {}, form: {})
11
+ #
12
+ def post_request(url, args = {})
13
+ args.compact!
14
+
15
+ uri = URI(url)
16
+ http = Net::HTTP.new(uri.host, uri.port)
17
+ http.use_ssl = true if uri.instance_of? URI::HTTPS
18
+
19
+ headers = args.delete(:headers) || {}
20
+ headers["Content-Type"] = "application/json" if args.has_key?(:json)
21
+
22
+ request = Net::HTTP::Post.new(uri.request_uri, headers)
23
+
24
+ if (basic_auth = args.delete(:basic_auth))
25
+ request.basic_auth basic_auth.fetch(:user), basic_auth.fetch(:pass)
26
+ end
27
+
28
+ if (json = args.delete(:json))
29
+ request.body = json.to_json
30
+ elsif (form = args.delete(:form))
31
+ request.set_form(form, "multipart/form-data")
32
+ end
33
+
34
+ logger.debug("POST #{url}")
35
+ logger.debug(request.body)
36
+ response = http.request(request)
37
+ logger.debug("Response: #{response.code}: #{response.body.inspect}")
38
+
39
+ raise ResponseUnsuccessful.new(response, url, args) unless response.code.start_with?("20")
40
+
41
+ response
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,46 @@
1
+ module Noticed
2
+ class BulkDeliveryMethod < ApplicationJob
3
+ include ApiClient
4
+ include RequiredOptions
5
+
6
+ class_attribute :logger, default: Rails.logger
7
+
8
+ attr_reader :config, :event
9
+
10
+ def perform(delivery_method_name, event)
11
+ @event = event
12
+ @config = event.bulk_delivery_methods.fetch(delivery_method_name).config
13
+
14
+ return false if config.has_key?(:if) && !evaluate_option(:if)
15
+ return false if config.has_key?(:unless) && evaluate_option(:unless)
16
+
17
+ deliver
18
+ end
19
+
20
+ def deliver
21
+ raise NotImplementedError, "Bulk delivery methods must implement the `deliver` method"
22
+ end
23
+
24
+ def fetch_constant(name)
25
+ option = config[name]
26
+ option.is_a?(String) ? option.constantize : option
27
+ end
28
+
29
+ def evaluate_option(name)
30
+ option = config[name]
31
+
32
+ # Evaluate Proc within the context of the notifier
33
+ if option&.respond_to?(:call)
34
+ event.instance_exec(&option)
35
+
36
+ # Call method if symbol and matching method
37
+ elsif option.is_a?(Symbol) && event.respond_to?(option)
38
+ event.send(option)
39
+
40
+ # Return the value
41
+ else
42
+ option
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,11 @@
1
+ module Noticed
2
+ module BulkDeliveryMethods
3
+ class Discord < BulkDeliveryMethod
4
+ required_options :json, :url
5
+
6
+ def deliver
7
+ post_request evaluate_option(:url), headers: evaluate_option(:headers), json: evaluate_option(:json)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ module Noticed
2
+ module BulkDeliveryMethods
3
+ class Slack < BulkDeliveryMethod
4
+ DEFAULT_URL = "https://slack.com/api/chat.postMessage"
5
+
6
+ required_options :json
7
+
8
+ def deliver
9
+ post_request url, headers: evaluate_option(:headers), json: evaluate_option(:json)
10
+ end
11
+
12
+ def url
13
+ evaluate_option(:url) || DEFAULT_URL
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ module Noticed
2
+ module BulkDeliveryMethods
3
+ class Webhook < BulkDeliveryMethod
4
+ required_options :url
5
+
6
+ def deliver
7
+ Rails.logger.debug(evaluate_option(:json))
8
+ post_request(
9
+ evaluate_option(:url),
10
+ basic_auth: evaluate_option(:basic_auth),
11
+ headers: evaluate_option(:headers),
12
+ json: evaluate_option(:json),
13
+ form: evaluate_option(:form)
14
+ )
15
+ end
16
+ end
17
+ end
18
+ end
data/lib/noticed/coder.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require "active_job/arguments"
2
+
1
3
  module Noticed
2
4
  class Coder
3
5
  def self.load(data)
@@ -0,0 +1,50 @@
1
+ module Noticed
2
+ class DeliveryMethod < ApplicationJob
3
+ include ApiClient
4
+ include RequiredOptions
5
+
6
+ class_attribute :logger, default: Rails.logger
7
+
8
+ attr_reader :config, :event, :notification
9
+ delegate :recipient, to: :notification
10
+
11
+ def perform(delivery_method_name, notification, overrides: {})
12
+ @notification = notification
13
+ @event = notification.event
14
+
15
+ # Look up config from Notifier and merge overrides
16
+ @config = event.delivery_methods.fetch(delivery_method_name).config.merge(overrides)
17
+
18
+ return false if config.has_key?(:if) && !evaluate_option(:if)
19
+ return false if config.has_key?(:unless) && evaluate_option(:unless)
20
+
21
+ deliver
22
+ end
23
+
24
+ def deliver
25
+ raise NotImplementedError, "Delivery methods must implement the `deliver` method"
26
+ end
27
+
28
+ def fetch_constant(name)
29
+ option = config[name]
30
+ option.is_a?(String) ? option.constantize : option
31
+ end
32
+
33
+ def evaluate_option(name)
34
+ option = config[name]
35
+
36
+ # Evaluate Proc within the context of the Notification
37
+ if option&.respond_to?(:call)
38
+ notification.instance_exec(&option)
39
+
40
+ # Call method if symbol and matching method on Notifier
41
+ elsif option.is_a?(Symbol) && event.respond_to?(option)
42
+ event.send(option, self)
43
+
44
+ # Return the value
45
+ else
46
+ option
47
+ end
48
+ end
49
+ end
50
+ end
@@ -1,46 +1,14 @@
1
1
  module Noticed
2
2
  module DeliveryMethods
3
- class ActionCable < Base
4
- def deliver
5
- channel.broadcast_to stream, format
6
- end
3
+ class ActionCable < DeliveryMethod
4
+ required_options :channel, :stream, :message
7
5
 
8
- private
9
-
10
- def format
11
- if (method = options[:format])
12
- notification.send(method)
13
- else
14
- notification.params
15
- end
16
- end
17
-
18
- def channel
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
32
- end
6
+ def deliver
7
+ channel = fetch_constant(:channel)
8
+ stream = evaluate_option(:stream)
9
+ message = evaluate_option(:message)
33
10
 
34
- def stream
35
- value = options[:stream]
36
- case value
37
- when String
38
- value
39
- when Symbol
40
- notification.send(value)
41
- else
42
- recipient
43
- end
11
+ channel.broadcast_to stream, message
44
12
  end
45
13
  end
46
14
  end
@@ -0,0 +1,11 @@
1
+ module Noticed
2
+ module DeliveryMethods
3
+ class Discord < BulkDeliveryMethod
4
+ required_options :json, :url
5
+
6
+ def deliver
7
+ post_request evaluate_option(:url), headers: evaluate_option(:headers), json: evaluate_option(:json)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,54 +1,18 @@
1
1
  module Noticed
2
2
  module DeliveryMethods
3
- class Email < Base
4
- option :mailer
3
+ class Email < DeliveryMethod
4
+ required_options :mailer, :method
5
5
 
6
6
  def deliver
7
- if options[:enqueue]
8
- mailer.with(format).send(mailer_method.to_sym).deliver_later
9
- else
10
- mailer.with(format).send(mailer_method.to_sym).deliver_now
11
- end
12
- end
13
-
14
- private
7
+ mailer = fetch_constant(:mailer)
8
+ email = evaluate_option(:method)
9
+ params = (evaluate_option(:params) || notification&.params || {}).merge(record: notification&.record)
10
+ args = evaluate_option(:args)
15
11
 
16
- # mailer: "UserMailer"
17
- # mailer: UserMailer
18
- # mailer: :my_method - `my_method` should return Class
19
- def mailer
20
- option = options.fetch(:mailer)
21
- case option
22
- when String
23
- option.constantize
24
- when Symbol
25
- notification.send(option)
26
- else
27
- option
28
- end
29
- end
30
-
31
- # Method should be a symbol
32
- #
33
- # If notification responds to symbol, call that method and use return value
34
- # If notification does not respond to symbol, use the symbol for the mailer method
35
- # Otherwise, use the underscored notification class name as the mailer method
36
- def mailer_method
37
- method_name = options[:method]&.to_sym
38
- if method_name.present?
39
- notification.respond_to?(method_name) ? notification.send(method_name) : method_name
40
- else
41
- notification.class.name.underscore
42
- end
43
- end
12
+ mail = mailer.with(params)
13
+ mail = args.present? ? mail.send(email, *args) : mail.send(email)
44
14
 
45
- def format
46
- params = if (method = options[:format])
47
- notification.send(method)
48
- else
49
- notification.params
50
- end
51
- params.merge(recipient: recipient, record: record)
15
+ (!!evaluate_option(:enqueue)) ? mail.deliver_later : mail.deliver_now
52
16
  end
53
17
  end
54
18
  end
@@ -1,95 +1,54 @@
1
1
  require "googleauth"
2
2
 
3
- # class CommentNotifier
4
- # deliver_by :fcm, credentials: Rails.root.join("config/certs/fcm.json"), format: :format_notification
5
- #
6
- # deliver_by :fcm, credentials: :fcm_credentials
7
- # def fcm_credentials
8
- # { project_id: "api-12345" }
9
- # end
10
- # end
11
-
12
3
  module Noticed
13
4
  module DeliveryMethods
14
- class Fcm < Base
15
- BASE_URI = "https://fcm.googleapis.com/v1/projects/"
16
-
17
- option :format
5
+ class Fcm < DeliveryMethod
6
+ required_option :credentials, :device_tokens, :json
18
7
 
19
8
  def deliver
20
- device_tokens.each do |device_token|
21
- post("#{BASE_URI}#{project_id}/messages:send", headers: {authorization: "Bearer #{access_token}"}, json: {message: format(device_token)})
22
- rescue ResponseUnsuccessful => exception
23
- if exception.response.code == 404
24
- cleanup_invalid_token(device_token)
25
- else
26
- raise
27
- end
9
+ evaluate_option(:device_tokens).each do |device_token|
10
+ send_notification device_token
28
11
  end
29
12
  end
30
13
 
31
- def cleanup_invalid_token(device_token)
32
- return unless notification.respond_to?(:cleanup_device_token)
33
- notification.send(:cleanup_device_token, token: device_token, platform: "fcm")
14
+ def send_notification(device_token)
15
+ post_request("https://fcm.googleapis.com/v1/projects/#{credentials[:project_id]}/messages:send",
16
+ headers: {authorization: "Bearer #{access_token}"},
17
+ json: notification.instance_exec(device_token, &config[:json]))
18
+ rescue Noticed::ResponseUnsuccessful => exception
19
+ if exception.response.code == "404" && config[:invalid_token]
20
+ notification.instance_exec(device_token, &config[:invalid_token])
21
+ else
22
+ raise
23
+ end
34
24
  end
35
25
 
36
26
  def credentials
37
27
  @credentials ||= begin
38
- option = options[:credentials]
39
- credentials_hash = case option
28
+ value = evaluate_option(:credentials)
29
+ case value
40
30
  when Hash
41
- option
31
+ value
42
32
  when Pathname
43
- load_json(option)
33
+ load_json(value)
44
34
  when String
45
- load_json(Rails.root.join(option))
46
- when Symbol
47
- notification.send(option)
35
+ load_json(Rails.root.join(value))
48
36
  else
49
- Rails.application.credentials.fcm
37
+ raise ArgumentError, "FCM credentials must be a Hash, String, Pathname, or Symbol"
50
38
  end
51
-
52
- credentials_hash.symbolize_keys
53
39
  end
54
40
  end
55
41
 
56
42
  def load_json(path)
57
- JSON.parse(File.read(path))
58
- end
59
-
60
- def project_id
61
- credentials[:project_id]
43
+ JSON.parse(File.read(path), symbolize_names: true)
62
44
  end
63
45
 
64
46
  def access_token
65
- token = authorizer.fetch_access_token!
66
- token["access_token"]
67
- end
68
-
69
- def authorizer
70
- @authorizer ||= options.fetch(:authorizer, Google::Auth::ServiceAccountCredentials).make_creds(
47
+ @authorizer ||= (evaluate_option(:authorizer) || Google::Auth::ServiceAccountCredentials).make_creds(
71
48
  json_key_io: StringIO.new(credentials.to_json),
72
49
  scope: "https://www.googleapis.com/auth/firebase.messaging"
73
50
  )
74
- end
75
-
76
- def format(device_token)
77
- notification.send(options[:format], device_token)
78
- end
79
-
80
- def device_tokens
81
- if notification.respond_to?(:fcm_device_tokens)
82
- Array.wrap(notification.fcm_device_tokens(recipient))
83
- else
84
- raise NoMethodError, <<~MESSAGE
85
- You must implement `fcm_device_tokens` to send Firebase Cloud Messaging notifications
86
-
87
- # This must return an Array of FCM device tokens
88
- def fcm_device_tokens(recipient)
89
- recipient.fcm_device_tokens.pluck(:token)
90
- end
91
- MESSAGE
92
- end
51
+ @authorizer.fetch_access_token!["access_token"]
93
52
  end
94
53
  end
95
54
  end