You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JDA中实现带回复交互的Discord机器人离开反馈DM功能

解决Discord机器人离开反馈的私聊监听问题

你的思路方向是对的,但JDA的监听器机制是全局注册生效的,没办法直接给单个私聊频道绑定专属的监听器实例。我们需要换一种更合理的方式:用一个全局监听器,配合用户跟踪集合来识别哪些用户正在提交离开反馈。下面是具体的实现方案:

1. 全局跟踪需要反馈的用户

首先在你的Main类里添加一个线程安全的集合,用来记录当前需要提交反馈的用户ID(因为JDA的事件是多线程处理的,必须用线程安全的容器避免并发问题):

import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

public class Main {
    public static JDA jda;
    // 用ConcurrentHashMap的keySet实现线程安全的Set
    public static Set<Long> feedbackPendingUsers = ConcurrentHashMap.newKeySet();
    
    // ... 你的其他初始化代码
}

2. 修改离开事件代码,标记需要反馈的用户

在发送离开DM的同时,把用户ID加入到刚才的跟踪集合里:

// 成员离开事件的处理代码
event.getUser().openPrivateChannel()
 .flatMap(channel -> {
     // 将用户标记为需要提交反馈
     Main.feedbackPendingUsers.add(event.getUser().getIdLong());
     return channel.sendMessage("Hello, we are sorry you're leaving "+event.getGuild().getName()+", if you don't mind, please tell us why you left or leave any other feedback here, it'll help us improve the server and improve experience for you if you re-join again in the future.\n\nThank you ❤.");
 })
 .queue(
     success -> {},
     error -> {
         // 如果DM发送失败,记得移除用户标记,避免无效跟踪
         Main.feedbackPendingUsers.remove(event.getUser().getIdLong());
     }
 );

3. 重构全局反馈监听器

把你原来的Feedback类改成全局监听器,不需要绑定特定频道和用户,而是通过集合判断是否需要处理当前消息:

import bot.Main;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;

public class FeedbackListener extends ListenerAdapter {

 @Override
 public void onMessageReceived(MessageReceivedEvent event) {
     // 跳过机器人发送的消息
     if (event.getAuthor().isBot()) return;
     
     // 只处理:私聊频道 + 用户在反馈跟踪集合里
     if (!event.isFromPrivateChannel() || !Main.feedbackPendingUsers.contains(event.getAuthor().getIdLong())) {
         return;
     }

     User user = event.getAuthor();
     String feedbackContent = event.getMessage().getContentRaw();

     // 回复用户感谢消息
     event.getChannel().sendMessage("Thanks for your feedback!").queue();

     // 构建反馈Embed
     EmbedBuilder feedbackEmbed = new EmbedBuilder();
     feedbackEmbed.setTitle("Automated System Operations - Leaving Feedback");
     feedbackEmbed.addField("Feedback", feedbackContent, false);
     feedbackEmbed.setColor(0xC90004);
     feedbackEmbed.setAuthor(user.getAsTag() + " - " + user.getId(), null, user.getAvatarUrl());
     feedbackEmbed.setImage("https://media.discordapp.net/attachments/894913784823566428/896323821336948736/unknown.png?width=384&height=192");

     // 发送到服务器的指定反馈频道
     TextChannel feedbackLogChannel = Main.jda.getGuildById("894913620868202506")
                                             .getTextChannelById("896322509874540545");
     if (feedbackLogChannel != null) {
         feedbackLogChannel.sendMessage(feedbackEmbed.build()).queue(
             success -> {
                 // 处理成功后,移除用户的跟踪标记
                 Main.feedbackPendingUsers.remove(user.getIdLong());
             },
             error -> {
                 // 即使发送失败,也要移除标记,避免用户重复提交
                 Main.feedbackPendingUsers.remove(user.getIdLong());
             }
         );
     } else {
         // 如果找不到日志频道,也要移除标记并告知用户
         Main.feedbackPendingUsers.remove(user.getIdLong());
         event.getChannel().sendMessage("Oops, we ran into an issue saving your feedback. Sorry about that!").queue();
     }
 }
}

4. 注册全局监听器

最后在Main类初始化JDA的时候,别忘了注册这个监听器:

public static void main(String[] args) throws Exception {
    jda = JDABuilder.createDefault("YOUR_BOT_TOKEN")
                   .addEventListeners(new FeedbackListener()) // 注册反馈监听器
                   // ... 其他监听器或配置
                   .build();
}

为什么你的原方法行不通?

JDA的ListenerAdapter实例是全局生效的,一旦通过addEventListeners注册,就会接收所有匹配的事件。你原来的思路是给每个私聊频道创建一个监听器实例,但这样会导致监听器实例越来越多,而且JDA不会区分哪个监听器对应哪个频道——所有监听器都会收到所有消息事件,既浪费资源又容易出问题。用全局监听器+用户跟踪的方式,既简洁又高效。

内容的提问来源于stack exchange,提问作者Abdullah Ahmed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 17:17:28