AEM Cloud Service - NodeJS Script to iterate and delete folders recursively


In situations where you have to clean up the environment, so delete the nested folder structures, deleting the root may not always work when its too nested with many assets(say 200k assets in 80k folders). This script iterates and deletes the folders bottom up one by one...


1) Get the access token from Developer Console




2) In the following script saved in file delete-folders-recursively.js, set the value of AEM_TOKEN to access token generated above and run it using node eg. node delete-folders-recursively.js (used node -v = v19.0.1)

const https = require('https');
const fs = require('fs');
const QS = require('querystring');

let log = "C:/dev/projects/test/deleted-folders.csv";
let AEM_HOST = 'author-p9999-e99999.adobeaemcloud.com';
let AEM_TOKEN = "eyJhbGciOiJSU....";
let ROOT_FOLDER = "/content/dam/staging/choices/historical-test";
let goAhead = true;

requestFolderJson(ROOT_FOLDER);

function requestFolderJson(parentFolderPath) {
const options = {
hostname: AEM_HOST,
path: parentFolderPath + ".1.json",
headers: {
Authorization: 'Bearer ' + AEM_TOKEN
}
}

const INTERVAL = setInterval(() => {
if(goAhead){
clearInterval(INTERVAL);
doRequest(options, parentFolderPath);
}
}, 500);
}

function doRequest(options, parentFolderPath){
goAhead = false;

https.get(options,(res) => {
let body = "";

res.on("data", (chunk) => {
body += chunk;
});

res.on("end", () => {
try {
let json = JSON.parse(body);
let assetCountInFolder = 0, childPath, noChildFolders = true;

Object.keys(json).forEach(function(name) {
childPath = parentFolderPath + "/" + name;

if(json[name]["jcr:primaryType"] == "sling:Folder"){
requestFolderJson(parentFolderPath + "/" + name);
noChildFolders = false;
}else if(json[name]["jcr:primaryType"] == "dam:Asset"){
assetCountInFolder++;
}
});

if(noChildFolders){
console.log("DELETING Folder : " + parentFolderPath + ", with children count " + assetCountInFolder);
fs.appendFileSync(log, parentFolderPath + "," + assetCountInFolder + "\n");
doDeleteJob(parentFolderPath);
}

goAhead = true;
} catch (error) {
console.error("ERROR : " + parentFolderPath + " : " + error.message);
goAhead = true;
}
});
}).on("error", (error) => {
console.error("CONN ERROR : " + parentFolderPath + " : " + error.message);
goAhead = true;
});
}

function doDeleteJob(folderPath){
const postData = {
":operation" : "delete"
};

let payload = QS.stringify(postData);

const options = {
hostname: AEM_HOST,
path: folderPath,
method: 'POST',
headers: {
Authorization: 'Bearer ' + AEM_TOKEN,
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': payload.length
}
}

let req = https.request(options, (res) => {
res.setEncoding('utf8');

let body = "";

res.on("data", (chunk) => {
body += chunk;
});

res.on('end', () => {
console.log(res.statusCode + " : DELETED Folder : " + folderPath);
});
});

req.on('error', (e) => {
console.log("ERROR DELETE : " + folderPath + " , " + e);
goAhead = true;
});

req.write(payload);
req.end();
}


 

1 comment: