Skip to content

Instantly share code, notes, and snippets.

@rcx
Forked from niahoo/delete-all-messages.js
Last active November 9, 2023 19:12
Show Gist options
  • Star 29 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save rcx/a29eac843a8ecf97a22accb34ef60b88 to your computer and use it in GitHub Desktop.
Save rcx/a29eac843a8ecf97a22accb34ef60b88 to your computer and use it in GitHub Desktop.
Delete all your messages in a Discord channel
/*
* Discord: Don't copy stuff into this box
* Me: dOn'T COpy sTuFf iNtO tHIs bOx
*/
clearMessages = function (guild_id, author_id, authToken, deleted = new Set()) {
if (guild_id[0] == "_" && guild_id[guild_id.length - 1] == "_") {
alert("Oops! You forgot to set the guild_id. Please fill it in.")
return;
}
if (author_id[0] == "_" && author_id[author_id.length - 1] == "_") {
alert("Oops! You forgot to set the author_id. Please fill it in.")
return;
}
const searchURL = `https://discordapp.com/api/v9/guilds/${guild_id}/messages/search?author_id=${author_id}&include_nsfw=true&sort_by=timestamp&sort_order=asc`
const headers = { Authorization: authToken }
let clock = 0
interval = 3000
function delay(duration) {
return new Promise((resolve, reject) => {
setTimeout(resolve, duration)
})
}
function loadMessages() {
return fetch(searchURL, { headers })
}
function tryDeleteMessage(message) {
// RAce coNDItiOn
if (!deleted.has(message.id)) { // skip already deleted messages
console.log(`Deleting message ${message.id} from ${message.author.username} (${message.content}...)`)
return fetch(`https://discordapp.com/api/v9/channels/${message.channel_id}/messages/${message.id}`, { headers, method: 'DELETE' })
}
}
let messagesStore = []
loadMessages()
.then(resp => resp.json())
.then(messages => {
messages = messages.messages
if (messages === undefined || messages === null || messages.length == 0) {
console.log(`Couldn't load messages. Check guild id, author id, and auth token.`)
return
}
messages = messages.filter(m => m) // clean undefined
messages = [].concat.apply([], messages); // flatten
messages = messages.filter(m => m) // clean undefined
if (messages.length === 0) {
console.log(`Couldn't load messages. Check guild id, author id, and auth token.`)
return
}
// only delete hits
messages = messages.filter(m => m.hit == true)
// unique by id
messages = messages.filter((e, i) => messages.findIndex(a => a.id === e.id) === i);
beforeId = messages[messages.length-1].id
messagesStore = messagesStore.concat(messages)
return Promise.all(messagesStore.map(message => {
return delay(clock += interval)
.then(() => tryDeleteMessage(message))
.then(resp => {
if (resp) {
if (resp.status == 429) {
interval += 100
console.log(`Too fast; bumping interval to ${interval}`)
} else if (resp.status === 204) {
deleted.add(message.id) // mark deleted
return resp.text()
}
}
})
}))
})
.then(function() {
if (messagesStore.length !== 0) {
clearMessages(guild_id, author_id, authToken, deleted)
} else {
console.log(`We have loaded all messages in this chat.`)
}
})
}
// If the script is having trouble automatically grabbing auth token, please fill it in manually here. Check README for instructions.
authToken = "";
guild_id = '____________guild_id_here_______________'
author_id = '____________author_id_here______________'
function grabAuthTokenFast() {
var localToken = document.body.appendChild(document.createElement(`iframe`)).contentWindow.localStorage.token;
if (localToken !== undefined) {
authToken = JSON.parse(localToken);
return true;
}
return false;
}
function grabAuthToken() {
if (authToken.length === 0) {
// Lmao bypass token security measures
window.onbeforeunload = grabAuthToken;
window.location.reload();
// yoink
var localToken = document.body.appendChild(document.createElement(`iframe`)).contentWindow.localStorage.token;
if (localToken !== undefined) {
authToken = JSON.parse(localToken);
setTimeout(main, 100, authToken);
}
}
return false;
}
function main(authToken) {
if (authToken.length !== 0) {
console.log(`Successfully grabbed your auth token: ` + authToken)
console.log(`Don't share this token with anyone!`)
clearMessages(guild_id, author_id, authToken);
} else {
console.log(`Getting the auth token from localStorage isn't supported on your client. Use Firefox or grab it from a network request's headers.`)
console.log(`To do that go to the Network tab of your inspector and copy the Authorization header of a request. There are detailed instructions in the README.`)
}
}
if (grabAuthTokenFast()) {
console.log("Successfully grabbed auth token using easy method");
main(authToken);
} else {
window.alert("Grabbing your auth token. If a confirm window shows up, please click 'Cancel' in Chrome / 'Stay on Page' in Firefox.");
if (authToken.length !== 0) {
main(authToken);
} else {
grabAuthToken();
}
}

