使用不和谐的 JDA 清除聊天

Clearing chat using discord JDA

我正在 java 中编写一个 discord 机器人,我使用 discord JDA 和实用程序依赖项,我尝试使用实用程序但我没有让它工作,所以我尝试只使用正常的 JDA,这就是我所做的,但我需要一些方法告诉机器人如果命令不是 运行.

不要在新频道中发送消息
public class NukeCommand extends ListenerAdapter {

    @Override
    public void onGuildMessageReceived(GuildMessageReceivedEvent event){
        if (event.getMessage().getContentRaw().equalsIgnoreCase(".nuke")){
            event.getChannel().createCopy().queue();
            event.getChannel().delete().queue();
        }
    }
    @Override
    public void onTextChannelCreate(TextChannelCreateEvent createEvent){
        createEvent.getChannel().sendMessage(":warning:Nuked channel:warning:\nhttps://imgur.com/a/93vq9R8").queue();
    }

我愿意在这两个依赖项中寻求答案。 这是我想要的效果:https://gyazo.com/e549fd8dda0ded62db19fb84e31d3a61 我有同样的效果,但每次我创建文本通道时它都会发送消息。 我希望它仅在 .nuke 命令为 运行.

时发送消息

我找到了一个解决方案,您可以将消耗品或其调用的任何内容传递到 .queue 方法中,每当创建通道时,此代码都会得到 运行。 我做了什么:


    @Override
    public void onGuildMessageReceived(GuildMessageReceivedEvent event){
        if (event.getMember().hasPermission(Permission.MESSAGE_MANAGE)){
            if (event.getMessage().getContentRaw().equalsIgnoreCase(".nuke")){
                event.getChannel().createCopy().queue(channel->channel.sendMessage(":warning:Nuked channel:warning:\nhttps://imgur.com/a/93vq9R8").queue());
                event.getChannel().delete().queue();
            }
        }
    }

你说你已经知道了,但我想更多地解释它的实际工作原理并完善你的答案。

ListenerAdapter 的方法会为机器人整个范围内发生的每个事件调用,例如,如果您有

class Adapter extends ListenerAdapter {
    @Override
    public void onMessageReceived(MessageReceivedEvent event){
       /*This will be called for every message, everywhere, including the bot's private channel*/
    }
}

所以你需要在方法体内过滤那些事件,你在回答中所做的是检查发送消息的人是否有管理消息的权限,这不是你真正需要删除频道的那个,它是Permission.MANAGE_CHANNELS,您可以在服务器的角色选项卡中找到。

然后调用 createCopy(),这基本上创建了频道信息的浅表副本

我不认为你真的想那样做。

然后你将该动作排队,(这是实际执行它的)它被放入队列中以供 JDA 的线程异步处理,随后将通过 websocket 连接发送到不和谐。

那个queue方法可以接受一个Consumer<TextChannel>作为参数,什么意思?

基本上,消费者代表一个操作,该操作将单个参数作为输入(在本例中为 TextChannel)并且 returns 什么都没有。更多相关信息:https://docs.oracle.com/javase/8/docs/api/java/util/function/Consumer.html

你在答案中给出的消费者正在做你真正想做的事情,发送消息,在之前队列操作的通道上,这意味着,createCopy() 完全没用,TextChannel 对象相同,合适的是:

event.getChannel().sendMessage(":warning:Nuked channel:warning:\nhttps://imgur.com/a/93vq9R8").queue();

之后,您立即删除了该频道,这没有多大意义,因为很可能没有人甚至能够看到核弹消息。 为此,JDA 提供了另一种排队任务的方法,这次有延迟: queueAfter() 它以一个 long 作为值,一个 TimeUnit 对象指定该值的时间单位,例如:

event.getChannel().delete().queueAfter(10, TimeUnit.SECONDS);

complete() 方法不同,这会将任务排队等待 10 秒后执行,并且不会停止代码的执行。

或者,您可以只使用 Thread.sleep(),它将长值作为输入:Thread.sleep(10000) 10 秒(10000 毫秒)。

您可以在此处找到有关 JDA 和启动提示的更多信息:https://github.com/DV8FromTheWorld/JDA#creating-the-jda-object

这似乎有效(不删除频道)

@Override
    public void onMessageReceived(@NotNull MessageReceivedEvent event) {
        String message = event.getMessage().getContentRaw();

    if (message.toLowerCase().equals("$" + "clear")) {
        for (int i = 0; i <= 1000; i++) {
            
            TextChannel channel = (TextChannel) event.getChannel();

            MessageHistory history = new MessageHistory(channel);
            List<Message> msgs;
    
            msgs = history.retrievePast(100).complete();
            if (msgs.size() > 1) {
                channel.deleteMessages(msgs).queue();
    
            } else {
                channel.sendMessage("Mensagens deletadas").queue();
                return;
            }

        }

    }`