diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 00000000000..cb2b00e4f7a --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +3.0.1 diff --git a/app/services/post_alerter.rb b/app/services/post_alerter.rb index 081fd70c9ba..7b49d0d158c 100644 --- a/app/services/post_alerter.rb +++ b/app/services/post_alerter.rb @@ -37,6 +37,10 @@ class PostAlerter def self.push_notification(user, payload) return if user.do_not_disturb? + DiscoursePluginRegistry.push_notification_filters.each do |filter| + return unless filter.call(user, payload) + end + if user.push_subscriptions.exists? Jobs.enqueue(:send_push_notification, user_id: user.id, payload: payload) end diff --git a/lib/discourse_plugin_registry.rb b/lib/discourse_plugin_registry.rb index 8106809144d..53a05aa4b49 100644 --- a/lib/discourse_plugin_registry.rb +++ b/lib/discourse_plugin_registry.rb @@ -91,6 +91,8 @@ class DiscoursePluginRegistry define_filtered_register :presence_channel_prefixes + define_filtered_register :push_notification_filters + def self.register_auth_provider(auth_provider) self.auth_providers << auth_provider end diff --git a/lib/plugin/instance.rb b/lib/plugin/instance.rb index 7158f0d3c1a..fe8a0297b3c 100644 --- a/lib/plugin/instance.rb +++ b/lib/plugin/instance.rb @@ -950,6 +950,12 @@ class Plugin::Instance DiscoursePluginRegistry.register_presence_channel_prefix([prefix, block], self) end + # Registers a new push notification filter. User and notification payload are passed into block, and if all + # filters return `true`, the push notification will be sent. + def register_push_notification_filter(&block) + DiscoursePluginRegistry.register_push_notification_filter(block, self) + end + # Register a ReviewableScore setting_name associated with a reason. # We'll use this to build a site setting link and add it to the reason's translation. # diff --git a/spec/services/post_alerter_spec.rb b/spec/services/post_alerter_spec.rb index c9da51111dc..56338868e64 100644 --- a/spec/services/post_alerter_spec.rb +++ b/spec/services/post_alerter_spec.rb @@ -721,12 +721,8 @@ describe PostAlerter do describe "push_notification" do let(:mention_post) { create_post_with_alerts(user: user, raw: 'Hello @eviltrout :heart:') } let(:topic) { mention_post.topic } - - it "pushes nothing to suspended users" do + before do SiteSetting.allowed_user_api_push_urls = "https://site.com/push|https://site2.com/push" - - evil_trout.update_columns(suspended_till: 1.year.from_now) - 2.times do |i| UserApiKey.create!(user_id: evil_trout.id, client_id: "xxx#{i}", @@ -734,20 +730,33 @@ describe PostAlerter do scopes: ['notifications'].map { |name| UserApiKeyScope.new(name: name) }, push_url: "https://site2.com/push") end + end + describe "DiscoursePluginRegistry#push_notification_filters" do + it "sends push notifications when all filters pass" do + Plugin::Instance.new.register_push_notification_filter do |user, payload| + true + end + + expect { mention_post }.to change { Jobs::PushNotification.jobs.count }.by(1) + DiscoursePluginRegistry.reset! + end + + it "does not send push notifications when a filters returns false" do + Plugin::Instance.new.register_push_notification_filter do |user, payload| + false + end + expect { mention_post }.not_to change { Jobs::PushNotification.jobs.count } + DiscoursePluginRegistry.reset! + end + end + + it "pushes nothing to suspended users" do + evil_trout.update_columns(suspended_till: 1.year.from_now) expect { mention_post }.to_not change { Jobs::PushNotification.jobs.count } end it "pushes nothing when the user is in 'do not disturb'" do - SiteSetting.allowed_user_api_push_urls = "https://site.com/push|https://site2.com/push" - 2.times do |i| - UserApiKey.create!(user_id: evil_trout.id, - client_id: "xxx#{i}", - application_name: "iPhone#{i}", - scopes: ['notifications'].map { |name| UserApiKeyScope.new(name: name) }, - push_url: "https://site2.com/push") - end - Fabricate(:do_not_disturb_timing, user: evil_trout, starts_at: Time.zone.now, ends_at: 1.day.from_now) expect { mention_post }.to_not change { Jobs::PushNotification.jobs.count } @@ -755,16 +764,6 @@ describe PostAlerter do it "correctly pushes notifications if configured correctly" do Jobs.run_immediately! - SiteSetting.allowed_user_api_push_urls = "https://site.com/push|https://site2.com/push" - - 2.times do |i| - UserApiKey.create!(user_id: evil_trout.id, - client_id: "xxx#{i}", - application_name: "iPhone#{i}", - scopes: ['notifications'].map { |name| UserApiKeyScope.new(name: name) }, - push_url: "https://site2.com/push") - end - body = nil headers = nil