Work with Application Links
HAPI provides a simpler method of working with other Atlassian products that have been connected via Application Links (app link). HAPI is optimized for the most common integration solutions, such as making requests over an app link configured with OAuth (with impersonation) authentication.
The steps to making a request over an app link are:
- Select the app link.
For exampleApplicationLinks.primaryJiraLink
, orApplicationLinks.getByName('Dogfood Jira')
- Execute a request using the extension method
com.adaptavist.hapi.jira.extensions.ApplicationLinkExtensions#executeRequest
Working with Confluence
Create a page and add an attachment to the page
In the following example, we're using the Confluence REST API to create a page and then add an attachment to that page.
To find the key for your Confluence space, go to Space tools > Overview.
import static com.atlassian.sal.api.net.Request.MethodType.POST
import com.atlassian.sal.api.net.RequestFilePart
def confluenceLink = ApplicationLinks.primaryConfluenceLink
def pageResponse = confluenceLink.executeRequest(POST, 'rest/api/content') {
setHeader('Content-Type', 'application/json')
setEntity([
type : 'page',
title: 'new page',
space: [
key: 'AAA'
],
body : [
storage: [
value : "<p>This is <br/> a new page</p>",
representation: "storage"
]
]
])
} as Map
def pageId = pageResponse.id
def filePart = new RequestFilePart(new File('/path/to/screenshot.png'), 'file')
confluenceLink.executeRequest(POST, "rest/api/content/${pageId}/child/attachment") {
addHeader("X-Atlassian-Token", "no-check")
setFiles([filePart])
}
Create a page for every subtask of a Jira issue and add a label
Run the following script in the Script Console to create a page with labels for Jira issues:
import static com.atlassian.sal.api.net.Request.MethodType.GET
def spaceToCreatePagesIn = 'HT'
def issueKey = 'HAPI-1'
def subTasks = ApplicationLinks.primaryJiraLink.executeRequest(GET, "/rest/api/2/issue/$issueKey/subtask") as List<Map<String,String>>
subTasks.each {
Pages.create(spaceToCreatePagesIn, "${it.key} - ${it.fields.summary}") {
setLabels("hapi")
}
}
After you run the script and open the space, you'll see a page with labels created for each sub-task on the issue that you assigned in the script:
The Jira task and subtasks are untouched and appear like this:
Customize this script
You can customize the Confluence space, the Jira issue key, and the label of this script:
import static com.atlassian.sal.api.net.Request.MethodType.GET
def spaceToCreatePagesIn = 'SPACEKEY'
def issueKey = 'ISSUEKEY'
def subTasks = ApplicationLinks.primaryJiraLink.executeRequest(GET, "/rest/api/2/issue/$issueKey/subtask") as List<Map<String,String>>
subTasks.each {
Pages.create(spaceToCreatePagesIn, "${it.key} - ${it.fields.summary}") {
setLabels("LABEL")
}
}
Working with Jira
In the following example, make a request to get the current user via the primary Jira app link. The primary Jira app link is the Jira application link that is marked with PRIMARY
when you're on the Application Links page.
import static com.atlassian.sal.api.net.Request.MethodType.GET
def result = ApplicationLinks.primaryJiraLink.executeRequest(GET, '/rest/auth/1/session') as Map
def userName = result.name
The result is coerced to a map, list, or whatever is appropriate. If you request XML, you will be returned a groovy.util.slurpersupport.GPathResult
.
Making requests as a different user
You can make the request as a different user by utilizing Users.runA
s. For example :
import static com.atlassian.sal.api.net.Request.MethodType.GET
def result = Users.runAs('anuser') {
ApplicationLinks.primaryJiraLink.executeRequest(GET, '/rest/auth/1/session') as Map
}
assert result.name == 'anuser'
Making a POST request
You can make a post request as well as GET
requests (as we have done previously). To make a POST request set the Content-Type
header, typically to application/json
, and provide a Map or List to setEntity
, this converts to JSON automatically. In the following example, we're making a POST request and creating an issue in the connected Jira instance.
See the documentation for Creating an Issue.
import static com.atlassian.sal.api.net.Request.MethodType.POST
def result = ApplicationLinks.primaryJiraLink.executeRequest(POST, '/rest/api/2/issue') {
setHeader('Content-Type', 'application/json')
setEntity([
fields: [
project : [
key: 'SR',
],
summary : 'Help me!',
issuetype: [
name: 'Task'
]
]
])
} as Map
def issueKey = result.key
Creating attachments in Jira
In the following example, we're creating an attachment for a specific issue in the connected Jira instance.
import static com.atlassian.sal.api.net.Request.MethodType.POST
import com.atlassian.sal.api.net.RequestFilePart
// note the 'file' string as the second argument is important, and should not be anything other than 'file'
def filePart = new RequestFilePart(new File('/path/to/screenshot.png'), 'file')
def issueKey = 'SR-100'
ApplicationLinks.primaryJiraLink.executeRequest(POST, "/rest/api/2/issue/${issueKey}/attachments") {
addHeader("X-Atlassian-Token", "no-check")
setFiles([filePart])
}
Handling errors
If a request is not successful (that is, a response status code greater than 400 or less than 200), an exception is thrown. The response body will be parsed into a map or whatever is appropriate. In the following example, not all mandatory fields have been entered for creating an issue.
import static com.atlassian.sal.api.net.Request.MethodType.POST
import com.adaptavist.hapi.platform.applinks.exceptions.AppLinkResponseException
try {
def result = ApplicationLinks.primaryJiraLink.executeRequest(POST, '/rest/api/2/issue') {
setHeader('Content-Type', 'application/json')
setEntity([
fields: [
// note: project is missing
summary : 'Help me!',
issuetype: [
name: 'Task'
]
]
])
} as Map
} catch (AppLinkResponseException e) {
assert (e.entity as Map<String, Map>).errors.project == 'project is required'
assert e.response.statusCode == 500
}
You also have access to the Response object through the exception, as shown.