API for apps to register for push notifications

This commit is contained in:
Eugen Rochko
2017-01-29 01:30:32 +01:00
parent 1992575d57
commit 3f075c7794
13 changed files with 112 additions and 2 deletions

View File

@ -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

7
app/models/device.rb Normal file
View File

@ -0,0 +1,7 @@
# frozen_string_literal: true
class Device < ApplicationRecord
belongs_to :account
validates :account, :registration_id, presence: true
end

View File

@ -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

View File

@ -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

View File

@ -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