I have ScriptRunner installed on a Confluence server and I want to be able to create a page via the REST API. All of the examples I see creating a Confluence page are setup to run from Jira to create a discussion page or assume there is an Application Link setup for the Confluence site, but I want to create directly from the Confluence Script Runner.
This is what I have so far, but it won’t work as it complains about the authentication part
import com.atlassian.applinks.api.ApplicationLink
import com.atlassian.applinks.api.ApplicationLinkService
import com.atlassian.applinks.api.application.confluence.ConfluenceApplicationType
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
import groovy.json.JsonSlurper
def confluenceLink = getPrimaryConfluenceLink()
assert confluenceLink // must have a working app link set up
def authenticatedRequestFactory = confluenceLink.createImpersonatingAuthenticatedRequestFactory()
// set the page title - this should be unique in the space or page creation will fail
def pageTitle = "Teset Discussion"
def pageBody = """h3. Test
{quote}This is a quote{quote}
Yada yada, use this page to discuss the above...
"""
def params = [
type: "page",
title: pageTitle,
space: [
key: "COM" // set the space key - or calculate it from the project or something
],
/* // if you want to specify create the page under another, do it like this:
ancestors: [
[
type: "page",
id: "14123220",
]
],*/
body: [
storage: [
value: pageBody,
representation: "wiki"
],
],
]
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) {
throw new Exception(response.getResponseBodyAsString())
}
else {
def webUrl = new JsonSlurper().parseText(response.responseBodyAsString)["_links"]["webui"]
}
}
})
@Panos since this is being executed through the Admin console, does it need auth at all? Are you aware of any documentation that talks through how to do this with ScriptRunner? I feel like the example I’m going off of is too specific to the external app setup.
Something strange was that my Confluence was not displaying the logs in Script Console, but they were logged in the atlassian-confluence.log.
The below code worked in a Confluence 6.11.2 with Scriprunner 5.4.26. You will need to change some parameter such as your credential,confluence url and page json body. I suggest you to use Postman to test tour body payload.
PS: This could be without scriptrunner by JAVA/NodeJS/Python or any other language through REST API.
import groovyx.net.http.RESTClient
import static groovyx.net.http.ContentType.JSON
import groovy.json.JsonSlurper
import groovy.json.JsonOutput
import groovyx.net.http.HttpResponseException
import groovyx.net.http.HttpResponseDecorator
import java.util.Base64
import java.util.Base64.Encoder
def url = "http://localhost:8090/rest/api/content/"
def client = new RESTClient(url)
//Change to match your username/password
def authBasic = Base64.getEncoder().encodeToString(("USERNAME"+":"+"PASSWORD").getBytes());
// Change this json to match what you need
// This is creating a simple page in DEMO space
def jsonObj = new JsonSlurper().parseText('{"type":"page","title":"new page","space":{"key":"DEMO"},"body":{"storage":{"value":"<p>This is <br/> a new page</p>","representation":"storage"}}}')
try{
HttpResponseDecorator response = (HttpResponseDecorator) client.post(path: "/rest/api/content/",
contentType: JSON,
body: jsonObj,
headers: [Accept: 'application/json',Authorization:"Basic ${authBasic}"]);
log.error("Status: " + response.status)
if (response.data) {
log.error("Content Type: " + response.contentType)
log.error("Headers: " + response.getAllHeaders())
log.error("Body:\n" + JsonOutput.prettyPrint(JsonOutput.toJson(response.data)))
}
}
catch(HttpResponseException e){
log.error e.getResponse().getData()
}