How to Use ScriptRunner to Automatically Exalate Subtasks Whenever a Parent is Exalated?

Scriptrunner subtask sync

This article was originally published on the Atlassian Community.

We got this question from one of the users about how to automatically exalate all subtasks whenever an issue is being exalated.

Exalate is an issue sync solution allowing for integration between Jira, ServiceNow, Salesforce, Zendesk, and more (and yes – I’m part of the team building that add-on).

Therefore I thought to implement this requirement with ScriptRunner…

The article shows how the exalate classes can be instantiated to trigger an exalate operation.

The way it works

  • Whenever an exalate operation is finished, a ‘Exalate’ issueEvent is raised.
  • A ScriptRunner custom listener picks up the issue event.
  • The custom listener will trigger a new exalate event for each subtask on the issue.

Setting up the custom Listener

An image is worth 1000 words.  The event the listener needs to listen to is ‘com.exalate.api.domain.trigger.EXALATED’ 


How does it work in detail?
The whole script code can be found in this snippet.

event.issue contains the parent issue which has been exalated.  The exalateNow function is called on every subtask.


The exalateNow function is a closure taking an issue object and a connection name.

  • On line 26 – the connection that needs to be used to exalate the subtask is looked up, an error is raised if the name is not found.
  • On line 33 – an exalate issue key is generated.
  • On line 36 – the outgoing sync processor is run on the subtask, creating a ‘hubIssue’ which is the object that will be sent over.
  • On line 39, the exalate operation is scheduled (internally, it’s called Pairing an issue).

The exalateNow code is using a couple of classes that need to be instantiated.  
This can be done using the code below:

  • Line 6,7 – get the exalate class loader from the PluginAccessor.
  • Line 9 – 13 are used to retrieve the classes from the class loader.
  • Line 9 – BasicIssueKey class is used to generate a unique identifier for the issue.
  • Line 10 – EventSchedulerService is the exalate service responsible to manage the sync events.
  • Line 11 – a twin is the couple of issues that are related to each other.  The twin trace repository contains all the twins managed by this exalate. It is not used in the code but it can be useful in certain use cases.
  • Line 12 – a relation is another name for connection – the relation repository contains all the defined connections.
  • Line 13 – the node helper class is used to run the outgoing sync processor.
  • Line 15-18 are used to get access to the OSGiComponents.

Wrap up

This article is meant to give an example of how to instantiate the exalate classes and use these to perform a more advanced synchronization case.

Using the above logic it is possible to write a procedure to synchronize a complete issue structure (Project -> Epic -> Story) and all related subtasks.


This example uses non-public APIs which will change between different versions of the add-on.  Take this into account to implement production scripts whenever using the APIs.

This example is an example and there is no guarantee that it would work in your case.  If in doubt – there are 130+ Exalate partners providing professional services to help out.

Comments are closed.