FEATURE: enhance post created edited trigger in automation (#31900)

1. **Multiselect Support for Choice Fields**
   - Added a `multiselect` option to the choices field component
   - Updated Field model to accept arrays as values for choices fields

2. **Post Content Feature Filtering**
   - Added ability to filter posts based on content features:
     - Posts with images
     - Posts with links
     - Posts with code blocks
     - Posts with uploads

3. **Improved Group Filtering**
- Renamed `restricted_user_group` to `restricted_groups` to allow
filtering by multiple groups
- Added `excluded_groups` to replace `ignore_group_members` which was
complex for end users
- Renamed `restricted_groups` to `restricted_inbox_groups` for more
specific PM filtering and clarity.

4. **Public Topics Filter**
- Added a "Public Topics" filter option that excludes all secure
categories
This commit is contained in:
Sam
2025-03-20 08:05:06 +11:00
committed by GitHub
parent 2a73387029
commit 0e62acd57f
8 changed files with 427 additions and 69 deletions

View File

@ -12,10 +12,24 @@ module DiscourseAutomation
DiscourseAutomation::Automation
.where(trigger: name, enabled: true)
.find_each do |automation|
action_type = automation.trigger_field("action_type")
selected_action = action_type["value"]&.to_sym
if selected_action
next if selected_action == :created && action != :create
next if selected_action == :edited && action != :edit
end
restricted_archetype = automation.trigger_field("restricted_archetype")["value"]
if restricted_archetype.present?
topic_archetype = topic.archetype
next if restricted_archetype != topic_archetype
if restricted_archetype == "public"
next if topic.archetype != Archetype.default
next if !topic.category
next if topic.category.read_restricted?
else
topic_archetype = topic.archetype
next if restricted_archetype != topic_archetype
end
end
original_post_only = automation.trigger_field("original_post_only")
@ -66,29 +80,35 @@ module DiscourseAutomation
next if (restricted_tags["value"] & topic.tags.map(&:name)).empty?
end
restricted_group_ids = automation.trigger_field("restricted_groups")["value"]
if restricted_group_ids.present?
restricted_inbox_group_ids = automation.trigger_field("restricted_inbox_groups")["value"]
if restricted_inbox_group_ids.present?
next if !topic.private_message?
target_group_ids = topic.allowed_groups.pluck(:id)
next if (restricted_group_ids & target_group_ids).empty?
ignore_group_members = automation.trigger_field("ignore_group_members")["value"]
next if ignore_group_members && post.user.in_any_groups?(restricted_group_ids)
next if (restricted_inbox_group_ids & target_group_ids).empty?
end
user_group = automation.trigger_field("restricted_user_group")["value"]
next if user_group && !post.user.in_any_groups?([user_group])
user_group_ids = automation.trigger_field("restricted_groups")["value"]
next if user_group_ids.present? && !post.user.in_any_groups?(user_group_ids)
excluded_group_ids = automation.trigger_field("excluded_groups")["value"]
next if excluded_group_ids.present? && post.user.in_any_groups?(excluded_group_ids)
ignore_automated = automation.trigger_field("ignore_automated")
next if ignore_automated["value"] && post.incoming_email&.is_auto_generated?
action_type = automation.trigger_field("action_type")
selected_action = action_type["value"]&.to_sym
if selected_action
next if selected_action == :created && action != :create
next if selected_action == :edited && action != :edit
post_features = automation.trigger_field("post_features")["value"]
if post_features.present?
cooked = post.cooked
# note the only 100% correct way is to lean on an actual HTML parser
# however triggers may pop up during the post creation process, we can not afford a full parse
next if post_features.include?("with_images") && !cooked.match?(/<img[^>]+>/i)
next if post_features.include?("with_links") && !cooked.match?(/<a[^>]+>/i)
next if post_features.include?("with_code") && !cooked.match?(/<pre[^>]+>/i)
if post_features.include?("with_uploads") &&
!cooked.match?(/<a[^>]+class=["']attachment[^>]+>/i)
next
end
end
automation.trigger!(