Calculated Custom Field

This example is similar to the calculated field example for Script Listeners except in this case, the calculation occurs when the issue transitions to a specific status in a workflow.


Here we specify and retrieve the details of the parent issue. If you copied this code into a Post Function or an issue-related Script Listener, you could remove the first 5 lines of code as an issue variable would already be available for your script.def parentKey = 'DEMO-1'
def issueResp = get("/rest/api/2/issue/${parentKey}")
.asObject(Map)
assert issueResp.status == 200
def issue = issueResp.body as Map

// We retrieve all issue types
def typeResp = get('/rest/api/2/issuetype')
.asObject(List)
assert typeResp.status == 200
def issueTypes = typeResp.body as List<Map>

// Here we set the basic subtask issue details
def summary = "Subtask summary"
def issueType = "Sub-task"
def issueTypeId = issueTypes.find { it.subtask && it.name == issueType }?.id

assert issueTypeId : "No subtasks issue type found called '${issueType}'"

def createDoc = [
fields: [
project: (issue.fields as Map).project,
issuetype: [
id: issueTypeId
],
parent: [
id: issue.id
],
summary: summary
]
]

// Now we create the subtask
def resp = post("/rest/api/2/issue")
.header("Content-Type", "application/json")
.body(createDoc)
.asObject(Map)
def subtask = resp.body
assert resp.status >= 200 && resp.status < 300 && subtask && subtask.key != null

subtask
GROOVY


  1. Grab the values of the custom fields from the event

  2. Sanity check for null values - the issue may not have a value for any input

  3. Here we check to see if the output field already has the calculated value, if it does do nothing. This is important because an IssueUpdated event will fire for the update we are about to perform

  4. Update the value of the custom field

  5. If using the Add-on user to run the script, it is possible to set the overrideScreenSecurity property to modify fields that are not on the current screen

Create Sub-Task

Run this code in the Script Console to create a sub-task.

// Here we specify and retrieve the details of the parent issue
// If you copied this code into a Post Function or an issue-related Script Listener you could remove
// the first 5 lines of code as an issue variable would already be available to your script
def parentKey = 'DEMO-1'
def issueResp = get("/rest/api/2/issue/${parentKey}")
        .asObject(Map)
assert issueResp.status == 200
def issue = issueResp.body as Map

// We retrieve all issue types
def typeResp = get('/rest/api/2/issuetype')
        .asObject(List)
assert typeResp.status == 200
def issueTypes = typeResp.body as List<Map>

// Here we set the basic subtask issue details
def summary = "Subtask summary"
def issueType = "Sub-task"
def issueTypeId = issueTypes.find { it.subtask && it.name == issueType }?.id

assert issueTypeId : "No subtasks issue type found called '${issueType}'"

def createDoc = [
        fields: [
                project: (issue.fields as Map).project,
                issuetype: [
                        id: issueTypeId
                ],
                parent: [
                        id: issue.id
                ],
                summary: summary
        ]
]

// Now we create the subtask
def resp = post("/rest/api/2/issue")
        .header("Content-Type", "application/json")
        .body(createDoc)
        .asObject(Map)
def subtask = resp.body
assert resp.status >= 200 && resp.status < 300 && subtask && subtask.key != null

subtask
GROOVY

Post to Slack

Use this example to send a simple Slack post, notifying users that an issue has been updated.


def apiToken = 'YOUR_SECRET_TOKEN'

def msg = [
        channel: 'your-channel-here',
        username: 'Any Username Here',
        icon emoji: ':rocket:',
        text: "${issue.key} Updated",
]

post('https://slack.com/api/chat.postMessage')
        .header('Content-Type', 'application/json')
        .header(Authorization', "Bearer ${apiToken}")
        .body(msg)
        .asString()
GROOVY


  1. Generate a Slack API token and use it here. This API token should be saved as a script variable.

  2. Add the name of the channel you wish to post to.

  3. Enter the username ScriptRunner will post as.

  4. Enter the notification text.

Link to an Issue

Automatically link the issue being transitioned to another issue.

def issueId = issue.id

def link = post('/rest/api/2/issueLink')
        .header('Content-Type', 'application/json')
        .body([
        type: [ name: "Blocks" ],
        outwardIssue: [ id: issueId ],  // This is the issue that the link 'starts' at
        inwardIssue: [ key: 'EX-1' ]  // You'll need to specify an issue ID or key here
])
        .asString()
assert link.status == 201
GROOVY

Add a Customer Facing Comment on a Linked Service Management

This script allows you to add a comment on a linked Jira Service Management Cloud project after the transition of an issue. For example, you may want to let a bug reporter know that the related development is marked as complete.

We advise you run this script as the ScriptRunner Add-on User.

// Define a counter which will be the number of support tickets updated by this script
def counter = 0

// Define the Service Desk Issuetypes you only want updated if a linked Jira software issue is closed
def serviceDeskIssueTypes = [
        "Incident",
        "Feature Request"
]

// Find the linked issues
def linkedIssues = issue.fields.issuelinks

// Loop over each linked issue
linkedIssues.each {
    // For each linked issue, comment only on Service Desk Tickets
    if (serviceDeskIssueTypes.contains(it.outwardIssue.fields.issuetype.name)) {
        def commentResp = post("/rest/api/2/issue/${it.outwardIssue.key}/comment")
                .header('Content-Type', 'application/json')
                .body([
                        body: """
                    Good news! We've now completed the development work related to this ticket.
                    """ // Define on the line above what you want the comment to look like to customers on the Service Desk ticket
                ])
                .asObject(Map)
        counter ++
        // Log info about which Service Desk ticket was just updated
        logger.info("Issue ${issue.key} has been closed. \nService Desk ticket ${it.outwardIssue.key} has been commented to inform affected customers.")
    }
}
return "The script finished successfully. ${counter} support ticket/s were commented on."
GROOVY