重新启动后,Discord JS通过React命令添加角色不起作用

时间:2020-09-12 09:42:35

标签: javascript discord discord.js

我正在尝试执行“通过反应添加角色”命令。因此,当成员对特定消息做出反应时,该成员将获得角色。它实际上可以工作,但是当我重新启动机器人时,它不再添加任何角色。有人可以帮忙吗?

此处是代码:

bot.on('message', msg=>{
    if(msg.content.startsWith(prefix + "react")){
        let embed = new Discord.MessageEmbed()
        .setTitle("Reactions Roles")
        .setDescription("React to get a role!")
        .setColor("BLUE")
        msg.channel.send(embed).then(m=> m.react("emoji_id"))
    }
})

bot.on("messageReactionAdd", async (reaction, user)=>{
    if (reaction.message.partial) await reaction.message.fetch();
    if (reaction.partial) await reaction.fetch();
    if(user.bot) return;
    if(!reaction.message.guild) return;
    if(reaction.message.channel.id === "channel_id"){
        if(reaction.emoji.id === "emoji_id"){
            await reaction.message.guild.members.cache.get(user.id).roles.add("role_id")
        }
    }
})

bot.on('messageReactionRemove', async (reaction, user)=>{
    if(reaction.message.partial) await reaction.message.fetch();
    if(reaction.partial) await reaction.fetch();

    if(user.bot) return;
    if(!reaction.message.guild) return;

    if(reaction.message.channel.id === "channel_id"){
        if(reaction.emoji.id === "emoji_id"){
            await reaction.message.guild.members.cache.get(user.id).roles.remove("role_id")
        }
    }
})

4 个答案:

答案 0 :(得分:1)

我只是遇到了同样的问题并已解决。您的确切用例已在文档中深入解释,尽管我也会做一个小小的解释:https://discordjs.guide/popular-topics/reactions.html#listening-for-reactions-on-old-messages

DiscordJS具有一个“缓存”,可用于加快查询速度(即,每当用户发送消息时,DiscordJS会将其保存在本地,它最多可保存一定数量的最新消息,我相信是100个)。因此,当您聆听反应时,discordJS基本上只会听缓存的(至少从我的理解)。为了使其能够收听未缓存的消息,您必须使用“ Partials”,这听起来像是完整对象的部分。这意味着您将只获得具有ID的对象,而不是完整的MessageReaction / User对象(它们上有一个名为fetch()的函数,尽管它可以使您获得完整的对象)。通过使用“部分访问”,您可以侦听对旧的未缓存邮件的反应。

要使用Partials,请按以下方式创建客户端:

const bot = new Client({
  partials: ['MESSAGE', 'CHANNEL', 'USER', 'REACTION'],
});

,以后再听messageReactionAdd之类的东西时要小心!您将按照以下步骤进行操作:

client.on(
  'messageReactionAdd',
  async (potentialPartialReaction, potentialPartialUser) => {
    try {
      const reaction = await potentialPartialReaction.fetch();
      const user = await potentialPartialUser.fetch();
    } catch (err) {
      console.log(err);
    }

    // can use reaction and user here!
});

我认为这应该适合您的情况,但如果不行,请通知我。这在DiscordJS v12中对我有用。

答案 1 :(得分:0)

我建议阅读有关Reactions的正式discord.js文档。这是link

答案 2 :(得分:0)

要让您的漫游器检查以前的消息是否已被响应,您可以使用与此类似的代码

let guildID = "xxx";
let channelID = "xxx";
let emojiID = "xxx";
let roleID = "xxx";


bot.on("ready", async () => {

    let guild = bot.guilds.cache.find(guild => guild.id == guildID);
    let channel = await guild.channels.cache.find(ch => ch.id == channelID)

    // You can set any limit you want, for performance I used a low number
    channel.messages.fetch({ limit: 10 })
        .then(async messages => {
            messages.forEach(async message => {

                if (message.partial) await message.fetch();
                if (!message.guild) return;

                for (let reactionObj of message.reactions.cache) {
                    for (let reaction of reactionObj) {
                        if (typeof reaction == "string") continue;
                        if (reaction.emoji.id != emojiID) continue;
                        reaction.users.fetch()
                            .then(async users => {
                                users.forEach(async user => {
                                    if (user.bot) return;
                                    console.log("Adding role")
                                    await reaction.message.guild.members.cache.get(user.id).roles.add(roleID)
                                })
                            })
                    }
                }

            });
        })
        .catch(console.error);
});

您可能需要进行一些更改,但这是可行的。

要分解它...

  1. 获取特定渠道(或多个渠道)中的消息
  2. 检查消息是否有反应
  3. 检查是否有任何反应与特定表情符号匹配
  4. 将角色添加到公会成员
  5. (可选)在尝试添加成员之前检查该成员是否已经具有该角色

请注意,此代码可能不是最有效的,但是可以完成工作。另外,它不能与“非自定义”表情符号一起使用,因为您必须检查emoji.name而不是emoji.id。

如@ michael.grigoryan所建议,建议您查阅文档。

编辑:删除了先前的答案,以消除混乱

答案 3 :(得分:0)

我做了一些测试,发现有些奇怪的地方。

当您重新启动bot并尝试对重新启动bot之前发送的消息做出反应时,该bot不会注册该响应。但是,如果您发送新消息并对它做出反应,则该机器人会突然开始在所有消息上注册反应。

我认为这与局部变量有关,但我不是专家!