Let's work our way to a solution step by step.
To gather a Collection of Messages from a channel, use the TextBasedChannel.fetchMessages()
method.
With Collection.filter()
, you can return only the elements from a Collection that meet certain conditions.
You can check if a message contains a string in a variety of ways, but perhaps the simplest is the combination of Message.content
and String.includes()
.
The sender of a message can be referenced via the Message.author
property. To check the author against another user, you should compare their IDs, returned by User.id
.
In the filter method's predicate function, "unless" would translate to the logical NOT operator, !
. We can place it before a set of conditions so that if they are met, the operator will return false
. That way, messages that don't meet your specified constrains will be excluded from the returned Collection.
Tying this together so far...
channel.fetchMessages(...)
.then(fetchedMessages => {
const messagesToDelete = fetchedMessages.filter(msg => !(msg.author.id === 'someID' && msg.content.includes('keep')));
...
})
.catch(console.error);
- To bulk delete messages, you can use the
TextChannel.bulkDelete()
method, as you have discovered.
- After the correct messages have been deleted, you can add a response if you wish, employing
TextBasedChannel.send()
.
Altogether...
// Depending on your use case...
// const channel = message.channel;
// const channel = client.channels.get('someID');
channel.fetchMessages({ limit: 100 })
// ^^^^^^^^^^
// You can only bulk delete up to 100 messages per call.
.then(fetchedMessages => {
const messagesToDelete = fetchedMessages.filter(msg => !(msg.author.id === 'someID' && msg.content.includes('keep')));
return channel.bulkDelete(messagesToDelete, true);
// ^^^^
// The second parameter here represents whether or not to automatically skip messages
// that are too old to delete (14 days old) due to API restrictions.
})
.then(deletedMessages => channel.send(`Deleted **${deletedMessages.size}** message${deletedMessages.size !== 1 ? 's' : ''}.`))
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// This template literal will add an 's' if the word 'message' should be plural.
.catch(console.error);
To maintain better flow of your code, consider using async/await
.