2020-05-01 09:23:43 +00:00
|
|
|
class Notification::PushNotificationService
|
2020-05-05 18:40:56 +00:00
|
|
|
include Rails.application.routes.url_helpers
|
|
|
|
|
2020-05-01 09:23:43 +00:00
|
|
|
pattr_initialize [:notification!]
|
|
|
|
|
|
|
|
def perform
|
|
|
|
return unless user_subscribed_to_notification?
|
2020-05-05 18:40:56 +00:00
|
|
|
|
|
|
|
notification_subscriptions.each do |subscription|
|
2020-06-04 18:45:50 +00:00
|
|
|
send_browser_push(subscription)
|
|
|
|
send_fcm_push(subscription)
|
2021-08-16 20:14:16 +00:00
|
|
|
send_push_via_chatwoot_hub(subscription)
|
2020-05-05 18:40:56 +00:00
|
|
|
end
|
2020-05-01 09:23:43 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
2020-05-05 18:40:56 +00:00
|
|
|
delegate :user, to: :notification
|
|
|
|
delegate :notification_subscriptions, to: :user
|
|
|
|
delegate :notification_settings, to: :user
|
|
|
|
|
2020-05-01 09:23:43 +00:00
|
|
|
def user_subscribed_to_notification?
|
2020-05-05 18:40:56 +00:00
|
|
|
notification_setting = notification_settings.find_by(account_id: notification.account.id)
|
2020-05-01 09:23:43 +00:00
|
|
|
return true if notification_setting.public_send("push_#{notification.notification_type}?")
|
|
|
|
|
|
|
|
false
|
|
|
|
end
|
2020-05-05 18:40:56 +00:00
|
|
|
|
|
|
|
def conversation
|
2021-02-15 18:45:45 +00:00
|
|
|
@conversation ||= notification.conversation
|
2020-05-05 18:40:56 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def push_message
|
|
|
|
{
|
2020-06-09 12:12:18 +00:00
|
|
|
title: notification.push_message_title,
|
2020-05-05 18:40:56 +00:00
|
|
|
tag: "#{notification.notification_type}_#{conversation.display_id}",
|
|
|
|
url: push_url
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
def push_url
|
|
|
|
app_account_conversation_url(account_id: conversation.account_id, id: conversation.display_id)
|
|
|
|
end
|
|
|
|
|
2020-06-16 14:09:57 +00:00
|
|
|
def send_browser_push?(subscription)
|
2021-11-09 16:06:32 +00:00
|
|
|
VapidService.public_key && subscription.browser_push?
|
2020-06-16 14:09:57 +00:00
|
|
|
end
|
|
|
|
|
2020-05-05 18:40:56 +00:00
|
|
|
def send_browser_push(subscription)
|
2020-06-16 14:09:57 +00:00
|
|
|
return unless send_browser_push?(subscription)
|
2020-06-04 18:45:50 +00:00
|
|
|
|
2020-05-05 18:40:56 +00:00
|
|
|
Webpush.payload_send(
|
|
|
|
message: JSON.generate(push_message),
|
|
|
|
endpoint: subscription.subscription_attributes['endpoint'],
|
|
|
|
p256dh: subscription.subscription_attributes['p256dh'],
|
|
|
|
auth: subscription.subscription_attributes['auth'],
|
|
|
|
vapid: {
|
|
|
|
subject: push_url,
|
2021-11-09 16:06:32 +00:00
|
|
|
public_key: VapidService.public_key,
|
|
|
|
private_key: VapidService.private_key
|
2020-05-05 18:40:56 +00:00
|
|
|
},
|
|
|
|
ssl_timeout: 5,
|
|
|
|
open_timeout: 5,
|
|
|
|
read_timeout: 5
|
|
|
|
)
|
|
|
|
rescue Webpush::ExpiredSubscription
|
|
|
|
subscription.destroy!
|
2020-09-10 13:49:15 +00:00
|
|
|
rescue Errno::ECONNRESET, Net::OpenTimeout, Net::ReadTimeout => e
|
2022-03-28 12:44:30 +00:00
|
|
|
Rails.logger.error "Webpush operation error: #{e.message}"
|
2020-05-05 18:40:56 +00:00
|
|
|
end
|
2020-06-04 18:45:50 +00:00
|
|
|
|
|
|
|
def send_fcm_push(subscription)
|
2020-06-16 14:09:57 +00:00
|
|
|
return unless ENV['FCM_SERVER_KEY']
|
2020-06-04 18:45:50 +00:00
|
|
|
return unless subscription.fcm?
|
|
|
|
|
2022-07-15 02:51:59 +00:00
|
|
|
fcm = FCM.new(ENV.fetch('FCM_SERVER_KEY', nil))
|
2020-06-15 08:06:56 +00:00
|
|
|
response = fcm.send([subscription.subscription_attributes['push_token']], fcm_options)
|
2021-08-16 20:14:16 +00:00
|
|
|
remove_subscription_if_error(subscription, response)
|
|
|
|
end
|
|
|
|
|
|
|
|
def send_push_via_chatwoot_hub(subscription)
|
|
|
|
return if ENV['FCM_SERVER_KEY']
|
|
|
|
return unless ActiveModel::Type::Boolean.new.cast(ENV.fetch('ENABLE_PUSH_RELAY_SERVER', true))
|
|
|
|
return unless subscription.fcm?
|
|
|
|
|
|
|
|
ChatwootHub.send_browser_push([subscription.subscription_attributes['push_token']], fcm_options)
|
|
|
|
end
|
|
|
|
|
|
|
|
def remove_subscription_if_error(subscription, response)
|
2020-06-15 08:06:56 +00:00
|
|
|
subscription.destroy! if JSON.parse(response[:body])['results']&.first&.keys&.include?('error')
|
|
|
|
end
|
|
|
|
|
|
|
|
def fcm_options
|
|
|
|
{
|
2021-06-07 11:56:08 +00:00
|
|
|
notification: {
|
|
|
|
title: notification.notification_type.titleize,
|
2021-09-09 08:29:42 +00:00
|
|
|
body: notification.push_message_title,
|
|
|
|
sound: 'default'
|
2020-06-09 12:12:18 +00:00
|
|
|
},
|
2021-11-08 06:02:07 +00:00
|
|
|
android: { priority: 'high' },
|
2021-09-09 08:29:42 +00:00
|
|
|
data: { notification: notification.fcm_push_data.to_json },
|
2021-06-07 11:56:08 +00:00
|
|
|
collapse_key: "chatwoot_#{notification.primary_actor_type.downcase}_#{notification.primary_actor_id}"
|
2020-06-09 12:12:18 +00:00
|
|
|
}
|
2020-06-04 18:45:50 +00:00
|
|
|
end
|
2020-05-01 09:23:43 +00:00
|
|
|
end
|