@kattebak/markdown-confluence-cli
v1.7.1
Published
Synchronize markdown files to a confluence page
Readme
Markdown to Confluence Sync Action
Sync markdown files to Confluence pages using the Confluence REST API v2/v1.
Usage
CLI Usage
This package is published to npm, and can be ran directly from your commandline using the node package manager npm.
npx @kattebak/markdown-confluence-cli --title <title> -f <file> -u <user> -t <token> -p <page_id> -d <domain> -s <space_id>Alternatively, install this package in your node project and invoke it as markdown-confluence-sync directly.
Parameters
Run npx @kattebak/markdown-confluence-cli to view the built-in documentation:
npx @kattebak/markdown-confluence-cli
Usage: markdown-confluence-sync [command] <options>
Options:
-f --file <Markdown file to sync>
-u --user <Confluence username/email>
-t --token <Confluence API token>
-p --pageId <Parent page ID in Confluence>
-a --attachmentId <Attachment ID>
-d --domain <Confluence domain (e.g., your-company.atlassian.net)>
-i --spaceId <Confluence space ID>
-w --webtriggerUrl <Forge web trigger URL. Routes writes through the app identity instead of --user/--token>
-s --webtriggerSecret <Shared secret for the Forge web trigger proxy>
-I --id <Page ID to delete>
-l --title <Override page title (default: derived from file name)>
Commands: sync list dump upload list-attachments get get-attachment deletePublishing as an app
By default, pages are authored by whichever human's --user/--token you pass. To have pages
authored by an app identity instead, deploy the Forge app in forge/ and route the CLI through
its web trigger with --webtriggerUrl/--webtriggerSecret (or CONFLUENCE_WEBTRIGGER_URL /
CONFLUENCE_WEBTRIGGER_SECRET). --user/--token are not required in this mode; --domain is
still used to build request URLs and CLI link output.
npx @kattebak/markdown-confluence-cli sync -f README.md -d $CONFLUENCE_DOMAIN -i $CONFLUENCE_SPACE_ID \
--webtriggerUrl "$CONFLUENCE_WEBTRIGGER_URL" --webtriggerSecret "$CONFLUENCE_WEBTRIGGER_SECRET"To deploy the app and wire it up (from forge/, see forge/README.md):
forge deploy -e development
forge install --site <your-site>.atlassian.net --product confluence --confirm-scopes
forge variables set --encrypt -e development SYNC_SECRET <a-random-secret>
forge webtrigger -e developmentA site admin must run forge install on a production site — installing a Forge app always
requires site-admin permission, whether from this CLI or the Forge web console.
Example
Create a new page, or update an existing page:
npx @kattebak/markdown-confluence-cli sync -l "Markdown to Confluence" -f README.md -u $CONFLUENCE_USER -t $CONFLUENCE_TOKEN -d $CONFLUENCE_DOMAIN -i $CONFLUENCE_SPACEIn this case, @kattebak/markdown-confluence-cli will:
- Create the page if it doesn't exist
- Or find the page by title
- Upload images found in markdown
- Update the page to reference confluence page attachments
sequenceDiagram
participant CC as ConfluenceClient
participant PA as PageApi (v2)
participant CAA as ContentAttachmentsApi (v1)
participant AA as AttachmentApi (v2)
participant FS as File System
Note over CC: Initial Create Operation
CC->>PA: createPage(document)
PA-->>CC: pageId
Note over CC: Update with Inline Images
CC->>CC: updatePageWithInlineImages(pageId, document)
CC->>CC: traverseForLocalFiles(document)
CC->>CC: Find local file references in mediaSingle nodes
rect rgb(255, 255, 200)
Note over CC, FS: loop [For each local file]
CC->>FS: Check file exists
FS-->>CC: File buffer
Note over CC, CAA: Upload using v1 API
CC->>CAA: uploadAttachment(pageId, filePath)
CAA->>CAA: createOrUpdateAttachments()
CAA-->>CC: attachmentInfo (id, title, mediaType)
Note over CC, AA: Get details using v2 API
CC->>AA: getAttachment(attachmentId)
AA->>AA: getAttachmentById()
AA-->>CC: attachmentDetails (fileId, downloadLink)
Note over CC: Update media node with attachment info
CC->>CC: Set attrs: id=fileId, collection=contentId-pageId, type=file
end
CC->>PA: getPage(pageId)
PA-->>CC: currentPage (version info)
CC->>PA: updatePage(pageInfo, updatedDocument)
PA-->>CC: Updated page with attachments
Documentation
This implementation has been completely reverse-engineered, because Atlassian provides no documentation on how to deal with the adf format in the REST api. By uploading pages in adf you get the modern rendering behaviour and editor. If you don't care for any of that, you could simply post HTML with inlined images instead.
- https://github.com/marketplace/actions/markdown-to-confluence-sync
- https://www.npmjs.com/package/@telefonica/markdown-confluence-sync
I learned a lot from studying these implementations as well.
Development
Test cli in development:
tsx src/cli.ts sync -f README.md -u $CONFLUENCE_USER -t $CONFLUENCE_TOKEN -d $CONFLUENCE_DOMAIN -i $CONFLUENCE_SPACE_ID