[Tutorial] How to handle multiple messages in 1 command using awaitMessages

Hello, if you want to understand what we are doing, read through the entire tutorial instead of just skipping ahead to get the code. You wont learn anything by just copy pasting.

Alright, so in this tutorial I am going to teach you how to use awaitMessages in a command such as ban - which will be the example command I will use.
If you don’t know what awaitMessages is, it is a function in discord.js that will allow your bot to wait for a few messages before continuing, and it will even be able to use your messages as variables.

So, let’s get started!
First of all we need to make our command file and insert our command handler exporting.
In my case that will be this.

const Discord = require(`discord.js`);

module.exports.run = async(client, message, args) => {

}

Ok so now that we are exporting the major items to our command, we can start making the command variables, if you want to just have something like %ban <mention> as the first message, your code may look like this

const Discord = require(`discord.js`);

module.exports.run = async(client, message, args) => {
if (message.member.hasPermission(`BAN_MEMBERS`) {
return message.reply(`You can’t ban!`);
}

let Author = message.author;
let Authorid = Author.id; //You will need this in the future
let User = message.mentions.users.first();
let bUser = message.guild.members(User);
}

In a case like that, you will only need 1 awaitMessages. However if you want the mention in a second message, you will need 2 awaitMessages, 1 for the mention and 1 for the reason - because come on, who just bans their members for no reason?

So, now let’s begin with the awaitMessages function, for that we will need a code like this,

const filter = response => {
return response.author.id === Authorid;
}

message.channel.awaitMessages(filter, { max: 1 })
.then(collected => {
const response = collected.first();
});

Now you may see that we are reusing response, the reason for that is, the first response item is inside of the filter and can not be used outside of the filter, and it’s the same with the awaitMessages, this makes us able to reuse the variable as a different item for something different. Now, this is not the case in a code where you would use 2 awaitMessages in 1 command.
The way you would do that is like this,

const filter1 = response1 => {
return response1.author.id === Authorid;
}

message.channel.awaitMessages(filter1, { max: 1 })
.then(collected1 => {
const response1 = collected1.first();

const filter2 = response2 => {
return response2.author.id === Authorid;
}

message.channel.awaitMessages(filter2, { max: 1 })
.then(collected2 => {
const response2 = collected2.first();
});
});

Now, the way we would put this into our ban command is simple,
If you would only have 1 awaitMessages and have the mention in the message containing the command, this is what you pretty much would do,

const Discord = require(`discord.js`);

module.exports.run = async(client, message, args) => {
// Checking if the author can ban.
if (message.member.hasPermission(`BAN_MEMBERS`) {
return message.reply(`You can’t ban!`);
}

//Making variables that we will need later in the code.
let Author = message.author;
let Authorid = Author.id; //You will need this in the future
let User = message.mentions.users.first();
let bUser = message.guild.members(User);

//Creating the filter to see if there is someone else setting the reason or if the is the author.
const filter = response => {
return response.author.id === Authorid;
}

//Awaiting messages
message.channel.awaitMessages(filter, { max: 1 })
.then(collected => {
const response = collected.first(); //Collected.first() is the first message that got collected that was appropriate with the filter. Collected.first() is a message object, so you will be able to do the same with that as a normal message.
let bReason = response.content;

bUser.ban(bReason);
});
}

Now, if you were to make it with the mention in the second message, the code would be like this,

const Discord = require(`discord.js`);

module.exports.run = async(client, message, args) => {
if (message.member.hasPermission(`BAN_MEMBERS`) {
return message.reply(`You can’t ban!`);
}

let Author = message.author;
let Authorid = Author.id; //You will need this in the future

const filter1 = response1 => {
return response1.author.id === Authorid;
}

message.channel.awaitMessages(filter1, { max: 1 })
.then(collected1 => {
const response1 = collected1.first();
let User = response1.mentions.users.first(); //Getting the user from the collected message.
let bUser = message.guild.members(User);

const filter2 = response2 => {
return response2.author.id === Authorid;
}

message.channel.awaitMessages(filter2, { max: 1 })
.then(collected2 => {
const response2 = collected2.first();
let bReason = response2.content;

bUser.ban(bReason);
});
});
}

And there we go! We now got a working multi message command!
And now if you want make something like a poll, you could do something like,

const filter = answer => {
return [`yes`, `no`].includes(answer.content);
}

let hourTime = 1000*60*60;

message.channel.awaitMessages(filter, { max: 99, time: hourTime})
.then(collected => {
//Code here
});

You can set the max to whatever you want, I just set it to 99 so that if it fills up within an hour, it can’t be a draw.
Anyways, so now you should know awaitMessages a bit better, there is also a thing called awaitReactions which pretty much works the same way.
Anyways,
Hope this helped you,
Later,

4 Likes

this could be useful, I’m curious if this can help me avoid storing a users current state in a database for games. Maybe we can get a simpler form and write our code like this

// not actually valid just a concept
client.on("messageCreate", (message){
await message.channel.send("Hello, guess a number between 1 and 10");
int correctNum = Math.floor(Math.random()*10);
let number = parseInt((await framework.input("Input a number: ")).content);
if(number == correctNum){
await message.channel.send("CORRECT! You got it");
}else{
await message.channel.send("Ouf, you didn't get it right better luck next time");
}
}

1 Like