diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/controllers/api/v1/devices_controller.rb | 18 | ||||
-rw-r--r-- | app/models/device.rb | 7 | ||||
-rw-r--r-- | app/services/notify_service.rb | 5 | ||||
-rw-r--r-- | app/services/send_push_notification_service.rb | 28 | ||||
-rw-r--r-- | app/workers/push_notification_worker.rb | 11 |
5 files changed, 69 insertions, 0 deletions
diff --git a/app/controllers/api/v1/devices_controller.rb b/app/controllers/api/v1/devices_controller.rb new file mode 100644 index 000000000..c565e972b --- /dev/null +++ b/app/controllers/api/v1/devices_controller.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +class Api::V1::DevicesController < ApiController + before_action -> { doorkeeper_authorize! :read } + before_action :require_user! + + respond_to :json + + def register + Device.where(account: current_account, registration_id: params[:registration_id]).first_or_create!(account: current_account, registration_id: params[:registration_id]) + render_empty + end + + def unregister + Device.where(account: current_account, registration_id: params[:registration_id]).delete_all + render_empty + end +end diff --git a/app/models/device.rb b/app/models/device.rb new file mode 100644 index 000000000..2782a7f38 --- /dev/null +++ b/app/models/device.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class Device < ApplicationRecord + belongs_to :account + + validates :account, :registration_id, presence: true +end diff --git a/app/services/notify_service.rb b/app/services/notify_service.rb index 1ec36637c..d1504cadf 100644 --- a/app/services/notify_service.rb +++ b/app/services/notify_service.rb @@ -10,6 +10,7 @@ class NotifyService < BaseService create_notification send_email if email_enabled? + send_push_notification rescue ActiveRecord::RecordInvalid return end @@ -57,6 +58,10 @@ class NotifyService < BaseService NotificationMailer.send(@notification.type, @recipient, @notification).deliver_later end + def send_push_notification + PushNotificationWorker.perform_async(@notification.id) + end + def email_enabled? @recipient.user.settings.notification_emails[@notification.type] end diff --git a/app/services/send_push_notification_service.rb b/app/services/send_push_notification_service.rb new file mode 100644 index 000000000..802614fce --- /dev/null +++ b/app/services/send_push_notification_service.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +class SendPushNotificationService < BaseService + def call(notification) + return if ENV['FCM_API_KEY'].blank? + + devices = Device.where(account: notification.account).pluck(:registration_id) + fcm = FCM.new(ENV['FCM_API_KEY']) + + response = fcm.send(devices, data: { notification_id: notification.id }, collapse_key: :notifications, priority: :high) + handle_response(response) + end + + private + + def handle_response(response) + update_canonical_ids(response[:canonical_ids]) if response[:canonical_ids] + remove_bad_ids(response[:not_registered_ids]) if response[:not_registered_ids] + end + + def update_canonical_ids(ids) + ids.each { |pair| Device.find_by(registration_id: pair[:old]).update(registration_id: pair[:new]) } + end + + def remove_bad_ids(bad_ids) + Device.where(registration_id: bad_ids).delete_all + end +end diff --git a/app/workers/push_notification_worker.rb b/app/workers/push_notification_worker.rb new file mode 100644 index 000000000..a61d0e349 --- /dev/null +++ b/app/workers/push_notification_worker.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +class PushNotificationWorker + include Sidekiq::Worker + + def perform(notification_id) + SendPushNotificationService.new.call(Notification.find(notification_id)) + rescue ActiveRecord::RecordNotFound + true + end +end |