I upload a file via atlassian-connect-express to a confluence attachment, from a dynamic content macro.
this.httpClient(userAccountId).post('/rest/api/content/{id}/child/attachment', input);
input is
{
pathParameters: {
id: confluencePageId
},
formdata: {
file: [
stream,
{
filename: `File-${processId}`
}
]
},
headers: {
'X-Atlassian-Token': 'nocheck',
'Content-Type': 'multipart/form-data'
}
}
That works fine. Unless I try this from a macro that has been created in a not yet published draft of a confluence page.
Two questions:
- Is it possible to use this endpoint with drafts
- If not, how can I determine from a dynamic content macro (custom editor) if the enclosing Confluence page is a draft and has never been published before?
1 Like
Hi @m.schmidt ,
I haven’t actually tested the following - it is based on my reading of the API.
POST /wiki/rest/api/content/{id}/child/attachment takes a query parameter status
which defaults to current
if not provided, but can be set to draft
when the attachment should be added as part of the current draft. If your dynamic content macro is adding the attachment, then I suspect you always should set the status=draft
query parameter so that the attachment occurs as part of the user’s drafting of the page.
By the way, to determine whether the page has not yet been published, you can call AP.context.getContext()
and observe the property confluence.content.version
. If the version is 1
, then the page has not yet been published. Alternatively, there’s a content.version
context parameter which you can use so long as the macro is not declare as cacheable: true
.
Regards,
Dugald
Your reply is very useful for me. Thank you.
As you mentioned, creating attachment to draft page can be done with POST /wiki/rest/api/content/{id}/child/attachment setting status=draft.
However, when I create a new page, the attached files to the draft page are lost.
Created page doesn’t have the attachments that the draft has.
I create pages via REST API POST /rest/api/content setting id=DraftPageId.
My steps are,
- create draft with POST /wiki/rest/api/content setting status=draft.
- attach file with POST /wiki/rest/api/content/{id}/child/attachment setting status=draft.
- create page with POST /wiki/rest/api/content setting id=DraftPageIdFromStep1.
Is there any way to attach files to drafts when creating pages?
1 Like
I really would like to do this. We didn’t solve it and ask the user to publish the page before.
1 Like
Hi @takafumiohtake and @m.schmidt ,
I’ve created a small demo app to show how to do this. Here’s how to use it:
- Install the app using the URL https://dx-page-attachment-adder.glitch.me/connect.json.
- Visit a page.
- Click the
...
menu besides the Share
button.
- Click the option
Add attachment to a new page
.
- Check a modal dialog appears.
- Click the Brows button to select an attachment.
- Click the
Add attachment to a new page
link.
- Observe that a few messages get added to the dialog. They should show the content ID of the published page.
- Visit the published page
https://your-tenant.atlassian.net/wiki/spaces/{spaceKey}/pages/{contentId}
- Check the page is published and has the attachment.
Let me know if this helps.
Regards,
Dugald
2 Likes
Hi @dmorrow ,
Thank you very much for the demo and a quick reply.
I found out how to attach files to draft when creating a page.
It works for my app.
The correct steps are,
- create draft with POST /wiki/rest/api/content setting status=draft.
- attach file with POST /wiki/rest/api/content/{id}/child/attachment setting status=draft.
- update page with POST /wiki/rest/api/content/{id} setting status(in body)=current, status(in query)=draft, version.number=1, space.key=[SpaceKey]
3 Likes
Hi @takafumiohtake ,
Great to see you are unblocked. The steps you listed match what’s in my demo app and I suspect the trick is the different status in the query and body of the request at step 3.
Regards,
Dugald
1 Like
@dmorrow AP.context.getContext()
in a custom macro ui returns an empty object for me in edit mode. Is there any other way of figuring out if a page has been published?
@PhilipFeldmann I do this. Not sure if there’s any better method…
const draftStatus= () =>
new Promise((resolve) => {
AP.navigator.getLocation((location) => {
const contentId = location.context.contentId
AP.request({
url: `/rest/api/content/${contentId}`,
})
.then(() => resolve({ id: contentId, status: 'current' }))
.catch(() => resolve({ id: contentId, status: 'draft' }))
})
})
2 Likes
Thank you! Yeah, that’s a reasonable workaround, even though the call to /content
might fail for other reasons and this might occasionally result in a faulty “draft” status.
My current workaround is checking whether draftShareId
is in the URL of the top window - but that also seems potentially flaky. Best thing would be if Atlassian fixes getContext