87

We currently have a Slack channel with ~8K messages all comes from Jenkins integration. Is there any programmatic way to delete all messages from that channel? The web interface can only delete 100 messages at a time.

Pale Blue Dot
  • 5,611
  • 10
  • 66
  • 100
Hann
  • 1,623
  • 1
  • 8
  • 6

11 Answers11

72

I quickly found out there's someone already made a helper: slack-cleaner for this.

And for me it's just:

slack-cleaner --token=<TOKEN> --message --channel jenkins --user "*" --perform

Dane Jordan
  • 811
  • 1
  • 12
  • 26
Hann
  • 1,623
  • 1
  • 8
  • 6
  • Another option comes from [npm](https://libraries.io/npm/slack-cleanup), just have not tried yet. – Hann Sep 28 '15 at 13:47
  • 3
    Where i can find my token and channel? – kk78626 Nov 30 '16 at 06:58
  • 6
    `--user "*"` is also necessary to make it work. Also if you want to actually perform the removing task, you should add `--perform`. – Shayan Salehian Aug 31 '17 at 18:46
  • 7
    The https://github.com/sgratzl/slack-cleaner fork is more active and includes features like `--quiet` to not display every message being deleted on stdout. – puzzlement Jan 14 '18 at 06:17
29

I wrote a simple node script for deleting messages from public/private channels and chats. You can modify and use it.

https://gist.github.com/firatkucuk/ee898bc919021da621689f5e47e7abac

First, modify your token in the scripts configuration section then run the script:

node ./delete-slack-messages CHANNEL_ID

Get an OAuth token:

  1. Go to https://api.slack.com/apps
  2. Click 'Create New App', and name your (temporary) app.
  3. In the side nav, go to 'Oauth & Permissions'
  4. On that page, find the 'Scopes' section. Click 'Add an OAuth Scope' and add 'channels:history' and 'chat:write'. (see scopes)
  5. At the top of the page, Click 'Install App to Workspace'. Confirm, and on page reload, copy the OAuth Access Token.

Find the channel ID

Also, the channel ID can be seen in the browser URL when you open slack in the browser. e.g.

https://mycompany.slack.com/messages/MY_CHANNEL_ID/

or

https://app.slack.com/client/WORKSPACE_ID/MY_CHANNEL_ID
Attaque
  • 4,156
  • 2
  • 28
  • 45
Fırat KÜÇÜK
  • 4,536
  • 1
  • 42
  • 52
  • 2
    Thanks for that. One thing I notice is that it slows down after a few messages have been deleted. – Bertl Mar 20 '18 at 09:04
  • 3
    Generally, there is a rate limitation. That's why after a time period delete operations are going to stall or slow down. – Fırat KÜÇÜK Jul 20 '18 at 13:54
  • 2
    Works like a charm! Thanks for this! – brianrhea Nov 26 '19 at 17:21
  • 1
    Used it, easy, sweet. Note that the above answer currently says to use legacy tokens, which are no longer supported, but Firat has already updated the gist itself with that info and gives the list of OAuth scopes that are needed. It was **surprisingly** quick-n-easy to create the slack app necessary to get OAuth token and add the list of scopes—I'm talkin' 100 seconds. – Daryn Sep 20 '20 at 11:44
23

default clean command did not work for me giving following error:

$ slack-cleaner --token=<TOKEN> --message --channel <CHANNEL>

Running slack-cleaner v0.2.4
Channel, direct message or private group not found

but following worked without any issue to clean the bot messages

slack-cleaner --token <TOKEN> --message --group <CHANNEL> --bot --perform --rate 1 

or

slack-cleaner --token <TOKEN> --message --group <CHANNEL> --user "*" --perform --rate 1 

to clean all the messages.

I use rate-limit of 1 second to avoid HTTP 429 Too Many Requests error because of slack api rate limit. In both cases, channel name was supplied without # sign

OWADVL
  • 8,899
  • 6
  • 50
  • 66
Samir
  • 617
  • 8
  • 18
11

!!UPDATE!!

as @niels-van-reijmersdal metioned in comment.

This feature has been removed. See this thread for more info: twitter.com/slackhq/status/467182697979588608?lang=en

!!END UPDATE!!

Here is a nice answer from SlackHQ in twitter, and it works without any third party stuff. https://twitter.com/slackhq/status/467182697979588608?lang=en

You can bulk delete via the archives (http://my.slack.com/archives ) page for a particular channel: look for "delete messages" in menu

Braggae
  • 815
  • 3
  • 12
  • 26
  • 1
    Just putting it out there, this only works for channels and not direct messages. – TheRodeo Apr 26 '17 at 05:54
  • 1
    This only delete the last 10 messages at time – MatPag May 12 '17 at 12:59
  • 1
    No, I used to delete a lot of messages with this method. It was about 100 or something. – Braggae May 16 '17 at 13:14
  • 1
    I just used it. If first only showed 10, but once I deleted them it showed the rest (the channel had less than 100 messages in total, so it could still be limited to 100). – Albin May 29 '17 at 15:16
  • 6
    This doesn't seem to work for me. It redirects to http://.slack.com/messages/ (appears to be the last channel I viewed) – JOATMON Jun 26 '17 at 20:40
  • 1
    This feature has been removed. See this thread for more info: https://twitter.com/slackhq/status/467182697979588608?lang=en – Niels van Reijmersdal Jul 19 '17 at 10:23
11

For anyone else who doesn't need to do it programmatic, here's a quick way:

(probably for paid users only)

  1. Open the channel in web or the desktop app, and click the cog (top right).
  2. Choose "Additional options..." to bring up the archival menu. notes
  3. Select "Set the channel message retention policy".
  4. Set "Retain all messages for a specific number of days".
  5. All messages older than this time are deleted permanently!

I usually set this option to "1 day" to leave the channel with some context, then I go back into the above settings, and set it's retention policy back to "default" to go continue storing them from now-on.

Notes:
Luke points out: If the option is hidden: you have to go to global workspace Admin settings, Message Retention & Deletion, and check "Let workspace members override these settings"

Hicsy
  • 406
  • 7
  • 17
  • 2
    Actually it's just hidden. To make it appear you have to go to global workspace Admin settings, Message Retention & Deletion, and check "Let workspace members override these settings". – Luke Jun 18 '18 at 02:29
  • Thanks, I have updated to include your comment. Also please note we even offered to pay Slack for the dev-time to delete retrospectively, but they said it simply wasnt possible other than enterprise edition (due to the different environment for storing data). – Hicsy Jan 08 '19 at 03:01
  • As mentioned by @Hicsy, the "Message Retention & Deletion" option is a "Paid Feature" – Phil Oct 15 '20 at 22:00
4

Option 1 You can set a Slack channel to automatically delete messages after 1 day, but it's a little hidden. First, you have to go to your Slack Workspace Settings, Message Retention & Deletion, and check "Let workspace members override these settings". After that, in the Slack client you can open a channel, click the gear, and click "Edit message retention..."

Option 2 The slack-cleaner command line tool that others have mentioned.

Option 3 Below is a little Python script that I use to clear Private channels. Can be a good starting point if you want more programmatic control of deletion. Unfortunately Slack has no bulk-delete API, and they rate-limit the individual delete to 50 per minute, so it unavoidably takes a long time.

# -*- coding: utf-8 -*-
"""
Requirement: pip install slackclient
"""
import multiprocessing.dummy, ctypes, time, traceback, datetime
from slackclient import SlackClient
legacy_token = raw_input("Enter token of an admin user. Get it from https://api.slack.com/custom-integrations/legacy-tokens >> ")
slack_client = SlackClient(legacy_token)


name_to_id = dict()
res = slack_client.api_call(
  "groups.list", # groups are private channels, conversations are public channels. Different API.
  exclude_members=True, 
  )
print ("Private channels:")
for c in res['groups']:
    print(c['name'])
    name_to_id[c['name']] = c['id']

channel = raw_input("Enter channel name to clear >> ").strip("#")
channel_id = name_to_id[channel]

pool=multiprocessing.dummy.Pool(4) #slack rate-limits the API, so not much benefit to more threads.
count = multiprocessing.dummy.Value(ctypes.c_int,0)
def _delete_message(message):
    try:
        success = False
        while not success:
            res= slack_client.api_call(
                  "chat.delete",
                  channel=channel_id,
                  ts=message['ts']
                )
            success = res['ok']
            if not success:
                if res.get('error')=='ratelimited':
#                    print res
                    time.sleep(float(res['headers']['Retry-After']))
                else:
                    raise Exception("got error: %s"%(str(res.get('error'))))
        count.value += 1
        if count.value % 50==0:
            print(count.value)
    except:
        traceback.print_exc()

retries = 3
hours_in_past = int(raw_input("How many hours in the past should messages be kept? Enter 0 to delete them all. >> "))
latest_timestamp = ((datetime.datetime.utcnow()-datetime.timedelta(hours=hours_in_past)) - datetime.datetime(1970,1,1)).total_seconds()
print("deleting messages...")
while retries > 0:
    #see https://api.slack.com/methods/conversations.history
    res = slack_client.api_call(
      "groups.history",
      channel=channel_id,
      count=1000,
      latest=latest_timestamp,)#important to do paging. Otherwise Slack returns a lot of already-deleted messages.
    if res['messages']:
        latest_timestamp = min(float(m['ts']) for m in res['messages'])
    print datetime.datetime.utcfromtimestamp(float(latest_timestamp)).strftime("%r %d-%b-%Y")

    pool.map(_delete_message, res['messages'])
    if not res["has_more"]: #Slack API seems to lie about this sometimes
        print ("No data. Sleeping...")
        time.sleep(1.0)
        retries -= 1
    else:
        retries=10

print("Done.")

Note, that script will need modification to list & clear public channels. The API methods for those are channels.* instead of groups.*

Luke
  • 4,149
  • 2
  • 24
  • 33
1

Tip: if you gonna use the slack cleaner https://github.com/kfei/slack-cleaner

You will need to generate a token: https://api.slack.com/custom-integrations/legacy-tokens

Helder Robalo
  • 1,793
  • 2
  • 12
  • 15
1

As other answers allude, Slack's rate limits make this tricky - the rate limit is relatively low for their chat.delete API at ~50 requests per minute.

The best strategy that respects the rate limit is to retrieve messages from the channel you want to clear, then delete the messages in batches under 50 that run on a minutely interval.

I've built a project containing an example of this batching that you can easily fork and deploy on Autocode - it lets you clear a channel via slash command (and allows you restrict access to the command to just certain users of course!). When you run /cmd clear in a channel, it marks that channel for clearing and runs the following code every minute until it deletes all the messages in the channel:

console.log(`About to clear ${messages.length} messages from #${channel.name}...`);

let deletionResults = await async.mapLimit(messages, 2, async (message) => {
  try {
    await lib.slack.messages['@0.6.1'].destroy({
      id: clearedChannelId,
      ts: message.ts,
      as_user: true
    });
    return {
      successful: true
    };
  } catch (e) {
    return {
      successful: false,
      retryable: e.message && e.message.indexOf('ratelimited') !== -1
    };
  }
});

You can view the full code and a guide to deploying your own version here: https://autocode.com/src/jacoblee/slack-clear-messages/

Jacob Lee
  • 56
  • 6
0

If you like Python and have obtained a legacy API token from the slack api, you can delete all private messages you sent to a user with the following:

import requests
import sys
import time
from json import loads

# config - replace the bit between quotes with your "token"
token = 'xoxp-854385385283-5438342854238520-513620305190-505dbc3e1c83b6729e198b52f128ad69'

# replace 'Carl' with name of the person you were messaging
dm_name = 'Carl'

# helper methods
api = 'https://slack.com/api/'
suffix = 'token={0}&pretty=1'.format(token)

def fetch(route, args=''):
  '''Make a GET request for data at `url` and return formatted JSON'''
  url = api + route + '?' + suffix + '&' + args
  return loads(requests.get(url).text)

# find the user whose dm messages should be removed
target_user = [i for i in fetch('users.list')['members'] if dm_name in i['real_name']]
if not target_user:
  print(' ! your target user could not be found')
  sys.exit()

# find the channel with messages to the target user
channel = [i for i in fetch('im.list')['ims'] if i['user'] == target_user[0]['id']]
if not channel:
  print(' ! your target channel could not be found')
  sys.exit()

# fetch and delete all messages
print(' * querying for channel', channel[0]['id'], 'with target user', target_user[0]['id'])
args = 'channel=' + channel[0]['id'] + '&limit=100'
result = fetch('conversations.history', args=args)
messages = result['messages']
print(' * has more:', result['has_more'], result.get('response_metadata', {}).get('next_cursor', ''))
while result['has_more']:
  cursor = result['response_metadata']['next_cursor']
  result = fetch('conversations.history', args=args + '&cursor=' + cursor)
  messages += result['messages']
  print(' * next page has more:', result['has_more'])

for idx, i in enumerate(messages):
  # tier 3 method rate limit: https://api.slack.com/methods/chat.delete
  # all rate limits: https://api.slack.com/docs/rate-limits#tiers
  time.sleep(1.05)
  result = fetch('chat.delete', args='channel={0}&ts={1}'.format(channel[0]['id'], i['ts']))
  print(' * deleted', idx+1, 'of', len(messages), 'messages', i['text'])
  if result.get('error', '') == 'ratelimited':
    print('\n ! sorry there have been too many requests. Please wait a little bit and try again.')
    sys.exit()
duhaime
  • 19,699
  • 8
  • 122
  • 154
-1

There is a slack tool to delete all slack messages on your workspace. Check it out: https://www.messagebender.com

mrdev
  • 429
  • 5
  • 4
-2

Here is a great chrome extension to bulk delete your slack channel/group/im messages - https://slackext.com/deleter , where you can filter the messages by star, time range, or users. BTW, it also supports load all messages in recent version, then you can load your ~8k messages as you need.

Huan
  • 238
  • 4
  • 11