Skip to content

Instantly share code, notes, and snippets.

@orion-v
Last active May 5, 2024 16:14
Show Gist options
  • Save orion-v/95cb48fa73808cdc5c589fe415cc65f1 to your computer and use it in GitHub Desktop.
Save orion-v/95cb48fa73808cdc5c589fe415cc65f1 to your computer and use it in GitHub Desktop.
Delete all messages of an user in a Discord channel or server

Delete discord user message history

This script allow for user specific message deletion from an entire server or a single channel using the browser console. This script uses discord search API and it will only delete messages of a chosen user.

How to use

1. Enable developer mode in discord

Go to user settings > appearance in discord and enable Developer mode.

2. Copy and paste the script to a file so you can change the server and author ids.

3. Replace the server and author ids with your own.

Open discord and right click on the server icon and click copy id. Replace the server id in the script with your server id. Do the same process for the author id by right clicking the avatar image.

4. Run script in console

Press F12 in Chrome or Firefox to open the console. Paste the modified script in the console and press enter.

The more messages the longer it takes. You can check if the messages have been deleted by using the search.


Notes

I think there are some channels that this script won't work with. I think they may be NSFW channels but I haven't tested enough.

Use this script at your own risk

This script was based on the following scripts https://gist.github.com/niahoo/c99284a8908cd33d59b4aff802179e9b#gistcomment-2397287 https://gist.github.com/IMcPwn/0c838a6248772c6fea1339ddad503cce

async function clearMessages() {
const server = "000000000000000000"; // server id number
const author = "000000000000000000"; // user id number
const channel = window.location.href.split('/').pop(); // remove this line to delete all messages of an user from a server
const authToken = document.body.appendChild(document.createElement`iframe`).contentWindow.localStorage.token.replace(/"/g, "");
const headers = { 'Authorization': authToken, 'Content-Type': 'application/json' };
const baseURL = `https://discordapp.com/api/v6/channels`;
let searchURL = `https://discordapp.com/api/v6/guilds/${server}/messages/search?author_id=${author}`;
if (typeof channel !== 'undefined') searchURL = searchURL + `&channel_id=${channel}`;
let clock = 0;
let interval = 500;
function delay(duration) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(), duration);
});
}
const response = await fetch(searchURL, {headers});
const json = await response.json();
console.log("There are " + json.total_results + " messages left to delete.");
await Array.from(json.messages).map(message => {
message.forEach(async function(item) {
if(item.hit == true) {
await delay(clock += interval);
await fetch(`${baseURL}/${item.channel_id}/messages/${item.id}`, { headers, method: 'DELETE' });
}
});
});
if (json.total_results > 0) {
delay(clock += interval).then(() => { clearMessages(); });
} else {
console.log("Finished deleting messages")
};
}
clearMessages();
@swordfite
Copy link

This script by a-SynKronus works well in DMs. But make sure you keep the dms of the person you want your dms deleted in open.


clearMessages= function() {
const author = "YOUR_ID_HERE";
const authToken = "YOUR_TOKEN_HERE";
const channel = window.location.href.split('/').pop();
const headers = { 'Authorization': authToken, 'Content-Type': 'application/json' };

let clock = 0;
let interval = 500;
function delay(duration) {
	return new Promise((resolve, reject) => {
		setTimeout(() => resolve(), duration);
	});
}

fetch(`https://discordapp.com/api/v6/channels/${channel}/messages/search?author_id=${author}`, {headers})
	.then(response => response.json())
	.then(json => {
		Array.from(json.messages).map(message => {
			message.forEach(function(item) {
				if(item.hit == true) {
					delay(clock += interval).then(() => { fetch(`https://discordapp.com/api/v6/channels/${item.channel_id}/messages/${item.id}`, { headers, method: 'PATCH', body: JSON.stringify({'content': 'This comment has been overwritten.'}) }) });
					delay(clock += interval).then(() => { fetch(`https://discordapp.com/api/v6/channels/${item.channel_id}/messages/${item.id}`, { headers, method: 'DELETE' }) });
				}
			});
		});

		if (json.total_results > 0) { delay(clock += interval).then(() => { clearMessages(); }); }
	});

}
clearMessages();

