角色反应 Discord Bot

Posted

技术标签:

【中文标题】角色反应 Discord Bot【英文标题】:Role Reactions Discord Bot 【发布时间】:2020-06-29 20:37:36 【问题描述】:

我一直在尝试用一个命令在 discord.js 中编写一个不和谐机器人,该命令允许用户对消息做出反应并接收角色。这是我当前的代码。我不确定如何在用户添加反应时赋予角色以及当用户的反应移除它带走的角色时如何使其成为。

const  RichEmbed  = require('discord.js');
const Discord = require("discord.js");
const colors = require("../colors");
const botconfig = require("../botconfig");



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

   await message.delete().catch(O_o=>);

  const role1 = message.guild.roles.get('688477558982836344'); // Replace with Updates ID
  const role2 = message.guild.roles.get('688477690344374283'); // Replace with Events ID
  const role3 = message.guild.roles.get('688477467840872452'); // Replace with QOTD ID
  const role4 = message.guild.roles.get('688477868078137369'); // Replace with Polls ID
  const role5 = message.guild.roles.get('687498488295981069'); // Replace with Social Media ID

  const embed = new Discord.RichEmbed()
        .setTitle('Pinged Roles')
        .setDescription(`

        Tip: *Double React to remove a role*

        ❤️ $role1.toString()
        ???? $role2.toString()
        ???? $role3.toString()
        ???? $role4.toString()
        ???? $role5.toString()

        `)
        .setColor(colors.purple)
        .setFooter('mc.advancius.net')

  message.channel.send(embed).then(async msg => 

    await msg.react('❤️');
    await msg.react('????');
    await msg.react('????');
    await msg.react('????');
    await msg.react('????');


    ); 



module.exports.help = 
    name: "roles"
;

【问题讨论】:

【参考方案1】:

从您的代码看来,您使用的是 Discord.js v11,但我也会包含 v12 的代码,因为这是最新版本。

v11

您需要使用ClientmessageReactionAddmessageReactionRemove 事件,因为ReactionCollector 没有remove 事件。

// I added this object because I prefer having this than having lots of repeated code
// you can still do this the way you were doing before
const roles = 
  '❤️': '688477558982836344',
  '?': '688477690344374283',
  '?': '688477467840872452',
  '?': '688477868078137369',
  '?': '687498488295981069'


exports.run = async (client, message, args) => 
  await message.delete()

  const embed = new RichEmbed()
    .setTitle('Pinged Roles')
    .setDescription(`
      Tip: *Double React to remove a role*

      $Object.entries(roles)
        .map(([emoji, id]) => `$emoji $message.guild.roles.get(id).toString()`)
        .join('\n')
    `)
    .setColor(colors.purple)
    .setFooter('mc.advancius.net')

  message.channel.send(embed).then(async msg => 
    // react with every emoji
    for (const emoji of Object.keys(roles)) await msg.react(emoji)

    client.on('messageReactionAdd', (emoji, message, user) => 
      // if the message that the user reacted to is the same as the message with
      // the reactions, add the role
      if (message.id === msg.id) message.guild.members.get(user.id).addRole(roles[emoji.name])
    )

    client.on('messageReactionRemove', (emoji, message, user) => 
      // same as above but remove the role
      if (message.id === msg.id) message.guild.members.get(user.id).removeRole(roles[emoji.name])
    )
  )

v12/v13

您可以使用createReactionCollector,因为ReactionCollector 有一个remove 事件,当反应被移除时触发。

// I added this object because I prefer having this than having lots of repeated code
// you can still do this the way you were doing before
const roles = 
  '❤️': '688477558982836344',
  '?': '688477690344374283',
  '?': '688477467840872452',
  '?': '688477868078137369',
  '?': '687498488295981069'


exports.run = async (client, message, args) => 
  await message.delete()

  // because RoleManager.fetch is async
  const rolesArray = await Promise.all(Object.entries(roles)
    .map(async ([emoji, id]) => `$emoji $(await message.guild.roles.fetch(id)).toString()`)
  )
  const embed = new MessageEmbed()
    .setTitle('Pinged Roles')
    .setDescription(`
      Tip: *Double React to remove a role*

      $rolesArray.join('\n')
    `)
    .setColor(colors.purple)
    .setFooter('mc.advancius.net')

  // for v12:
  // message.channel.send(embed).then(async msg => 
  message.channel.send(embeds: [embed]).then(async msg => 
    const emojis = Object.keys(roles)
    for (const emoji of emojis) await msg.react(emoji)

    // only collect reactions that are the role emojis
    // for v12:
    // const collector = msg.createReactionCollector((emoji) => emojis.includes(emoji.name))
    const collector = msg.createReactionCollector(
      filter: (emoji) => emojis.includes(emoji.name)
    )

    collector.on('collect', (emoji, message, user) => 
      message.guild.members.fetch(user).then(member => 
        member.roles.add(roles[emoji.name])
      )
    )

    collector.on('remove', (emoji, message, user) => 
      message.guild.members.fetch(user).then(member => 
        member.roles.remove(roles[emoji.name])
      )
    )
  )

【讨论】:

以上是关于角色反应 Discord Bot的主要内容,如果未能解决你的问题,请参考以下文章

为 discord.js 设置嵌入的反应角色时遇到问题

对表情符号 discord.py 做出反应时添加角色

当用户添加反应 Discord.py 时错误赋予角色

Discord.js v12.2.0 |根据反应添加角色

当用户添加反应 Discord.py 时赋予角色

discord.js V12中根据反应赋予角色时出错