Нужна подсказка по написанию бота Discord на Java для опроса людей

#java #discord #bots #discord-jda

#java #Discord #боты #discord-jda

Вопрос:

Я пишу небольшого бота для опросов. Работать это должно так: человек нажимает на реакцию или вводит команду, после чего бот создает для него личный канал и задает человеку вопросы, на которые он должен ответить.

Но мне нужно, чтобы бот мог работать с несколькими людьми одновременно. Я застрял на моменте создания канала и задавания вопросов. Дело в том, что если человек, например, нажимает на реакцию и начинает проходить опрос, и в этот момент другой человек также начинает проходить опрос, то бот прекращает опрос первого человека.

Скорее всего, это связано с тем, что я не знаю, как правильно заставить бота проверять, по какому каналу опрашивается определенный человек. Мой вопрос немного сбивает с толку, потому что я не могу сформулировать его правильно, поэтому я попытаюсь объяснить его в своем коде.

Итак, у меня есть два класса с двумя слушателями. Во-первых ReactionListener.java , этот класс должен проверять, нажал ли человек определенную реакцию на определенное сообщение, а затем создает личный канал для человека, на котором бот будет задавать ему вопросы.

 public class ReactionListener extends ListenerAdapter {
    public static TextChannel channel;
    private long msgID = "some id of message...";
    private long categoryID = "some id of category...";
    @Override
    public void onMessageReactionAdd(MessageReactionAddEvent event) {
        MessageReaction.ReactionEmote reaction = event.getReaction().getReactionEmote();
        if (event.getMessageId().equals(msgID) amp;amp; reaction.getEmoji().equals("✅")) {
            Category category = event.getGuild().getCategoryById(categoryID);
            channel = category.createTextChannel("survey")
                    .addPermissionOverride(guild.getPublicRole(), null, EnumSet.of(Permission.VIEW_CHANNEL))
                    .addPermissionOverride(member, EnumSet.of(Permission.VIEW_CHANNEL, Permission.MESSAGE_WRITE, Permission.MESSAGE_HISTORY), null)
                    .complete();
            channel.sendMessage("Some first question to member").queue();
        }
    }
}
 

Второй класс — это MessageListener.java , вот тут-то я и застрял. Мне нужно правильно передать
этому классу личный канал для человека, который был создан в ReactionListener.java класс.

 public class MessageListener extends ListenerAdapter {
    public static String answer;
    @Override
    public void onMessageReceived(MessageReceivedEvent event) {
        TextChannel channel = ReactionListener.channel;
        if (event.getChannel().equals(channel) amp;amp; !event.getAuthor().isBot()) {
            answer = event.getMessage().getContentRaw();
            event.getChannel().sendMessage("Some second question").queue();
            // the rest of the code...
        }
    }
}
 

Как я уже говорил выше, бот не может опрашивать несколько человек одновременно.
Скорее всего, это связано с тем, что я не могу корректно передать приватный канал из одного класса в другой.
По-видимому, когда второй человек начинает проходить опрос, бот начинает проверять соответствие канала не первого человека,
а второго. Мне нужна подсказка о том, как сделать так, чтобы бот мог работать с несколькими людьми одновременно.

Ответ №1:

Вы сохраняете свои данные как объекты класса, поэтому каждый раз, когда событие запускается и вы его обрабатываете, вы перезаписываете объект. Вместо использования объектов класса для хранения данных используйте структуры данных.


ReactionListener.java:

 public class ReactionListener extends ListenerAdapter {

    public static Map<Member, List<String>> answerMap = new HashMap<>();
    public static Map<Member, TextChannel> surveyChannelMap = new HashMap<>();
    private final static long msgID = 11111; // Insert a valid msgId;
    private final long categoryID = 1111; // insert a valid category id

    @Override
    public void onMessageReactionAdd(MessageReactionAddEvent event) {
        MessageReaction.ReactionEmote reaction = event.getReaction().getReactionEmote();
        if (event.getMessageIdLong() == msgID amp;amp; reaction.getEmoji().equals("✅")) {
            Guild guild = event.getGuild();
            Category category = guild.getCategoryById(categoryID);
            Member member = event.getMember();
            category.createTextChannel("survey-"   member.getEffectiveName())
                    .addPermissionOverride(guild.getPublicRole(), null, EnumSet.of(Permission.VIEW_CHANNEL))
                    .addPermissionOverride(member, EnumSet.of(Permission.VIEW_CHANNEL, Permission.MESSAGE_WRITE, Permission.MESSAGE_HISTORY), null)
                    .queue(textChannel -> {
                        surveyChannelMap.put(member, textChannel);
                        textChannel.sendMessage("Some first question to member").queue();
                    });
        }
    }
}
 

MessageListener.java:

 public class MessageListener extends ListenerAdapter {

    @Override
    public void onMessageReceived(MessageReceivedEvent event) {
        Member member = event.getMember();
        if (ReactionListener.surveyChannelMap.containsKey(member)) {
            if (event.getTextChannel().equals(ReactionListener.surveyChannelMap.get(member))) {
                if (answerMap.containsKey(member)){
                    List<String> answers = answerMap.get(member);
                    answerMap.put(member, answers);
                } else {
                    answerMap.put(member, new ArrayList<>(Collections.singletonList(event.getMessage().getContentRaw())));
                }
                event.getChannel().sendMessage("Some second question").queue();
                // the rest of the code...
            }
        }
    }
}
 

В приведенных выше примерах я использовал структуры данных для хранения информации об участниках таким образом, чтобы они не переопределяли друг друга, и вы сможете сохранить все ответы и каналы эффективным и простым способом.

Для получения дополнительной информации о структуре данных HashMap, которую я использовал, смотрите Здесь .