JDA - 机器人听取其他机器人的反应

Posted

技术标签:

【中文标题】JDA - 机器人听取其他机器人的反应【英文标题】:JDA - Bot listens to other bots reactions 【发布时间】:2020-12-27 08:39:52 【问题描述】:

出于某种原因,我的机器人会听取所有其他机器人的反应。

示例:如果我的服务器中有一个随机赠品机器人,它使用反应来加入它,我的机器人会出于某种奇怪的原因收听这个随机机器人的反应。

这是我的反应监听器;

public void onGuildMessageReactionAdd(GuildMessageReactionAddEvent e) 
        if (e.getUser().isBot()) return;

        e.retrieveMessage().queue(message -> 
            if (message.getAuthor().getIdLong() != ProjectWar.getInstance().getDiscord().getJda().getSelfUser().getIdLong()) return;
            if (!e.getMember().hasPermission(Permission.ADMINISTRATOR)) 
                DiscordUtils.noPerm(e.getMember(), message);
                e.getChannel().removeReactionById(e.getMessageId(), e.getReactionEmote().getName(), e.getUser()).queue();
                return;
            
            for (MessageEmbed embed : message.getEmbeds()) 
                for (MessageEmbed.Field field : embed.getFields()) 
                    switch (field.getName()) 
                        case "Player":
                            this.reporter = field.getValue();
                            break;
                        case "FactionOne":
                            factionOne = field.getValue();
                            break;
                        case "FactionTwo":
                            this.factionTwo = field.getValue();
                            break;
                        case "ID":
                            this.ID = Integer.parseInt(field.getValue());
                            break;
                        case "Reason":
                            this.reason = field.getValue();
                            break;
                        case "State":
                            this.state = field.getValue();
                            break;
                        case "Date":
                            this.date = ProjectWar.getInstance().parse(field.getValue());
                            break;
                    
                
            
            WarReport report = new WarReport(reporter, factionOne, factionTwo, reason, (ID + 1), date, state);

            MessageReaction reaction = message.getReactions().stream()
                    .filter(r -> r.getReactionEmote().getName().equals(e.getReactionEmote().getName()))
                    .findFirst()
                    .orElse(null);

            if (reaction != null) 
                if (reaction.getCount() > 2) 
                    e.getChannel().removeReactionById(e.getMessageId(), e.getReactionEmote().getName(), e.getUser()).queue();
                
            
            //todo: convert to class with emotes.
            if (e.getReactionEmote().getName().equals("\uD83D\uDDD1")) 
                ReportManager.removeReport(report);
                e.getChannel().deleteMessageById(e.getMessageId()).queue();
             else if (e.getReactionEmote().getName().equals("❌")) 
                ProjectWar.getInstance().getDiscord().editStatus(e.getMessageId(), e.getChannel(), false);
                ReportManager.setReportState(report, false);
             else if (e.getReactionEmote().getName().equals("✅")) 
                ProjectWar.getInstance().getDiscord().editStatus(e.getMessageId(), e.getChannel(), true);
                ReportManager.setReportState(report, true);
            
        );
    
    
    // no perm method
    public static void noPerm(Member member, Message message) 
        EmbedBuilder embedBuilder = new EmbedBuilder().setColor(Color.RED).setTitle("Missing permission!");
        embedBuilder.addField("", "You're not allowed to do that <@" + member.getId() + ">!", false);
        message.getChannel().sendMessage(embedBuilder.build()).queue(message1 -> message1.delete().queueAfter(5, TimeUnit.SECONDS));
    

如何让我的机器人只收听我自己的机器人发送的消息?

【问题讨论】:

我很确定错误在其他地方。我可能错了,但我在您的代码中找不到错误。 【参考方案1】:

您必须检查某人回应的消息是否已由您的机器人发送。 要做到这一点,你必须先得到某人反应的消息。

Message msg = e.getChannel().retrieveMessageById(e.getMessageId()).complete();

然后您可以轻松检查该消息是否已由您的机器人发送:

if (msg.getAuthor().equals(e.getJDA().getSelfUser())) 
    // message that someone reacted to has been sent by your bot

【讨论】:

您可能应该使用 e.retrieveMessage() 检索消息,但它的作用相同。【参考方案2】:

如果做出反应的用户不是当前正在运行的实例,则以下代码将返回。

import net.dv8tion.jda.api.events.message.guild.react.GuildMessageReactionAddEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;

public class Example extends ListenerAdapter 

    @Override
    public void onGuildMessageReactionAdd(GuildMessageReactionAddEvent event) 
        if (event.getUser().getIdLong() != event.getJDA().getSelfUser().getIdLong()) return;

        // ...
    

【讨论】:

您现在正在检查添加反应的用户是否是自己的用户:您要检查消息的所有者是否是自己的用户。

以上是关于JDA - 机器人听取其他机器人的反应的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 JDA 添加多个反应以嵌入消息

如何对命令中的表情做出反应 (Discord JDA)?

JDA 事件获取器返回 null 并让所有成员在一个角色中只返回机器人本身

如何根据反应发送消息,然后根据用户消息发送另一个消息?使用 JDA

JDA:一旦用户被封禁,机器人就不会通知用户

在 Heroku 成功的机器人上部署不起作用 - JDA