0

I'm trying to fetch more than 100 messages in DiscordJS. I've found this code here but it doesn't work:

async function lots_of_messages_getter(channel, limit = 500) {
    const sum_messages = [];
    let last_id;

    while (true) {
        const options = { limit: 100 };
        if (last_id) {
            options.before = last_id;
        }

        const messages = await channel.fetch(options);
        sum_messages.push(...messages.array());
        last_id = messages.last().id;

        if (messages.size != 100 || sum_messages >= limit) {
            break;
        }
    }

    return sum_messages;
}

client.on("message", async message => {
    const channel = client.channels.cache.get("12345");
    if (message.content.startsWith(prefix+"random")){
        console.log(lots_of_messages_getter());
    }
});

It gives me this error:

(node:6312) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'fetch' of undefined

How can this be fixed? I'm kinda new to Node.js.

Zsolt Meszaros
  • 21,961
  • 19
  • 54
  • 57
martino
  • 34
  • 5
  • You try to read `fetch` from `channel`. `channel` is a parameter of your `lots_of_messages_getter` function, but when you call that function, you never pass any parameters. Where do you expect `channel` to come from? – Ivar Feb 19 '21 at 17:06

2 Answers2

4

The following works in discord.js v12 and v13. Unlike the older answers where you got your code from, it returns a collection, so you can use methods like .first(), .last(), .find(), .get(), .filter(), etc.

const { Collection } = require('discord.js');

async function fetchMore(channel, limit = 250) {
  if (!channel) {
    throw new Error(`Expected channel, got ${typeof channel}.`);
  }
  if (limit <= 100) {
    return channel.messages.fetch({ limit });
  }

  let collection = new Collection();
  let lastId = null;
  let options = {};
  let remaining = limit;

  while (remaining > 0) {
    options.limit = remaining > 100 ? 100 : remaining;
    remaining = remaining > 100 ? remaining - 100 : 0;

    if (lastId) {
      options.before = lastId;
    }

    let messages = await channel.messages.fetch(options);

    if (!messages.last()) {
      break;
    }

    collection = collection.concat(messages);
    lastId = messages.last().id;
  }

  return collection;
}

Example usage:

client.on('message', async (message) => {
  if (message.author.bot) return;

  try {
    const list = await fetchMore(message.channel, 120);

    console.log(
      list.size,
      list.filter((msg) => msg.content.includes('something')),
    );
  } catch (err) {
    console.log(err);
  }
});
Zsolt Meszaros
  • 21,961
  • 19
  • 54
  • 57
  • It's working but how can I get for example the senders username? I've tried `list.find(user => user.username === "example")` but it gives me `undefined`. With your filter example it gives me this: `TypeError: Cannot read property 'includes' of undefined` – martino Feb 19 '21 at 17:58
  • `list` is a collection of messages, not users. Did you mean `list.find(msg => msg.author.username === 'example')`? – Zsolt Meszaros Feb 19 '21 at 18:01
  • Either way it gives me TypeError. If I console log `list` under the author it is [User] only, but if I go through the list with a `for` loop it gives me the user details also. – martino Feb 19 '21 at 18:41
  • I'm not sure if I can understand what you want to achieve. `list` is a collection of messages. `list.find(msg => msg.author.username === 'example')` returns the first message where the author's username is example. `list.map((msg) => msg.author.username)` returns an array of usernames for each messages in the list, etc. – Zsolt Meszaros Feb 19 '21 at 19:41
  • `list.map` gives me `Cannot read property 'username' of undefined`. Somehow it can't get the value. – martino Feb 20 '21 at 08:25
  • 1
    helped me get more than 100.000 messages. – Danielr Aug 15 '21 at 22:11
-1

You might need node fetch const fetch = require('node-fetch'); on the top of your file if your program runs on nodeJS.

  • It's a completely different fetch. The error says that `channel` is `undefined` and there is no `fetch` property on `undefined`. – Zsolt Meszaros Mar 24 '21 at 17:26