0
import DiscordJS, { TextChannel, Intents, Message, Channel } from 'discord.js'
import dotenv from 'dotenv'
dotenv.config()

//sets prefix to be used when running bot commands
const prefix = '~';

//This lets the discord bot know what your intentions are using this bot. Hence the guilds, guilds messages and message reactions
const client = new DiscordJS.Client({
    intents: [
        Intents.FLAGS.GUILDS,
        Intents.FLAGS.GUILD_MESSAGES,
        Intents.FLAGS.GUILD_MESSAGE_REACTIONS,
        Intents.FLAGS.DIRECT_MESSAGES
    ]
})


//Deleting messages in bulk
client.on("message", (message) => {
    if (message.content.toLowerCase().startsWith(prefix + "clearchat")) {
        async function clear() {
            message.delete();
            var fetched = await message.channel.messages.fetch({limit: 99})
            message.channel.bulkDelete(fetched);
        }
        clear();
    }
});

I'm trying to bulk delete, but the problem is that message.channel.bulkDelete(fetched); The .channel part is saying its a TextBasedChannel and not TextChannel. And I asked someone about this earlier and they said that I'm using a DMChannel when I should be using a TextChannel. I understand that they are different classes, but I'm not sure how I'm using DMChannel and not TextChannel in my code. I'm not sure how to fix this and if someone had a link to something that tells me the difference, I'd appreciate it. Just having a hard time understanding DMChannel since I'm using the bot in a server and not in the Direct Messages. I'm just confused

This is the error I get

EDIT: I was able to clear the chat as intended, but now I get a DiscordAPIError. Can I just catch the error? Here's the error message:

EDIT 2: This is what is after the above Error message

 DiscordAPIError: You can only bulk delete messages that are under 14 days old.
    at RequestHandler.execute (C:\Users\theod\Desktop\DiscordBot\node_modules\discord.js\src\rest\RequestHandler.js:298:13)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async RequestHandler.push (C:\Users\theod\Desktop\DiscordBot\node_modules\discord.js\src\rest\RequestHandler.js:50:14)
    at async TextChannel.bulkDelete (C:\Users\theod\Desktop\DiscordBot\node_modules\discord.js\src\structures\interfaces\TextBasedChannel.js:312:7) {
  method: 'post',
  path: '/channels/872986149294047234/messages/bulk-delete',
  code: 50034,
  httpStatus: 400,
  requestData: { json: { messages: [Array] }, files: [] }
TheoChow
  • 47
  • 5

1 Answers1

0

The message could be in a DM, and you can't bulk delete messages in a DM channel. Check if the message is in a guild first:

import type { NewsChannel, TextChannel, ThreadChannel } from 'discord.js';

type GuildTextBasedChannel = TextChannel | NewsChannel | ThreadChannel

if (message.content.toLowerCase().startsWith(prefix + "clearchat")) {
    if (message.guild) {
        async function clear() {
            message.delete();
            var fetched = await message.channel.messages.fetch({limit: 99})
            (message.channel as GuildTextBasedChannel).bulkDelete(fetched, true);
        }
        clear();
    }
}

Unfortunately, the typings for Discord.js aren't that great, so the type assertion as GuildTextBasedChannel is needed to let TypeScript know that message.channel must be a guild text-based channel if if message.guild is not null.


If you want, you can define a helper function that would eliminate the need for this type assertion:

import type { Message } from 'discord.js';

function inGuild(message: Message): message is Message & { readonly channel: GuildTextBasedChannel } {
    return message.guild !== null;
}

if (inGuild(message)) {
  message.channel.bulkDelete(99, true); // no type assertion needed
}

Alternatively, you could use something like this:

import type * as Discord from 'discord.js';

type Message = Discord.Message &
  (
    | {
        readonly channel: GuildTextBasedChannel;
        readonly guild: Discord.Guild;
      }
    | {
        readonly channel:
          | Discord.DMChannel
          // if you're using partials
          | Discord.PartialDMChannel;
        readonly guild: null;
      }
  );

client.on("messageCreate", (_message) => {
    const message = _message as Message;
    // rest of code...
    // type assertion not required
});

The true argument in bulkDelete(fetched, true) means that Discord.js will automatically filter out messages that are over 14 days old. Discord doesn't allow you to bulk delete messages over 14 days old, which is what your error message is telling you.

Lauren Yim
  • 12,700
  • 2
  • 32
  • 59
  • Yeah I solved the problem! thank you, but now theres an error that pops up after it clears the chat. I posted the picture of the error msg above. – TheoChow Oct 04 '21 at 00:34
  • The screenshot in your question shows a deprecation warning because the [`message` event got renamed to `mesageCreate`](https://discordjs.guide/additional-info/changes-in-v13.html#client-message). Could you please edit your question with the full error relating to the `DiscordAPIError` (there should be more information under the `throw new DiscordAPIError` line)? Please copy and paste the error **as text** into your question; do not use an image. – Lauren Yim Oct 04 '21 at 04:06
  • I just put in the other part above. – TheoChow Oct 05 '21 at 03:49
  • @TheoChow Sorry for the late response! I've updated my answer. – Lauren Yim Oct 15 '21 at 23:59