-
-
Save firatkucuk/ee898bc919021da621689f5e47e7abac to your computer and use it in GitHub Desktop.
#!/usr/bin/env node | |
// Channel ID is on the the browser URL.: https://mycompany.slack.com/messages/MYCHANNELID/ | |
// Pass it as a parameter: node ./delete-slack-messages.js CHANNEL_ID | |
// CONFIGURATION ####################################################################################################### | |
const token = 'SLACK TOKEN'; | |
// Legacy tokens are no more supported. | |
// Please create an app or use an existing Slack App | |
// Add following scopes in your app from "OAuth & Permissions" | |
// - channels:history | |
// - groups:history | |
// - im:history | |
// - mpim:history | |
// - chat:write | |
// VALIDATION ########################################################################################################## | |
if (token === 'SLACK TOKEN') { | |
console.error('Token seems incorrect. Please open the file with an editor and modify the token variable.'); | |
} | |
let channel = ''; | |
if (process.argv[0].indexOf('node') !== -1 && process.argv.length > 2) { | |
channel = process.argv[2]; | |
} else if (process.argv.length > 1) { | |
channel = process.argv[1]; | |
} else { | |
console.log('Usage: node ./delete-slack-messages.js CHANNEL_ID'); | |
process.exit(1); | |
} | |
// GLOBALS ############################################################################################################# | |
const https = require('https') | |
const historyApiUrl = `/api/conversations.history?channel=${channel}&count=1000&cursor=`; | |
const deleteApiUrl = '/api/chat.delete'; | |
const repliesApiUrl = `/api/conversations.replies?channel=${channel}&ts=` | |
let delay = 300; // Delay between delete operations in milliseconds | |
// --------------------------------------------------------------------------------------------------------------------- | |
const sleep = delay => new Promise(r => setTimeout(r, delay)); | |
const request = (path, data) => new Promise((resolve, reject) => { | |
const options = { | |
hostname: 'slack.com', | |
port : 443, | |
path : path, | |
method : data ? 'POST' : 'GET', | |
headers : { | |
'Authorization': `Bearer ${token}`, | |
'Content-Type' : 'application/json; charset=utf-8', | |
'Accept' : 'application/json' | |
} | |
}; | |
const req = https.request(options, res => { | |
let body = ''; | |
res.on('data', chunk => (body += chunk)); | |
res.on('end', () => resolve(JSON.parse(body))); | |
}); | |
req.on('error', reject); | |
if (data) { | |
req.write(JSON.stringify(data)); | |
} | |
req.end(); | |
}); | |
// --------------------------------------------------------------------------------------------------------------------- | |
async function deleteMessages(threadTs, messages) { | |
if (messages.length == 0) { | |
return; | |
} | |
const message = messages.shift(); | |
if (message.thread_ts !== threadTs) { | |
await fetchAndDeleteMessages(message.thread_ts, ''); // Fetching replies, it will delete main message as well. | |
} else { | |
const response = await request(deleteApiUrl, {channel: channel, ts: message.ts}); | |
if (response.ok === true) { | |
console.log(message.ts + (threadTs ? ' reply' : '') + ' deleted!'); | |
} else if (response.ok === false) { | |
console.log(message.ts + ' could not be deleted! (' + response.error + ')'); | |
if (response.error === 'ratelimited') { | |
await sleep(1000); | |
delay += 100; // If rate limited error caught then we need to increase delay. | |
messages.unshift(message); | |
} | |
} | |
} | |
await sleep(delay); | |
await deleteMessages(threadTs, messages); | |
} | |
// --------------------------------------------------------------------------------------------------------------------- | |
async function fetchAndDeleteMessages(threadTs, cursor) { | |
const response = await request((threadTs ? repliesApiUrl + threadTs + '&cursor=' : historyApiUrl) + cursor); | |
if (!response.ok) { | |
console.error(response.error); | |
return; | |
} | |
if (!response.messages || response.messages.length === 0) { | |
return; | |
} | |
await deleteMessages(threadTs, response.messages); | |
if (response.has_more) { | |
await fetchAndDeleteMessages(threadTs, response.response_metadata.next_cursor); | |
} | |
} | |
// --------------------------------------------------------------------------------------------------------------------- | |
fetchAndDeleteMessages(null, ''); |
thanks to @firatkucuk and @JonathanNobrega , this script worked fine for me!
Glad to help @im-syk and @doschkinow!
Hey! When deleting messages from a DM, I got the message:
vada {
ok: false,
error: 'cant_delete_message',
warning: 'missing_charset',
response_metadata: { warnings: [ 'missing_charset' ] }
}
1650841222.763739 could not be deleted! (cant_delete_message)
Any ideas?
Thanks, I was using the bot token. Changed to user token and reinstalled the app. It worked.
Is there any chance to run this script just with 'node ./slack-delete-messages', without the channel id in the terminal?
@alevaldiviezo what do you want to achieve? Deleting all messages in all channels or just running without channel_id.?
let channel = 'put your channel id here';
// ------------------- delete following section from here
if (process.argv[0].indexOf('node') !== -1 && process.argv.length > 2) {
channel = process.argv[2];
} else if (process.argv.length > 1) {
channel = process.argv[1];
} else {
console.log('Usage: node ./delete-slack-messages.js CHANNEL_ID');
process.exit(1);
}
// ------------------- to here
Hi, thanks for your reply, I got it, the idea is to run the script as a second process with the fork command, many thanks I got it now.
Excellent script - thanks @firatkucuk !
@im-syk et al. - if anyone is interested in a version of this that deletes last 30 days, I made a version that does that. To change how long it keeps things for, update the keepTime
variable as needed.
Please tell me.
Is it possible to specify the period to be deleted by this script?