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"
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:
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!
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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Updated:
For Security Reasons I have completely changed my approach for this requirement.
Many Thanks.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Online forums and learning are now in one easy-to-use experience.
By continuing, you accept the updated Community Terms of Use and acknowledge the Privacy Policy. Your public name, photo, and achievements may be publicly visible and available in search engines.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.