JDA - 如何等待下一条消息

Posted

技术标签:

【中文标题】JDA - 如何等待下一条消息【英文标题】:JDA - How to wait for next message 【发布时间】:2021-01-31 03:11:55 【问题描述】:

我正在使用 JDA 制作一个不和谐的机器人,我想知道如何等待消息。像这样的

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

public class Listener extends ListenerAdapter 
    public void onGuildMessageReceived(GuildMessageReceivedEvent event) 
        String message = event.getMessage().getContentRaw();
        boolean isBot = event.getAuthor().isBot();

        // Check if message is not from a bot
        if (!isBot) 
            if (message.equalsIgnoreCase("hi")) 
                event.getChannel().sendMessage("Hello, what's your name?").queue();
                // Wait for second message
                String name = event.getMessage().getContentRaw(); // Saving content from second message
                event.getChannel().sendMessage("Your name is: " + name).queue();
            
        
    

用户:嗨

Bot:你好,你叫什么名字?

用户:发送姓名

Bot:你的名字是:name

我如何获得第二条消息?

【问题讨论】:

这能回答你的问题吗? How to make a Discord Bot wait for a specific user to send a message with JDA? 【参考方案1】:

正如Minn 在评论中所说的那样。您可以使用线程中给出的方法。但是,我建议使用 JDA-Utilities EventWaiter。

如果您使用的是 Maven 或 Gradle,请使用以下任一:

<!--- Place this in your repositories block --->
  <repository>
    <id>central</id>
    <name>bintray</name>
    <url>http://jcenter.bintray.com</url>
  </repository>
<!--- Place this in your dependencies block --->
  <dependency>
    <groupId>com.jagrosh</groupId>
    <artifactId>jda-utilities</artifactId>
    <version>JDA-UTILITIES-VERSION</version>  <!--- This will be the latest JDA-Utilities version. Currently: 3.0.4 --->
    <scope>compile</scope>
    <type>pom</type>
  </dependency>
  <dependency>
    <groupId>net.dv8tion</groupId>
    <artifactId>JDA</artifactId> <!--- This will be your JDA Version --->
    <version>JDA-VERSION</version>
  </dependency>

对于 gradle 来说要容易得多:


# Add this to the dependencies (What's inside this block, not the block itself.

dependencies 
    compile 'com.jagrosh:jda-utilities:JDA-UTILITIES-VERSION'
    compile 'net.dv8tion:JDA:JDA-VERSION'


# Same story for the repo's
repositories 
    jcenter()

加载完成后,我建议您检查ExampleBot main class. 以向其中添加您自己的内容。因为我只会解释让 EventWaiter 工作的基础知识。

这将是启动机器人的主要类,当您运行它时,它将使用这些命令启动机器人。 ShutdownCommand 和 PingCommand 是实用程序的一部分。所以这些会自动添加。

public static void main(String[] args) throws IOException, LoginException, IllegalArgumentException, RateLimitedException
    
        // the first is the bot token
        String token = "The token of your bot"
        // the second is the bot's owner's id
        String ownerId = "The ID of your user account"
        // define an eventwaiter, dont forget to add this to the JDABuilder!
        EventWaiter waiter = new EventWaiter();
        // define a command client
        CommandClientBuilder client = new CommandClientBuilder();
        // sets the owner of the bot
        client.setOwnerId(ownerId);
        // sets the bot prefix
        client.setPrefix("!!");
        // adds commands
        client.addCommands(
                // command to say hello
                new HelloCommand(waiter),
                // command to check bot latency
                new PingCommand(),
                // command to shut off the bot
                new ShutdownCommand());

        // start getting a bot account set up
        new JDABuilder(AccountType.BOT)
                // set the token
                .setToken(token)
                // set the game for when the bot is loading
                .setStatus(OnlineStatus.DO_NOT_DISTURB)
                .setActivity(Activity.playing("loading..."))
                // add the listeners
                .addEventListeners(waiter, client.build())
                // start it up!
                .build();
    

现在,为HelloCommand。首先创建一个名为“HelloCommand”的新类。在本课程中,您将扩展实用程序的“命令”部分。

public class HelloCommand extends Command

    private final EventWaiter waiter; // This variable is used to define the waiter, and call it from anywhere in this class.

    public HelloCommand(EventWaiter waiter)
    
        this.waiter = waiter; // Define the waiter
        this.name = "hello"; // The command
        this.aliases = new String[]"hi"; // Any aliases about the command 
        this.help = "says hello and waits for a response"; // Description of the command
    
    
    @Override
    protected void execute(CommandEvent event)
    
        // ask what the user's name is
        event.reply("Hello. What is your name?"); // Respond to the command with a message.
        
        // wait for a response
        waiter.waitForEvent(MessageReceivedEvent.class, 
                // make sure it's by the same user, and in the same channel, and for safety, a different message
                e -> e.getAuthor().equals(event.getAuthor()) 
                        && e.getChannel().equals(event.getChannel()) 
                        && !e.getMessage().equals(event.getMessage()), 
                // respond, inserting the name they listed into the response
                e -> event.reply("Hello, `"+e.getMessage().getContentRaw()+"`! I'm `"+e.getJDA().getSelfUser().getName()+"`!"),
                // if the user takes more than a minute, time out
                1, TimeUnit.MINUTES, () -> event.reply("Sorry, you took too long."));
    
    

现在,我们来看看有趣的东西。使用事件服务程序时。您需要检查几个区域。

        // wait for a response
        waiter.waitForEvent(MessageReceivedEvent.class, 
                // make sure it's by the same user, and in the same channel, and for safety, a different message
                e -> e.getAuthor().equals(event.getAuthor()) 
                        && e.getChannel().equals(event.getChannel()) 
                        && !e.getMessage().equals(event.getMessage()), 
                // respond, inserting the name they listed into the response
                e -> event.reply("Hello, `"+e.getMessage().getContentRaw()+"`! I'm `"+e.getJDA().getSelfUser().getName()+"`!"),
                // if the user takes more than a minute, time out
                1, TimeUnit.MINUTES, () -> event.reply("Sorry, you took too long."));

更详细的解释:

        waiter.waitForEvent(GuildMessageReceivedEvent.class, // What event do you want to wait for?
            p -> p.getAuthor().equals(message.getAuthor()) && p.getChannel().equals(message.getChannel()), // This is important to get correct, check if the user is the same as the one who executed the command. Otherwise you'll get a user who isn't the one who executed it and the waiter responds to it.
            run -> 
            // Run whatever stuff you want here.
        , 1, // How long should it wait for an X amount of Y?
            TimeUnit.MINUTES, // Y == TimeUnit.<TIME> (Depending on the use case, a different time may be needed)
            () -> message.getChannel().sendMessage("You took longer then a minute to respond. So I've reverted this message.").queue()); // If the user never responds. Do this.

这应该是使用 EventWaiter 的 BASICS。这可能取决于您的用例。也可以只使用 eventwaiter 类来完成。

【讨论】:

以上是关于JDA - 如何等待下一条消息的主要内容,如果未能解决你的问题,请参考以下文章

JDA - 发送消息

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

使用 discordJDA 等待消息未按预期工作

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

如何获取 Bot 消息 ID 并编辑消息 - Discord JDA Java

JDA 在特定日期检索消息