Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

This comment has been minimized.

Copy link

commented Oct 9, 2018

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

This comment has been minimized.

Copy link

commented Oct 11, 2018

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

This comment has been minimized.

Copy link

commented Feb 22, 2019

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
You can’t perform that action at this time.