From 6c2c6904794c1e3580a4bea93fb9bb7fe6f7c1b1 Mon Sep 17 00:00:00 2001 From: Mark VanLandingham Date: Thu, 29 Feb 2024 12:49:46 -0600 Subject: [PATCH] DEV: Add push notification filtering to MessageBus alerts (#25965) --- app/services/post_alerter.rb | 21 ++++++++++++------- .../app/jobs/regular/chat/notify_watching.rb | 12 ++++++++++- .../jobs/regular/chat/notify_watching_spec.rb | 10 +++++++++ spec/services/post_alerter_spec.rb | 20 ++++++++++++------ 4 files changed, 49 insertions(+), 14 deletions(-) diff --git a/app/services/post_alerter.rb b/app/services/post_alerter.rb index a1755ad3b6d..da1235300f9 100644 --- a/app/services/post_alerter.rb +++ b/app/services/post_alerter.rb @@ -38,13 +38,20 @@ class PostAlerter DiscourseEvent.trigger(:pre_notification_alert, user, payload) if user.allow_live_notifications? - payload = - DiscoursePluginRegistry.apply_modifier( - :post_alerter_live_notification_payload, - payload, - user, - ) - MessageBus.publish("/notification-alert/#{user.id}", payload, user_ids: [user.id]) + send_notification = + DiscoursePluginRegistry.push_notification_filters.all? do |filter| + filter.call(user, payload) + end + + if send_notification + payload = + DiscoursePluginRegistry.apply_modifier( + :post_alerter_live_notification_payload, + payload, + user, + ) + MessageBus.publish("/notification-alert/#{user.id}", payload, user_ids: [user.id]) + end end push_notification(user, payload) diff --git a/plugins/chat/app/jobs/regular/chat/notify_watching.rb b/plugins/chat/app/jobs/regular/chat/notify_watching.rb index 0acf217c590..2816a1cd5e2 100644 --- a/plugins/chat/app/jobs/regular/chat/notify_watching.rb +++ b/plugins/chat/app/jobs/regular/chat/notify_watching.rb @@ -76,7 +76,17 @@ module Jobs } if membership.desktop_notifications_always? && !membership.muted? - ::MessageBus.publish("/chat/notification-alert/#{user.id}", payload, user_ids: [user.id]) + send_notification = + DiscoursePluginRegistry.push_notification_filters.all? do |filter| + filter.call(user, payload) + end + if send_notification + ::MessageBus.publish( + "/chat/notification-alert/#{user.id}", + payload, + user_ids: [user.id], + ) + end end if membership.mobile_notifications_always? && !membership.muted? diff --git a/plugins/chat/spec/jobs/regular/chat/notify_watching_spec.rb b/plugins/chat/spec/jobs/regular/chat/notify_watching_spec.rb index 18aecd0f3b8..15fd2492094 100644 --- a/plugins/chat/spec/jobs/regular/chat/notify_watching_spec.rb +++ b/plugins/chat/spec/jobs/regular/chat/notify_watching_spec.rb @@ -85,6 +85,16 @@ RSpec.describe Jobs::Chat::NotifyWatching do end end + context "with push_notification_filter registered to block push notifications" do + after { DiscoursePluginRegistry.reset_register!(:push_notification_filters) } + + it "doesn't send notification alert via MessageBus" do + Plugin::Instance.new.register_push_notification_filter { |user, payload| false } + + expect(notification_messages_for(user2)).to be_empty + end + end + context "when the channel is muted via membership preferences" do before { membership2.update!(muted: true) } diff --git a/spec/services/post_alerter_spec.rb b/spec/services/post_alerter_spec.rb index ff4cf400020..420a4ec8952 100644 --- a/spec/services/post_alerter_spec.rb +++ b/spec/services/post_alerter_spec.rb @@ -1188,21 +1188,29 @@ RSpec.describe PostAlerter do end describe "DiscoursePluginRegistry#push_notification_filters" do + after { DiscoursePluginRegistry.reset_register!(:push_notification_filters) } + it "sends push notifications when all filters pass" do + evil_trout.update!(last_seen_at: 10.minutes.ago) Plugin::Instance.new.register_push_notification_filter { |user, payload| true } - expect { mention_post }.to change { Jobs::PushNotification.jobs.count }.by(1) - DiscoursePluginRegistry.reset! + alerts = + MessageBus.track_publish("/notification-alert/#{evil_trout.id}") do + expect { mention_post }.to change { Jobs::PushNotification.jobs.count }.by(1) + end + + expect(alerts).not_to be_empty end it "does not send push notifications when a filters returns false" do Plugin::Instance.new.register_push_notification_filter { |user, payload| false } - expect { mention_post }.not_to change { Jobs::PushNotification.jobs.count } - events = DiscourseEvent.track_events { mention_post } - expect(events.find { |event| event[:event_name] == :push_notification }).not_to be_present + alerts = + MessageBus.track_publish("/notification-alert/#{evil_trout.id}") do + expect { mention_post }.not_to change { Jobs::PushNotification.jobs.count } + end - DiscoursePluginRegistry.reset! + expect(alerts).to be_empty end end