Delete all messages in a Discord channel

This works best in Firefox, I haven't tested it in Chrome. On the desktop client, it may have trouble getting the Auth token from LocalStorage so you need to grab it from a request's headers and replace the parameter "authToken" on the last line with it. There's instructions on how to do that below.

Preqrequisites:

  • computer
  • general knowledge of your browser's inspector/developer tools
  • possibly even a brain

1. Grab guild and author ids

The script uses the internal id values Discord refers to the selected server and user by. The easy way to do this is to enable Developer Mode in your Discord settings, after which you can simply right click the server's icon and your name and click "Copy ID". Otherwise, you can grab the server's id from the URL, and you can get your own id using the network tab of your browser's inspector.

2. Get your authorization token (now automated)

This is now automated thanks to @cntVertex, despite Discord "hiding" the token from localStorage and the DOM. If it isn't able to automatically grab it then you need to get it from a network request. Follow these easy steps:

  1. Open the inspector (Ctrl-Shift-I)
  2. Open the Network tab of your inspector
  3. Open any request to Discord's servers
  4. Look for the "Authorization" request header. Copy that into the line var authToken = "". For example it might look like var authToken = "mfa.a9ushg92ru9gh9ufhsgjuidfhsgiojfhgjishefrgih3er9u3rg_asdfu9ghauisdfhguiahsdguiahsdigua"

3. Get the script

Copy-paste the script into the javascript console, and replace ____________guild_id_here_______________ and ____________author_id_here______________ with the respective ids copied in Step 1.

4. Launch

Strike the Return key on your keyboard...come on, this is not rocket science man.

Also if it does not get your auth token successfully the first time just try running it again.

FAQ

  • How do I use this to delete DMs? Replace searchURL with https://discordapp.com/api/v6/channels/${guild_id}/messages/search?author_id=${author_id}&include_nsfw=true. For example, replace this line:
const searchURL = `https://discordapp.com/api/v8/guilds/${guild_id}/messages/search?author_id=${author_id}&include_nsfw=true`

with

const searchURL = `https://discordapp.com/api/v8/channels/${guild_id}/messages/search?author_id=${author_id}&include_nsfw=true`

The guild_id however isn't the ID of the person who you are DMing. It is actually the ID of the channel of the DM which is a subtle but important distinction. I'm not aware of any easy way to grab this other than to just look at the network inspector under the developer tools.

  • How to delete by oldest messages first?

Add &sort_by=timestamp&sort_order=asc to searchURL

  • How to only delete messages containing some text "abcd"?

Add &content=whatever into the searchURL. For example, https://discordapp.com/api/v6/channels/${guild_id}/messages/search?author_id=${author_id}&include_nsfw=true&content=badword to delete only messages containing "badword".

  • (By @ivmirx) If you want to delete messages before a specific date, do the following:
  1. Open any server to make the search field visible.
  2. Open the "Network" tab in the inspector and clean it from old requests with the trash can icon.
  3. Click in Discord's search field to show the dropdown, then click the "before" option.
  4. Select the date in the calendar.
  5. In the "Network" tab look for the request that contains ?max_id=....
  6. Click on it and copy the max_id=... part from the URL on the right.
  7. Append it to the script's request in the Line 6 by using &.

