bruhbruh
bruhbruh

Reputation: 33

Discord.js: how can I make paticular permissons for each reaction?

I am coding a !ticket command and cannot handle allowing members without any permissions to react ⛔.

Code

module.exports = {
  name: "ticket",
  slash: true,
  aliases: [],
  permissions: [],
  description: "open a ticket!",
  async execute(client, message, args) {
    let chanel = message.guild.channels.cache.find(c => c.name === `ticket-${(message.author.username).toLowerCase()}`);
    if (chanel) return message.channel.send('You already have a ticket open.');
    const channel = await message.guild.channels.create(`ticket-${message.author.username}`)
    
    channel.setParent("837065612546539531");

    channel.updateOverwrite(message.guild.id, {
      SEND_MESSAGE: false,
      VIEW_CHANNEL: false,
    });
    channel.updateOverwrite(message.author, {
      SEND_MESSAGE: true,
      VIEW_CHANNEL: true,
    });

    const reactionMessage = await channel.send(`${message.author}, welcome to your ticket!\nHere you can:\n:one: Report an issue or bug of the server.\n:two: Suggest any idea for the server.\n:three: Report a staff member of the server.\n\nMake sure to be patient, support will be with you shortly.\n<@&837064899322052628>`)

    try {
      await reactionMessage.react("🔒");
      await reactionMessage.react("⛔");
    } catch (err) {
      channel.send("Error sending emojis!");
      throw err;
    }

    const collector = reactionMessage.createReactionCollector(
      (reaction, user) => message.guild.members.cache.find((member) => member.id === user.id).hasPermission("ADMINISTRATOR"),
      { dispose: true }
    );

    collector.on("collect", (reaction, user) => {
      switch (reaction.emoji.name) {
        case "🔒":
          channel.updateOverwrite(message.author, { SEND_MESSAGES: false });
          break;
        case "⛔":
          channel.send("Deleting this ticket in 5 seconds...");
          setTimeout(() => channel.delete(), 5000);
          break;
      }
    });

    message.channel
      .send(`We will be right with you! ${channel}`)
      .then((msg) => {
        setTimeout(() => msg.delete(), 7000);
        setTimeout(() => message.delete(), 3000);
      })
      .catch((err) => {
        throw err;
      });
  },
};

It is related to the following part of the code.

const collector = reactionMessage.createReactionCollector(
      (reaction, user) => message.guild.members.cache.find((member) => member.id === user.id).hasPermission("ADMINISTRATOR"),
      { dispose: true }
    );

I want it to allow lock the ticket for administrators, and allow to close for everyone.

Upvotes: 1

Views: 353

Answers (1)

Zsolt Meszaros
Zsolt Meszaros

Reputation: 23170

Not sure if I understand you correctly, but it seems you have two reactions and only want admins to use the 🔒, and both admins and the original author to use the .

Your current code only collects reactions from members who have ADMINISTRATOR permissions. You should change the filter to also collect reactions from the member who created the ticket.

The following filter does exactly that.

const filter = (reaction, user) => {
  const isOriginalAuthor = message.author.id === user.id;
  const isAdmin = message.guild.members.cache
    .find((member) => member.id === user.id)
    .hasPermission('ADMINISTRATOR');

  return isOriginalAuthor || isAdmin;
}

There are other errors in your code, like there is no SEND_MESSAGE flag, only SEND_MESSAGES. You should also use more try-catch blocks to catch any errors.

It's also a good idea to explicitly allow the bot to send messages in the newly created channel. I use overwritePermissions instead of updateOverwrite. It allows you to use an array of overwrites, so you can update it with a single method.

To solve the issue with the lock emoji... I check the permissions of the member who reacted with a 🔒, and if it has no ADMINISTRATOR, I simply delete their reaction using reaction.users.remove(user).

Check out the working code below:

module.exports = {
  name: 'ticket',
  slash: true,
  aliases: [],
  permissions: [],
  description: 'open a ticket!',
  async execute(client, message, args) {
    const username = message.author.username.toLowerCase();
    const parentChannel = '837065612546539531';
    const ticketChannel = message.guild.channels.cache.find((ch) => ch.name === `ticket-${username}`);
    if (ticketChannel)
      return message.channel.send(`You already have a ticket open: ${ticketChannel}`);

    let channel = null;
    try {
      channel = await message.guild.channels.create(`ticket-${username}`);

      await channel.setParent(parentChannel);
      await channel.overwritePermissions([
        // disable access to everyone
        {
          id: message.guild.id,
          deny: ['SEND_MESSAGES', 'VIEW_CHANNEL'],
        },
        // allow access for the one opening the ticket
        {
          id: message.author.id,
          allow: ['SEND_MESSAGES', 'VIEW_CHANNEL'],
        },
        // make sure the bot can also send messages
        {
          id: client.user.id,
          allow: ['SEND_MESSAGES', 'VIEW_CHANNEL'],
        },
      ]);
    } catch (error) {
      console.log(error);
      return message.channel.send('⚠️ Error creating ticket channel!');
    }

    let reactionMessage = null;
    try {
      reactionMessage = await channel.send(
        `${message.author}, welcome to your ticket!\nHere you can:\n:one: Report an issue or bug of the server.\n:two: Suggest any idea for the server.\n:three: Report a staff member of the server.\n\nMake sure to be patient, support will be with you shortly.\n<@&837064899322052628>`,
      );
    } catch (error) {
      console.log(error);
      return message.channel.send(
        '⚠️ Error sending message in ticket channel!',
      );
    }

    try {
      await reactionMessage.react('🔒');
      await reactionMessage.react('⛔');
    } catch (err) {
      console.log(err);
      return channel.send('⚠️ Error sending emojis!');
    }

    const collector = reactionMessage.createReactionCollector(
      (reaction, user) => {
        // collect only reactions from the original
        // author and users w/ admin permissions
        const isOriginalAuthor = message.author.id === user.id;
        const isAdmin = message.guild.members.cache
          .find((member) => member.id === user.id)
          .hasPermission('ADMINISTRATOR');

        return isOriginalAuthor || isAdmin;
      },
      { dispose: true },
    );

    collector.on('collect', (reaction, user) => {
      switch (reaction.emoji.name) {
        // lock: admins only
        case '🔒':
          const isAdmin = message.guild.members.cache
            .find((member) => member.id === user.id)
            .hasPermission('ADMINISTRATOR');

          if (isAdmin) {
            channel.updateOverwrite(message.author, {
              SEND_MESSAGES: false,
            });
          } else {
            // if not an admin, just remove the reaction
            // like nothing's happened
            reaction.users.remove(user);
          }
          break;
        // close: anyone i.e. any admin and the member
        // created the ticket
        case '⛔':
          channel.send('Deleting this ticket in 5 seconds...');
          setTimeout(() => channel.delete(), 5000);
          break;
      }
    });

    try {
      const msg = await message.channel.send(`We will be right with you! ${channel}`);
      setTimeout(() => msg.delete(), 7000);
      setTimeout(() => message.delete(), 3000);
    } catch (error) {
      console.log(error);
    }
  },
};

enter image description here

enter image description here

enter image description here

Upvotes: 1

Related Questions