Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

Confluence Scriptrunner Macro API: Upload an attachment (JQuery) Example.

IT Support December 24, 2020

Confluence Scriptrunner Macro API: Upload an attachment (JQuery) Example.

Please can someone advise me if it is possible to upload an attachment via an API using JQuery within a Confluence SR Macro?

I have successfully created a new page using the following example:

 var jsondata = {"type":"page",
"title":"My Test Page1",
"space":{"key":"TST"},
"body":{"storage":{"value":"<p>This is a TEST new page</p>","representation":"storage"}}};

AJS.$.ajax({
url: "https://confluence_server:8100/confluence/rest/api/content/",
type: "POST",
data:JSON.stringify(jsondata),
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function(msg){
console.log("Success !");
}
});  

The Atlassian Documentation:

Confluence REST API examples (atlassian.com)

Gives a curl example:

curl -v -S -u admin:admin -X POST -H "X-Atlassian-Token: no-check" -F "file=@myfile.txt" -F "comment=this is my file" "http://localhost:8080/confluence/rest/api/content/3604482/child/attachment" | python -mjson.tool

Please can you also advise what upload file paths are allowed for Windows Edge Chromium Browser i.e:

1)    file : "//confluenec_server/temp/test.txt"

2)    file : "file://localserver/temp/test.txt"

 

1 answer

1 vote
Jonny Carter
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
January 8, 2021

So, this is an interesting question, and the answer may vary a little bit, depending on your use case. I'd like to hear a bit more about the why and what of what you're trying to accomplish.

Still, I can give you at least a couple of pointers on the "how".

I've created a very simple scripted macro for this example. It adds a form to the page that lets the end user upload an attachment to the page that they are on. Obviously, that's not very useful by itself, but it at least should give some idea how to interact with Confluence's REST API for attachments from JavaScript.

The macro's Groovy code is:

import groovy.xml.MarkupBuilder

def writer = new StringWriter()
def builder = new MarkupBuilder(writer)
builder.form(class: "avatar-uploader") {
input(type: "file", class: "avatar-image", name: "file", accept: "image/png, image/jpeg")
button(class: "avatar-submit", type: 'button', "Upload attachment")
}

return writer.toString()

The JavaScript code is. I've left some rough console.log statements in there, just to help you follow the execution if you want to try it out.

AJS.toInit(($) => {
console.log("Running intialization function");
$('.avatar-uploader').each((index, $rootForm) => {
console.log("Found avatar form", $rootForm);
const submitButton = $rootForm.querySelector('button');
console.log("Found submit button", submitButton);
submitButton.addEventListener("click", clickEvent => {
console.log("Clicked the button!");
clickEvent.preventDefault();
const pageId = Confluence.getContentId();
console.log("Page id:", pageId);
const formData = new FormData($rootForm);
fetch(`${AJS.contextPath()}/rest/api/content/${pageId}/child/attachment`, {
method: "POST",
credentials: 'same-origin',
headers: {
'X-Atlassian-token': 'no-check',
},
body : formData
}).then(response => console.log("Response", response));
});
});
});

The result should look something like this:

example script macro to upload attachments.png

I assume that for your use case, you'll want to do things like target a different page for the attachments, or something along those lines. That could be accomplished by adjusting the pageId variable in the above JavaScript.

Best of luck!

IT Support January 12, 2021

Hi Jonny

Many thanks for you example. This works really well!

My Confluence page has a 'Select2' Dropdown Picker('select2-multiple') created by a Confluence Scriptrunner Macro. This Gets the JSON Metadata from a Confluence Scriptrunner Rest Endpoint(External MS SQL Stored Procedure).

I have the selected file URL( "localserver/temp/test.txt") to automatically add  as an attachment to the Context  PageID. This is also obtained from another Confluence Scriptrunner Rest Endpoint(External MS SQL Stored Procedure).

Please can you advise how I can change the script below:

const formData = new FormData($rootForm);
fetch(`${AJS.contextPath()}/rest/api/content/${pageId}/child/attachment`, {
method: "POST",
credentials: 'same-origin',
headers: {
'X-Atlassian-token': 'no-check',
},
body : formData
}).then(response => console.log("Response", response));

Can I automatically add the attachment details (File URL) to the formData object without the need for the input control?

Or Instead of passing formData object, is it possible to construct the required attachment File:value?

Below is a quick crude test example, I used  to see if I could add a custom property value to a Confluence Page:

Example: Select2 Data =  {key: "", value: "[{"text":"File Name"}]"}

AJS.$('#select2-multiple').change(function() {
var dropdownData = {};
dropdownData.key = '';
const myObjStr = JSON.stringify($(this).select2('data'));
dropdownData.value = myObjStr;
console.log(dropdownData);
AJS.$.ajax({
url: "https://srvxxxxxx:8xxx/confluence/rest/api/content/26804233/property/my-property",
type: "POST",
data:JSON.stringify(dropdownData),
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function(msg){
console.log("Success !");
}
});
});

Please can you advise the best way forward?

Best Regards

Jonathan.

IT Support January 18, 2021

Updated:

For Security Reasons I have completely changed my approach for this requirement.

Many Thanks.

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events