Skip to content

Instantly share code, notes, and snippets.

@jackcarter
Last active November 29, 2023 07:03
Show Gist options
  • Save jackcarter/d86808449f0d95060a40 to your computer and use it in GitHub Desktop.
Save jackcarter/d86808449f0d95060a40 to your computer and use it in GitHub Desktop.
Delete Slack files older than 30 days. Rewrite of https://gist.github.com/jamescmartinez/909401b19c0f779fc9c1
import requests
import time
import json
token = ''
#Delete files older than this:
ts_to = int(time.time()) - 30 * 24 * 60 * 60
def list_files():
params = {
'token': token
,'ts_to': ts_to
,'count': 1000
}
uri = 'https://slack.com/api/files.list'
response = requests.get(uri, params=params)
return json.loads(response.text)['files']
def delete_files(file_ids):
count = 0
num_files = len(file_ids)
for file_id in file_ids:
count = count + 1
params = {
'token': token
,'file': file_id
}
uri = 'https://slack.com/api/files.delete'
response = requests.get(uri, params=params)
print count, "of", num_files, "-", file_id, json.loads(response.text)['ok']
files = list_files()
file_ids = [f['id'] for f in files]
delete_files(file_ids)
@jindov
Copy link

jindov commented Mar 4, 2019

I update this script because I want to delete file by id, this will handle case can't not delete because the file is not belong to another user and workaround ratelimit of Slack's API. With some default value as count=1000. You have to get a list of id, token, username to fill in the users list. Run with command python slack_delete.py --days 30. Note python 2.7

import argparse
import requests
import time
import json
requests.packages.urllib3.disable_warnings()

users = [{"name": "myName", "user":"UDPKXJ8JU", "token": "xoxp-xxxxxxxxxx"}]

def main():
    """
    Entry point of the application
    :return: void
    """
    parser = argparse.ArgumentParser()
    parser.add_argument("-d", "--days", type=int, default=None, help="Delete files older than x days (optional)")
    options = parser.parse_args()

    try:
        print "[*] Fetching file list.."
        file_ids = list_file_ids(days=options.days)
    except KeyboardInterrupt:
        print "\b\b[-] Aborted"
        exit(1)

def calculate_days(days):
    """
    Calculate days to unix time
    :param days: int
    :return: int
    """
    return int(time.time()) - days * 24 * 60 * 60

def list_file_ids(days=None):
    for user in users:
        user_name = user['name']
        print "delete files of user: "+user_name
        user_id = user['user']
        user_token = user['token']
        if days:
            params = {'token': user_token, 'count': 1000, 'ts_to': calculate_days(days), 'user': user_id}
            print "ts_to: ", calculate_days(days)
        else:
            params = {'token': user_token, 'count': 1000, 'user': user_id}
        uri = 'https://slack.com/api/files.list'
        response = requests.get(uri, params=params).json()
        files = response['files']
        #return [f['id'] for f in files]
        print [f['id'] for f in files]
        for f in files:
            dresponse = json.loads(requests.get('https://slack.com/api/files.delete', params={'token': user_token, 'file': f['id']}).text)
            time.sleep(2)
            if dresponse["ok"]:
                print "[+] Deleted: ", f['id']
            else:
                print "[!] Unable to delete: ", f['id'] + ", reason:", dresponse["error"]

if __name__ == '__main__':
    main()

@Redsandro
Copy link

api.slack.com is a maze. I've tried so many tokens. Where exactly do I get the proper token? Or this user and token combination?

@Bears-Beets-BSG
Copy link

I'm not a programmer/coder, but I love tinkering with code to get stuff done more efficiently. Apologies in advance if anything below is wrong/misleading. I hope it helps others running into this problem.

We have long ago reached and passed the storage limit of our free Slack plan (>22GB). Naturally, older files were "tombstoned" or archived automatically once our storage usage passed 5.0GB. I've been trying to figure how to delete the tombstoned files using this script or its variations above (thank you for all the work, by the way!) to no avail. It seems I missed a little section in the Slack API documentation:

In order to gather information on tombstoned files in Free workspaces, so that you can delete or revoke them, pass the show_files_hidden_by_limit parameter. While the yielded files will still be redacted, you'll gain the id of the files so that you can delete or revoke them.

In @jackcarter's original code at the top, which worked fine for me except for the "hidden" files, I added the missing parameter as below. (I also used a workspace owner legacy token.)

def list_files():
   params = {
    'token': token,  
    'ts_to': ts_to,  
    'count': 1000,  
    'show_files_hidden_by_limit': 1,  
}

It seems to have worked. I've deleted thousands more files older than X days. Slack analytics also showed a significant decrease in storage usage. Unfortunately, and as confirmed with Slack Support, (with a Free plan) we are unable to see or delete files shared by users in private channels or direct messages, even through the API.

Anyway, hope this still helps someone.

@IlanVivanco
Copy link

As of today, legacy tester tokens may no longer be created.
However, you can still use this script following this steps:

  1. Create a Slack app on https://api.slack.com/apps?new_app=1 and assign that to your workspace.

  2. Then within this new app, go to OAuth & Permissions and in the section Scopes > User Token Scopes add the files:read and files:write Oauth scopes.

  3. Finally, you can now go to the top of the page and install the app to the workspace. After that you'll get the User OAuth Token that you can use on the script.

* Bare in mind that if you forget to add the scopes, or you need to modify them after you install the app to the workspace, you would need to reinstall it after changing the scopes.

I have also adapted the code to work with the Oauth authentication.
https://gist.github.com/IlanVivanco/d2a96abb364ccb3b59e198f1c5fdf673

@dengwt
Copy link

dengwt commented Jul 13, 2021

@IlanVivanco good job! saved my time.

@dgarciam
Copy link

None of the scripts listed here works anymore for me. Something changed @slack?

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