Assign new tags to a tag group

AI-generated summary

In a Dev category discussion titled “Assign new tags to a tag group,” tknospdr seeks to automate assigning user-created tags in a specific category to a designated tag group. They shared a plugin code snippet that uses site settings and a Topic model callback to check if a tag was created near the topic’s creation time and assign it to the configured tag group if not already present. faithererer confirms encountering a similar need but no solution yet, and tknospdr replies they haven’t solved it either, inviting collaboration. The discussion centers on extending Discourse’s tag management with automated tag group assignment based on category context.

Trying to figure out a way to have tags created by users in a specific category be automatically assigned to a specified tag group. I searched and didn’t find anything currently available.

Does this code look like it would do what I want?

enabled_site_setting :auto_tag_to_group_enabled

# Plugin settings
register_site_setting :auto_tag_to_group_enabled, default: true
register_site_setting :auto_tag_category_name, default: "RestrictedCategory"
register_site_setting :auto_tag_group_name, default: "RestrictedTags"

after_initialize do
  module ::DiscourseAutoTagToGroup
    class Engine < ::Rails::Engine
      engine_name "discourse_auto_tag_to_group"
      isolate_namespace DiscourseAutoTagToGroup
    end
  end

  require_dependency "topic"
  class ::Topic
    after_save :auto_assign_new_tags_to_group, if: :auto_tag_to_group_conditions_met?

    private

    def auto_tag_to_group_conditions_met?
      # Check if plugin is enabled and topic has tags
      SiteSetting.auto_tag_to_group_enabled && self.tags.present?
    end

    def auto_assign_new_tags_to_group
      # Get the configured category and tag group names
      target_category_name = SiteSetting.auto_tag_category_name
      target_tag_group_name = SiteSetting.auto_tag_group_name

      # Find the category and tag group
      target_category = Category.find_by(name: target_category_name)
      target_tag_group = TagGroup.find_by(name: target_tag_group_name)

      # Exit if category or tag group not found
      return unless target_category && target_tag_group
      return unless self.category_id == target_category.id

      # Get the timestamp of the topic creation
      topic_created_at = self.created_at

      self.tags.each do |tag|
        # Check if the tag was created close to the topic creation time
        # Allow a small window (e.g., 1 minute) to account for processing delays
        if tag.created_at && tag.created_at >= (topic_created_at - 1.minute)
          # Check if tag is already in the target tag group
          unless TagGroupMembership.exists?(tag_id: tag.id, tag_group_id: target_tag_group.id)
            # Add the tag to the tag group
            TagGroupMembership.create!(tag_id: tag.id, tag_group_id: target_tag_group.id)
          end
        end
      end
    end
  end
end

I also encountered a similar requirement. Have you solved it?

Nope. Let me know if you come up with something.