Display Multiple Connected Issues in a Rich Text Field in Jira Cloud

This use case is designed for scenarios where a single Jira Cloud issue is connected to multiple remote tickets or issues. It allows you to display information from all those connected items, such as their key, summary, status, assignee, or other relevant fields, in a single Jira custom field.

  • Platforms: Jira Cloud + any supported remote instance, such as Zendesk, ServiceNow, Salesforce, Azure DevOps, or another Jira instance.

This example uses Zendesk → Jira Cloud and a Paragraph (supports rich text) field called Connected Tickets. The same logic can be adapted to other platforms depending on the fields and field types used.

Example:


Script Overview

  • Connect to an existing Jira issue: The script checks the Jira Issue URL field received from Zendesk. If a Jira issue is specified during the first synchronization, Exalate connects the Zendesk ticket to that existing Jira issue.
String jiraUrn = replica.customFields."Jira Issue URL"?.value

if(firstSync && jiraUrn){

    jiraUrn = jiraUrn.trim()

    def tmp = httpClient.get("/rest/api/3/issue/${jiraUrn}")

    if(tmp){

        issue.key = tmp?.key
        issue.id = tmp?.id

    }
}
  • Create a new Jira issue when no issue is specified: If the Zendesk ticket does not contain an existing Jira issue reference, the script creates a new issue in the configured project.
else if (firstSync) {
  issue.projectKey  = "PRD"
  issue.type   = nodeHelper.getIssueType(replica.type?.name, issue.projectKey) ?: nodeHelper.getIssueType("Task", issue.projectKey)
}
  • Retrieve the current connected tickets: The script reads the existing value of the Connected Tickets custom field and separates each Zendesk ticket using a delimiter.
String delimiter = "----------"

String zdIssues = issue.customFields."Connected Tickets"?.value ?: ""

List blocks = zdIssues ?
    zdIssues.split(delimiter).findAll { it.trim() } :
    []
  • Identify each Zendesk ticket: The Zendesk ticket key is extracted from each existing block so the script can determine whether that ticket is already listed.
def keyOf = { String block ->
    (block =~ /issue key:\s*(\S+)/).with {
        it.find() ? it.group(1) : null
    }
}
  • Build the Zendesk ticket entry: The information that should appear in the Jira field is created from the incoming replica.
String newBlock = """

    issue key: ${replica.key}

    Summary: ${replica.summary}

    status: ${replica.status?.name}

    assignee: ${replica.assignee?.email}

  """
  • Update or add the ticket: If the Zendesk ticket is already listed, its existing entry is updated. Otherwise, a new entry is added.
int idx = blocks.findIndexOf {
    keyOf(it) == replica.key
}

if (idx >= 0) {

    blocks[idx] = newBlock

} else {

    blocks << newBlock

}

Final Solution

Jira Cloud Incoming Sync

String jiraUrn = replica.customFields."Jira Issue URL"?.value
if(firstSync && jiraUrn){
  jiraUrn = jiraUrn.trim()
  def tmp = httpClient.get("/rest/api/3/issue/${jiraUrn}")
  if(tmp){
    issue.key = tmp?.key
    issue.id = tmp?.id
  }
}else if (firstSync) {
  issue.projectKey  = "PRD"
  issue.type   = nodeHelper.getIssueType(replica.type?.name, issue.projectKey) ?: nodeHelper.getIssueType("Task", issue.projectKey)
}


String delimiter = "----------"
String zdIssues  = issue.customFields."Connected Tickets"?.value ?: ""
List blocks = zdIssues ? zdIssues.split(delimiter).findAll { it.trim() } : []

def keyOf = { String block -> (block =~ /issue key:\s*(\S+)/).with { it.find() ? it.group(1) : null } }

String newBlock = """
    issue key: ${replica.key}
    Summary: ${replica.summary}
    status: ${replica.status?.name}
    assignee: ${replica.assignee?.email}
  """

int idx = blocks.findIndexOf { keyOf(it) == replica.key }
if (idx >= 0) {
  blocks[idx] = newBlock
} else {
  blocks << newBlock
}

boolean isPrimary = blocks.isEmpty() ? true : (keyOf(blocks[0]) == replica.key)
if(isPrimary){
  //issue.summary      = replica.summary
  issue.description  = replica.description
  issue.comments     = commentHelper.mergeComments(issue, replica)
  issue.attachments  = attachmentHelper.mergeAttachments(issue, replica)
  issue.labels       = replica.labels
}
issue.customFields."Connected Tickets"?.value = blocks.join(delimiter) + delimiter

Notes

  1. In this example, Connected Tickets is a Paragraph (supports rich text) field.
  2. In case you want to sync to an existing Jira Cloud issue From ZD, The Zendesk side needs to send the Jira Issue URL
  3. The Jira Cloud Connected Tickets field must exist or replaced with your own

Version

5.36.0