alexsouye
alexsouye

Reputation: 740

I need to remove user reaction after reacting

I have a command which allows me to go and query an API to retrieve images and then display them in discord.

Currently I come to search from my API 10 images, I want to set up a navigation system thanks to the discord reactions. Everything works but the problem is that once the user has clicked the reaction remains active. I need to delete the reaction to improve the user experience. Currently it is therefore necessary to double click which is not very practical. Here's the method that doesn't work for deletion :

  const removeReaction = (m, msg, emoji) => {
    try {
      m.reactions.find(r => r.emoji.name == emoji).users.remove(msg.author.id);
    } catch(err) {
        console.log('err: ', err)
    }
  }

here is all my code

bot.on('message', async msg => {
  if (msg.content.startsWith('!test')) {
    const args = msg.content.slice('!test').split(' ')
    console.log('args :', args[1])
    axios(`https://json-api.example.com/posts?tags=${args[1]}&limit=10`, {
        method: 'GET',
    })
      .then((response) => {
        if (response.status === 500) {
          msg.channel.send('error')
        } else {
          if (response.data.posts.length === 0) {
             msg.channel.send(`No result for ${args[1]}`)
          }
          if (response.data.posts.length > 0) {
             const resultsLength = response.data.posts.length
             const options = {
               limit: 60000,
               min: 1,
               max: resultsLength - 1,
               page: 1
             }
             const pages = []
             response.data.posts.map((i, index) => {
                 pages.push({
                    "title": `Result page number ${index} for ${args[1]}`,
                    "url": `${response.data.posts[index].sample_url}`,
                    "color": 43333,
                    "footer": {
                      "icon_url": "https://cdn.discordapp.com/app-icons/708760465999790244/228b2993e942a361518b557ee4511b26.png?size=32",
                      "text": "Cool footer"
                    },
                    "image": {
                      "url": `${response.data.posts[index].url}`
                    },
                    "fields": [
                      {
                        "name": "tags",
                        "value": `${response.data.posts[index].tags[0] || '/'}, ${response.data.posts[index].tags[1] || '/'}, ${response.data.posts[index].tags[2] || '/'}, ${response.data.posts[index].tags[3] || '/'}`
                      }
                    ]
                 })
             })

             const m = msg.channel.send({ embed: pages[options.page] }).then((el) => {
                el.react('⬅️')
                el.react('➡️')
                el.react('🗑️')
             })
             const filter = (reaction, user) => {
               return ['⬅️', '➡️', '🗑️'].includes(reaction.emoji.name) && user.id == msg.author.id
             }


             const awaitReactions = (msg, m, options, filter) => {
               const { min, max, page, limit } = options
               m.awaitReactions(filter, { max: 1, time: limit, errors: ['time'] })
               .then((collected) => {
                  const reaction = collected.first()
                  const removeReaction = (m, msg, emoji) => {
                    try { m.reactions.find(r => r.emoji.name == emoji).users.remove(msg.author.id); } catch(err) { console.log('err: ', err) }
                  }

                  if (reaction.emoji.name === '⬅️') {
                     removeReaction(m, msg, '⬅️')
                     if (page != min) {
                       page = page - 1
                       m.edit({ embed: pages[page] })
                     }
                    awaitReactions(msg, m, options, filter)
                  }
                  else if (reaction.emoji.name === '➡️') {
                     removeReaction(m, msg, '➡️');
                     if (page != max) {
                       page = page + 1
                       m.edit({ embed: pages[page] })
                     }
                     awaitReactions(msg, m, options, filter);
                  }
                  else if (reaction.emoji.name === '➡️') {
                     removeReaction(m, msg, '➡️');
                     if (page != max) {
                       page = page + 1
                       m.edit({ embed: pages[page] })
                     }
                     awaitReactions(msg, m, options, filter);
                  }
                  else if (reaction.emoji.name === '🗑️') {
                    return m.delete()
                  }
                  else {
                    awaitReactions(msg, m, options, filter)
                  }

               }).catch((err) => { console.log('err: ', err) })
             }

             awaitReactions(msg, m, options, filter)

Thanks in advance for your help

Upvotes: 1

Views: 2939

Answers (2)

alexsouye
alexsouye

Reputation: 740

so, after much research I finally found. I share the answer here.

With the 12+ version of discord.js package a lot has evolved including my problem:

m.reactions.find(r => r.emoji.name == emoji).users.remove(msg.author.id);

must become :

m.reactions.cache.find(r => r.emoji.name == emoji).users.remove(msg.author);

Upvotes: 1

Aiden
Aiden

Reputation: 320

I have made this code a while ago. It is for an older version of Discord.js but according to docs it should still work. Basically what you want to do is to use Discord.js createReactionCollector function after you send the picture, then inside this.reactionCollector.on('collect', (reaction, reactionCollector) => {//do your work here}) you can change the picture then call reaction.remove(user); which immediately removes the reaction for that user.

Here's my code: Note: I have made a class for this command so it might look a bit different for you.
Also in my version, only the user who initially called the command can change the picture. So you will need to modify that part if you want to let anyone change the picture. (It might be a pretty bad idea if your bot is in a large server.)

this.channel.send({embed}).then(msg => {
             this.message = msg;
             this.message.react('⬅️').then(x => {
                 this.message.react('➡️');
             })

             const filter = (reaction, user) => {
                return (reaction.emoji.name === '➡️' ||  reaction.emoji.name === '⬅️') && user.id === this.user.id;
            };
             this.reactionCollector = this.message.createReactionCollector(filter, { time: 600000 });
                this.reactionCollector.on('collect', (reaction, reactionCollector) => {

                    if(reaction.emoji.name === '➡️') {
                        if(this.index + 1 < result.length) {
                            this.index++;
                         var embed = this.makeEmbed(result[this.index].img);
                         this.message.edit({embed});
                        }
                    }
                    else if(reaction.emoji.name === '⬅️') {
                        if(this.index - 1 > -1) {
                            this.index--;
                         var embed = this.makeEmbed(result[this.index].img);
                         this.message.edit({embed});
                        }
                }
                reaction.remove(this.user);
                });
         });

Upvotes: 0

Related Questions