Skip to content
This repository was archived by the owner on May 30, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions app/models/discourse_automation/field.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ def metadata_schema
"type" => %w[string integer null],
},
},
"category_notification_level" => {
"value" => {
"type" => "integer",
},
},
"user" => {
"value" => {
"type" => "string",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import BaseField from "./da-base-field";

export default class CategoryNotficiationLevelField extends BaseField {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<section class="field category-notification-level-field">
<div class="control-group">
{{fields/da-field-label label=label field=field}}

<div class="controls">
{{category-notifications-button
value=field.metadata.value
onChange=(action (mut field.metadata.value))
}}

{{fields/da-field-description description=description}}
</div>
</div>
</section>
14 changes: 14 additions & 0 deletions config/locales/client.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,11 @@ en:
restricted_category:
label: Category
description: Optional, allows to limit trigger execution to this category
category_created_edited:
fields:
restricted_category:
label: Parent Category
description: Optional, allows to limit trigger execution to this category
pm_created:
fields:
restricted_user:
Expand Down Expand Up @@ -189,6 +194,15 @@ en:
label: Topic ID
post:
label: Post content
group_category_notification_default:
fields:
group:
label: Group
notification_level:
label: Notification level
update_existing_members:
label: Update existing members
description: Updates the notification level for existing group members
user_global_notice:
fields:
level:
Expand Down
6 changes: 6 additions & 0 deletions config/locales/server.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ en:
title: API call
description: Making a POST request to trigger an automation
doc: The POST request should be made to `/automations/:id/trigger.json` with a global API key.
category_created_edited:
title: Category created/edited
description: When a category is created or edited the automation will be triggered
recurring:
title: Recurring
point_in_time:
Expand Down Expand Up @@ -110,3 +113,6 @@ en:
button_text: Done
add_user_to_group_through_custom_field:
title: "Add user to group through User Custom Field"
group_category_notification_default:
title: "Group Category Notification Default"
description: "Set the default notification level of a category for members of a group"
15 changes: 15 additions & 0 deletions lib/discourse_automation/event_handlers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,21 @@ def self.handle_post_created_edited(post, action)
end
end

def self.handle_category_created_edited(category, action)
name = DiscourseAutomation::Triggerable::CATEGORY_CREATED_EDITED

DiscourseAutomation::Automation
.where(trigger: name, enabled: true)
.find_each do |automation|
restricted_category = automation.trigger_field("restricted_category")
if restricted_category["value"].present?
next if restricted_category["value"] != category.parent_category_id
end

automation.trigger!("kind" => name, "action" => action, "category" => category)
end
end

def self.handle_pm_created(topic)
return if topic.user_id < 0

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# frozen_string_literal: true

DiscourseAutomation::Scriptable::GROUP_CATEGORY_NOTIFICATION_DEFAULT =
"group_category_notification_default"

DiscourseAutomation::Scriptable.add(
DiscourseAutomation::Scriptable::GROUP_CATEGORY_NOTIFICATION_DEFAULT,
) do
version 1

field :group, component: :group
field :notification_level, component: :category_notification_level
field :update_existing_members, component: :boolean

triggerables %i[category_created_edited]

script do |context, fields|
category_id = context["category"].id
group_id = fields.dig("group", "value")
notification_level = fields.dig("notification_level", "value")

unless group = Group.find_by(id: group_id)
Rails.logger.warn "[discourse-automation] Couldn’t find group with id #{group_id}"
next
end

GroupCategoryNotificationDefault
.find_or_initialize_by(group_id: group_id, category_id: category_id)
.tap do |gc|
gc.notification_level = notification_level
gc.save!
end

if fields.dig("update_existing_members", "value")
group
.users
.select(:id, :user_id)
.find_in_batches do |batch|
user_ids = batch.pluck(:user_id)

category_users = []
existing_users =
CategoryUser.where(category_id: category_id, user_id: user_ids).where(
"notification_level IS NOT NULL",
)
skip_user_ids = existing_users.pluck(:user_id)

batch.each do |group_user|
next if skip_user_ids.include?(group_user.user_id)
category_users << {
category_id: category_id,
user_id: group_user.user_id,
notification_level: notification_level,
}
end

next if category_users.blank?

CategoryUser.insert_all!(category_users)
end
end
end
end
7 changes: 7 additions & 0 deletions lib/discourse_automation/triggers/category_created_edited.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

DiscourseAutomation::Triggerable::CATEGORY_CREATED_EDITED = "category_created_edited"

DiscourseAutomation::Triggerable.add(DiscourseAutomation::Triggerable::CATEGORY_CREATED_EDITED) do
field :restricted_category, component: :category
end
10 changes: 10 additions & 0 deletions plugin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ module ::DiscourseAutomation
lib/discourse_automation/scripts/close_topic
lib/discourse_automation/scripts/flag_post_on_words
lib/discourse_automation/scripts/gift_exchange
lib/discourse_automation/scripts/group_category_notification_default
lib/discourse_automation/scripts/pin_topic
lib/discourse_automation/scripts/post
lib/discourse_automation/scripts/send_pms
Expand All @@ -54,6 +55,7 @@ module ::DiscourseAutomation
lib/discourse_automation/scripts/zapier_webhook
lib/discourse_automation/triggers/after_post_cook
lib/discourse_automation/triggers/api_call
lib/discourse_automation/triggers/category_created_edited
lib/discourse_automation/triggers/pm_created
lib/discourse_automation/triggers/point_in_time
lib/discourse_automation/triggers/post_created_edited
Expand Down Expand Up @@ -162,6 +164,14 @@ module ::DiscourseAutomation
DiscourseAutomation::EventHandlers.handle_post_created_edited(post, :edit)
end

on(:category_created) do |category|
DiscourseAutomation::EventHandlers.handle_category_created_edited(category, :create)
end

on(:category_edited) do |category|
DiscourseAutomation::EventHandlers.handle_category_created_edited(category, :edit)
end

Plugin::Filter.register(:after_post_cook) do |post, cooked|
DiscourseAutomation::EventHandlers.handle_after_post_cook(post, cooked)
end
Expand Down
71 changes: 71 additions & 0 deletions spec/scripts/group_category_notification_default_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# frozen_string_literal: true

require_relative "../discourse_automation_helper"

describe "GroupCategoryNotificationDefault" do
fab!(:category) { Fabricate(:category) }
fab!(:group) { Fabricate(:group) }

before { SiteSetting.discourse_automation_enabled = true }

context "when using category_created_edited trigger" do
fab!(:automation) do
Fabricate(
:automation,
script: DiscourseAutomation::Scriptable::GROUP_CATEGORY_NOTIFICATION_DEFAULT,
trigger: DiscourseAutomation::Triggerable::CATEGORY_CREATED_EDITED,
)
end

before do
automation.upsert_field!(
"restricted_category",
"category",
{ value: category.id },
target: "trigger",
)
automation.upsert_field!("group", "group", { value: group.id }, target: "script")
automation.upsert_field!(
"notification_level",
"category_notification_level",
{ value: 4 },
target: "script",
)
end

context "when category is allowed" do
it "creates a GroupCategoryNotificationDefault record" do
subcategory = nil
expect { subcategory = Fabricate(:category, parent_category_id: category.id) }.to change {
GroupCategoryNotificationDefault.count
}.by(1)

record = GroupCategoryNotificationDefault.last
expect(record.category_id).to eq(subcategory.id)
expect(record.group_id).to eq(group.id)
expect(record.notification_level).to eq(4)
end

it "updates category notification level for existing members" do
automation.upsert_field!(
"update_existing_members",
"boolean",
{ value: true },
target: "script",
)
user = Fabricate(:user)
group.add(user)
subcategory = nil

expect { subcategory = Fabricate(:category, parent_category_id: category.id) }.to change {
CategoryUser.count
}.by(1)

record = CategoryUser.last
expect(record.category_id).to eq(subcategory.id)
expect(record.user_id).to eq(user.id)
expect(record.notification_level).to eq(4)
end
end
end
end
52 changes: 52 additions & 0 deletions spec/triggers/category_created_edited_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# frozen_string_literal: true

require_relative "../discourse_automation_helper"

describe "CategoryCreatedEdited" do
before { SiteSetting.discourse_automation_enabled = true }

fab!(:automation) do
Fabricate(:automation, trigger: DiscourseAutomation::Triggerable::CATEGORY_CREATED_EDITED)
end

context "when editing/creating a post" do
it "fires the trigger" do
category = nil

list = capture_contexts { category = Fabricate(:category) }

expect(list.length).to eq(1)
expect(list[0]["kind"]).to eq("category_created_edited")
expect(list[0]["action"].to_s).to eq("create")
end

context "when category is restricted" do
let(:parent_category_id) { Category.first.id }
before do
automation.upsert_field!(
"restricted_category",
"category",
{ value: parent_category_id },
target: "trigger",
)
end

context "when category is allowed" do
it "fires the trigger" do
list = capture_contexts { Fabricate(:category, parent_category_id: parent_category_id) }

expect(list.length).to eq(1)
expect(list[0]["kind"]).to eq("category_created_edited")
end
end

context "when category is not allowed" do
it "doesn’t fire the trigger" do
list = capture_contexts { Fabricate(:category) }

expect(list).to be_blank
end
end
end
end
end