Automation of functions across Jira and Confluence

David Stokes April 10, 2019

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

3 answers

0 votes
Deleted user April 16, 2019

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

0 votes
Kristian Walker _Adaptavist_
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
April 11, 2019

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

David Stokes April 11, 2019

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

0 votes
Gezim Shehu [Communardo]
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
April 11, 2019

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:

  1. User creates a new issue (fills in some fields)
  2. Only for certain issue types, I want to create a new Confluence page, linking it to the current Jira issue, getting both info from the issue as direct values, but also using Confluence Jira macros
  3. A Script Listener which does step2 , is listening for the Issue Created event
  4. I have also another listener for the Issue Updated event, to update the page properties of the linked Confluence page. But I assume this is not useful to you.

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

1.PNG

 

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

2.PNG

 

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.ComponentAccessor

Issue 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("&", "&amp;"))}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

Gezim Shehu [Communardo]
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
April 11, 2019

@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.

David Stokes April 11, 2019

@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.

Suggest an answer

Log in or Sign up to answer