diff --git a/app/services/notification_emailer.rb b/app/services/notification_emailer.rb index 60d124dc965..4acd8f5e28e 100644 --- a/app/services/notification_emailer.rb +++ b/app/services/notification_emailer.rb @@ -138,6 +138,11 @@ class NotificationEmailer email_user = EmailUser.new(notification, no_delay: no_delay) email_method = Notification.types[notification.notification_type] + + DiscoursePluginRegistry.email_notification_filters.each do |filter| + return unless filter.call(notification) + end + email_user.public_send(email_method) if email_user.respond_to? email_method end end diff --git a/lib/discourse_plugin_registry.rb b/lib/discourse_plugin_registry.rb index cb1e8e22ba2..6925e2ba720 100644 --- a/lib/discourse_plugin_registry.rb +++ b/lib/discourse_plugin_registry.rb @@ -99,6 +99,7 @@ class DiscoursePluginRegistry define_filtered_register :presence_channel_prefixes + define_filtered_register :email_notification_filters define_filtered_register :push_notification_filters define_filtered_register :notification_consolidation_plans diff --git a/lib/plugin/instance.rb b/lib/plugin/instance.rb index 83e18d3a0ec..beb19cde414 100644 --- a/lib/plugin/instance.rb +++ b/lib/plugin/instance.rb @@ -999,6 +999,12 @@ class Plugin::Instance DiscoursePluginRegistry.register_presence_channel_prefix([prefix, block], self) end + # Registers a new email notification filter. Notification is passed into block, and if all + # filters return `true`, the email notification will be sent. + def register_email_notification_filter(&block) + DiscoursePluginRegistry.register_email_notification_filter(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) diff --git a/spec/services/notification_emailer_spec.rb b/spec/services/notification_emailer_spec.rb index e889bead882..da827721f91 100644 --- a/spec/services/notification_emailer_spec.rb +++ b/spec/services/notification_emailer_spec.rb @@ -274,4 +274,31 @@ RSpec.describe NotificationEmailer do end end end + + describe "with plugin-added email_notification_filters" do + let!(:plugin) { Plugin::Instance.new } + let!(:notification) { create_notification(:quoted) } + let(:no_delay) { true } + let(:type) { :user_quoted } + + after { DiscoursePluginRegistry.reset! } + + it "sends email when all filters return true" do + plugin.register_email_notification_filter { |_| true } + plugin.register_email_notification_filter { |_| true } + + expect_enqueued_with(job: :user_email, args: { type: type }) do + NotificationEmailer.process_notification(notification, no_delay: no_delay) + end + end + + it "doesn't send email when all one filter returns false" do + plugin.register_email_notification_filter { |_| true } + plugin.register_email_notification_filter { |_| false } + + expect_not_enqueued_with(job: :user_email, args: { type: type }) do + NotificationEmailer.process_notification(notification, no_delay: no_delay) + end + end + end end