mirror of
				https://github.com/lingble/chatwoot.git
				synced 2025-10-31 19:17:48 +00:00 
			
		
		
		
	feat: Use relay server for self-hosted mobile push notifications (#2757)
This commit is contained in:
		| @@ -161,3 +161,7 @@ USE_INBOX_AVATAR_FOR_BOT=true | |||||||
| # LETTER_OPENER=true | # LETTER_OPENER=true | ||||||
| # meant to be used in github codespaces | # meant to be used in github codespaces | ||||||
| # WEBPACKER_DEV_SERVER_PUBLIC= | # WEBPACKER_DEV_SERVER_PUBLIC= | ||||||
|  |  | ||||||
|  | # If you want to use official mobile app, | ||||||
|  | # the notifications would be relayed via a Chatwoot server | ||||||
|  | ENABLE_PUSH_RELAY_SERVER=true | ||||||
|   | |||||||
| @@ -9,6 +9,7 @@ class Notification::PushNotificationService | |||||||
|     notification_subscriptions.each do |subscription| |     notification_subscriptions.each do |subscription| | ||||||
|       send_browser_push(subscription) |       send_browser_push(subscription) | ||||||
|       send_fcm_push(subscription) |       send_fcm_push(subscription) | ||||||
|  |       send_push_via_chatwoot_hub(subscription) | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
|  |  | ||||||
| @@ -74,6 +75,18 @@ class Notification::PushNotificationService | |||||||
|  |  | ||||||
|     fcm = FCM.new(ENV['FCM_SERVER_KEY']) |     fcm = FCM.new(ENV['FCM_SERVER_KEY']) | ||||||
|     response = fcm.send([subscription.subscription_attributes['push_token']], fcm_options) |     response = fcm.send([subscription.subscription_attributes['push_token']], fcm_options) | ||||||
|  |     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) | ||||||
|     subscription.destroy! if JSON.parse(response[:body])['results']&.first&.keys&.include?('error') |     subscription.destroy! if JSON.parse(response[:body])['results']&.first&.keys&.include?('error') | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ class ChatwootHub | |||||||
|   BASE_URL = ENV['CHATWOOT_HUB_URL'] || 'https://hub.2.chatwoot.com' |   BASE_URL = ENV['CHATWOOT_HUB_URL'] || 'https://hub.2.chatwoot.com' | ||||||
|   PING_URL = "#{BASE_URL}/ping".freeze |   PING_URL = "#{BASE_URL}/ping".freeze | ||||||
|   REGISTRATION_URL = "#{BASE_URL}/instances".freeze |   REGISTRATION_URL = "#{BASE_URL}/instances".freeze | ||||||
|  |   PUSH_NOTIFICATION_URL = "#{BASE_URL}/send_push".freeze | ||||||
|   EVENTS_URL = "#{BASE_URL}/events".freeze |   EVENTS_URL = "#{BASE_URL}/events".freeze | ||||||
|  |  | ||||||
|   def self.installation_identifier |   def self.installation_identifier | ||||||
| @@ -51,7 +52,16 @@ class ChatwootHub | |||||||
|   rescue *ExceptionList::REST_CLIENT_EXCEPTIONS => e |   rescue *ExceptionList::REST_CLIENT_EXCEPTIONS => e | ||||||
|     Rails.logger.info "Exception: #{e.message}" |     Rails.logger.info "Exception: #{e.message}" | ||||||
|   rescue StandardError => e |   rescue StandardError => e | ||||||
|     Raven.capture_exception(e) |     Sentry.capture_exception(e) | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   def self.send_browser_push(fcm_token_list, fcm_options) | ||||||
|  |     info = { fcm_token_list: fcm_token_list, fcm_options: fcm_options } | ||||||
|  |     RestClient.post(PUSH_NOTIFICATION_URL, info.merge(instance_config).to_json, { content_type: :json, accept: :json }) | ||||||
|  |   rescue *ExceptionList::REST_CLIENT_EXCEPTIONS => e | ||||||
|  |     Rails.logger.info "Exception: #{e.message}" | ||||||
|  |   rescue StandardError => e | ||||||
|  |     Sentry.capture_exception(e) | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   def self.emit_event(event_name, event_data) |   def self.emit_event(event_name, event_data) | ||||||
|   | |||||||
| @@ -20,17 +20,20 @@ describe Notification::PushNotificationService do | |||||||
|       described_class.new(notification: notification).perform |       described_class.new(notification: notification).perform | ||||||
|       expect(Webpush).to have_received(:payload_send) |       expect(Webpush).to have_received(:payload_send) | ||||||
|       expect(FCM).not_to have_received(:new) |       expect(FCM).not_to have_received(:new) | ||||||
|       ENV['ENABLE_ACCOUNT_SIGNUP'] = nil |       ENV['VAPID_PUBLIC_KEY'] = nil | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     it 'sends a fcm notification for firebase subscription' do |     it 'sends a fcm notification for firebase subscription' do | ||||||
|       ENV['FCM_SERVER_KEY'] = 'test' |       ENV['FCM_SERVER_KEY'] = 'test' | ||||||
|  |       ENV['ENABLE_PUSH_RELAY_SERVER'] = 'false' | ||||||
|       create(:notification_subscription, user: notification.user, subscription_type: 'fcm') |       create(:notification_subscription, user: notification.user, subscription_type: 'fcm') | ||||||
|  |  | ||||||
|       described_class.new(notification: notification).perform |       described_class.new(notification: notification).perform | ||||||
|       expect(FCM).to have_received(:new) |       expect(FCM).to have_received(:new) | ||||||
|       expect(Webpush).not_to have_received(:payload_send) |       expect(Webpush).not_to have_received(:payload_send) | ||||||
|       ENV['ENABLE_ACCOUNT_SIGNUP'] = nil |  | ||||||
|  |       ENV['FCM_SERVER_KEY'] = nil | ||||||
|  |       ENV['ENABLE_PUSH_RELAY_SERVER'] = nil | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
| end | end | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Pranav Raj S
					Pranav Raj S