#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, которую я использовал, смотрите Здесь .