【问题标题】:DiscordJS 获取超过 100 条消息
【发布时间】:2021-05-22 16:51:37
【问题描述】:

我正在尝试在 DiscordJS 中获取超过 100 条消息。我找到了这段代码here,但它不起作用:

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());
    }
});

它给了我这个错误:

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

如何解决这个问题?我对 Node.js 有点陌生。

【问题讨论】:

  • 您尝试从channel 读取fetchchannel 是您的 lots_of_messages_getter 函数的参数,但是当您调用该函数时,您永远不会传递任何参数。你认为channel 来自哪里?

标签: javascript node.js discord discord.js


【解决方案1】:

以下适用于 discord.js v12 和 v13。与获取代码的older answers 不同,它返回collection,因此您可以使用.first().last().find().get().filter() 等方法。

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;
}

示例用法:

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);
  }
});

【讨论】:

  • 它正在工作,但我怎样才能获得例如发件人用户名?我试过list.find(user =&gt; user.username === "example"),但它给了我undefined。使用您的过滤器示例,它给了我这个:TypeError: Cannot read property 'includes' of undefined
  • list 是消息的集合,而不是用户。你的意思是list.find(msg =&gt; msg.author.username === 'example')
  • 无论哪种方式,它都会给我 TypeError。如果我在作者下控制台登录list,它只是 [User],但如果我使用 for 循环浏览列表,它也会给我用户详细信息。
  • 我不确定我是否能理解您想要实现的目标。 list 是消息的集合。 list.find(msg =&gt; msg.author.username === 'example') 返回第一条以作者用户名为示例的消息。 list.map((msg) =&gt; msg.author.username) 返回列表中每条消息的用户名数组等。
  • 帮助我收到了超过 100.000 条消息。
【解决方案2】:

如果您的程序在 nodeJS 上运行,您可能需要在文件顶部获取 node fetch const fetch = require('node-fetch');

【讨论】:

  • 这是一个完全不同的抓取方式。错误表明channelundefined 并且undefined 上没有fetch 属性。
猜你喜欢
  • 2019-08-04
  • 2021-05-22
  • 2023-03-15
  • 2012-02-28
  • 1970-01-01
  • 2019-12-28
  • 2020-06-06
  • 2021-05-05
  • 1970-01-01
相关资源
最近更新 更多