Discord Bot - Wait for Reply after Interaction

Viewed 1455

Probably I didn't understand quite well how Discord API works when we use awaitMessages. What I'm trying to do is to wait for a message from the user after a button was clicked in a private channel:

client.on('interactionCreate', async interaction => {

if (interaction.isButton()) {
    if (interaction.customId.startsWith('dialogue-')) {
        const embed = new MessageEmbed()
            .setColor('#1a8175')
            .setTitle(' Dialogue')
            .setDescription('Please type your dialgoue')

        await interaction.channel.send({embeds: [embed]})

        // My problem lies here
        const filter = m => m.author.id === interaction.author.id;
        await interaction.channel.awaitMessages(filter, {
            max: 1,
            time: 60000,
            errors: ['time']
        }).then(
            async(collected) => {
                await interaction.channel.send('Received: ' + collected.first().content.toLowerCase())
            })
    }
}

As you can see, the user clicks on the button, a message is sent asking for the dialogue. After that the bot should receive the next message.

After debugging I saw that everything that I type after the message is sent to the user, triggers the messageCreate event, which is why my code is not working. In my understanding, when we use awaitMessages the bot should wait for the Promise to be completed. I can't figure out what I am missing here. Any ideas? Thanks in advance

3 Answers

To get the user who initialised the interaction, you should use Interaction#user. Whilst you should use Message#author to access the author of a message, you would need to use user for interactions.

const filter = m => m.author.id === interaction.user.id;

You can always refer to the documentation if you don't know about certain properties or methods.

Reading more the documentation, I found another way to do the same task: Using MessageCollectors

const filter = m => m.author.id === interaction.user.id
        const collector = interaction.channel.createMessageCollector(filter, {max: 1, time: 60000})
        collector.once('collect', async (message) => {
            const embed = new MessageEmbed()
                .setColor('#1a8175')
                .setTitle(` Dialogue ${dialogueNumber} received with success!!`)
                .setDescription(`Dialogue received: ${message.content}`)

            await interaction.channel.send({embeds: [embed]})
        })

It does the job and works well. However the time directive is not working properly. I have set the time to 4s in order to send a message back to the user if it takes too long to reply. Using the listener end should do the job, somehow is not working and the bot is waiting for the reply for a long time (I prefer that way) but I would like to understand why the bot is still hanging there, waiting for the user to reply. I have a feeling that the filter must be wrong:

        collector.on('end', collected => {
            if (collected.size === 0) {
                interaction.channel.send('Timeout - You did not send a dialogue')
            }
        });

As @GodderE2D said you need to change interaction.author.id to interaction.user.id in your filter.

You also need to move your filter in the object according to the docs like this:

const filter = m => m.author.id === interaction.user.id
interaction.channel.awaitMessages({ filter, max: 1, time: 60000 })
Related