Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

Create linked issue from remote issue hyperlink

Samuel Burchmore
I'm New Here
I'm New Here
Those new to the Atlassian Community have posted less than three times. Give them a warm welcome!
January 28, 2025

I have 2 JSM instances connected with OAuth.

On the first instance, I have a text field which stores a hyperlink to another issue on the second JSM instance. I'm trying to write a script which automatically creates a reciprocal link between the 2 issues.

My understanding so far is -

  1. I need to write a rest api call which creates the link on the remote issue using the local issues information.
  2. Retrieve the remote issues information and use that to create a reciprocal link on the local instance.

I've cobbled this script together based on similar questions here -

--------------------------------------------------------------------------------------------

 

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.link.RemoteIssueLinkManager
import com.atlassian.jira.issue.link.RemoteIssueLinkManager
import com.atlassian.jira.bc.user.search.UserSearchService
import com.atlassian.jira.issue.link.RemoteIssueLinkBuilder
import com.atlassian.jira.bc.issue.link.RemoteIssueLinkService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.applinks.api.ApplicationLinkService
import com.atlassian.applinks.api.application.jira.JiraApplicationType
import com.atlassian.sal.api.component.ComponentLocator
import com.atlassian.sal.api.net.Response
import com.atlassian.sal.api.net.ResponseException
import com.atlassian.sal.api.net.ResponseHandler
import groovy.json.JsonBuilder
import static com.atlassian.sal.api.net.Request.MethodType.POST
import com.atlassian.jira.component.ComponentAccessor

def appLinkService = ComponentLocator.getComponent(ApplicationLinkService)
def appLink = appLinkService.getPrimaryApplicationLink(JiraApplicationType)
def applicationLinkRequestFactory = appLink.createAuthenticatedRequestFactory()

def user = Users.getByName("<admin username>")
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def customField = customFieldManager.getCustomFieldObject("customfield_<custom field id>")

// get hyperlink from current ticket
def remoteIssueLink = issue.getCustomFieldValue(customField) as String
def localIssueLink = ("<local link>" + issue.getKey())
def remoteIssueKey = remoteIssueLink.split("/").last()

// create post call for remote ticket
def post = ("/rest/api/2/issue/" + remoteIssueKey + "/remotelink")

// create input for remote post call
def input = new JsonBuilder([
    object: [
        url: localIssueLink,
        title: issue
        ]
]).toString()

// define request
def request = applicationLinkRequestFactory.createRequest(POST, post)
    .addHeader("Content-Type", "application/json")
    .setEntity(input)

// make request and store response
def responseContentJson
request.execute(new ResponseHandler<Response>() {
    @Override
    void handle(Response response) throws ResponseException {
        responseContentJson = response.responseBodyAsString
        if ( response.statusCode != 201) {
            issue.addComment("Fail: ${response.responseBodyAsString}")
        }
    }
})

// instantiate remote issue link builder
def linkBuilder = new RemoteIssueLinkBuilder()

// populate link builder with remote issue detals
linkBuilder.url(remoteIssueLink)
linkBuilder.title(remoteIssueKey)
linkBuilder.issueId(issue.id)

// create link
def remoteIssueLinkService = ComponentAccessor.getComponentOfType(RemoteIssueLinkService.class)
def validationResult = remoteIssueLinkService.validateCreate(user, linkBuilder.build())
remoteIssueLinkService.create(user, validationResult)

-----------------------------------------------------------------------------------------------

 

When I run this script I encounter a stack overflow. I'm really quite new to scriptrunner and the rest API. My understanding is poor and I'm struggling to understand whats going wrong.

 

 

1 answer

2 votes
Pablo Vergara
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Champions.
June 19, 2026

Hi @Samuel Burchmore

This is an interesting challenge. Have you considered using Automation for Jira and the Jira DC API instead of a Groovy-scripted solution?

While it might take me a considerable amount of time to test this (right now I've only 1 Jira DC test instance available also), I'm thinking about something as described below:

  • Trigger: issue created, field value changed, or scheduled backfill.
  • Condition: the "remote-key" (let's call it that way) custom field is not empty and matches your expected key pattern/structure.
  • Send a web request: GET the remote issue from instance B to confirm the specified key exists.
  • Send a web request: POST the remote link to instance A.
  • Send a web request: POST the reciprocal remote link to instance B.
  • Add an audit comment, label, or issue property only if you need traceability.

I'd like to hear your thoughts or maybe an alternative solution that other members can describe or even test.

(I might not be fully right in my approach, so feel free to discuss any correction or improvement)

- Pablo / ServiceRocket SSE

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events