Expand my Community achievements bar.

Join expert-led, customer-led sessions on Adobe Experience Manager Assets on August 20th at our Skill Exchange.

How to Capture Tag Edit, Merge, and Delete Events in AEM?

Avatar

Level 1

Hi Community,

 

I’m currently working on a requirement where I need to trigger a custom service whenever an author edits, merges, or deletes an existing tag in AEM.

 

I explored using ResourceChangeListener, but it appears too generic for this use case. It doesn’t provide specific context—like whether a tag was merged or which properties (e.g., jcr:title or jcr:description) were updated.

 

I'm looking for a way to capture detailed tag-related activities as precisely as possible. Ideally, I want to hook into the tag lifecycle and differentiate between operations such as update vs. merge vs. delete.

 

Has anyone implemented a similar use case or is aware of any specific event handlers or listeners in AEM that are better suited for monitoring tag changes?

 

Any insights or suggestions would be greatly appreciated!

 

Thanks,
Praveen

Topics

Topics help categorize Community content and increase your ability to discover relevant content.

3 Replies

Avatar

Community Advisor

Hi @PraveenKM1,

Try using javax.jcr.observation.EventListener

This provides more control and granularity than ResourceChangeListener. You can register a listener specifically for events under the /etc/tags path and listen for:

  • PROPERTY_CHANGED – for changes like jcr:title, jcr:description

  • NODE_REMOVED – for tag deletion

  • NODE_ADDED – possibly triggered during merge or creation

Example:

observationManager.addEventListener(
    this,
    Event.PROPERTY_CHANGED | Event.NODE_REMOVED | Event.NODE_ADDED,
    "/etc/tags",
    true,
    null,
    null,
    false
);

Then, in onEvent, inspect the path and event type to determine what changed.

 

Tag merge is tricky because AEM performs it by moving the merged tag’s children and then deleting the merged node.

To detect this:

  • Watch for a sequence of NODE_MOVED or NODE_ADDED events followed by NODE_REMOVED

  • Correlate these in logic (some timestamp or path patterns help)

Unfortunately, there’s no out-of-the-box merge-specific event, so this part may require some custom logic.


Santosh Sai

AEM BlogsLinkedIn


Avatar

Level 4

Using javax.jcr.observation.EventListener with deep filtering on /content/cq:tags

 

 

@component(service = TagChangeListener.class, immediate = true)
public class TagChangeListener implements EventListener {

    @reference
    private ResourceResolverFactory resolverFactory;

    @activate
    protected void activate() throws Exception {
        try (ResourceResolver resolver = resolverFactory.getServiceResourceResolver(
                Collections.singletonMap(ResourceResolverFactory.SUBSERVICE, "datawrite"))) {
            
            Session session = resolver.adaptTo(Session.class);
            if (session != null) {
                ObservationManager observationManager = session.getWorkspace().getObservationManager();
                observationManager.addEventListener(
                        this,
                        Event.NODE_ADDED | Event.NODE_REMOVED | Event.PROPERTY_CHANGED | Event.NODE_MOVED,
                        "/content/cq:tags", // or /etc/tags in 6.5
                        true,
                        null,
                        null,
                        false
                );
            }
        }
    }

    @Override
    public void onEvent(EventIterator events) {
        while (events.hasNext()) {
            Event event = events.nextEvent();
            log.info("Tag event type: {}, path: {}", event.getType(), event.getPath());
            // Add custom logic here
        }
    }
}

 

Avatar

Level 1

Hi @SantoshSai / @Nilesh_Mali ,

 

Thanks for your response. I implemented the EventListener as suggested, targeting the /content/cq:tags path. However, the onEvent method is never invoked, regardless of the event types registered in the activate method.

 

I've verified that both the ResourceResolver and Session objects are valid (not null), and the observation listener service is properly registered.

Despite all these checks, editing or deleting tags does not trigger any events. Do you have any suggestions on what might be missing?

 

Thanks,
Praveen