Hello Atlassian Community!
Just looking for a bit of guidance to know whether something is possible.
It relates to JIRA and Confluence in the cloud and automation. I know there are products like Bob Swift's addons that might do the job, but I don't want to wade through the documentation to find out (and I'm not technical enough to know from looking at it whether it will do what I want or not).
Anyway, here I go:
From a Jira record, I want to be able to click on a button (or trigger it in some way), to create a Confluence page based on a template. The name of the page should be the same as the Jira Summary field. Embedded on the Confluence template is a Jira Issue/Filter Macro with a JQL query in it - in that query, I want to insert the key of the Jira record into that query (the rest of the query needs to stay there). When the new Confluence page is published, then I want to copy the URL (preferably the shorten URL) of that page and insert it into a URL field on the Jira record.
At the moment this is all done manually and it isn't the nicest thing for normal users to do. So if I can automate it, it would be fantastic.
So, is it possible?
Many Thanks
David
Hi David,
After going through your requirements, understood that we can do automation of the tasks and tried to achieve them by using our app 'Run CLI actions for jira'.
Confluence page creation is possible based on the transition. But it cannot be created based on a template.
Please do the implementation as specified below.
1) Create a postfunction, through which we can create confluence page and its name can set as same as the Jira Summary field.
Please create an application link with a name like, 'Jira-Test' which links Jira and Confluence.
Inside the workflow, please create a screen and in its comment field, we need to enter jira issue-id and associate the screen with your workflow.
Please use the below action in your post function.
--action addPage --space "GT" --title "%original_summary%" --content "<ac:structured-macro ac:macro-id='a348d484-8df5-4fde-b950-23b52aee8c7b' ac:name='jira' ac:schema-version='1'><ac:parameter ac:name='server'>Jira-Test</ac:parameter><ac:parameter ac:name='columns'>key,summary,type,created,updated,due,assignee,reporter,priority,status,resolution</ac:parameter><ac:parameter ac:name='key'>%transition_comment%</ac:parameter></ac:structured-macro>" --noConvert
2) Inside the post function, please provide a JQL query to fetch your Jira issue.
After making changes, please publish the post function.
3) Once the transition happens in the Jira issue, we can see a confluence page created (page name matches with corresponding jira issue summary field) inside your space. In the jira issue, you can see the confluence page is linked in its Issue Links section.
Please let us know if you have any questions. We are happy to help you.
Regards,
Raja
Hi David,
Thank you for your response.
I can confirm that it is possible to create a Confluence Cloud page from Jira Cloud using the ScriptRunner for Cloud add on and that we have an example script which shows how to do this in the documentation page here.
This example is a Script Console script but you will be able to take this and adapt it to include it inside of a Script Listener or a Post Function to suit your requirement.
If this response has answered your question can you please mark it as accepted so that other users can see it is correct when searching for similar answers.
Regards,
Kristian
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Kristian
Would I need both ScriptRunner for both Jira and Confluence?
Will ScriptRunner be able to make changes to a macro within the Confluence template? Eg: I have a Jira Issue/Filter Macro with a JQL query in it in the Confluence template and all I need to do is add to the filter the Key of a Jira issue.
Also, will ScriptRunner allow me to automate making a set of configuration changes to a Jira instance, eg: add custom fields, add fields to screens, create workflows, set up projects, etc.
Thanks
David
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @David Stokes ,
I don't know if it helps in Cloud, as my implementation of this is in Server. I assume though that with a bit of tinkering you could sort it out.
For my implementation I have used ScriptRunner for Jira. I've also used guidelines from this article.
My use case is this:
Since I was not able to get the template from Confluence's saved templates, instead I created a dummy page, with the complete styling/layout and macros that I wanted and took the body.storage content from it and used it in my Script Listener.
Dummy page
To get the body.storage you can do a simple curl or navigate to the url
https://yourConfluenceURL/rest/api/content/?spaceKey=yourSpaceKey&title=yourPageTitle&expand=body.storage
You need the "value".Looks something like this
After you get the template, modify it to include some variable names. Example might be the issue key. In my case was AA-20. So I simply replaced AA-20 with "varKey" so I could later work with it in the script. And so on for other fields.
From there, the only missing link is the code for the script listener itself:
import com.atlassian.applinks.api.ApplicationLink
import com.atlassian.applinks.api.ApplicationLinkService
import com.atlassian.applinks.api.application.confluence.ConfluenceApplicationType
import com.atlassian.jira.issue.Issue
import com.atlassian.sal.api.component.ComponentLocator
import com.atlassian.sal.api.net.Request
import com.atlassian.sal.api.net.Response
import com.atlassian.sal.api.net.ResponseHandler
import com.atlassian.sal.api.net.ResponseException
import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
import com.atlassian.jira.component.ComponentAccessorIssue issue = event.issue
if(issue.getIssueType().getName() != 'Epic'){
return
}static ApplicationLink getPrimaryConfluenceLink(){
def applicationLinkService = ComponentLocator.getComponent(ApplicationLinkService.class)
final ApplicationLink confLink = applicationLinkService.getPrimaryApplicationLink(ConfluenceApplicationType.class)
confLink
}//confluence link
def confluenceLink = getPrimaryConfluenceLink()
assert confluenceLink
def authenticatedRequestFactory = confluenceLink.createImpersonatingAuthenticatedRequestFactory()def pageBodyTemplate="" //put here the value your retrieved from the dummy page.
pageBodyTemplate= pageBodyTemplate.replace("varKey", issue.getKey()).replace("varPriority",issue.priority.name).replace("varStatus",issue.status.name) //first replace system fields, then check if others exist
def parentPageId = 50331675 //hard coded id of Ancestor Page as I want this page to be a child
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def area = issue.getCustomFieldValue(customFieldManager.getCustomFieldObjectByName('Area'))
def sponsor = issue.getCustomFieldValue(customFieldManager.getCustomFieldObjectByName('Sponsor'))
if(issue.getAssignee()){pageBodyTemplate = pageBodyTemplate.replace("varAssignee",issue.assignee.displayName)}else{pageBodyTemplate = pageBodyTemplate.replace("varAssignee","")}
if(area){pageBodyTemplate = pageBodyTemplate.replace("varArea",((String)area.get(null) + " - " + (String)area.get("1")).replace("&", "&"))}else{pageBodyTemplate = pageBodyTemplate.replace("varArea","")}
if(sponsor){pageBodyTemplate = pageBodyTemplate.replace("varSponsor",sponsor.displayName)}else{pageBodyTemplate = pageBodyTemplate.replace("varSponsor","")}def params =[
type:"page"
,title:issue.summary
,space:[
key:issue.getProjectObject().key //same key for both Confluence Space and Jira Project
]
,ancestors: [[id: parentPageId]]
,body:[
storage: [
value: pageBodyTemplate,
representation: "storage"
],
],
]authenticatedRequestFactory
.createRequest(Request.MethodType.POST, "rest/api/content")
.addHeader("Content-Type", "application/json")
.setRequestBody(new JsonBuilder(params).toString())
.execute(new ResponseHandler<Response>() {
@Override
void handle(Response response) throws ResponseException{
if(response.statusCode != HttpURLConnection.HTTP_OK){
def commentManager = ComponentAccessor.getCommentManager()
def robotUser = ComponentAccessor.getUserManager().getUserByKey('robotUser')
String commentBody = "*Failed to create Confluence page via API due to exception:*\n" + response.getResponseBodyAsString() + "\n\n*Contact your Jira Administrator!*"
commentManager.create(issue, robotUser,commentBody , null, null, true)
}else{
//after page created - update label (since not possible in 1 call to create with label)
String pageId = new JsonSlurper().parseText(response.responseBodyAsString)["id"]
authenticatedRequestFactory
.createRequest(Request.MethodType.POST, "rest/api/content/"+pageId+"/label")
.addHeader("Content-Type", "application/json")
.setRequestBody(new JsonBuilder(["prefix": "global","name": "yourDesiredLabelGoesHere"]).toString())
.execute()
}
}
})
//x
I hope I was clear enough :)
Cheers
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@David Stokesfor the URL or other Confluence response parts I can also share the script for something similar, but go ahead and try if this implementation actually works for you.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@Gezim Shehu [Communardo] - thanks so much for that - it's great to know that there is the ability to do things like this. Looks like I'm going to need to do some learning and experimenting to see if I can make the specific changes to the Confluence page.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Online forums and learning are now in one easy-to-use experience.
By continuing, you accept the updated Community Terms of Use and acknowledge the Privacy Policy. Your public name, photo, and achievements may be publicly visible and available in search engines.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.