DEV Community

Andrii Maliuta
Andrii Maliuta

Posted on • Edited on

10 3

Interact with Confluence Server via REST API using NodeJS(JS)

Sometimes there can be a need to automate some actions in Confluence or perform some action multiple times, etc. For this Confluence REST API can be used together with the programming language and API to interact via HTTP.

Previous example using Groovy - https://dev.to/andriimaliuta/how-to-update-several-pages-in-confluence-via-rest-api-k6c.

In this example we will use JavaScript and axios library (you do not need the very axios and can use core FETCH if you want - this is just one of ways) to initiate Confluence REST endpoints to:

  • getPage.js
  • getChildren.js
  • getDescendants.js
  • createComment.js
  • createPage.js
  • deleteLabel.js
  • getPageLabels.js

Git repo - https://github.com/ahndmal/js-atlassian-rest-client

Data file

Approximate file structure:

Image description

First we create data.js file to store constants with data:

const dotenv = require('dotenv');
dotenv.config();
const username = process.env.username;
const password = process.env.password;
const CONF_URL = process.env.CONF_URL;

module.exports = {
  authData: Buffer.from(`${username}:${password}`).toString('base64'),
  CONF_URL
};
Enter fullscreen mode Exit fullscreen mode

We create Basic Auth Base64 token from username and password.

Get Page information

Request:

GET /rest/content
Enter fullscreen mode Exit fullscreen mode

CONTENT is the entity that represents:

  • page
  • comment
  • blogpost

The example of getPage.js file:

const axios = require('axios');
const https = require('https');
const { authData, CONF_URL } = require('./data');

module.exports = async function getPage(pageId) {
  console.log('>>> Initiating REST request...');

  return axios.get(`${CONF_URL}/rest/api/content/${pageId}`, {
    headers: {
      Authorization: `Basic ${authData}`,
    },
    httpsAgent: new https.Agent({
      rejectUnauthorized: false,
    }),
  });
};
Enter fullscreen mode Exit fullscreen mode

getChildren.js

Request:

GET ${CONF_URL}/rest/api/content/${pageId}/child/page
Enter fullscreen mode Exit fullscreen mode
const axios = require("axios");
const https = require("https");
const { authData, CONF_URL } = require("./data");

module.exports = async function getPageChildren(pageId) {
  console.log(" Initiating REST request...");

  return await axios.get(`${CONF_URL}/rest/api/content/${pageId}/child/page`, {
    headers: {
      Authorization: `Basic ${authData}`,
    },
    httpsAgent: new https.Agent({
      rejectUnauthorized: false,
    }),
  });
};
Enter fullscreen mode Exit fullscreen mode

getDescendants.js

const axios = require("axios");
const https = require("https");
const { authData, CONF_URL } = require("./data");

module.exports = async function getPageChildren(pageId) {
  console.log(">>> Initiating REST request...");

  return await axios.get(
    `${CONF_URL}/rest/api/search?cql=type+=+"page"+and+ancestor+%3D+"${pageId}"`,
    {
      headers: {
        Authorization: `Basic ${authData}`,
      },
      httpsAgent: new https.Agent({
        rejectUnauthorized: false,
      }),
    }
  );
};
Enter fullscreen mode Exit fullscreen mode

Create Page (Blogpost / Comment)

createPage.js

const axios = require('axios');
const https = require('https');
const { authData, CONF_URL } = require('./data');

module.exports = async function createPage(space, title, body, parent_id) {
  console.log(' Initiating REST request...');
  data = {
    type: 'page',
    title: title,
    space: { key: space },
    body: {
      storage: {
        value: body,
        representation: 'storage',
      },
    },
    ancestors: [{ id: parent_id }],
  };

  return await axios.post(`${CONF_URL}/rest/api/content`, {
    headers: {
      Authorization: `Basic ${authData}`,
      'Content-Type': 'application/json',
    },
    httpsAgent: new https.Agent({
      rejectUnauthorized: false,
    }),
    data: data,
  });
};
Enter fullscreen mode Exit fullscreen mode

Making requests

Now we craete index.js file (name is up to you :), of course ) and perform necessary actions. Here we will CONSOLE.LOG the result of requests, but of course you can further adjust, combine and expand code to do what you need.

const getPage = require('./getPage');
const getChildren = require('./getChildren');
const getDescendants = require('./getDescendants');
const createPage = require('./createPage');
const getPageLabels = require('./getPageLabels');
const createComment = require('./createComment');

const PAGE_ID = 123456; // specify the PAGE ID

async function init() {

// GET PAGE
   getPage(PAGE_ID)
     .then((res) => console.log(res.data))
     .catch((err) => console.log(err));

  // GET all descendant pages of the root one
   getDescendants(PAGE_ID).then((res) => console.log(res.data));

  // ====== Create Page =====
const SPACE_KEY = "TEST";
  createPage(SPACE_KEY, 'MY PAGE TITLE', 'this is body', PAGE_ID).then((res) =>
    console.log(res.data)
  );

  // ====== Create comment ======
   createComment('TEST', 'test title', 'rest comment!', 1000, PAGE_ID).then(
     (res) => console.log(res.data)
   );

// labels

   const PAGE_ID = 12345;
   getPageLabels(PAGE_ID).then((res) => {
     for (label of res.data.results) {
       deleteLabel(PAGE_ID, label.name);
     }
   });

   deleteLabel(labelId, "error-template").then((res) => console.log(res.data));

}

// ========= initiate the code !!
init();

Enter fullscreen mode Exit fullscreen mode

That is all. Of course , these are promitive examples , but the sooth is to understand the very principles and then further do almost any actions you need via REST API that to ease your work with Confluence :)

Please let me know if it is helpful.

Thanks!

Image of Timescale

Timescale – the developer's data platform for modern apps, built on PostgreSQL

Timescale Cloud is PostgreSQL optimized for speed, scale, and performance. Over 3 million IoT, AI, crypto, and dev tool apps are powered by Timescale. Try it free today! No credit card required.

Try free

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more