提问者:小点点

如何让我的机器人获取已从信道中的用户发送的随机消息,并在触发自动响应时发送随机消息


正如标题所说的,我试图使用fetchMessages来检查某个通道发送的消息,但当我试图弄乱它时,它只是在控制台中给了我无穷无尽的信息块。

我试着阅读它,但似乎没有实际的消息在那里,只是给了我有关服务器的信息,如频道id,成员id,他们的烫发等。

一开始,我认为使用这个方法会给我随机的消息,所以我可以让机器人直接将消息发送到一个通道,但是它给了我一个错误,所以我只是使用console.log来获取更多的信息。但事实并非如此,或者我只是用错了。。。

下面是我正在尝试的代码:

    bot.on('message', msg =>{

    if(msg.author.bot) return;
    lowerCase = msg.content.toLowerCase();

    if(lowerCase.includes ("fetch")){ 
        msg.channel.fetchMessages({limit: 1}).then(console.log);
    }
})

此外,很明显,它不能跟踪旧消息,因为当我尝试使用用户id过滤消息时,它显示他们发送了0条消息,尽管他们以前一直在发送消息?我试图实现这样的目标:当我使用autoresponse消息时,它仍然可以读取非常旧的消息,并且仍然可以发送这些消息。


共1个答案

匿名用户

TextChannel.FetchMessages()一次最多只能提取100条消息

简短的回答:

虽然文档中没有显示它,但是如果您获取的数据超过100个,您将得到一个API错误:

DiscordAPIError: Invalid Form Body
limit: int value should be less than or equal to 100.

控制台记录message对象确实会为您提供有关guild和其中其他所有内容的大量信息。您可能只需要控制台日志消息的内容和作者ID/UserTag

因此,如果您希望搜索过去100条消息以外的消息,则必须在每个连续的TextChannel.FetchMessages()调用中使用ChannelLogsqueryOptionsBefore参数中最早的消息的ID,然后使用Collection.Concat()将每个集合连接在一起,从而连续获取100条消息。

长答:

例如,如果您希望获取过去的200条消息,您可以编写如下内容:

// using .then()
await channel.fetchMessages({limit: 100})
.then(first100 => {
  let next100 = await channel.fetchMessages({limit: 100, before: first100.lastKey()})
  .then(next100 => {
    let all200 = first100.concat(next100);
  });
});
// in async function
let first100 = await channel.fetchMessages({limit: 100});
let next100 = await channel.fetchMessages({limit: 100, before: first100.last().id});
let all200 = first100.concat(next100);

看一看这个异步函数的答案,这个函数将过去的消息存储在数组中。

我制作了自己的版本,它将为您提供一个集合,并将其作为正确的承诺返回:

const fetchManyMessages = (channel, limit = 200) => {
  return new Promise((resolve, reject) => {
    channel.fetchMessages({limit: limit < 100 ? limit : 100})
    .then(collection => {
      const nextBatch = () => {
        console.log(collection.size);
        let remaining = limit - collection.size;

        channel.fetchMessages({limit: remaining<100 ? remaining : 100, before: collection.lastKey()})
        .then(next => {
          let concatenated = collection.concat(next);

          // resolve when limit is met or when no new msgs were added (reached beginning of channel)
          if (collection.size >= limit || collection.size == concatenated.size) return resolve(concatenated);

          collection = concatenated;
          nextBatch();
        })
        .catch(error => reject(error));
      }

      nextBatch();
    })
    .catch(error => reject(error));
  });
}

示例用法:

fetchManyMessages(message.channel, 1500)
.then(msgs => console.log(msgs.size))
.catch(err => console.log(err));

在这里,我还制作了一个prototype版本,我认为它在句法上非常出色:

Discord.TextChannel.prototype.fetchManyMessages = function (limit = 200) {
  return new Promise((resolve, reject) => {
    this.fetchMessages({limit: limit < 100 ? limit : 100})
    .then(collection => {
      const nextBatch = () => {
        console.log(collection.size);
        let remaining = limit - collection.size;

        this.fetchMessages({limit: remaining<100 ? remaining : 100, before: collection.lastKey()})
        .then(next => {
          let concatenated = collection.concat(next);

          // resolve when limit is met or when no new msgs were added (reached beginning of channel)
          if (collection.size >= limit || collection.size == concatenated.size) return resolve(concatenated);

          collection = concatenated;
          nextBatch();
        })
        .catch(error => reject(error));
      }

      nextBatch();
    })
    .catch(error => reject(error));
  });
}

示例用法:

message.channel.fetchManyMessages(1500)
.then(msgs => console.log(msgs.size))
.catch(err => console.log(err));