import { Message } from "discord.js"; import { logUnexpectedDiscordAPIError, replyWithCleanup } from "../utilities"; import { logUnexpectedDiscordAPIResult } from "../../../shared/log"; import { disableMessageDeletionListener, enableMessageDeletionListener, } from "../listeners/messageDeletion"; export const handleDeleteCommand = async (message: Message) => { if (message.author.bot) return; if (message.content.toLowerCase().startsWith("uma!delete")) { const application = await message.client.application?.fetch(); const ownerId = application?.owner?.id; if (message.author.id !== ownerId) { await replyWithCleanup( message, "❌ Only the server owner can use this command.", ); return; } const parameters = message.content.split(" ").slice(1); if (parameters.length < 1) { await replyWithCleanup( message, "❌ Usage: `uma!delete [channel_id] [message_id2] [message_id3] ...`\nExamples:\n- `uma!delete 1234567890123456789` (current channel)\n- `uma!delete 9876543210987654321 1234567890123456789 1111111111111111111` (specific channel, multiple messages)", ); return; } let targetChannel = null; let messageIds: string[] = []; if (parameters.length === 1) { messageIds = [parameters[0]]; targetChannel = message.channel; } else { const channelId = parameters[0]; messageIds = parameters.slice(1); if (!/^\d{17,19}$/.test(channelId)) { await message.reply( "❌ Invalid channel ID format. Please provide a valid Discord channel ID.", ); return; } targetChannel = message.client.channels.cache.get(channelId); if (!targetChannel || !targetChannel.isTextBased()) { await message.reply("❌ Channel not found or is not a text channel."); return; } } for (const messageId of messageIds) if (!/^\d{17,19}$/.test(messageId)) { await message.reply( "❌ Invalid message ID format. Please provide valid Discord message IDs.", ); return; } disableMessageDeletionListener(); try { if (messageIds.length > 1) { try { const messagesToDelete = []; let failedFetchCount = 0; for (const messageId of messageIds) try { const targetMessage = await targetChannel.messages.fetch(messageId); messagesToDelete.push(targetMessage); } catch { failedFetchCount += 1; } if (messagesToDelete.length === 0) { await message.reply("❌ No valid messages found to delete."); return; } if ("bulkDelete" in targetChannel && messagesToDelete.length > 1) { try { await targetChannel.bulkDelete(messagesToDelete); await message.delete(); if (failedFetchCount > 0) logUnexpectedDiscordAPIResult( `Failed to fetch ${failedFetchCount} out of ${messageIds.length} messages for bulk delete`, ); } catch (bulkError) { logUnexpectedDiscordAPIError(bulkError); let failedDeleteCount = 0; for (const message of messagesToDelete) try { await message.delete(); } catch { failedDeleteCount += 1; } await message.delete(); if (failedDeleteCount > 0 || failedFetchCount > 0) logUnexpectedDiscordAPIResult( `Failed to delete ${failedDeleteCount} messages and fetch ${failedFetchCount} messages`, ); } } else { let failedDeleteCount = 0; for (const message of messagesToDelete) try { await message.delete(); } catch { failedDeleteCount += 1; } await message.delete(); if (failedDeleteCount > 0 || failedFetchCount > 0) logUnexpectedDiscordAPIResult( `Failed to delete ${failedDeleteCount} messages and fetch ${failedFetchCount} messages`, ); } } catch (error) { logUnexpectedDiscordAPIError(error); await message.reply( "❌ Failed to delete messages. Check bot permissions and try again.", ); } } else { try { const targetMessage = await targetChannel.messages.fetch( messageIds[0], ); await targetMessage.delete(); await message.delete(); } catch { await message.reply( "❌ Failed to delete message. Check bot permissions and try again.", ); } } } catch (error) { logUnexpectedDiscordAPIError(error); await message.reply( "❌ Failed to delete messages. Check bot permissions and try again.", ); } finally { enableMessageDeletionListener(); } } };