Files
discord-selfbot/commands/delete.js

346 lines
13 KiB
JavaScript
Raw Permalink Normal View History

2024-09-08 10:50:45 -04:00
let isDeleting = false;
let cancelDelete = false;
2025-04-10 15:09:11 -04:00
let deletedMessages = new Set();
const CACHE_CLEANUP_INTERVAL = 30 * 60 * 1000;
2025-04-10 15:50:25 -04:00
const { sendCommandResponse } = require('../utils/messageUtils');
2025-04-10 15:09:11 -04:00
setInterval(() => {
if (deletedMessages.size > 1000) {
console.log(`[DELETE] Cleaning message cache (size: ${deletedMessages.size})`);
deletedMessages.clear();
}
}, CACHE_CLEANUP_INTERVAL);
2024-09-08 10:50:45 -04:00
2024-02-05 19:18:42 -05:00
module.exports = {
name: 'delete',
2024-09-08 10:50:45 -04:00
description: 'Delete a specified number of your messages or all messages from a server with human-like delays.',
2024-02-05 19:18:42 -05:00
async execute(message, args, deleteTimeout) {
2024-09-08 10:50:45 -04:00
if (args[0] && args[0].toLowerCase() === 'cancel') {
cancelDelete = true;
2025-04-10 15:50:25 -04:00
await sendCommandResponse(message, 'Delete operation canceled.', deleteTimeout, true);
2024-09-08 10:50:45 -04:00
return;
}
if (isDeleting) {
2025-04-10 15:50:25 -04:00
await sendCommandResponse(message, 'A delete operation is already in progress. Please wait or cancel it with `.delete cancel`.', deleteTimeout, true);
2024-09-08 10:50:45 -04:00
return;
}
isDeleting = true;
cancelDelete = false;
2025-04-10 15:09:11 -04:00
let speed = 'medium';
if (args[0] && ['slow', 'medium', 'fast'].includes(args[0].toLowerCase())) {
speed = args[0].toLowerCase();
2025-04-10 15:34:40 -04:00
args.shift();
2025-04-10 15:09:11 -04:00
}
2024-02-05 19:18:42 -05:00
const deleteCount = parseInt(args[0], 10);
2024-09-08 10:50:45 -04:00
const targetGuildId = args[1];
2024-02-05 19:18:42 -05:00
2024-09-08 10:50:45 -04:00
if (!isNaN(deleteCount) && deleteCount > 0) {
2025-04-10 15:09:11 -04:00
await deleteMessagesFromChannel(message, deleteCount, deleteTimeout, speed);
2024-09-08 10:50:45 -04:00
} else if (targetGuildId) {
2025-04-10 15:09:11 -04:00
await deleteMessagesFromServer(message, targetGuildId, deleteTimeout, speed);
2024-09-08 10:50:45 -04:00
} else {
2025-04-10 15:50:25 -04:00
await sendCommandResponse(message, 'Please specify how many messages to delete or a server ID. You can also set speed: `.delete [slow/medium/fast] [count/server]`', deleteTimeout, true);
2024-02-05 19:18:42 -05:00
}
2024-09-08 10:50:45 -04:00
isDeleting = false;
},
};
2025-04-10 15:09:11 -04:00
async function deleteMessagesFromChannel(message, deleteCount, deleteTimeout, speed = 'medium') {
let deleteIntervalMin, deleteIntervalMax, jitterFactor, pauseChance, pauseLengthMin, pauseLengthMax, batchSize;
switch(speed) {
case 'slow':
deleteIntervalMin = 3000;
deleteIntervalMax = 6000;
jitterFactor = 0.5;
pauseChance = 0.25;
pauseLengthMin = 15000;
pauseLengthMax = 45000;
batchSize = 5;
break;
case 'fast':
deleteIntervalMin = 1500;
deleteIntervalMax = 3000;
jitterFactor = 0.3;
pauseChance = 0.05;
pauseLengthMin = 5000;
pauseLengthMax = 15000;
batchSize = 15;
break;
case 'medium':
default:
deleteIntervalMin = 2000;
deleteIntervalMax = 4500;
jitterFactor = 0.4;
pauseChance = 0.15;
pauseLengthMin = 10000;
pauseLengthMax = 30000;
batchSize = 10;
}
const getHumanlikeDelay = () => {
const baseInterval = Math.floor(Math.random() * (deleteIntervalMax - deleteIntervalMin + 1)) + deleteIntervalMin;
const jitterAmount = baseInterval * jitterFactor;
const jitter = Math.random() * jitterAmount * 2 - jitterAmount;
return Math.max(1000, Math.floor(baseInterval + jitter));
};
2025-04-10 15:34:40 -04:00
const getReadingDelay = () => Math.floor(Math.random() * 3000) + 1000;
2024-09-08 10:50:45 -04:00
try {
2025-04-10 15:09:11 -04:00
console.log(`[DELETE] Starting deletion of up to ${deleteCount} messages with ${speed} speed`);
let deletedCount = 0;
let batchCount = 0;
while (deletedCount < deleteCount && !cancelDelete) {
if (deletedCount > 0 && deletedCount % 25 === 0) {
console.log(`[DELETE] Progress: ${deletedCount}/${deleteCount} messages deleted`);
}
const fetchLimit = Math.min(deleteCount - deletedCount, batchSize);
2025-04-10 15:34:40 -04:00
const messages = await message.channel.messages.fetch({ limit: 100 });
2025-04-10 15:09:11 -04:00
const filteredMessages = messages.filter(msg =>
msg.author.id === message.author.id &&
!deletedMessages.has(msg.id)
);
if (filteredMessages.size === 0) {
console.log(`[DELETE] No more messages found in this channel`);
break;
}
batchCount++;
let messagesInThisBatch = 0;
2024-09-08 10:50:45 -04:00
for (const msg of filteredMessages.values()) {
2025-04-10 15:09:11 -04:00
if (cancelDelete) {
console.log(`[DELETE] Operation canceled by user`);
return;
}
if (deletedCount >= deleteCount) break;
2024-09-08 10:50:45 -04:00
try {
2025-04-10 15:09:11 -04:00
if (msg.deletable && !msg.deleted && !deletedMessages.has(msg.id)) {
if (Math.random() < 0.25) {
const readingDelay = getReadingDelay();
console.log(`[DELETE] Taking ${readingDelay}ms to "read" before deleting message ${msg.id}`);
await new Promise(resolve => setTimeout(resolve, readingDelay));
}
const preDeleteDelay = Math.floor(Math.random() * 1000) + 250;
await new Promise(resolve => setTimeout(resolve, preDeleteDelay));
2024-09-08 10:50:45 -04:00
await msg.delete().catch(err => {
2025-04-10 15:09:11 -04:00
if (err.code === 10008) {
console.log(`[DELETE] Message ${msg.id} already deleted`);
deletedMessages.add(msg.id);
} else if (err.code === 429) {
console.log(`[DELETE] Rate limited. Taking a longer break...`);
return;
} else {
console.error(`[DELETE] Failed to delete message:`, err);
2024-09-08 10:50:45 -04:00
}
});
2025-04-10 15:09:11 -04:00
deletedMessages.add(msg.id);
deletedCount++;
messagesInThisBatch++;
const delay = getHumanlikeDelay();
console.log(`[DELETE] Waiting ${delay}ms before next deletion`);
await new Promise(resolve => setTimeout(resolve, delay));
2024-09-08 10:50:45 -04:00
}
} catch (error) {
2025-04-10 15:09:11 -04:00
console.error('[DELETE] Error deleting message:', error);
2024-09-08 10:50:45 -04:00
}
}
2025-04-10 15:09:11 -04:00
if (messagesInThisBatch === 0) {
console.log(`[DELETE] No deletable messages found in batch`);
break;
2024-09-08 10:50:45 -04:00
}
2025-04-10 15:09:11 -04:00
if (!cancelDelete && deletedCount < deleteCount) {
const adjustedPauseChance = pauseChance * (1 + (Math.min(batchCount, 5) / 10));
if (Math.random() < adjustedPauseChance) {
const pauseDuration = Math.floor(Math.random() * (pauseLengthMax - pauseLengthMin + 1)) + pauseLengthMin;
console.log(`[DELETE] Taking a break for ${Math.round(pauseDuration/1000)} seconds. Progress: ${deletedCount}/${deleteCount}`);
await new Promise(resolve => setTimeout(resolve, pauseDuration));
2025-04-10 15:34:40 -04:00
batchCount = 0;
2025-04-10 15:09:11 -04:00
}
}
}
if (cancelDelete) {
2025-04-10 15:50:25 -04:00
await sendCommandResponse(message, `Delete operation canceled after removing ${deletedCount} messages.`, deleteTimeout, true);
2025-04-10 15:09:11 -04:00
} else {
2025-04-10 15:50:25 -04:00
await sendCommandResponse(message, `Finished deleting ${deletedCount} messages.`, deleteTimeout, true);
2024-09-08 10:50:45 -04:00
}
} catch (error) {
2025-04-10 15:09:11 -04:00
console.error('[DELETE] Failed to delete messages:', error);
2025-04-10 15:50:25 -04:00
await sendCommandResponse(message, 'There was an error while trying to delete messages.', deleteTimeout, true);
2024-09-08 10:50:45 -04:00
}
}
2025-04-10 15:09:11 -04:00
async function deleteMessagesFromServer(message, guildId, deleteTimeout, speed = 'medium') {
2024-09-08 10:50:45 -04:00
const guild = message.client.guilds.cache.get(guildId);
2024-09-08 10:35:46 -04:00
2024-09-08 10:50:45 -04:00
if (!guild) {
2025-04-10 15:50:25 -04:00
await sendCommandResponse(message, `Guild with ID ${guildId} not found.`, deleteTimeout, true);
2024-09-08 10:50:45 -04:00
return;
}
2025-04-10 15:09:11 -04:00
let deleteIntervalMin, deleteIntervalMax, jitterFactor, pauseChance, pauseLengthMin, pauseLengthMax, batchSize;
switch(speed) {
case 'slow':
deleteIntervalMin = 3000;
deleteIntervalMax = 6000;
jitterFactor = 0.5;
2025-04-10 15:34:40 -04:00
pauseChance = 0.4;
2025-04-10 15:09:11 -04:00
pauseLengthMin = 30000;
pauseLengthMax = 90000;
batchSize = 5;
break;
case 'fast':
deleteIntervalMin = 1500;
deleteIntervalMax = 3000;
jitterFactor = 0.3;
pauseChance = 0.2;
pauseLengthMin = 15000;
pauseLengthMax = 45000;
batchSize = 15;
break;
case 'medium':
default:
deleteIntervalMin = 2000;
deleteIntervalMax = 4500;
jitterFactor = 0.4;
pauseChance = 0.3;
pauseLengthMin = 20000;
pauseLengthMax = 60000;
batchSize = 10;
}
const getHumanlikeDelay = () => {
const baseInterval = Math.floor(Math.random() * (deleteIntervalMax - deleteIntervalMin + 1)) + deleteIntervalMin;
const jitterAmount = baseInterval * jitterFactor;
const jitter = Math.random() * jitterAmount * 2 - jitterAmount;
return Math.max(1000, Math.floor(baseInterval + jitter));
};
2024-09-08 10:35:46 -04:00
2025-04-10 15:09:11 -04:00
console.log(`[DELETE] Starting server-wide deletion in server: ${guild.name}`);
let totalDeleted = 0;
2024-09-08 10:35:46 -04:00
2024-09-08 10:50:45 -04:00
try {
const channels = guild.channels.cache.filter(channel => channel.isText());
2025-04-10 15:09:11 -04:00
let processedChannels = 0;
2024-09-08 10:50:45 -04:00
for (const [channelId, channel] of channels) {
2025-04-10 15:09:11 -04:00
if (cancelDelete) {
console.log(`[DELETE] Operation canceled by user`);
break;
}
processedChannels++;
console.log(`[DELETE] Processing channel ${processedChannels}/${channels.size}: ${channel.name}`);
2024-09-08 10:50:45 -04:00
let hasMoreMessages = true;
2025-04-10 15:09:11 -04:00
let messagesDeletedInChannel = 0;
let batchCount = 0;
2024-09-08 10:50:45 -04:00
while (hasMoreMessages && !cancelDelete) {
2025-04-10 15:09:11 -04:00
const messages = await channel.messages.fetch({ limit: 100 });
2024-09-08 10:35:46 -04:00
2024-09-08 10:50:45 -04:00
if (messages.size === 0) {
hasMoreMessages = false;
continue;
}
2024-09-08 10:35:46 -04:00
2025-04-10 15:09:11 -04:00
const filteredMessages = messages.filter(msg =>
msg.author.id === message.author.id &&
!deletedMessages.has(msg.id)
);
if (filteredMessages.size === 0) {
hasMoreMessages = false;
continue;
}
batchCount++;
let messagesInThisBatch = 0;
2024-09-08 10:35:46 -04:00
for (const msg of filteredMessages.values()) {
2024-09-08 10:50:45 -04:00
if (cancelDelete) return;
2025-04-10 15:09:11 -04:00
2024-09-08 10:35:46 -04:00
try {
2025-04-10 15:09:11 -04:00
if (msg.deletable && !msg.deleted && !deletedMessages.has(msg.id)) {
const preDeleteDelay = Math.floor(Math.random() * 1000) + 250;
await new Promise(resolve => setTimeout(resolve, preDeleteDelay));
2024-09-08 10:35:46 -04:00
await msg.delete().catch(err => {
2025-04-10 15:09:11 -04:00
if (err.code === 10008) {
console.log(`[DELETE] Message ${msg.id} already deleted`);
deletedMessages.add(msg.id);
} else if (err.code === 429) {
console.log(`[DELETE] Rate limited. Taking a longer break...`);
return new Promise(resolve => setTimeout(resolve, 30000 + Math.random() * 30000));
} else {
console.error(`[DELETE] Failed to delete message:`, err);
2024-09-08 10:35:46 -04:00
}
});
2025-04-10 15:09:11 -04:00
deletedMessages.add(msg.id);
totalDeleted++;
messagesDeletedInChannel++;
messagesInThisBatch++;
const delay = getHumanlikeDelay();
await new Promise(resolve => setTimeout(resolve, delay));
2024-09-08 10:35:46 -04:00
}
} catch (error) {
2025-04-10 15:09:11 -04:00
console.error('[DELETE] Error deleting message:', error);
2024-09-08 10:35:46 -04:00
}
2025-04-10 15:09:11 -04:00
if (messagesInThisBatch >= batchSize) break;
2024-09-08 10:35:46 -04:00
}
2025-04-10 15:09:11 -04:00
if (messagesInThisBatch < batchSize) {
2024-09-08 10:50:45 -04:00
hasMoreMessages = false;
} else {
2025-04-10 15:09:11 -04:00
const shouldPause = Math.random() < pauseChance;
if (shouldPause && !cancelDelete) {
const pauseDuration = Math.floor(Math.random() * (pauseLengthMin - pauseLengthMin/2 + 1)) + pauseLengthMin/2;
console.log(`[DELETE] Taking a short break for ${Math.round(pauseDuration/1000)} seconds in channel ${channel.name}. Deleted so far: ${messagesDeletedInChannel}`);
await new Promise(resolve => setTimeout(resolve, pauseDuration));
}
2024-09-08 10:35:46 -04:00
}
}
2025-04-10 15:09:11 -04:00
console.log(`[DELETE] Completed channel ${channel.name}: ${messagesDeletedInChannel} messages deleted`);
if (!cancelDelete && processedChannels < channels.size) {
const pauseDuration = Math.floor(Math.random() * (pauseLengthMax - pauseLengthMin + 1)) + pauseLengthMin;
console.log(`[DELETE] Moving to next channel in ${Math.round(pauseDuration/1000)} seconds. Total deleted so far: ${totalDeleted}`);
await new Promise(resolve => setTimeout(resolve, pauseDuration));
}
}
if (cancelDelete) {
2025-04-10 15:50:25 -04:00
await sendCommandResponse(message, `Delete operation canceled after removing ${totalDeleted} messages across ${processedChannels} channels.`, deleteTimeout, true);
2025-04-10 15:09:11 -04:00
} else {
2025-04-10 15:50:25 -04:00
await sendCommandResponse(message, `Finished cleaning up ${guild.name}: ${totalDeleted} messages deleted across ${processedChannels} channels.`, deleteTimeout, true);
2024-09-08 10:35:46 -04:00
}
2024-09-08 10:50:45 -04:00
} catch (error) {
2025-04-10 15:09:11 -04:00
console.error('[DELETE] Failed to delete messages in the server:', error);
2025-04-10 15:50:25 -04:00
await sendCommandResponse(message, 'There was an error while trying to delete messages from the server.', deleteTimeout, true);
2024-09-08 10:50:45 -04:00
}
2025-02-05 21:02:07 -05:00
}