@marcosrocha85
Copy link

marcosrocha85 commented Nov 17, 2020

Uncaught (in promise) TypeError: document.body.appendChild(...).contentWindow.localStorage.token is undefined
When trying to use the script to delete all messages from myself in all channels.

I think Discord does not save token on localStorage anymore. Now we should use OAuth2 in order to get Authorization token.


Quick workaround: Follow this.

@scsmash3r
Copy link

Works well, but often catches up the rate limits. Thanks to @marcosrocha85 for the token tip.

@mikecann
Copy link

Okay just as a reference this works for me, deletes all of a users messages from the entire server:

async function clearMessages() {
	const server = "000000000000000000"; // server id number
	const author = "000000000000000000"; // user id number

	const authToken = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
	const headers = { 'Authorization': authToken, 'Content-Type': 'application/json' };
	const baseURL = `https://discordapp.com/api/v6/channels`;
	let searchURL = `https://discordapp.com/api/v6/guilds/${server}/messages/search?author_id=${author}`;

	let clock = 0;
	let interval = 2000;
	function delay(duration) {
		return new Promise((resolve, reject) => {
			setTimeout(() => resolve(), duration);
		});
	}

	const response = await fetch(searchURL, {headers});
	const json = await response.json();
	console.log("There are " + json.total_results + " messages left to delete.");
	await Array.from(json.messages).map(message => {
		message.forEach(async function(item) {
			if(item.hit == true) {
				await delay(clock += interval);
				await fetch(`${baseURL}/${item.channel_id}/messages/${item.id}`, { headers, method: 'DELETE' });
			}
		});
	});

	if (json.total_results > 0) { 
		delay(clock += interval).then(() => { clearMessages(); }); 
	} else {
		console.log("Finished deleting messages")
	};
}
clearMessages();

As @instinctualjealousy mentioned you need to manually get the auth token.

The "token" in Local Storage wasnt there so I refreshed the page by typing window.location.reload(). It then turned up. I grabbed it and smashed it into this script and it worked. I had to increase the timeout to 2000 otherise I would be rate limited.

@KLEPTOROTH
Copy link

Okay just as a reference this works for me, deletes all of a users messages from the entire server:

async function clearMessages() {
	const server = "000000000000000000"; // server id number
	const author = "000000000000000000"; // user id number

	const authToken = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
	const headers = { 'Authorization': authToken, 'Content-Type': 'application/json' };
	const baseURL = `https://discordapp.com/api/v6/channels`;
	let searchURL = `https://discordapp.com/api/v6/guilds/${server}/messages/search?author_id=${author}`;

	let clock = 0;
	let interval = 2000;
	function delay(duration) {
		return new Promise((resolve, reject) => {
			setTimeout(() => resolve(), duration);
		});
	}

	const response = await fetch(searchURL, {headers});
	const json = await response.json();
	console.log("There are " + json.total_results + " messages left to delete.");
	await Array.from(json.messages).map(message => {
		message.forEach(async function(item) {
			if(item.hit == true) {
				await delay(clock += interval);
				await fetch(`${baseURL}/${item.channel_id}/messages/${item.id}`, { headers, method: 'DELETE' });
			}
		});
	});

	if (json.total_results > 0) { 
		delay(clock += interval).then(() => { clearMessages(); }); 
	} else {
		console.log("Finished deleting messages")
	};
}
clearMessages();

As @instinctualjealousy mentioned you need to manually get the auth token.

The "token" in Local Storage wasnt there so I refreshed the page by typing window.location.reload(). It then turned up. I grabbed it and smashed it into this script and it worked. I had to increase the timeout to 2000 otherise I would be rate limited.

