4f126c7def72d814bfc99981444106f524abbb5d
[discord-clear.git] / delete-private.py
1 # Discord private message full removal script - public domain
2 #
3 # Usage:
4 # 1. Place this script next to the extracted package/ directory
5 # 2. Create auth.txt with your discord auth token in it
6 # 3. On the terminal enter:
7 # python3 delete-private.py
8 #
9 import os, json, csv, atexit, time, requests
10
11 delete_total = 0
12 all_messages = []
13 auth = ""
14
15 # Get auth token
16 # =============================================================================
17 try:
18 with open( "auth.txt" ) as a:
19 auth = a.readlines()[0].strip()
20 except:
21 print( "Error: no auth.txt found" )
22 exit(0)
23
24 # Crash recovery
25 # =============================================================================
26 print( "Step 1/3: Resume state... ", end="" )
27
28 def exit_handler():
29 with open( "delete_total.txt", "w" ) as cur:
30 cur.write( str(delete_total) )
31
32 atexit.register(exit_handler)
33
34 try:
35 with open( "delete_total.txt", "r" ) as cur:
36 delete_total = int(cur.read())
37 print( "restored" )
38 except:
39 print( "starting new" )
40
41 # Collect messages
42 # =============================================================================
43 print( "Step 2/3: Collect messages... ", end="" )
44
45 for d in os.listdir( "package/messages" ):
46 channel_path = "package/messages/" + d + "/"
47
48 if os.path.isdir( channel_path ):
49 with open( channel_path + "channel.json" ) as index:
50 data = json.load( index )
51
52 # Filter for non-public channel types, these are the only type of
53 # channels we are garunteed to have access to.
54 if data["type"] != 0:
55 with open( channel_path + "messages.csv" ) as messages:
56 reader = csv.reader( messages, delimiter=',', quotechar='"' )
57 i = 0
58 for row in reader:
59 if not i == 0:
60 all_messages.append((data["id"],row[0]))
61 i += 1
62
63 print( "done" )
64
65 # Delete all messages
66 # =============================================================================
67 time_hours = ((len(all_messages)-delete_total)*4)/60/60
68
69 print( "Step 3/3: Delete, ETA: {:.2f} hours".format(time_hours) )
70 print( "===============================" )
71
72 while delete_total < len( all_messages ):
73 percentage = (delete_total / len(all_messages)) * 100.0
74
75 print("{:.2f}% | Process message {} of {}: ".format(
76 percentage, delete_total, len(all_messages)), end=""
77 )
78
79 api_url = "https://discord.com/api/v6/channels/{}/messages/{}".format(
80 all_messages[ delete_total ][0], all_messages[ delete_total ][1]
81 )
82
83 x = requests.delete( api_url, headers = { "Authorization": auth } )
84
85 if x.status_code != 204:
86 print( "ERROR: " + str(x.status_code) )
87 with open( "failed_urls.txt", "a" ) as errs:
88 errs.write( "{},{}\n".format(x.status_code, api_url) )
89 else:
90 print( "204, deleted" )
91
92 delete_total += 1
93 time.sleep( 4 )