mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-11-16 22:25:30 +08:00
115 lines
3.5 KiB
Ruby
115 lines
3.5 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Notifications
|
|
class SyncSystemNotificationsService
|
|
extend Service
|
|
include HTTParty
|
|
base_uri Rails.application.secrets.system_notifications_uri
|
|
|
|
attr_reader :errors
|
|
|
|
def initialize
|
|
@errors = {}
|
|
end
|
|
|
|
def call
|
|
call_api
|
|
|
|
save_new_notifications if succeed?
|
|
|
|
self
|
|
end
|
|
|
|
def succeed?
|
|
@errors.none?
|
|
end
|
|
|
|
def self.available?
|
|
channel = Rails.application.secrets.system_notifications_channel
|
|
query = { query: { last_sync_timestamp: Time.now.to_i, channels_slug: channel },
|
|
headers: { 'accept': 'application/vnd.system-notifications.1+json' } }
|
|
response = get('/api/system_notifications', query)
|
|
response.code < Rack::Utils::SYMBOL_TO_STATUS_CODE[:bad_request]
|
|
end
|
|
|
|
private
|
|
|
|
def call_api
|
|
last_sync = SystemNotification.last_sync_timestamp
|
|
channel = Rails.application.secrets.system_notifications_channel
|
|
|
|
unless last_sync
|
|
@errors[:last_sync_timestamp] = 'Cannot find last_sync_timestamp'
|
|
return false
|
|
end
|
|
|
|
query = { query: { last_sync_timestamp: last_sync,
|
|
channels_slug: channel },
|
|
headers: { 'accept':
|
|
'application/vnd.system-notifications.1+json' } }
|
|
|
|
# rubocop:disable Lint/ShadowedException:
|
|
begin
|
|
@api_call = self.class.get('/api/system_notifications', query)
|
|
|
|
if @api_call.response.code.to_i != 200
|
|
@errors[:api_error] =
|
|
[@api_call.response.code.to_s, @api_call.response.message].join('-')
|
|
|
|
# Add message for logging if exists
|
|
if @api_call.parsed_response.try('error')
|
|
@errors[:api_error] += ': ' + @api_call
|
|
.parsed_response['error']
|
|
.flatten&.join(' - ').to_s
|
|
end
|
|
end
|
|
rescue SocketError, HTTParty::Error, StandardError => e
|
|
@errors[e.class.to_s.downcase.to_sym] = e.message
|
|
end
|
|
# rubocop:enable Lint/ShadowedException:
|
|
end
|
|
|
|
def save_new_notifications
|
|
@api_call.parsed_response['notifications'].each do |sn|
|
|
# Save new notification if not exists or override old 1
|
|
attrs =
|
|
sn.slice('title',
|
|
'description',
|
|
'modal_title',
|
|
'modal_body',
|
|
'show_on_login',
|
|
'source_id')
|
|
.merge('source_created_at':
|
|
Time.parse(sn['source_created_at']),
|
|
'last_time_changed_at':
|
|
Time.parse(sn['last_time_changed_at']))
|
|
.symbolize_keys
|
|
|
|
n = SystemNotification
|
|
.where(source_id: attrs[:source_id]).first_or_initialize(attrs)
|
|
|
|
if n.new_record?
|
|
save_notification n
|
|
elsif n.last_time_changed_at < attrs[:last_time_changed_at]
|
|
n.update!(attrs)
|
|
end
|
|
end
|
|
end
|
|
|
|
def save_notification(notification)
|
|
ActiveRecord::Base.transaction do
|
|
notification.save!
|
|
|
|
User.find_in_batches do |user_ids|
|
|
user_system_notifications = user_ids.pluck(:id).collect do |item|
|
|
Hash[:user_id, item, :system_notification_id, notification.id]
|
|
end
|
|
UserSystemNotification.import user_system_notifications, validate: false
|
|
end
|
|
end
|
|
|
|
Notifications::PushToCommunicationChannelService.delay.call(item_id: notification.id,
|
|
item_type: notification.class.name)
|
|
end
|
|
end
|
|
end
|