Skip to content

Instantly share code, notes, and snippets.

@dominikwilkowski
Forked from evangs/delete-old-files.js
Last active March 9, 2020 05:16
Show Gist options
  • Save dominikwilkowski/76d99ae84848c39e54494f4dbdd4327d to your computer and use it in GitHub Desktop.
Save dominikwilkowski/76d99ae84848c39e54494f4dbdd4327d to your computer and use it in GitHub Desktop.
Batch delete old files from Slack

Batch delete old file from your slack workspace

Freeing space

To free up some space in your slack workspace and having to delete each file by hand

To run the app you first need a legacy token from slack for your workspace. Then download the cleanSlack.js file and run it via Node.js.

By default the script will delete files older than a year. You can change that in the TIMESTAMP variable.

cd path/to/cleanSlack.js
token=xxxxxxxxxxxxxxxxxxxxxxxxxx node cleanSlack.js

This will run the script and delete each file one by one until done.

const https = require('https');
// CONFIGURATION
const TOKEN = process.env.token; // to be generated via https://api.slack.com/custom-integrations/legacy-tokens
const DELAY = 300; // delay between delete operations in millisecond
// ms sec min h days
const TIMESTAMP = ( new Date().getTime() - (1000 * 60 * 60 * 24 * 365) ) / 1000;
// SLACK CONFIG
const baseApiUrl = 'https://slack.com/api/';
const filesApiUrl = `${ baseApiUrl }files.list?token=${ TOKEN }&count=10000`;
const deleteApiUrl = `${ baseApiUrl }files.delete?token=${ TOKEN }`;
/**
* Send a request to slack and run a callback function
*
* @param {string} url - The url of the request
* @param {function} callback - The function to be run, parameters passed in: the response object
*
* @return {promise} - Resolves with whatever the callback returns
*/
const ShootRequest = ( url, callback ) => {
if( !TOKEN ) {
console.error(`Please set your token via \u001B[33mtoken=xxx node cleanSlack.js\u001b[39m`);
return Promise.resolve();
}
return new Promise( ( resolve, reject ) => {
https
.get( url, result => {
let body = '';
result
.on('data', chunk => body += chunk )
.on('end', () => {
const response = JSON.parse( body );
resolve( callback( response ) );
});
})
.on('error', error => {
reject( error );
});
});
};
/**
* Self-calling function to delete a set of files from the slack workspace
*
* @param {array} files - An array of all file IDs that need to be deleted
* @param {integer} files - The number of total files
*/
const DeleteFile = ( files, max ) => {
if( files.length == 0 ) {
console.log(`Job done ❤️ (\u001B[32m${ max }\u001b[39m successfully deleted)`);
return;
}
const fileID = files.shift();
ShootRequest( `${ deleteApiUrl }&file=${ fileID }`, response => {
if( response.ok ) {
process.stdout.write(`\u001b[1A\u001b[2K`);
console.log(
`${ Math.round( ( ( max - files.length ) / max ) * 100 ).toString().padEnd( 3 ) }%` +
` (\u001B[32m${ fileID }\u001b[39m successfully deleted)`
);
}
else if ( response.ok === false ) {
files.push( fileID );
}
setTimeout( () => DeleteFile( files, max ), DELAY );
});
};
ShootRequest( `${ filesApiUrl }&ts_to=${ TIMESTAMP }`, response => {
const files = [];
response.files.map( file => files.push( file.id ) );
console.log(`\u001B[32m${ files.length }\u001b[39m files to be deleted`);
console.log(`${ '0'.padEnd( 3 ) }%`);
DeleteFile( files, files.length );
}).catch( error => console.error(`\u001B[31m${ error }\u001b[39m`) );
@teemujonkkari
Copy link

Map returns an array so maybe something to consider

original:

const files = []; response.files.map( file => files.push( file.id ) );

suggestion:

const files = response.files.map( f => f.id );

@comat0se
Copy link

This doesn't seem to fully work... first pass I got 100 files deleted, second pass 0, third pass 15, ... keeps returning 0 and then a handful etc. I used https://www.npmjs.com/package/slack-delete-files and it removed 900 in one pass.

@danibram
Copy link

I just developed a bot that helps you to manage this, any contribution is welcome!
https://github.com/danibram/scrapy-slack-bot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment