Skip to main content
Skip table of contents

Starting an Export from within Your App

If your app needs to initiate an export as part of your own functionality or in events specific to your app, you can use the macro-based integration as an alternative to the exporter’s REST API.

  • Use the REST API, if a dedicated Confluence user account should be used for the exports

  • Use the macro-based integration, if your app impersonates any Confluence user and needs to perform an export in the scope of that user

Getting Started

To use the macro based approach:

  • Your app sends a storage format fragment with a macro containing export instructions to Confluence

    • Confluence then asks the Scroll Exporter macro endpoint to render the macro

    • Upon rendering the macro, Scroll Exporter initiates an export and reports the export job ID as macro output to Confluence, which includes it in the render output returned back to your app

  • Your app uses the same mechanism to poll the export job’s status (repeatedly), until the job finished and a download URL is available

  • Your app fetches the exported file via the download URL

All render requests your app makes to Confluence must include a user-impersonating access token.

Connect apps require the ACT_AS_USER scope to do so.

See https://developer.atlassian.com/cloud/confluence/user-impersonation-for-connect-apps for further details.

export-via-macro.svg

Export Macro

The export macro is provided by the Scroll Exporter app but remains hidden from the Confluence editor because it is not intended for use on Confluence pages.

Macro Parameters

When sending export and status requests, you need to prepare storage format containing the macro:

CODE
<ac:structured-macro ac:name="scroll-pdf-export-job">
    <ac:parameter ac:name="issued-at">1728403475</ac:parameter>
    <ac:parameter ac:name="issued-by-app">My custom app</ac:parameter>
    <ac:parameter ac:name="export-request"><![CDATA[{"pageId": "1376263", "templateId": "d6d04ab9-53c0-42d9-9ae2-f4903275f654"}]]></ac:parameter>
    <ac:parameter ac:name="export-job-id">0f517c20-3e5d-42c0-8021-0cb5e2c168ea</ac:parameter>
</ac:structured-macro>
  • issued-at - Set this to the current time in UNIX epoch seconds, for example 1728403475 for 2024-10-08T16:04:35Z

    • This is to prevent unintended exports if the macro ends up on a Confluence page.

    • We allow a leeway of 10 seconds here, so make sure the clock on your server is synchronized and there’s not too much delay between taking the timestamp and sending the request.

  • issued-by-app - Specify your app’s name as set in Atlassian Marketplace here. We use this to keep track of other apps using this endpoint.

  • export-request - A JSON representation of the export configuration.

    • When specified, the macro performs the ‘Start Export’ operation as described in the OpenAPI specs of the REST API docs. The macro output corresponds to that operation’s response value.

    • The value may be included in a <[CDATA[ ... ]]> tag.

  • export-job-id - The ID of the export job retrieved when starting the export.

    • When specified, the macro performs the ‘Get Export Status’ operation as described in the OpenAPI specs of the REST API docs. The macro output corresponds to that operation’s response value.

Not all parameters are required in each step. See below for details.

Macro Operation Modes

The set of supplied macro parameters decide what operation the macro invokes: Starting a new export, or reporting the status of an existing export job.

The macro will output some wrapper HTML containing HTML-escaped JSON structures. The wrapper HTML is required to prevent Confluence from modifying the JSON content. The JSON structures correspond to the responses of the export REST APIs.

‘Start Export’ Mode

Storage Format with required parameters:

CODE
<ac:structured-macro ac:name="scroll-pdf-export-job">
    <ac:parameter ac:name="issued-at">1728403475</ac:parameter>
    <ac:parameter ac:name="issued-by-app">My custom app</ac:parameter>
    <ac:parameter ac:name="export-request"><![CDATA[{"pageId": "1376263", "templateId": "d6d04ab9-53c0-42d9-9ae2-f4903275f654"}]]></ac:parameter>
</ac:structured-macro>

Macro Output:

CODE
<div class="result">
    <code class="success">{&quot;jobId&quot;:&quot;0f517c20-3e5d-42c0-8021-0cb5e2c168ea&quot;}</code>
</div>

Use the export job ID for retrieving the export job status.

‘Get Export Status’ Mode

Storage Format with required parameters:

CODE
<ac:structured-macro ac:name="scroll-pdf-export-job">
    <ac:parameter ac:name="issued-at">1728403475</ac:parameter>
    <ac:parameter ac:name="export-job-id">0f517c20-3e5d-42c0-8021-0cb5e2c168ea</ac:parameter>
</ac:structured-macro>

Macro Output:

CODE
<div class="result">
    <code class="success">{&quot;status&quot;:&quot;complete&quot;,&quot;step&quot;:3,&quot;totalSteps&quot;:3,&quot;stepProgress&quot;:100,&quot;downloadUrl&quot;:&quot;https://scroll-pdf.us.exporter.k15t.app/download/Demo-v1-20241008_172721.pdf?jwt=...&quot;}</code>
</div>

Error Handling

If the macro is used with invalid parameters, it will output an HTML wrapper with a JSON structure containing error details.

CODE
<div class="result">
    <code class="error">{&quot;status&quot;: 400,&quot;message&quot;: &quot;Must set 'issued-at' parameter to current time as Unix Epoch seconds.&quot;}</code>
</div>

The code element now has an error class instead of success, and the JSON structure corresponds to the error objects produced by the REST API.

Examples

The examples below are IntelliJ HTTP snippets. Substitute these variables:

  • {{baseUrl}} - The base URL of the Confluence instance

  • {{token}} - A user impersonation token for the user in the context of which the export will be performed

  • the values of other macro parameters as required

Step 1: Starting an export

Request

CODE
### Call export macro: new export request (this is an IntelliJ HTTP snippet, see https://www.jetbrains.com/help/idea/http-client-in-product-code-editor.html)

POST {{baseUrl}}/rest/api/contentbody/convert/export_view
Content-Type: application/json
Authorization: Bearer {{token}}

{
    "value": "<ac:structured-macro ac:name=\"scroll-pdf-export-job\"><ac:parameter ac:name=\"issued-at\">{{$timestamp}}</ac:parameter><ac:parameter ac:name=\"issued-by-app\">My App</ac:parameter><ac:parameter ac:name=\"export-request\"><![CDATA[{\"pageId\": \"1376263\", \"scope\": \"current\", \"templateId\": \"d6d04ab9-53c0-42d9-9ae2-f4903275f654\", \"versionId\": \"\", \"variantId\": \"\", \"languageKey\": \"\", \"locale\": \"en-US\", \"timeZone\": \"Europe/Berlin\"}]]></ac:parameter></ac:structured-macro>",
    "representation": "storage"
}

Response

The response received from Confluence contains a JSON object as follows:

CODE
{
    "value": "<div class=\"result\"><code class=\"success\">{&quot;jobId&quot;:&quot;0f517c20-3e5d-42c0-8021-0cb5e2c168ea&quot;}</code></div>",
    "representation": "export_view",
    ...
}
Output handling
  1. Use a JSON parser to extract the HTML content of the value property (JSON unescaped):

    CODE
    <div class="result"><code class="success">{&quot;jobId&quot;:&quot;0f517c20-3e5d-42c0-8021-0cb5e2c168ea&quot;}</code></div>
  2. Use an HTML parser to extract the text content of the <code> element (HTML unescaped):
    (this JSON structure matches the response of the ‘Start Export’ REST API)

    CODE
    {"jobId":"0f517c20-3e5d-42c0-8021-0cb5e2c168ea"}
  3. Use a JSON parser to extract the Export Job ID from the jobId property (JSON unescaped):

    CODE
    0f517c20-3e5d-42c0-8021-0cb5e2c168ea

Use the extracted ID to request status updates in the next step

Step 2: Polling Export Job Status

Request

CODE
### Call export macro: poll status (this is an IntelliJ HTTP snippet, see https://www.jetbrains.com/help/idea/http-client-in-product-code-editor.html)

POST {{baseUrl}}/rest/api/contentbody/convert/export_view
Content-Type: application/json
Authorization: Bearer {{token}}

{
    "value": "<ac:structured-macro ac:name=\"scroll-pdf-export-job\"><ac:parameter ac:name=\"issued-at\">{{$timestamp}}</ac:parameter><ac:parameter ac:name=\"export-job-id\">{{$exportJobId}}</ac:parameter></ac:structured-macro>",
    "representation": "storage"
}

Response

The response received from Confluence contains a JSON object as follows:

CODE
{
    "value": "<div class=\"result\"><code class=\"success\">{&quot;status&quot;:&quot;complete&quot;,&quot;step&quot;:3,&quot;totalSteps&quot;:3,&quot;stepProgress&quot;:100,&quot;downloadUrl&quot;:&quot;https://scroll-pdf.us.exporter.k15t.app/download/Demo-v1-20241008_172721.pdf?jwt=...&quot;}</code></div>",
    "representation": "export_view",
    ...
}
Output Handling
  1. Use a JSON parser to extract the HTML content of the value property (JSON unescaped):

    CODE
    <div class="result"><code class="success">{&quot;status&quot;:&quot;complete&quot;,&quot;step&quot;:3,&quot;totalSteps&quot;:3,&quot;stepProgress&quot;:100,&quot;downloadUrl&quot;:&quot;https://scroll-pdf.us.exporter.k15t.app/download/Demo-v1-20241008_172721.pdf?jwt=...&quot;}</code></div>
  2. Use an HTML parser to extract the text content of the <code> element (HTML unescaped):
    The resulting JSON structure matches the response of the ‘Get Export Status’ REST API

    CODE
    {"status":"complete","step":3,"totalSteps":3,"stepProgress":100,"downloadUrl":"https://scroll-pdf.us.exporter.k15t.app/download/Demo-v1-20241008_172721.pdf?jwt=..."}
  3. Use a JSON parser to load the JSON structure

Repeat polling until status is either complete, error or cancelled, then extract the value of downloadUrl if available. See the REST API docs for more information on the properties.

Step 3: Download the Exported File

Simply perform a download from downloadUrl.

Do not send any Authorization headers. The URL contains the necessary authentication token as a query parameter.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.