Reputation: 41
Like the title says, I tried to use fetchMessages to check the messages a certain channel is sent but when I tried to mess with this, it just gives me unending blocks of information in the console.
I tried reading it but there seems to be no actual message in there and just gives me information about the server, like channel id, member id, their perms, etc.
At first I thought using this method would give me random messages so I could just have the bot send the messages directly to a channel but it gives me an error so I just used console.log to get more information. But that didn't seem the case, or I'm just using it wrong...
Here's the code I'm trying:
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);
}
})
Also apparently it can't track old messages since when I tried filtering out messages using a user id, it shows that they sent 0 messages even though they have been sending messages way before? I'm trying to achieve so that it can still read very old messages and still send those when I use an autorespond message.
Upvotes: 4
Views: 1884
Reputation: 615
TextChannel.fetchMessages() can only fetch up to 100 messages at a time
Short Answer:
Although it doesn't show in the docs, if you fetch more than 100, you'll get an API error:
DiscordAPIError: Invalid Form Body limit: int value should be less than or equal to 100.
Console logging the
Message
object will indeed give you a whole lot of information regarding theGuild
and everything else in it. You should probably want to only console log the message's content and author id/usertagSo if you want to search beyond the past 100 messages, you'll have to continuously fetch 100 messages by using the ID of the oldest message in
ChannelLogsQueryOptions
'sbefore
parameter in each consecutiveTextChannel.fetchMessages()
call, and then concatinating eachCollection
together usingCollection.concat()
.
Long Answer:
If you wanted, for example, to fetch the past 200 messages you could write something like this:
// 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);
Take a look at this answer for an async function that stores past messages in an array.
I made my own version which will give you a Collection
and returns it as a proper Promise
instead:
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));
});
}
Example Usage:
fetchManyMessages(message.channel, 1500)
.then(msgs => console.log(msgs.size))
.catch(err => console.log(err));
And here I've also made a prototype
version, which I think is great for some syntactical awesomeness:
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));
});
}
Example Usage:
message.channel.fetchManyMessages(1500)
.then(msgs => console.log(msgs.size))
.catch(err => console.log(err));
Upvotes: 3