-
-
Save AbdealiLoKo/7499bc364dfddc992d4801b1a0cc6de1 to your computer and use it in GitHub Desktop.
Deletes slack public/private channel and chat messages.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env node | |
| // To get stats on all channels, call: | |
| // node ./delete-slack-messages.js | |
| // To delete messages for a particular channel, get the Channel ID and pass as a param: | |
| // node ./delete-slack-messages.js CHANNEL_ID | |
| // Channel ID is on the the browser URL.: https://mycompany.slack.com/messages/MYCHANNELID/ | |
| // CONFIGURATION ####################################################################################################### | |
| const token = 'xoxp-TOKEN'; | |
| const tokenUser = 'user'; | |
| // ACCESS required: | |
| // >> For delete: | |
| // - chat:write:user | |
| // - channels:history | |
| // - groups:history | |
| // - mpim:history | |
| // - im:history | |
| // >> For stats: | |
| // - channels:read | |
| // - groups:read | |
| // - mpim:read | |
| // - im:read | |
| // - users:read | |
| // - channels:history | |
| // - groups:history | |
| // - mpim:history | |
| // - im:history | |
| // GLOBALS ############################################################################################################# | |
| const https = require('https'); | |
| const baseApiUrl = 'https://slack.com/api/'; | |
| const messages = []; | |
| let delay = 300; // Delay between delete operations in milliseconds | |
| let nextCursor = ''; | |
| // --------------------------------------------------------------------------------------------------------------------- | |
| function deleteMessage(channel) { | |
| if (messages.length == 0) { | |
| if (nextCursor) { | |
| processHistory(); | |
| } | |
| return; | |
| } | |
| const ts = messages.shift(); | |
| https.get(`${baseApiUrl}chat.delete?token=${token}&channel=${channel}&ts=${ts}`, function (res) { | |
| let body = ''; | |
| res.on('data', function (chunk) { | |
| body += chunk; | |
| }); | |
| res.on('end', function(){ | |
| const response = JSON.parse(body); | |
| if (response.ok === true) { | |
| console.log(ts + ' deleted!'); | |
| } else if (response.ok === false) { | |
| console.log(ts + ' could not be deleted! (' + response.error + ')'); | |
| console.log(response) | |
| if (response.error === 'ratelimited') { | |
| delay += 100; // If rate limited error caught then we need to increase delay. | |
| messages.push(ts); | |
| } | |
| } | |
| setTimeout(function() {deleteMessage(channel);}, delay); | |
| }); | |
| }).on('error', function (e) { | |
| console.error("Got an error: ", e); | |
| }); | |
| } | |
| // --------------------------------------------------------------------------------------------------------------------- | |
| function processHistory(channel) { | |
| https.get(`${baseApiUrl}conversations.history?token=${token}&limit=1000&channel=${channel}&cursor=${nextCursor}`, function(res) { | |
| let body = ''; | |
| res.on('data', function (chunk) { | |
| body += chunk; | |
| }); | |
| res.on('end', function () { | |
| nextCursor = null; | |
| const response = JSON.parse(body); | |
| if (response.messages && response.messages.length > 0) { | |
| console.log(`Got ${response.messages.length}${response.has_more?'+':''} messages`); | |
| if (response.has_more) { | |
| nextCursor = response.response_metadata.next_cursor; | |
| } | |
| for (let i = 0; i < response.messages.length; i++) { | |
| messages.push(response.messages[i].ts); | |
| } | |
| deleteMessage(channel); | |
| } | |
| }); | |
| }).on('error', function (e) { | |
| console.error("Got an error: ", e); | |
| }); | |
| } | |
| function getChannelStats() { | |
| https.get(`${baseApiUrl}conversations.list?token=${token}&types=public_channel,private_channel,mpim,im&limit=1000`, function(res) { | |
| let body = ''; | |
| res.on('data', function (chunk) { | |
| body += chunk; | |
| }); | |
| res.on('end', function () { | |
| const response = JSON.parse(body); | |
| if (response.channels || response.groups) { | |
| let channels = response.channels? response.channels: []; | |
| channels = channels.concat(response.groups? response.groups: []); | |
| channels = channels.sort(function (chan) { return chan.name; }); | |
| console.log(`Found ${channels.length} channels`); | |
| function getChannelHist() { | |
| const channel = channels.shift(); | |
| if (!channel) { | |
| return; | |
| } | |
| // Get channel name (if a private user chat - get that) | |
| let channelName = channel.name; | |
| if (!channelName && channel.user) { | |
| channelName = channel.user; | |
| https.get(`${baseApiUrl}users.info?token=${token}&user=${channel.user}`, function(userRes) { | |
| let userBody = ''; | |
| userRes.on('data', function (chunk) { | |
| userBody += chunk; | |
| }) | |
| userRes.on('end', function () { | |
| const userResponse = JSON.parse(userBody); | |
| if (userResponse.user && userResponse.user.name) { | |
| channelName = `user-${tokenUser}--${userResponse.user.name}`; | |
| } else { | |
| console.log(userResponse); | |
| } | |
| }); | |
| }); | |
| } | |
| // Get history of the channel to find all chat messages | |
| https.get(`${baseApiUrl}conversations.history?token=${token}&limit=1000&channel=${channel.id}`, function(channelRes) { | |
| let channelBody = ''; | |
| channelRes.on('data', function (chunk) { | |
| channelBody += chunk; | |
| }) | |
| channelRes.on('end', function () { | |
| const channelResponse = JSON.parse(channelBody); | |
| if (channelResponse.messages) { | |
| console.log(`${channel.id}; ${channelName}; ${channelResponse.messages.length}${channelResponse.has_more?'+':''}`); | |
| } else if (response.error === 'ratelimited') { | |
| delay += 100; // If rate limited error caught then we need to increase delay. | |
| channels.push(channel); | |
| } else { | |
| console.log(`${channel.id}; ${channelName}; ${JSON.stringify(channelResponse)}`); | |
| } | |
| setTimeout(getChannelHist, delay); | |
| }); | |
| }); | |
| } | |
| getChannelHist(); | |
| } else { | |
| console.log(response); | |
| } | |
| }); | |
| }); | |
| } | |
| // --------------------------------------------------------------------------------------------------------------------- | |
| let args = []; | |
| if (process.argv[0].indexOf('node') !== -1) { | |
| args = process.argv.slice(2, process.argv.length) | |
| channel = process.argv[2]; | |
| } else { | |
| args = process.argv.slice(1, process.argv.length) | |
| } | |
| if (args.length == 0) { | |
| console.log('To delete messages in a channel, give the channel ID as an argument') | |
| console.log('Fetching number of messages in each channel ...') | |
| getChannelStats(); | |
| } else { | |
| processHistory(args[0]); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment