OliPlays
OliPlays

Reputation: 35

Add reaction to a specific message Discord.JS

I am trying to create a command to add a reaction to a certain message.

The command is: /react "Channel-ID" "Message-ID" "Emoji"

But when running the command I get this error:

(node:4) UnhandledPromiseRejectionWarning: DiscordAPIError: Invalid Form Body :channel_id: Value "845345565700128788 <:XPLANE11:845383490286518322>" is not snowflake.

Is there any simple way of fixing this?

Thanks

client.on("message", message => {
        if (message.author.bot) return;
    
        let messageArray = message.content.split(" ");
        let command = messageArray[0];
        let channelid = messageArray.slice(1);
        let messageid = messageArray.slice(2);
        let emoji = messageArray.slice(3);
    
        if (message.channel.type === "dm") return;
    
        if (!message.content.startsWith('/')) return;
    
           if (command === '/react') {
    
            let memberrole = message.member.roles.cache.find(role => role.name === "CEO");
            if (!memberrole) return message.channel.send('Insufficiant Perms');
            
            message.client.channels.fetch(channelid.slice(1).join(" ")).then(channel => {
                channel.messages.fetch(messageid.slice(2).join(" ")).then(message => {
                    message.react(emoji.slice(3).join(" "));
                })
            })
          }});

For anyone wondering, this is the code that worked:

client.on('message', async (message) => {
    if (
      message.author.bot ||
      message.channel.type === 'dm' ||
      !message.content.startsWith(prefix)
    )
      return;
    
    const args = message.content.slice(prefix.length).split(/ +/);

    const command = args.shift().toLowerCase();
  
    if (command === 'react') {

      const [channelId, messageId, emoji] = args;
  

      if (!channelId)
        return message.channel.send(`You need to provide a channel ID`);

      const memberrole = message.member.roles.cache.find((role) => role.name === 'CEO');
      if (!memberrole) return message.channel.send('Insufficiant perms');
  
      try {
        const channel = await message.client.channels.fetch(channelId);
        if (!channel)
          return message.channel.send(`No channel found with the ID ${channelId}`);
  
        const msg = await channel.messages.fetch(messageId);
        if (!msg)
          return message.channel.send(`No message found with the ID ${messageId}`);
  
        msg.react(emoji);
      } catch (error) {
        console.log(error);
        message.channel.send('Oh-oh, there was an error...');
      }
    }
  });

Upvotes: 1

Views: 293

Answers (1)

Zsolt Meszaros
Zsolt Meszaros

Reputation: 23161

The problem is you're using Array#slice() incorrectly. Array#slice() returns a shallow copy of a portion of an array into a new array. When you use messageArray.slice(1) you actually create a new array by chopping off the first element of messageArray, the command. For messageid you're chopping off the first two elements of messageArray, leaving you the message ID and the emoji. Check out the snippet below. If you run it, you can see the values of each variables:

const message = { content: '/react 845345565700128700 845345565700128788 <:XPLANE11:845383490286518322>' }
let messageArray = message.content.split(' ');
let command = messageArray[0];
let channelid = messageArray.slice(1);
let messageid = messageArray.slice(2);
let emoji = messageArray.slice(3);

console.log({ command, channelid, messageid, emoji })

So, at this moment, channelid is an array of three elements; the channel ID, the message ID, and the emoji. Inside the channels.fetch() method you once again create a new array by chopping off the first element and then join the rest by a single space. So, it becomes 845345565700128788 <:XPLANE11:845383490286518322>. Check out the snippet below:

// messageArray.slice(1);
const channelid = [
  '845345565700128700',
  '845345565700128788',
  '<:XPLANE11:845383490286518322>',
]

console.log(channelid.slice(1).join(' '))

If you check the value you try to fetch, it's exactly the one in your error message, Value "845345565700128788 <:XPLANE11:845383490286518322>" is not snowflake. It's not a valid snowflake. It's actually the message ID and the emoji in a single string.

To solve this, you could simply get the second element of the messageArray as the channelid, the third one as the messageid, etc:

let messageArray = message.content.split(' ');
let command = messageArray[0];
let channelid = messageArray[1];
let messageid = messageArray[2];
let emoji = messageArray[3];

You could also use array destructuring to get the same:

let messageArray = message.content.split(' ');
let [command, channelid, messageid, emoji] = messageArray;

And here is the full code:

// use a prefix variable
const prefix = '/';

client.on('message', async (message) => {
  if (
    message.author.bot ||
    message.channel.type === 'dm' ||
    !message.content.startsWith(prefix)
  )
    return;

  // create an args variable that slices off the prefix and splits it into an array
  const args = message.content.slice(prefix.length).split(/ +/);
  // create a command variable by taking the first element in the array
  // and removing it from args
  const command = args.shift().toLowerCase();

  if (command === 'react') {
    // destructure args
    const [channelId, messageId, emoji] = args;

    // check if there is channelId, messageId, and emoji provided
    // if not, send an error message
    if (!channelId)
      return message.channel.send(`You need to provide a channel ID`);

    // same with messageId and emoji
    // ...

    const memberrole = message.member.roles.cache.find((role) => role.name === 'CEO');
    if (!memberrole) return message.channel.send('Insufficiant perms');

    try {
      const channel = await message.client.channels.fetch(channelId);
      if (!channel)
        return message.channel.send(`No channel found with the ID ${channelId}`);

      const fetchedMessage = await channel.messages.fetch(messageId);
      if (!fetchedMessage)
        return message.channel.send(`No message found with the ID ${messageId}`);

      fetchedMessage.react(emoji);
    } catch (error) {
      console.log(error);
      message.channel.send('Oh-oh, there was an error...');
    }
  }
});

Upvotes: 2

Related Questions