Thank you so much for this! One problem I'm having running this, is it didn't delete ALL messages from the user. I can still search and see many messages from the user I targeted. I did see some of them disappear, but it only got about 200 of 900+ messages. Any ideas why this would be?

@sbaysan21
Copy link

sbaysan21 commented Apr 2, 2022

Thank you so much for this! One problem I'm having running this, is it didn't delete ALL messages from the user. I can still search and see many messages from the user I targeted. I did see some of them disappear, but it only got about 200 of 900+ messages. Any ideas why this would be?

This same thing happened to me where it stopped deleting messages after about getting through 10% of what I wanted to get rid of. I figured out that it wasn't deleting messages that were archived in threads, so I had to unarchive them manually.

@0xAskar
Copy link

0xAskar commented Oct 13, 2022

I'm still getting rate limited even with using your exact script @mikecann. thoughts on why? Interval is 2000 ms right now

@PatrickKing
Copy link

PatrickKing commented Oct 26, 2022

I've created a modified version of the above script which pays attention to the server error that indicates we're being rate limited, and which pauses for a bit. It still has issues, in particular it doesn't handle the failure to delete a message due to it being archived.

It works for me. As before, this comes with zero warranty, use at your own risk!

Edited to add: when deleting many messages from the same channel it's common to see 'try again later' values higher than 7000 ms. But, often many messages can be deleted in a row without being rate limited

Edited again: modified to print an URL to archived messages, to more easily track them down.

function clearMessages () {
  const server = "000000000000000000"; // server id number
  const author = "000000000000000000"; // user id number

  const channel = window.location.href.split('/').pop(); // remove this line to delete all messages of an user from a server

  const authToken = document.body.appendChild(document.createElement`iframe`).contentWindow.localStorage.token.replace(/"/g, "");
  const headers = { 'Authorization': authToken, 'Content-Type': 'application/json' };
  const baseURL = `https://discordapp.com/api/v6/channels`;
  let searchURL = `https://discordapp.com/api/v6/guilds/${server}/messages/search?author_id=${author}`;
  if (typeof channel !== 'undefined') searchURL = searchURL + `&channel_id=${channel}`;


  let itemsForDeletion = []

  function checkForMessages () {
    fetch(searchURL, {headers})
    .then((response) => {
      return response.json()
    })
    .then((json) => {
      console.log("There are " + json.total_results + " messages left to delete.");
      if (json.total_results === 0) {
        console.log('Finished deleting messages!')
        return
      }

      for (const message of json.messages) {
        for (const item of message) {
          if (item.hit === true) {
            itemsForDeletion.push(item)
          }
        }
      }

      deleteNextMessage()
    })
  }

  function deleteNextMessage () {

    if (itemsForDeletion.length === 0) {
      checkForMessages()
      return
    }

    const item = itemsForDeletion[itemsForDeletion.length - 1]

    fetch(`${baseURL}/${item.channel_id}/messages/${item.id}`, { headers, method: 'DELETE' })
    .then((response) => {

      if (response.status === 200 || response.status === 204) {
        itemsForDeletion.pop()
        deleteNextMessage()
      }
      else if (response.status === 429) {
        // too many requests
        response.json().then((errorJson) => {
          console.log(`Waiting (${errorJson.retry_after}ms)`)
          setTimeout(deleteNextMessage, errorJson.retry_after)
        })
      }
      else if (response.status === 400) {
        console.log(`Check whether this message is in an archived/closed thread: https://discord.com/channels/${server}/${item.channel_id}/${item.id}`)
        itemsForDeletion.pop()
        deleteNextMessage()
      }
      else {
        itemsForDeletion.pop()
        deleteNextMessage()
      }

    })
    .catch((error) => {
      console.log(error)
    })

  }

  checkForMessages()

}

clearMessages()

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