使用 Java Discord4J 发送包含倒计时的频道消息

本文将演示如何使用 Java Discord4J 库,向指定 Discord 频道发送包含倒计时的消息,并定期更新消息内容。

代码示例:

import discord4j.core.DiscordClient;
import discord4j.core.event.domain.message.MessageCreateEvent;
import discord4j.core.object.entity.Message;
import discord4j.core.object.entity.channel.Channel;
import discord4j.core.object.entity.channel.TextChannel;
import discord4j.core.spec.EmbedCreateSpec;
import discord4j.core.spec.MessageCreateSpec;
import discord4j.rest.util.Color;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.atomic.AtomicInteger;

public class Main {

    private static final String CHANNEL_ID = '1234567890'; // 指定的频道ID
    private static final String COUNTDOWN_MESSAGE = '倒计时:'; // 倒计时前缀
    private static final String END_MESSAGE = '时间到了!'; // 时间到了的消息
    private static final LocalDateTime END_TIME = LocalDateTime.now().plusMinutes(1); // 倒计时结束时间

    private static DiscordClient client;

    public static void main(String[] args) {
        client = DiscordClient.create('YOUR_BOT_TOKEN');
        client.login().block();

        client.getEventDispatcher().on(MessageCreateEvent.class)
                .map(MessageCreateEvent::getMessage)
                .filter(message -> message.getContent().orElse('').equalsIgnoreCase('!countdown'))
                .flatMap(Message::getChannel)
                .flatMap(channel -> channel.createMessage(COUNTDOWN_MESSAGE + getFormattedTime()))
                .flatMap(message -> {
                    if (message.getChannelId().asString().equals(CHANNEL_ID)) {
                        startCountdown(message.getChannel().block());
                    }
                    return null;
                })
                .subscribe();
    }

    private static void startCountdown(TextChannel channel) {
        AtomicInteger seconds = new AtomicInteger((int) Duration.between(LocalDateTime.now(), END_TIME).getSeconds());
        client.getScheduler().createInterval(Duration.ofSeconds(1))
                .doOnNext(tick -> {
                    seconds.decrementAndGet();
                    if (seconds.get() < 0) {
                        channel.createMessage(END_MESSAGE).block();
                        tick.cancel();
                    } else {
                        updateMessage(channel, COUNTDOWN_MESSAGE + getFormattedTime(seconds.get()));
                    }
                })
                .subscribe();
    }

    private static void updateMessage(TextChannel channel, String content) {
        channel.getLatestMessage()
                .flatMap(Message::edit)
                .flatMap(spec -> spec.setContent(content))
                .block();
    }

    private static String getFormattedTime() {
        return getFormattedTime(Duration.between(LocalDateTime.now(), END_TIME).getSeconds());
    }

    private static String getFormattedTime(int seconds) {
        return String.format('%02d:%02d:%02d', seconds / 3600, (seconds % 3600) / 60, seconds % 60);
    }
}

这段代码会监听 '!countdown' 指令,并在收到该指令后向指定的频道发送一个包含倒计时的消息。当消息被发送后,会启动一个倒计时,每秒更新一次消息中的倒计时内容。当倒计时结束时,会向该频道发送一个消息,表示时间到了。

代码说明:

  1. 定义常量:

    • CHANNEL_ID: 需要发送消息的频道 ID。
    • COUNTDOWN_MESSAGE: 倒计时消息的前缀。
    • END_MESSAGE: 倒计时结束时的消息。
    • END_TIME: 倒计时结束的时间,这里设置为当前时间加上 1 分钟。
  2. 创建 Discord 客户端:

    • 使用 DiscordClient.create('YOUR_BOT_TOKEN') 创建 Discord 客户端,并将你的 bot token 替换为 YOUR_BOT_TOKEN
    • 使用 client.login().block() 登录 Discord 客户端。
  3. 监听 '!countdown' 指令:

    • 使用 client.getEventDispatcher().on(MessageCreateEvent.class) 监听 MessageCreateEvent 事件。
    • 使用 map(MessageCreateEvent::getMessage) 获取消息内容。
    • 使用 filter(message -> message.getContent().orElse('').equalsIgnoreCase('!countdown')) 过滤出包含 '!countdown' 的消息。
    • 使用 flatMap(Message::getChannel) 获取消息所在的频道。
    • 使用 flatMap(channel -> channel.createMessage(COUNTDOWN_MESSAGE + getFormattedTime())) 向频道发送包含倒计时的消息。
    • 使用 flatMap(message -> { ... }) 判断消息是否发送到指定的频道。
    • 如果是指定的频道,则使用 startCountdown(message.getChannel().block()) 启动倒计时。
  4. 启动倒计时:

    • 使用 client.getScheduler().createInterval(Duration.ofSeconds(1)) 创建一个每秒执行一次的任务。
    • 使用 doOnNext(tick -> { ... }) 在每次执行时更新倒计时内容。
    • 使用 seconds.decrementAndGet() 递减秒数。
    • 使用 if (seconds.get() < 0) { ... } 判断倒计时是否结束。
    • 如果倒计时结束,则使用 channel.createMessage(END_MESSAGE).block() 发送时间到了的消息,并使用 tick.cancel() 取消任务。
    • 如果倒计时未结束,则使用 updateMessage(channel, COUNTDOWN_MESSAGE + getFormattedTime(seconds.get())) 更新消息内容。
  5. 更新消息内容:

    • 使用 channel.getLatestMessage() 获取最新发送的消息。
    • 使用 flatMap(Message::edit) 编辑消息内容。
    • 使用 flatMap(spec -> spec.setContent(content)) 设置新的消息内容。
  6. 格式化倒计时时间:

    • 使用 getFormattedTime() 获取当前时间距离倒计时结束时间的时间差。
    • 使用 getFormattedTime(int seconds) 格式化时间,以 HH:MM:SS 的格式显示。

使用说明:

  1. 将代码保存为 Main.java 文件。
  2. 替换 YOUR_BOT_TOKEN 为你的 bot token。
  3. CHANNEL_ID 替换为你要发送消息的频道 ID。
  4. 编译并运行代码。
  5. 在 Discord 频道中发送 '!countdown' 指令,即可启动倒计时。

注意:

  • 这段代码只是示例,你需要根据自己的需求进行修改。
  • 为了更方便地管理 bot,建议使用 Discord.js 的库管理 bot 的配置和命令。
  • 为了避免 bot 因为长时间运行导致内存泄漏,建议使用异步编程方式。
  • 这段代码使用了阻塞方式,如果需要更快的响应速度,建议使用非阻塞方式。

希望本文能帮助你了解如何使用 Java Discord4J 库发送包含倒计时的频道消息。

Java Discord4J 频道倒计时消息发送示例

原文地址: https://www.cveoy.top/t/topic/mT1V 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录