valiantys-logo
Back

Advanced tips: creating a linked Confluence space

Atlassian has two flavours of JIRA and Confluence, cloud and server, and whilst these are mostly comparable, the Cloud version sometimes gets extra functionality which for whatever reason is not made available in the server version. One of these features is the ability to create a linked Confluence space during project creation in JIRA, and in this post I’ll show you how we can emulate this on the server version.

Where is my space?

So you need to create a new JIRA project and create a linked space in Confluence without leaving JIRA? Well, as long as you have JIRA cloud and Confluence cloud, this is pretty simple – just leave the “Confluence space” option on the Create Project dialogue checked, as shown below:

JIRA Cloud allows you to create a corresponding Confluence space

Unfortunately if you have the server version, this functionality is not available. This means you’re stuck with the manual method: Create your JIRA project, then switch to Confluence and create a corresponding space. Wouldn’t it be great if we could replicate the JIRA cloud functionality on our own server?

Let’s get technical!

With a little help from our favourite scripting add-on, ScriptRunner for JIRA, we can add this functionality into the server version.

Most operations within JIRA cause an event to be fired and one of those is the ProjectCreatedEvent, which we’ll be making use of in a scripted listener.

If you haven’t already, install the ScriptRunner add-on into your JIRA instance and then navigate to the Add-ons->Script Listeners screen and click on Custom listener.

Add a note about what this listener does, select All projects from the Project Key selection and then select the ProjectCreatedEvent from the Events list.

Screen Shot 2016-07-22 at 17.39.47

Copy the following Groovy script into the Inline script field.

import com.atlassian.applinks.api.ApplicationLink
import com.atlassian.applinks.api.ApplicationLinkService
import com.atlassian.applinks.api.application.confluence.ConfluenceApplicationType
import com.atlassian.jira.applinks.JiraAppLinksHostApplication
import com.atlassian.jira.event.ProjectCreatedEvent
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.ResponseException
import com.atlassian.sal.api.net.ResponseHandler
import groovy.json.JsonBuilder

/**
 * Retrieve the primary confluence application link
 * @return confluence application link
 */
def ApplicationLink getPrimaryConfluenceLink() {
    def applicationLinkService = ComponentLocator.getComponent(ApplicationLinkService.class)
    return applicationLinkService.getPrimaryApplicationLink(ConfluenceApplicationType.class)
}

def confluenceLink = getPrimaryConfluenceLink()
// we must have a working application link set up to proceed
assert confluenceLink

def event = event as ProjectCreatedEvent
def params = [
    key: event.project.key,
    name: event.project.name,
    description: [
        plain: [
            value: "Space created automatically for ${event.project.key} project on " + new Date().format("dd/MMM/yyyy HH:mm"),
            representation: "plain"
        ]
    ]
]

// make the REST API call to Confluence to create the space
def authenticatedRequestFactory = confluenceLink.createAuthenticatedRequestFactory()
authenticatedRequestFactory
    .createRequest(Request.MethodType.POST, "rest/api/space")
    .addHeader("Content-Type", "application/json")
    .setRequestBody(new JsonBuilder(params).toString())
    .execute(new ResponseHandler() {
        @Override
        void handle(Response response) throws ResponseException {
            if(response.statusCode != HttpURLConnection.HTTP_OK) {
                throw new Exception(response.getResponseBodyAsString())
            }
        }
	})

// Beyond this point we use non-public REST API calls
// Create reciprocal link to Confluence space
def linkRequest = [
    applicationId: ComponentLocator.getComponent(JiraAppLinksHostApplication.class).id.get(),
    key: event.project.key,
    name: event.project.name,
    typeId: "jira.project"
]

// Make the REST API call to Confluence to link the project and space
authenticatedRequestFactory
	.createRequest(Request.MethodType.PUT, "rest/applinks/1.0/entitylink/com.atlassian.applinks.api.application.confluence.ConfluenceSpaceEntityType/${event.project.key}?reciprocate=true")
	.addHeader("Content-Type", "application/json")
	.setRequestBody(new JsonBuilder(linkRequest).toString())
	.execute(new ResponseHandler() {
        @Override
        void handle(Response response) throws ResponseException {
            if(response.statusCode != HttpURLConnection.HTTP_CREATED) {
                throw new Exception(response.getResponseBodyAsString())
            }
        }        
    })

Next, create your project as per normal. Upon successful creation, you’ll be taken to your new project and notified that both a JIRA project and Confluence space have been created.

Screen Shot 2016-07-22 at 11.20.30

Screen Shot 2016-07-26 at 13.04.57

Finally, click on the link in the notification and verify that your new space is created in Confluence with the same name as your JIRA project!

Screen Shot 2016-07-22 at 17.48.26

Don’t forget that to make this all possible, your JIRA and Confluence need to be connected using Application Links.

Are there any similar tips or hacks you’ve implemented? Tell us in the comments below!

Cutted Triangle

Subscribe to Valiantys Newsletter

Registered request ! Subscribing... This is not an email An error occured

In accordance with our privacy policy, we are committed to respecting your personal data.

Contact us

Our Atlassian certified consultants will be happy to answer you.

Join us

We're building the next dream team - Are you in?

Follow us

We use cookies for the operation of our website. This is to improve its use, to personalize your experience, and to compile visitor statistics. By continuing to use this site, you consent to this policy. You can manage the settings and choose whether or not to accept certain cookies whilst browsing. For more information, see our privacy policy. Our privacy policy

Privacy settings

In order to facilitate your navigation and to provide you with the best possible service, we use cookies to improve the site to the needs of our visitors, particularly according to the number of visitors. For more information, please read our privacy policy. Our privacy policy

Recaptcha

Google reCAPTCHA is a system designed to distinguish humans from computers, so that bots are unable to maliciously fill out forms on behalf of a human being.

Analytics

Used to send data to Google Analytics about the visitor's device and behavior. Tracks the visitor across devices and marketing channels. Used by the social sharing platform AddThis to store the user's usage history of the AddThis sharing widget. Registers a unique ID that is used to generate statistical data on how the visitor uses the website.