So now you should have something like: https://discordapp.com/api/v6/guilds/${guild_id}/messages/search?author_id=${author_id}&include_nsfw=true&max_id=540727993958400000 (this example is for 2019-02-01). Also, by manually picking searchURL, you can delete messages matching a certain query, like mentioning someone, containing certain words, etc.

  • Is there a python version of this script so I can run it without opening Discord

Yes

@littlemower
Copy link

can anyone add me on discord to help me get this work? My discord is LittleMower#3447 Please!

@Raizen9
Copy link

Raizen9 commented Nov 23, 2019

It's not working anymore ?

@rcx
Copy link
Author

rcx commented Nov 23, 2019 via email

@Raizen9
Copy link

Raizen9 commented Nov 25, 2019

image
i get this but i still have messages on the server

@rcx
Copy link
Author

rcx commented Nov 27, 2019

I'm sorry... the script still works for me. Verify the guild id, author id, and auth token are configured properly in your copy of the script
Edit: Also I updated the script to make it easier to use, and fixed a bug grabbing the auth token on Desktop client.

@Raizen9
Copy link

Raizen9 commented Nov 28, 2019

Ok , It's working on chrome but not on brave , i'm on linux mint btw

@Unknown854
Copy link

Unknown854 commented Dec 1, 2019

Is there a way to get this to work for servers I'm no longer part of? I have the server IDs etc

@rcx
Copy link
Author

rcx commented Dec 1, 2019 via email

@sprokets101
Copy link

Hello again, I've been attempting to delete messages in a DM but it refuses to work. I've used your script successfully in the past numerous times and I also tried using victornpb's automated popup window script but every attempt gives me

"Error searching messages, API responded with status 404!
{"message":"404: Not Found","code":0}"

While your script gives me the following error:

d3beeefa39d6294d8b2a.js:53 GET https://discordapp.com/api/v6/channels/[the channel ID I'm trying to delete]/messages/search?author_id=[my author ID]&include_nsfw=true 404
(anonymous) @ d3beeefa39d6294d8b2a.js:53
loadMessages @ VM484:16
clearMessages @ VM484:27
(anonymous) @ VM484:82
d3beeefa39d6294d8b2a.js:53 Couldn't load messages. Check guild id, author id, and auth token.

Is this a temporary problem do you think, or has Discord changed something in their APIs?

Thanks!

@rcx
Copy link
Author

rcx commented Dec 16, 2019

@sprokets101

Hi, that api still works for me. Make sure you're using the right channel ID-- it's NOT the same as the USER id of the person you are trying to delete DMs for. You need the CHANNEL id of that dm.

@sprokets101
Copy link

@ec86

Hi, there seemed to be a problem with the API being down. I tried it again and it worked today, exact same script with the exact same figures.

Thanks, as ever, for maintaining this excellent tool. Happy holidays!

@Milamber59
Copy link

Hey guys. It's not working for me, i also checked every ID and the api can read messages but can't delete them (error 403)
Any idea?

**
image
**

@rcx
Copy link
Author

rcx commented Mar 23, 2020

@Milamber59 I have no idea, this script works for me this whole time.

@rcx
Copy link
Author

rcx commented Apr 4, 2020

Updated script so it works seamlessly in Discord electron client

@rcx
Copy link
Author

rcx commented Sep 14, 2020

Updated default frequency as Discord seems ever so slightly more stringent now

@rcx
Copy link
Author

rcx commented Oct 20, 2020

Updated: By default, delete by oldest first

@rcx
Copy link
Author

rcx commented Jul 19, 2021

Updated

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