mirror of
https://github.com/discourse/discourse.git
synced 2025-01-18 15:52:45 +08:00
FEATURE: Add 'New users only' option to user_updated trigger (#26648)
This commit adds a new option to the `user_updated` trigger of the automation plugin to only trigger an automation for new users that join after the automation is enabled. Internal topic: t/125829/9.
This commit is contained in:
parent
57d29b6f3b
commit
4733369f71
|
@ -20,6 +20,10 @@ module DiscourseAutomation
|
|||
validates :script, presence: true
|
||||
validate :validate_trigger_fields
|
||||
|
||||
after_destroy do |automation|
|
||||
UserCustomField.where(name: automation.new_user_custom_field_name).destroy_all
|
||||
end
|
||||
|
||||
attr_accessor :running_in_background
|
||||
|
||||
def running_in_background!
|
||||
|
@ -163,6 +167,10 @@ module DiscourseAutomation
|
|||
scriptable&.on_reset&.call(self)
|
||||
end
|
||||
|
||||
def new_user_custom_field_name
|
||||
"automation_#{self.id}_new_user"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def validate_trigger_fields
|
||||
|
|
|
@ -175,6 +175,9 @@ en:
|
|||
once_per_user:
|
||||
label: Once per user
|
||||
description: Will trigger only once per user
|
||||
new_users_only:
|
||||
label: New users only
|
||||
description: Will trigger only for new users that join after this automation is enabled
|
||||
category_created_edited:
|
||||
fields:
|
||||
restricted_category:
|
||||
|
|
|
@ -65,7 +65,7 @@ module DiscourseAutomation
|
|||
end
|
||||
end
|
||||
|
||||
def self.handle_user_updated(user)
|
||||
def self.handle_user_updated(user, new_user: false)
|
||||
return if user.id < 0
|
||||
|
||||
name = DiscourseAutomation::Triggers::USER_UPDATED
|
||||
|
@ -79,6 +79,13 @@ module DiscourseAutomation
|
|||
next
|
||||
end
|
||||
|
||||
new_users_only = automation.trigger_field("new_users_only")["value"]
|
||||
|
||||
new_user_custom_field = automation.new_user_custom_field_name
|
||||
new_user ||= user.custom_fields[new_user_custom_field].present?
|
||||
|
||||
next if new_users_only && !new_user
|
||||
|
||||
required_custom_fields = automation.trigger_field("custom_fields")
|
||||
user_data = {}
|
||||
user_custom_fields_data = DB.query <<-SQL
|
||||
|
@ -87,16 +94,22 @@ module DiscourseAutomation
|
|||
JOIN user_custom_fields ucf ON CONCAT('user_field_', uf.id) = ucf.name
|
||||
WHERE ucf.user_id = #{user.id};
|
||||
SQL
|
||||
|
||||
user_custom_fields_data =
|
||||
user_custom_fields_data.each_with_object({}) do |obj, hash|
|
||||
field_name = obj.field_name
|
||||
field_value = obj.field_value
|
||||
hash[field_name] = field_value
|
||||
end
|
||||
|
||||
if required_custom_fields["value"]
|
||||
if required_custom_fields["value"].any? { |field|
|
||||
user_custom_fields_data[field].blank?
|
||||
}
|
||||
if new_users_only
|
||||
user.custom_fields[new_user_custom_field] = "1"
|
||||
user.save_custom_fields
|
||||
end
|
||||
next
|
||||
end
|
||||
user_data[:custom_fields] = user_custom_fields_data
|
||||
|
@ -108,11 +121,20 @@ module DiscourseAutomation
|
|||
if required_user_profile_fields["value"].any? { |field|
|
||||
user_profile_data[field].blank?
|
||||
}
|
||||
if new_users_only
|
||||
user.custom_fields[new_user_custom_field] = "1"
|
||||
user.save_custom_fields
|
||||
end
|
||||
next
|
||||
end
|
||||
user_data[:profile_data] = user_profile_data
|
||||
end
|
||||
|
||||
if new_users_only && once_per_user
|
||||
user.custom_fields.delete(new_user_custom_field)
|
||||
user.save_custom_fields
|
||||
end
|
||||
|
||||
automation.attach_custom_field(user)
|
||||
automation.trigger!("kind" => name, "user" => user, "user_data" => user_data)
|
||||
end
|
||||
|
|
|
@ -8,6 +8,7 @@ DiscourseAutomation::Triggerable.add(DiscourseAutomation::Triggers::USER_UPDATED
|
|||
field :custom_fields, component: :custom_fields
|
||||
field :user_profile, component: :user_profile
|
||||
field :once_per_user, component: :boolean
|
||||
field :new_users_only, component: :boolean
|
||||
|
||||
validate do
|
||||
has_triggers = has_trigger_field?(:custom_fields) && has_trigger_field?(:user_profile)
|
||||
|
|
|
@ -208,6 +208,9 @@ after_initialize do
|
|||
register_topic_custom_field_type(DiscourseAutomation::AUTO_RESPONDER_TRIGGERED_IDS, [:integer])
|
||||
|
||||
on(:user_updated) { |user| DiscourseAutomation::EventHandlers.handle_user_updated(user) }
|
||||
on(:user_created) do |user|
|
||||
DiscourseAutomation::EventHandlers.handle_user_updated(user, new_user: true)
|
||||
end
|
||||
|
||||
register_user_custom_field_type(DiscourseAutomation::CUSTOM_FIELD, [:integer])
|
||||
register_post_custom_field_type(DiscourseAutomation::CUSTOM_FIELD, [:integer])
|
||||
|
|
|
@ -165,4 +165,21 @@ describe DiscourseAutomation::Automation do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "after_destroy" do
|
||||
fab!(:automation) { Fabricate(:automation, enabled: false) }
|
||||
fab!(:automation2) { Fabricate(:automation, enabled: false) }
|
||||
|
||||
it "deletes user custom fields that indicate new users" do
|
||||
user = Fabricate(:user)
|
||||
user.custom_fields[automation.new_user_custom_field_name] = "1"
|
||||
user.custom_fields[automation2.new_user_custom_field_name] = "1"
|
||||
user.save_custom_fields
|
||||
|
||||
automation.destroy!
|
||||
user.reload
|
||||
|
||||
expect(user.custom_fields).to eq({ automation2.new_user_custom_field_name => "1" })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -93,7 +93,7 @@ describe "UserUpdated" do
|
|||
end
|
||||
end
|
||||
|
||||
context "when once_per_user is no set" do
|
||||
context "when once_per_user is not set" do
|
||||
it "triggers every time" do
|
||||
output =
|
||||
capture_contexts { UserUpdater.new(user, user).update(location: "Japan", bio_raw: "fine") }
|
||||
|
@ -124,4 +124,138 @@ describe "UserUpdated" do
|
|||
expect(output.first["kind"]).to eq("user_updated")
|
||||
end
|
||||
end
|
||||
|
||||
context "when new_users_only is set" do
|
||||
before do
|
||||
automation.upsert_field!("new_users_only", "boolean", { value: true }, target: "trigger")
|
||||
end
|
||||
|
||||
it "triggers for new users" do
|
||||
user = nil
|
||||
output =
|
||||
capture_contexts do
|
||||
user = Fabricate(:user)
|
||||
user.set_user_field(user_field_1.id, "Answer new custom 1")
|
||||
user.set_user_field(user_field_2.id, "Answer new custom 2")
|
||||
UserUpdater.new(user, user).update(location: "Japan", bio_raw: "fine")
|
||||
end
|
||||
|
||||
expect(output.size).to eq(1)
|
||||
expect(output.first["kind"]).to eq("user_updated")
|
||||
expect(output.first["user"].id).to eq(user.id)
|
||||
expect(output.first["user_data"][:custom_fields]).to eq(
|
||||
{ "custom field 1" => "Answer new custom 1", "custom field 2" => "Answer new custom 2" },
|
||||
)
|
||||
expect(output.first["user_data"][:profile_data]["location"]).to eq("Japan")
|
||||
expect(output.first["user_data"][:profile_data]["bio_raw"]).to eq("fine")
|
||||
|
||||
output =
|
||||
capture_contexts do
|
||||
UserUpdater.new(user, user).update(location: "Japan22", bio_raw: "finegood")
|
||||
end
|
||||
expect(output.size).to eq(1)
|
||||
expect(output.first["kind"]).to eq("user_updated")
|
||||
expect(output.first["user"].id).to eq(user.id)
|
||||
expect(output.first["user_data"][:profile_data]["location"]).to eq("Japan22")
|
||||
expect(output.first["user_data"][:profile_data]["bio_raw"]).to eq("finegood")
|
||||
end
|
||||
|
||||
it "doesn't trigger for existing users" do
|
||||
output =
|
||||
capture_contexts { UserUpdater.new(user, user).update(location: "Japan", bio_raw: "fine") }
|
||||
|
||||
expect(output).to eq([])
|
||||
end
|
||||
|
||||
context "when once_per_user is set" do
|
||||
before do
|
||||
automation.upsert_field!("once_per_user", "boolean", { value: true }, target: "trigger")
|
||||
end
|
||||
|
||||
it "triggers only once for a new user" do
|
||||
user = nil
|
||||
output =
|
||||
capture_contexts do
|
||||
user = Fabricate(:user)
|
||||
user.set_user_field(user_field_1.id, "Answer new custom 1")
|
||||
user.set_user_field(user_field_2.id, "Answer new custom 2")
|
||||
UserUpdater.new(user, user).update(location: "Japan", bio_raw: "fine")
|
||||
end
|
||||
|
||||
expect(output.size).to eq(1)
|
||||
expect(output.first["kind"]).to eq("user_updated")
|
||||
expect(output.first["user"].id).to eq(user.id)
|
||||
expect(output.first["user_data"][:custom_fields]).to eq(
|
||||
{ "custom field 1" => "Answer new custom 1", "custom field 2" => "Answer new custom 2" },
|
||||
)
|
||||
expect(output.first["user_data"][:profile_data]["location"]).to eq("Japan")
|
||||
expect(output.first["user_data"][:profile_data]["bio_raw"]).to eq("fine")
|
||||
|
||||
output =
|
||||
capture_contexts do
|
||||
UserUpdater.new(user, user).update(location: "Japan22", bio_raw: "finegood")
|
||||
end
|
||||
expect(output).to eq([])
|
||||
end
|
||||
|
||||
it "doesn't trigger for an existing user" do
|
||||
output =
|
||||
capture_contexts do
|
||||
UserUpdater.new(user, user).update(location: "Japan", bio_raw: "fine")
|
||||
end
|
||||
|
||||
expect(output).to eq([])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when new_users_only is not set" do
|
||||
before do
|
||||
automation.upsert_field!("new_users_only", "boolean", { value: false }, target: "trigger")
|
||||
end
|
||||
|
||||
it "triggers for new users" do
|
||||
user = nil
|
||||
output =
|
||||
capture_contexts do
|
||||
user = Fabricate(:user)
|
||||
user.set_user_field(user_field_1.id, "Answer new custom 1")
|
||||
user.set_user_field(user_field_2.id, "Answer new custom 2")
|
||||
UserUpdater.new(user, user).update(location: "Japan", bio_raw: "fine")
|
||||
end
|
||||
|
||||
expect(output.size).to eq(1)
|
||||
expect(output.first["kind"]).to eq("user_updated")
|
||||
expect(output.first["user"].id).to eq(user.id)
|
||||
expect(output.first["user_data"][:custom_fields]).to eq(
|
||||
{ "custom field 1" => "Answer new custom 1", "custom field 2" => "Answer new custom 2" },
|
||||
)
|
||||
expect(output.first["user_data"][:profile_data]["location"]).to eq("Japan")
|
||||
expect(output.first["user_data"][:profile_data]["bio_raw"]).to eq("fine")
|
||||
end
|
||||
|
||||
it "triggers for existing users" do
|
||||
output =
|
||||
capture_contexts { UserUpdater.new(user, user).update(location: "Japan", bio_raw: "fine") }
|
||||
|
||||
expect(output.size).to eq(1)
|
||||
expect(output.first["kind"]).to eq("user_updated")
|
||||
expect(output.first["user"].id).to eq(user.id)
|
||||
expect(output.first["user_data"][:custom_fields]).to eq(
|
||||
{ "custom field 1" => "Answer custom 1", "custom field 2" => "Answer custom 2" },
|
||||
)
|
||||
expect(output.first["user_data"][:profile_data]["location"]).to eq("Japan")
|
||||
expect(output.first["user_data"][:profile_data]["bio_raw"]).to eq("fine")
|
||||
|
||||
output =
|
||||
capture_contexts do
|
||||
UserUpdater.new(user, user).update(location: "Japan22", bio_raw: "finegood")
|
||||
end
|
||||
expect(output.size).to eq(1)
|
||||
expect(output.first["kind"]).to eq("user_updated")
|
||||
expect(output.first["user"].id).to eq(user.id)
|
||||
expect(output.first["user_data"][:profile_data]["location"]).to eq("Japan22")
|
||||
expect(output.first["user_data"][:profile_data]["bio_raw"]).to eq("finegood")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue
Block a user