mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
DEV: Add hooks to allow overriding notify_user behavior (#23850)
Adds new plugin registry `:post_action_notify_user_handlers` and more!
This commit is contained in:
parent
38e7960082
commit
f29c476521
@ -116,6 +116,8 @@ class DiscoursePluginRegistry
|
|||||||
|
|
||||||
define_filtered_register :summarization_strategies
|
define_filtered_register :summarization_strategies
|
||||||
|
|
||||||
|
define_filtered_register :post_action_notify_user_handlers
|
||||||
|
|
||||||
def self.register_auth_provider(auth_provider)
|
def self.register_auth_provider(auth_provider)
|
||||||
self.auth_providers << auth_provider
|
self.auth_providers << auth_provider
|
||||||
end
|
end
|
||||||
|
@ -58,7 +58,19 @@ module PostGuardian
|
|||||||
|
|
||||||
if action_key == :notify_user &&
|
if action_key == :notify_user &&
|
||||||
!@user.in_any_groups?(SiteSetting.personal_message_enabled_groups_map)
|
!@user.in_any_groups?(SiteSetting.personal_message_enabled_groups_map)
|
||||||
return false
|
# The modifier below is used to add additional permissions for notifying users.
|
||||||
|
# In core the only method of notifying a user is personal messages so we check if the
|
||||||
|
# user can PM. Plugins can extend the behavior of how users are notifier via `notify_user`
|
||||||
|
# post action, and this allows extension for that use case.
|
||||||
|
can_notify = false
|
||||||
|
can_notify =
|
||||||
|
DiscoursePluginRegistry.apply_modifier(
|
||||||
|
:post_guardian_can_notify_user,
|
||||||
|
can_notify,
|
||||||
|
self,
|
||||||
|
post,
|
||||||
|
)
|
||||||
|
return can_notify
|
||||||
end
|
end
|
||||||
|
|
||||||
# we allow flagging for trust level 1 and higher
|
# we allow flagging for trust level 1 and higher
|
||||||
|
@ -1238,6 +1238,14 @@ class Plugin::Instance
|
|||||||
DiscoursePluginRegistry.register_summarization_strategy(strategy, self)
|
DiscoursePluginRegistry.register_summarization_strategy(strategy, self)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Register a block that will be called when PostActionCreator is going to notify a
|
||||||
|
# user of a post action. If any of these handlers returns false the default PostCreator
|
||||||
|
# call will be skipped.
|
||||||
|
def register_post_action_notify_user_handler(handler)
|
||||||
|
DiscoursePluginRegistry.register_post_action_notify_user_handler(handler, self)
|
||||||
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def self.js_path
|
def self.js_path
|
||||||
|
@ -116,12 +116,16 @@ class PostActionCreator
|
|||||||
# create meta topic / post if needed
|
# create meta topic / post if needed
|
||||||
if @message.present? && %i[notify_moderators notify_user spam].include?(@post_action_name)
|
if @message.present? && %i[notify_moderators notify_user spam].include?(@post_action_name)
|
||||||
creator = create_message_creator
|
creator = create_message_creator
|
||||||
post = creator.create
|
# We need to check if the creator exists because it's possible `create_message_creator` returns nil
|
||||||
if creator.errors.present?
|
# in the event that a `post_action_notify_user_handler` evaluated to false, haulting the post creation.
|
||||||
result.add_errors_from(creator)
|
if creator
|
||||||
return result
|
post = creator.create
|
||||||
|
if creator.errors.present?
|
||||||
|
result.add_errors_from(creator)
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
@meta_post = post
|
||||||
end
|
end
|
||||||
@meta_post = post
|
|
||||||
end
|
end
|
||||||
|
|
||||||
begin
|
begin
|
||||||
@ -339,8 +343,16 @@ class PostActionCreator
|
|||||||
else
|
else
|
||||||
create_args[:subtype] = TopicSubtype.notify_user
|
create_args[:subtype] = TopicSubtype.notify_user
|
||||||
|
|
||||||
create_args[:target_usernames] = if @post_action_name == :notify_user
|
if @post_action_name == :notify_user
|
||||||
@post.user.username
|
create_args[:target_usernames] = @post.user.username
|
||||||
|
|
||||||
|
# Evaluate DiscoursePluginRegistry.post_action_notify_user_handlers.
|
||||||
|
# If any return false, return early from this method
|
||||||
|
handler_values =
|
||||||
|
DiscoursePluginRegistry.post_action_notify_user_handlers.map do |handler|
|
||||||
|
handler.call(@created_by, @post, @message)
|
||||||
|
end
|
||||||
|
return if handler_values.any? { |value| value == false }
|
||||||
elsif @post_action_name != :notify_moderators
|
elsif @post_action_name != :notify_moderators
|
||||||
# this is a hack to allow a PM with no recipients, we should think through
|
# this is a hack to allow a PM with no recipients, we should think through
|
||||||
# a cleaner technique, a PM with myself is valid for flagging
|
# a cleaner technique, a PM with myself is valid for flagging
|
||||||
|
@ -327,4 +327,73 @@ RSpec.describe PostActionCreator do
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "With plugin adding post_action_notify_user_handlers" do
|
||||||
|
let(:message) { "oh that was really bad what you said there" }
|
||||||
|
let(:plugin) { Plugin::Instance.new }
|
||||||
|
|
||||||
|
after { DiscoursePluginRegistry.reset! }
|
||||||
|
|
||||||
|
it "evaluates all handlers and creates post if none return false" do
|
||||||
|
plugin.register_post_action_notify_user_handler(
|
||||||
|
Proc.new do |user, post, message|
|
||||||
|
MessageBus.publish("notify_user", { user_id: user.id, message: message })
|
||||||
|
end,
|
||||||
|
)
|
||||||
|
|
||||||
|
plugin.register_post_action_notify_user_handler(
|
||||||
|
Proc.new do |user, post, message|
|
||||||
|
MessageBus.publish("notify_user", { poster_id: post.user_id, message: message })
|
||||||
|
end,
|
||||||
|
)
|
||||||
|
|
||||||
|
messages =
|
||||||
|
MessageBus.track_publish("notify_user") do
|
||||||
|
result =
|
||||||
|
PostActionCreator.new(
|
||||||
|
user,
|
||||||
|
post,
|
||||||
|
PostActionType.types[:notify_user],
|
||||||
|
message: message,
|
||||||
|
flag_topic: false,
|
||||||
|
).perform
|
||||||
|
post_action = result.post_action
|
||||||
|
expect(post_action.related_post).to be_present
|
||||||
|
end
|
||||||
|
|
||||||
|
expect(
|
||||||
|
messages.find { |m| m.data[:user_id] == user.id && m.data[:message] == message },
|
||||||
|
).to be_present
|
||||||
|
expect(
|
||||||
|
messages.find { |m| m.data[:poster_id] == post.user_id && m.data[:message] == message },
|
||||||
|
).to be_present
|
||||||
|
end
|
||||||
|
|
||||||
|
it "evaluates all handlers and doesn't create a post one returns false" do
|
||||||
|
plugin.register_post_action_notify_user_handler(
|
||||||
|
Proc.new do |user, post, message|
|
||||||
|
MessageBus.publish("notify_user", { user_id: user.id, message: message })
|
||||||
|
false
|
||||||
|
end,
|
||||||
|
)
|
||||||
|
|
||||||
|
messages =
|
||||||
|
MessageBus.track_publish("notify_user") do
|
||||||
|
result =
|
||||||
|
PostActionCreator.new(
|
||||||
|
user,
|
||||||
|
post,
|
||||||
|
PostActionType.types[:notify_user],
|
||||||
|
message: message,
|
||||||
|
flag_topic: false,
|
||||||
|
).perform
|
||||||
|
post_action = result.post_action
|
||||||
|
expect(post_action.related_post).not_to be_present
|
||||||
|
end
|
||||||
|
|
||||||
|
expect(
|
||||||
|
messages.find { |m| m.data[:user_id] == user.id && m.data[:message] == message },
|
||||||
|
).to be_present
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user