You're on your way to the next level! Join the Kudos program to earn points and save your progress.
Level 1: Seed
25 / 150 points
Next: Root
1 badge earned
Challenges come and go, but your rewards stay with you. Do more to earn more!
What goes around comes around! Share the love by gifting kudos to your peers.
Keep earning points to reach the top of the leaderboard. It resets every quarter so you always have a chance!
Join now to unlock these features and more
The Atlassian Community can help you and your team get more value out of Atlassian products and practices.
Hello,
I am trying to create rest endpoint in scriptrunner to parse incoming json (webhook from another jira)
Here is an example of incoming json:
{
"any parameter": "#009900",
"issue": "S-1",
"iconUrl": "/images/icons/priorities/lowest.png",
"name": "Fred"
}
And my rest endpoint code (there are some extra classes):
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.config.PriorityManager
import com.atlassian.jira.issue.fields.rest.json.beans.JiraBaseUrls
import com.atlassian.jira.issue.fields.rest.json.beans.CommentJsonBean
import com.atlassian.jira.issue.priority.Priority
import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.transform.BaseScript
import groovy.json.JsonBuilder
import org.codehaus.jackson.map.ObjectMapper
import groovy.json.JsonSlurper
import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response
@BaseScript CustomEndpointDelegate delegate
doSomething(
httpMethod: "POST"
) { MultivaluedMap queryParams, String body ->
String jsonString = "body"
JsonSlurper slurper = new JsonSlurper()
Map parsedJson = slurper.parseText(jsonString)
String idValue = parsedJson.issue
String idValue2 = parsedJson.get("issue")
return "issue"
}
My curl:
curl -X POST -H "Content-type: text/json" --data "@priority.json" http://jira_url/rest/scriptrunner/latest/custom/doSomething
When I put my json as a file I ve got errors in the response:
{
"message": "Unable to determine the current character, it is not a string, number, array, or object\n\nThe current character read is 'b' with an int value of 98\nUnable to determine the current character, it is not a string, number, array, or object\nline number 1\nindex number 0\nbody\n^",
"stack-trace": "groovy.json.JsonException: Unable to determine the current character, it is not a string, number, array, or object\n\nThe current character read is 'b' with an int value of 98\nUnable to determine the current character, it is not a string, number, array, or object\nline number 1\nindex number 0\nbody\n^\n\tat org.apache.groovy.json.internal.JsonParserCharArray.decodeValueInternal(JsonParserCharArray.java:202)\n\tat org.apache.groovy.json.internal.JsonParserCharArray.decodeValue(JsonParserCharArray.java:153)\n\tat org.apache.groovy.json.internal.JsonParserCharArray.decodeFromChars(JsonParserCharArray.java:43)\n\tat org.apache.groovy.json.internal.JsonParserCharArray.parse(JsonParserCharArray.java:380)\n\tat org.apache.groovy.json.internal.BaseJsonParser.parse(BaseJsonParser.java:110)\n\tat Script234$_run_closure1.doCall(Script234.groovy:24)\n\tat com.onresolve.scriptrunner.runner.rest.common.UserCustomScriptEndpoint$_doEndpoint_closure2.doCall(UserCustomScriptEndpoint.groovy:225)\n\tat com.onresolve.scriptrunner.runner.rest.common.UserCustomScriptEndpoint$_doEndpoint_closure2.doCall(UserCustomScriptEndpoint.groovy)\n\tat com.onresolve.scriptrunner.runner.diag.DiagnosticsManagerImpl$DiagnosticsExecutionHandlerImpl$_execute_closure1.doCall(DiagnosticsManagerImpl.groovy:345)\n\tat com.onresolve.scriptrunner.runner.diag.DiagnosticsManagerImpl$DiagnosticsExecutionHandlerImpl$_execute_closure1.doCall(DiagnosticsManagerImpl.groovy)\n\tat com.onresolve.scriptrunner.runner.ScriptExecutionRecorder.withRecording(ScriptExecutionRecorder.groovy:13)\n\tat com.onresolve.scriptrunner.runner.ScriptExecutionRecorder$withRecording.call(Unknown Source)\n\tat com.onresolve.scriptrunner.runner.diag.DiagnosticsManagerImpl$DiagnosticsExecutionHandlerImpl.execute(DiagnosticsManagerImpl.groovy:343)\n\tat com.onresolve.scriptrunner.runner.rest.common.UserCustomScriptEndpoint.doEndpoint(UserCustomScriptEndpoint.groovy:215)\n\tat com.onresolve.scriptrunner.runner.rest.common.UserCustomScriptEndpoint.postUserEndpoint(UserCustomScriptEndpoint.groovy:123)\n",
"status-code": "INTERNAL_SERVER_ERROR"
}
Can someone help me?
Thanks a lot.
Hi @Николай Киселев ,
this row seems strange to me:
String jsonString = "body"
I think the variable jsonString would contain 4 characters "body" not the provided json data.
Hana, could you help me with the expression to add a comment to each found issue?
I guess I should make a list of found issuekeys, make each to object issue and for each create a comment
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.config.PriorityManager
import com.atlassian.jira.issue.fields.rest.json.beans.JiraBaseUrls
import com.atlassian.jira.issue.fields.rest.json.beans.CommentJsonBean
import com.atlassian.jira.issue.priority.Priority
import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.transform.BaseScript
import groovy.json.JsonBuilder
import org.codehaus.jackson.map.ObjectMapper
import groovy.json.JsonSlurper
import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response
import com.atlassian.jira.user.*;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.IssueManager;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.comments.CommentManager
import com.atlassian.jira.util.json.JSONObject
@BaseScript CustomEndpointDelegate delegate
doSomething(
httpMethod: "POST"
) { MultivaluedMap queryParams, String body ->
final SD_PUBLIC_COMMENT = "sd.public.comment" // needed for internal comments
CommentManager commentManager = ComponentAccessor.getCommentManager()
JsonSlurper slurper = new JsonSlurper()
Map parsedJson = slurper.parseText(body)
String idValue = parsedJson.issue
String idValue2 = parsedJson.get('summary')
def output = idValue2.findAll("SUP-[0-9]+") as List<Map> // creating a list of multiple issuekeys as string
def issueManager = ComponentAccessor.getIssueManager()
def issueObject = issueManager.getIssueObject(output).each { //I don't know how to get each found issue and create issueobject
//creating a comment
def properties = [(SD_PUBLIC_COMMENT): new JSONObject(["internal": true])]
commentManager.create(issueObject, loggedInUser, "my internal comment", null, null, new Date(), properties, true)
}
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I did some changes, editor doesn't show critical errors, but when I put my Json to the endpoint it returns error.
2020-08-04 14:04:40,296 ERROR [common.UserCustomScriptEndpoint]: ************************************************************************************* 2020-08-04 14:04:40,297 ERROR [common.UserCustomScriptEndpoint]: Script endpoint failed on method: POST doSomething java.lang.NullPointerException at com.atlassian.jira.issue.comments.DefaultCommentManager.create(DefaultCommentManager.java:251) at com.atlassian.jira.issue.comments.DefaultCommentManager.create(DefaultCommentManager.java:218) at com.atlassian.jira.issue.comments.CommentManager$create$2.call(Unknown Source) at Script193$_run_closure1$_closure2.doCall(Script193.groovy:49) at Script193$_run_closure1.doCall(Script193.groovy:45) at com.onresolve.scriptrunner.runner.rest.common.UserCustomScriptEndpoint$_doEndpoint_closure2.doCall(UserCustomScriptEndpoint.groovy:225) at com.onresolve.scriptrunner.runner.rest.common.UserCustomScriptEndpoint$_doEndpoint_closure2.doCall(UserCustomScriptEndpoint.groovy) at com.onresolve.scriptrunner.runner.diag.DiagnosticsManagerImpl$DiagnosticsExecutionHandlerImpl$_execute_closure1.doCall(DiagnosticsManagerImpl.groovy:345) at com.onresolve.scriptrunner.runner.diag.DiagnosticsManagerImpl$DiagnosticsExecutionHandlerImpl$_execute_closure1.doCall(DiagnosticsManagerImpl.groovy) at com.onresolve.scriptrunner.runner.ScriptExecutionRecorder.withRecording(ScriptExecutionRecorder.groovy:13) at com.onresolve.scriptrunner.runner.ScriptExecutionRecorder$withRecording.call(Unknown Source) at com.onresolve.scriptrunner.runner.diag.DiagnosticsManagerImpl$DiagnosticsExecutionHandlerImpl.execute(DiagnosticsManagerImpl.groovy:343) at com.onresolve.scriptrunner.runner.rest.common.UserCustomScriptEndpoint.doEndpoint(UserCustomScriptEndpoint.groovy:215) at com.onresolve.scriptrunner.runner.rest.common.UserCustomScriptEndpoint
.postUserEndpoint(UserCustomScriptEndpoint.groovy:123)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
and here is a script I got
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.config.PriorityManager
import com.atlassian.jira.issue.fields.rest.json.beans.JiraBaseUrls
import com.atlassian.jira.issue.fields.rest.json.beans.CommentJsonBean
import com.atlassian.jira.issue.priority.Priority
import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.transform.BaseScript
import groovy.json.JsonBuilder
import org.codehaus.jackson.map.ObjectMapper
import groovy.json.JsonSlurper
import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response
import com.atlassian.jira.user.*;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.IssueManager;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.comments.CommentManager
import com.atlassian.jira.util.json.JSONObject
import com.atlassian.jira.user.util.UserManager
@BaseScript CustomEndpointDelegate delegate
doSomething(
httpMethod: "POST"
) { MultivaluedMap queryParams, String body ->
final SD_PUBLIC_COMMENT = "sd.public.comment" // needed for internal comments
CommentManager commentManager = ComponentAccessor.getCommentManager()
def userManager = ComponentAccessor.getUserManager() as UserManager
def user = userManager.getUserByName("Kiseleff.trade")
log.info("obtained ${user}")
JsonSlurper slurper = new JsonSlurper()
Map parsedJson = slurper.parseText(body)
String idValue = parsedJson.issue
String idValue2 = parsedJson.get('summary')
String output = idValue2.findAll("SUP-[0-9]+") // creating a list of multiple issuekeys as string
def issueManager = ComponentAccessor.getIssueManager()
log.info("issue list ${output}")
output.each {
def issueObject = issueManager.getIssueObject(output)
def properties = [(SD_PUBLIC_COMMENT): new JSONObject(["internal": true])]
log.info("properties ${properties}")
commentManager.create(issueObject, user, "my internal comment3", null, null, new Date(), properties, true)
}
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Please, could you also attach your json file here? I need to know, how the structure of the file looks like, when there are more issue keys. Thank you.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Sure. Here is a incoming json
{
"any parameter": "#009900",
"summary": "jkrb23jkrb23jkb2jk3b SUP-1 rjk3b2sup-3k3rb3rjkb2rjkb3r2jkb SUP-3",
"iconUrl": "/images/icons/priorities/lowest.png",
"name": "Fred"
}
And the latest version of my script
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.config.PriorityManager
import com.atlassian.jira.issue.fields.rest.json.beans.JiraBaseUrls
import com.atlassian.jira.issue.fields.rest.json.beans.CommentJsonBean
import com.atlassian.jira.issue.priority.Priority
import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.transform.BaseScript
import groovy.json.JsonBuilder
import org.codehaus.jackson.map.ObjectMapper
import groovy.json.JsonSlurper
import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response
import com.atlassian.jira.user.*;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.IssueManager;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.comments.CommentManager
import com.atlassian.jira.util.json.JSONObject
import com.atlassian.jira.user.util.UserManager
@BaseScript CustomEndpointDelegate delegate
doSomething(
httpMethod: "POST"
) { MultivaluedMap queryParams, String body ->
final SD_PUBLIC_COMMENT = "sd.public.comment" // needed for internal comments
CommentManager commentManager = ComponentAccessor.getCommentManager()
def userManager = ComponentAccessor.getUserManager() as UserManager
def user = userManager.getUserByName("Kiseleff.trade")
log.info("obtained ${user}")
JsonSlurper slurper = new JsonSlurper()
Map parsedJson = slurper.parseText(body)
String idValue = parsedJson.issue
String idValue2 = parsedJson.get('summary')
String output = idValue2.findAll("SUP-[0-9]+") as List<String> // creating a list of multiple issuekeys as string
def issueManager = ComponentAccessor.getIssueManager()
log.info("issue list ${output}")
for (item in output) {
def ddd = output.toString()
def issueObject = issueManager.getIssueObject(ddd)
def properties = [(SD_PUBLIC_COMMENT): new JSONObject(["internal": true])]
commentManager.create(issueObject, user, "my internal comment", null, null, new Date(), properties, true)
}
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi,
just tested the code below with the provided json, works for me.
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.comments.CommentManager
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.util.json.JSONObject
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.user.util.UserManager
import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.json.JsonSlurper
import groovy.json.JsonBuilder
import groovy.transform.BaseScript
import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response
@BaseScript CustomEndpointDelegate delegate
doSomething(httpMethod: "POST") { MultivaluedMap queryParams, String body ->
final String SD_PUBLIC_COMMENT = "sd.public.comment" // needed for internal comments
final String REGEX = "SUP-[0-9]+"
final String USERNAME = "Kiseleff.trade"
final String COMMENT_BODY = "my internal comment"
CommentManager commentManager = ComponentAccessor.getCommentManager()
IssueManager issueManager = ComponentAccessor.getIssueManager()
UserManager userManager = ComponentAccessor.getUserManager()
ApplicationUser user = userManager.getUserByName(USERNAME)
Map<String,JSONObject> commentProperties = [(SD_PUBLIC_COMMENT): new JSONObject(["internal": true])]
JsonSlurper jsonSlurper = new JsonSlurper()
String summaryValue = jsonSlurper.parseText(body).summary
summaryValue.findAll(REGEX).each {issueKey ->
Issue issue = issueManager.getIssueObject(issueKey)
commentManager.create(issue, user, COMMENT_BODY, null, null, new Date(), commentProperties, true)
}
return Response.ok(new JsonBuilder([abc: 42]).toString()).build()
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hana,
thank you very much. I appreciate your patience.
Now it works like a charm!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hello,
I processed with the script. Now I can gather issuekeys from the text field. But I don't know how to add a comments and transition found issues
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.config.PriorityManager
import com.atlassian.jira.issue.fields.rest.json.beans.JiraBaseUrls
import com.atlassian.jira.issue.fields.rest.json.beans.CommentJsonBean
import com.atlassian.jira.issue.priority.Priority
import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.transform.BaseScript
import groovy.json.JsonBuilder
import org.codehaus.jackson.map.ObjectMapper
import groovy.json.JsonSlurper
import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response
import com.atlassian.jira.user.*;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.IssueManager;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.comments.CommentManager
@BaseScript CustomEndpointDelegate delegate
doSomething(
httpMethod: "POST"
) { MultivaluedMap queryParams, String body ->
JsonSlurper slurper = new JsonSlurper()
Map parsedJson = slurper.parseText(body)
String idValue = parsedJson.issue
log.info(idValue)
String idValue2 = parsedJson.get('issue')
def output = idValue2.findAll("SUP-[0-9]+")
def IssueManager issueMgr = ComponentAccessor.getIssueManager();
Issue issue = issueMgr.getIssueObject('output')
//and here is a comment added and all found issues will be transitioned to in progress
}
I appreciate any help.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi,
you need to add something like this:
import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.workflow.JiraWorkflow
import com.atlassian.jira.issue.IssueInputParameters
ApplicationUser loggedInUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
CommentManager commentManager = ComponentAccessor.getCommentManager()
// comment issue
String commentBody = 'comment text'
commentManager.create(issue, loggedInUser, commentBody, false)
// transition issue
IssueService issueService = ComponentAccessor.getIssueService()
JiraWorkflow workflow = ComponentAccessor.getWorkflowManager().getWorkflow(issue)
IssueInputParameters issueInputParameters = issueService.newIssueInputParameters()
String actionName = 'In Progress'
int actionId = workflow.getAllActions().findByName(actionName)?.getId()
IssueService.TransitionValidationResult transitionValidationResult = issueService.validateTransition(loggedInUser, issue.getId(), actionId, issueInputParameters)
assert transitionValidationResult.isValid(): transitionValidationResult.errorCollection
IssueService.IssueResult transitionResult = issueService.transition(loggedInUser, transitionValidationResult)
assert transitionResult.isValid(): transitionResult.errorCollection
Issue comment is quite easy, status change is more complicated, you need to provide id of the workflow transition, you want to perform.
There are a lot of nice examples available at library.adaptavist.com, e.g.:
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hana, thank you.
I tested adding a comments but unfortunately I can't add a comment. Could you take a look?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi,
the first parameter in the create function must be issue object, but according to the error message you are passing String variable. You need to obtain issue object somehow. Where exactly are you trying to test this script? It is still the rest enpoint section?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
No, it is just a console. I want to test it before. Here is a script:
import com.atlassian.jira.user.*;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.IssueManager;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.comments.CommentManager
ApplicationUser loggedInUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
CommentManager commentManager = ComponentAccessor.getCommentManager()
def issueManager = ComponentAccessor.getIssueManager()
def issue = "SUP-1"
def issueObject = issueManager.getIssueObject(issue)
// comment issue
String commentBody = 'comment text'
commentManager.create(issue, loggedInUser, commentBody, false)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Just replace "issue" with "issueObject" like this and it should work:
commentManager.create(issueObject, loggedInUser, commentBody, false)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Comment done. There was incorrect variable in the create method. fixed with:
commentManager.create(issueObject, loggedInUser, commentBody, false)
now I am going to check rest endpoint with the comments
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.