diff --git a/application/build.gradle b/application/build.gradle index 3e9ece84ca..14cd60d0b5 100644 --- a/application/build.gradle +++ b/application/build.gradle @@ -45,7 +45,7 @@ dependencies { implementation project(':database') implementation project(':utils') - implementation 'net.dv8tion:JDA:5.0.0-alpha.9' + implementation 'net.dv8tion:JDA:5.0.0-alpha.20' implementation 'org.apache.logging.log4j:log4j-core:2.19.0' runtimeOnly 'org.apache.logging.log4j:log4j-slf4j18-impl:2.18.0' diff --git a/application/src/main/java/org/togetherjava/tjbot/Application.java b/application/src/main/java/org/togetherjava/tjbot/Application.java index 5927afe8af..71128aef44 100644 --- a/application/src/main/java/org/togetherjava/tjbot/Application.java +++ b/application/src/main/java/org/togetherjava/tjbot/Application.java @@ -3,6 +3,7 @@ import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.JDABuilder; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.exceptions.InvalidTokenException; import net.dv8tion.jda.api.requests.GatewayIntent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -12,7 +13,6 @@ import org.togetherjava.tjbot.config.Config; import org.togetherjava.tjbot.db.Database; -import javax.security.auth.login.LoginException; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -79,7 +79,7 @@ public static void runBot(Config config) { Database database = new Database("jdbc:sqlite:" + databasePath.toAbsolutePath()); JDA jda = JDABuilder.createDefault(config.getToken()) - .enableIntents(GatewayIntent.GUILD_MEMBERS) + .enableIntents(GatewayIntent.GUILD_MEMBERS, GatewayIntent.MESSAGE_CONTENT) .build(); jda.awaitReady(); @@ -91,7 +91,7 @@ public static void runBot(Config config) { jda.addEventListener(core); logger.info("Bot is ready"); - } catch (LoginException e) { + } catch (InvalidTokenException e) { logger.error("Failed to login", e); } catch (InterruptedException e) { logger.error("Interrupted while waiting for setup to complete", e); diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/BotCommandAdapter.java b/application/src/main/java/org/togetherjava/tjbot/commands/BotCommandAdapter.java index f7cf697420..3a5e5af1f3 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/BotCommandAdapter.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/BotCommandAdapter.java @@ -51,7 +51,7 @@ public abstract class BotCommandAdapter implements BotCommand { * @param visibility the visibility of the command */ protected BotCommandAdapter(CommandData data, CommandVisibility visibility) { - this.data = Objects.requireNonNull(data, "The data shouldn't be null"); + this.data = data.setGuildOnly(visibility == CommandVisibility.GUILD); this.visibility = Objects.requireNonNull(visibility, "The visibility shouldn't be null"); this.name = data.getName(); diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/MessageContextCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/MessageContextCommand.java index 5a29c0c873..912f264450 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/MessageContextCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/MessageContextCommand.java @@ -1,6 +1,5 @@ package org.togetherjava.tjbot.commands; -import net.dv8tion.jda.api.entities.Emoji; import net.dv8tion.jda.api.events.interaction.command.MessageContextInteractionEvent; import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; import net.dv8tion.jda.api.events.interaction.component.SelectMenuInteractionEvent; @@ -50,7 +49,7 @@ public interface MessageContextCommand extends BotCommand { *

* Buttons or menus have to be created with a component ID (see * {@link ComponentInteraction#getComponentId()}, - * {@link net.dv8tion.jda.api.interactions.components.buttons.Button#of(ButtonStyle, String, Emoji)}) + * {@link net.dv8tion.jda.api.interactions.components.buttons.Button#of(ButtonStyle, String, String)}) * in a very specific format, otherwise the core system will fail to identify the command that * corresponded to the button or menu click event and is unable to route it back. *

diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/SlashCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/SlashCommand.java index 53b5456d65..ba72609bc2 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/SlashCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/SlashCommand.java @@ -1,6 +1,5 @@ package org.togetherjava.tjbot.commands; -import net.dv8tion.jda.api.entities.Emoji; import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; @@ -81,7 +80,7 @@ public interface SlashCommand extends BotCommand { *

* Buttons or menus have to be created with a component ID (see * {@link ComponentInteraction#getComponentId()}, - * {@link net.dv8tion.jda.api.interactions.components.buttons.Button#of(ButtonStyle, String, Emoji)}) + * {@link net.dv8tion.jda.api.interactions.components.buttons.Button#of(ButtonStyle, String, String)}) * in a very specific format, otherwise the core system will fail to identify the command that * corresponded to the button or menu click event and is unable to route it back. *

diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/UserContextCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/UserContextCommand.java index 95e278bbad..cb1cab4127 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/UserContextCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/UserContextCommand.java @@ -1,6 +1,5 @@ package org.togetherjava.tjbot.commands; -import net.dv8tion.jda.api.entities.Emoji; import net.dv8tion.jda.api.events.interaction.command.UserContextInteractionEvent; import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; import net.dv8tion.jda.api.events.interaction.component.SelectMenuInteractionEvent; @@ -51,7 +50,7 @@ public interface UserContextCommand extends BotCommand { *

* Buttons or menus have to be created with a component ID (see * {@link ComponentInteraction#getComponentId()}, - * {@link net.dv8tion.jda.api.interactions.components.buttons.Button#of(ButtonStyle, String, Emoji)}) + * {@link net.dv8tion.jda.api.interactions.components.buttons.Button#of(ButtonStyle, String, String)}) * in a very specific format, otherwise the core system will fail to identify the command that * corresponded to the button or menu click event and is unable to route it back. *

diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/basic/RoleSelectCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/basic/RoleSelectCommand.java index 096bb3327a..05a372eca1 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/basic/RoleSelectCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/basic/RoleSelectCommand.java @@ -3,6 +3,7 @@ import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.entities.*; +import net.dv8tion.jda.api.entities.emoji.Emoji; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.events.interaction.component.SelectMenuInteractionEvent; import net.dv8tion.jda.api.interactions.callbacks.IReplyCallback; @@ -183,9 +184,8 @@ private void sendRoleSelectionMenu(final CommandInteraction event, .map(RoleSelectCommand::mapToSelectOption) .forEach(menu::addOptions); - OptionMapping titleOption = event.getOption(TITLE_OPTION); - String title = titleOption == null ? "Select your roles:" : titleOption.getAsString(); - + String title = + event.getOption(TITLE_OPTION, "Select your roles:", OptionMapping::getAsString); MessageEmbed embed = createEmbed(title, event.getOption(DESCRIPTION_OPTION).getAsString()); event.replyEmbeds(embed).addActionRow(menu.build()).queue(); @@ -196,7 +196,7 @@ private static SelectOption mapToSelectOption(Role role) { SelectOption option = SelectOption.of(role.getName(), role.getId()); if (null != roleIcon && roleIcon.isEmoji()) { - option = option.withEmoji((Emoji.fromUnicode(roleIcon.getEmoji()))); + option = option.withEmoji(Emoji.fromUnicode(roleIcon.getEmoji())); } return option; diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/basic/SuggestionsUpDownVoter.java b/application/src/main/java/org/togetherjava/tjbot/commands/basic/SuggestionsUpDownVoter.java index f6bc7965b7..3ca76e4ae3 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/basic/SuggestionsUpDownVoter.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/basic/SuggestionsUpDownVoter.java @@ -1,8 +1,9 @@ package org.togetherjava.tjbot.commands.basic; -import net.dv8tion.jda.api.entities.Emote; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.entities.emoji.Emoji; +import net.dv8tion.jda.api.entities.emoji.RichCustomEmoji; import net.dv8tion.jda.api.events.message.MessageReceivedEvent; import net.dv8tion.jda.api.exceptions.ErrorResponseException; import net.dv8tion.jda.api.requests.ErrorResponse; @@ -22,8 +23,8 @@ public final class SuggestionsUpDownVoter extends MessageReceiverAdapter { private static final Logger logger = LoggerFactory.getLogger(SuggestionsUpDownVoter.class); private static final int TITLE_MAX_LENGTH = 60; - private static final String FALLBACK_UP_VOTE = "👍"; - private static final String FALLBACK_DOWN_VOTE = "👎"; + private static final Emoji FALLBACK_UP_VOTE = Emoji.fromUnicode("👍"); + private static final Emoji FALLBACK_DOWN_VOTE = Emoji.fromUnicode("👎"); private final SuggestionsConfig config; @@ -68,13 +69,13 @@ private static void createThread(Message message) { message.createThreadChannel(title).queue(); } - private static void reactWith(String emoteName, String fallbackUnicodeEmote, Guild guild, + private static void reactWith(String emojiName, Emoji fallbackEmoji, Guild guild, Message message) { - getEmoteByName(emoteName, guild).map(message::addReaction).orElseGet(() -> { + getEmojiByName(emojiName, guild).map(message::addReaction).orElseGet(() -> { logger.warn( - "Unable to vote on a suggestion with the configured emote ('{}'), using fallback instead.", - emoteName); - return message.addReaction(fallbackUnicodeEmote); + "Unable to vote on a suggestion with the configured emoji ('{}'), using fallback instead.", + emojiName); + return message.addReaction(fallbackEmoji); }).queue(ignored -> { }, exception -> { if (exception instanceof ErrorResponseException responseException @@ -88,7 +89,7 @@ private static void reactWith(String emoteName, String fallbackUnicodeEmote, Gui }); } - private static Optional getEmoteByName(String name, Guild guild) { - return guild.getEmotesByName(name, false).stream().findAny(); + private static Optional getEmojiByName(String name, Guild guild) { + return guild.getEmojisByName(name, false).stream().findAny(); } } diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/basic/VcActivityCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/basic/VcActivityCommand.java index 1322c62591..033616ab34 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/basic/VcActivityCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/basic/VcActivityCommand.java @@ -4,7 +4,7 @@ import net.dv8tion.jda.api.entities.GuildVoiceState; import net.dv8tion.jda.api.entities.Invite; import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.VoiceChannel; +import net.dv8tion.jda.api.entities.channel.concrete.VoiceChannel; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.interactions.commands.Command; import net.dv8tion.jda.api.interactions.commands.OptionMapping; diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/componentids/ComponentIdGenerator.java b/application/src/main/java/org/togetherjava/tjbot/commands/componentids/ComponentIdGenerator.java index dd8035e8d0..0a746965d8 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/componentids/ComponentIdGenerator.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/componentids/ComponentIdGenerator.java @@ -1,6 +1,5 @@ package org.togetherjava.tjbot.commands.componentids; -import net.dv8tion.jda.api.entities.Emoji; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.interactions.components.ComponentInteraction; import net.dv8tion.jda.api.interactions.components.buttons.Button; @@ -26,7 +25,7 @@ public interface ComponentIdGenerator { * interactions, such as button or selection menus. *

* See {@link ComponentInteraction#getComponentId()} and - * {@link Button#of(ButtonStyle, String, Emoji)} for details on where the generated ID can be + * {@link Button#of(ButtonStyle, String, String)} for details on where the generated ID can be * used. * * @param componentId the component ID payload to persist and generate a valid ID for diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/componentids/ComponentIdParser.java b/application/src/main/java/org/togetherjava/tjbot/commands/componentids/ComponentIdParser.java index 4e17409c6e..83173f0474 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/componentids/ComponentIdParser.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/componentids/ComponentIdParser.java @@ -1,6 +1,5 @@ package org.togetherjava.tjbot.commands.componentids; -import net.dv8tion.jda.api.entities.Emoji; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.interactions.components.ComponentInteraction; import net.dv8tion.jda.api.interactions.components.buttons.Button; @@ -28,7 +27,7 @@ public interface ComponentIdParser { * interactions, such as button or selection menus. *

* See {@link ComponentInteraction#getComponentId()} and - * {@link Button#of(ButtonStyle, String, Emoji)} for details on where the ID was originally + * {@link Button#of(ButtonStyle, String, String)} for details on where the ID was originally * transported with. * * @param uuid the UUID to parse which represents the component ID diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/filesharing/FileSharingMessageListener.java b/application/src/main/java/org/togetherjava/tjbot/commands/filesharing/FileSharingMessageListener.java index c36b37730d..9e145b6b2e 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/filesharing/FileSharingMessageListener.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/filesharing/FileSharingMessageListener.java @@ -2,10 +2,10 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import net.dv8tion.jda.api.entities.ChannelType; import net.dv8tion.jda.api.entities.Message; -import net.dv8tion.jda.api.entities.ThreadChannel; import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.entities.channel.ChannelType; +import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel; import net.dv8tion.jda.api.events.message.MessageReceivedEvent; import net.dv8tion.jda.api.interactions.components.buttons.Button; import org.slf4j.Logger; @@ -114,7 +114,8 @@ private void processAttachments(MessageReceivedEvent event, List> tasks = new ArrayList<>(); for (Message.Attachment attachment : attachments) { - CompletableFuture task = attachment.retrieveInputStream() + CompletableFuture task = attachment.getProxy() + .download() .thenApply(this::readAttachment) .thenAccept( content -> nameToFile.put(getNameOf(attachment), new GistFile(content))); @@ -217,7 +218,7 @@ private boolean isHelpThread(MessageReceivedEvent event) { return false; } - ThreadChannel thread = event.getThreadChannel(); + ThreadChannel thread = event.getChannel().asThreadChannel(); String rootChannelName = thread.getParentChannel().getName(); return isStagingChannelName.test(rootChannelName) || isOverviewChannelName.test(rootChannelName); diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/help/AskCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/help/AskCommand.java index 91ad35f2c0..59ce0f3fff 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/help/AskCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/help/AskCommand.java @@ -1,6 +1,11 @@ package org.togetherjava.tjbot.commands.help; -import net.dv8tion.jda.api.entities.*; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.IMentionable; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; +import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.exceptions.ErrorResponseException; import net.dv8tion.jda.api.interactions.InteractionHook; diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/help/AutoPruneHelperRoutine.java b/application/src/main/java/org/togetherjava/tjbot/commands/help/AutoPruneHelperRoutine.java index 2623c1b13f..5d20b179e1 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/help/AutoPruneHelperRoutine.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/help/AutoPruneHelperRoutine.java @@ -4,7 +4,7 @@ import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Role; -import net.dv8tion.jda.api.entities.TextChannel; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.togetherjava.tjbot.commands.Routine; diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/help/BotMessageCleanup.java b/application/src/main/java/org/togetherjava/tjbot/commands/help/BotMessageCleanup.java index 0ebe47f21e..768341fad0 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/help/BotMessageCleanup.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/help/BotMessageCleanup.java @@ -2,9 +2,9 @@ import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.entities.Guild; -import net.dv8tion.jda.api.entities.GuildMessageChannel; import net.dv8tion.jda.api.entities.Message; -import net.dv8tion.jda.api.entities.TextChannel; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; +import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel; import net.dv8tion.jda.api.requests.RestAction; import net.dv8tion.jda.internal.requests.CompletedRestAction; import org.slf4j.Logger; diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/help/HelpSystemHelper.java b/application/src/main/java/org/togetherjava/tjbot/commands/help/HelpSystemHelper.java index 59f4a54a25..2831d23400 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/help/HelpSystemHelper.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/help/HelpSystemHelper.java @@ -2,10 +2,17 @@ import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.JDA; -import net.dv8tion.jda.api.MessageBuilder; import net.dv8tion.jda.api.entities.*; +import net.dv8tion.jda.api.entities.channel.Channel; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; +import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel; +import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; +import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; import net.dv8tion.jda.api.requests.RestAction; -import net.dv8tion.jda.api.requests.restaction.MessageAction; +import net.dv8tion.jda.api.requests.restaction.MessageCreateAction; +import net.dv8tion.jda.api.utils.FileUpload; +import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder; +import net.dv8tion.jda.api.utils.messages.MessageCreateData; import net.dv8tion.jda.internal.requests.CompletedRestAction; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -110,9 +117,10 @@ RestAction sendExplanationMessage(MessageChannel threadChannel) { HelpSystemHelper.embedWith( "Don't forget to close your thread using the command **/help-thread close** when your question has been answered, thanks.")); - MessageAction action = threadChannel.sendMessage(message); + MessageCreateAction action = threadChannel.sendMessage(message); if (useCodeSyntaxExampleImage) { - action = action.addFile(codeSyntaxExampleData, CODE_SYNTAX_EXAMPLE_PATH); + action = action + .addFiles(FileUpload.fromData(codeSyntaxExampleData, CODE_SYNTAX_EXAMPLE_PATH)); } return action.setEmbeds(embeds); } @@ -295,7 +303,9 @@ private void executeUncategorizedAdviceCheck(long threadChannelId, long authorId Hey there 👋 You have to select a category for your help thread, otherwise nobody can see your question. Please use the `/help-thread change category` slash-command and pick what fits best, thanks 🙂 """); - Message message = new MessageBuilder(author.getAsMention()).setEmbeds(embed).build(); + MessageCreateData message = new MessageCreateBuilder().setContent(author.getAsMention()) + .setEmbeds(embed) + .build(); return threadChannel.sendMessage(message); }).queue(); diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/help/HelpThreadActivityUpdater.java b/application/src/main/java/org/togetherjava/tjbot/commands/help/HelpThreadActivityUpdater.java index 79553fcdee..75db5e8f1a 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/help/HelpThreadActivityUpdater.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/help/HelpThreadActivityUpdater.java @@ -1,7 +1,12 @@ package org.togetherjava.tjbot.commands.help; import net.dv8tion.jda.api.JDA; -import net.dv8tion.jda.api.entities.*; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; +import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel; +import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; import net.dv8tion.jda.api.requests.RestAction; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/help/HelpThreadAutoArchiver.java b/application/src/main/java/org/togetherjava/tjbot/commands/help/HelpThreadAutoArchiver.java index 312d170b1e..ef98c5f523 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/help/HelpThreadAutoArchiver.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/help/HelpThreadAutoArchiver.java @@ -2,7 +2,11 @@ import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.JDA; -import net.dv8tion.jda.api.entities.*; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.MessageEmbed; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; +import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel; +import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; import net.dv8tion.jda.api.utils.TimeUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/help/HelpThreadCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/help/HelpThreadCommand.java index 04c9b78cb5..b37c503537 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/help/HelpThreadCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/help/HelpThreadCommand.java @@ -3,7 +3,11 @@ import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.entities.*; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.entities.MessageEmbed; +import net.dv8tion.jda.api.entities.Role; +import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.interactions.InteractionHook; import net.dv8tion.jda.api.interactions.commands.OptionType; @@ -11,7 +15,7 @@ import net.dv8tion.jda.api.interactions.commands.build.SubcommandData; import net.dv8tion.jda.api.interactions.commands.build.SubcommandGroupData; import net.dv8tion.jda.api.requests.RestAction; -import net.dv8tion.jda.api.requests.restaction.WebhookMessageUpdateAction; +import net.dv8tion.jda.api.requests.restaction.WebhookMessageEditAction; import org.togetherjava.tjbot.commands.CommandVisibility; import org.togetherjava.tjbot.commands.SlashCommandAdapter; import org.togetherjava.tjbot.config.Config; @@ -92,7 +96,7 @@ public HelpThreadCommand(Config config, HelpSystemHelper helper) { @Override public void onSlashCommand(SlashCommandInteractionEvent event) { - ThreadChannel helpThread = event.getThreadChannel(); + ThreadChannel helpThread = event.getChannel().asThreadChannel(); Subcommand invokedSubcommand = Objects.requireNonNull(nameToSubcommand.get(event.getSubcommandName())); @@ -153,7 +157,7 @@ private void refreshCooldownFor(Subcommand subcommand, ThreadChannel helpThread) private RestAction sendCategoryChangedMessage(Guild guild, InteractionHook hook, ThreadChannel helpThread, String category) { String changedContent = "Changed the category to **%s**.".formatted(category); - WebhookMessageUpdateAction action = hook.editOriginal(changedContent); + WebhookMessageEditAction action = hook.editOriginal(changedContent); Optional helperRole = helper.handleFindRoleForCategory(category, guild); if (helperRole.isEmpty()) { diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/help/HelpThreadOverviewUpdater.java b/application/src/main/java/org/togetherjava/tjbot/commands/help/HelpThreadOverviewUpdater.java index eb32a0e5ac..3337e18f6e 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/help/HelpThreadOverviewUpdater.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/help/HelpThreadOverviewUpdater.java @@ -1,10 +1,17 @@ package org.togetherjava.tjbot.commands.help; import net.dv8tion.jda.api.JDA; -import net.dv8tion.jda.api.MessageBuilder; -import net.dv8tion.jda.api.entities.*; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.entities.MessageType; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; +import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel; +import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; import net.dv8tion.jda.api.events.message.MessageReceivedEvent; import net.dv8tion.jda.api.requests.RestAction; +import net.dv8tion.jda.api.utils.messages.MessageCreateData; +import net.dv8tion.jda.api.utils.messages.MessageEditBuilder; +import net.dv8tion.jda.api.utils.messages.MessageEditData; import net.dv8tion.jda.internal.requests.CompletedRestAction; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -112,7 +119,7 @@ private void updateOverview(TextChannel overviewChannel) { List activeThreads = helper.getActiveThreadsIn(overviewChannel); logger.debug("Found {} active questions", activeThreads.size()); - Message message = new MessageBuilder() + MessageEditData message = new MessageEditBuilder() .setContent(STATUS_TITLE + "\n\n" + createDescription(activeThreads)) .build(); @@ -165,7 +172,7 @@ private static boolean isStatusMessage(Message message) { } private RestAction sendUpdatedOverview(@Nullable Message statusMessage, - Message updatedStatusMessage, MessageChannel overviewChannel) { + MessageEditData updatedStatusMessage, MessageChannel overviewChannel) { logger.debug("Sending the updated question overview"); if (statusMessage == null) { int currentFailures = FIND_STATUS_MESSAGE_CONSECUTIVE_FAILURES.incrementAndGet(); @@ -174,7 +181,8 @@ private RestAction sendUpdatedOverview(@Nullable Message statusMessage, "Failed to locate the question overview too often ({} times), sending a fresh message instead.", currentFailures); FIND_STATUS_MESSAGE_CONSECUTIVE_FAILURES.set(0); - return overviewChannel.sendMessage(updatedStatusMessage); + return overviewChannel + .sendMessage(MessageCreateData.fromEditData(updatedStatusMessage)); } logger.info( diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/help/ImplicitAskListener.java b/application/src/main/java/org/togetherjava/tjbot/commands/help/ImplicitAskListener.java index 629d022128..38289df454 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/help/ImplicitAskListener.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/help/ImplicitAskListener.java @@ -3,13 +3,16 @@ import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.MessageBuilder; import net.dv8tion.jda.api.entities.*; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; +import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel; import net.dv8tion.jda.api.events.message.MessageReceivedEvent; import net.dv8tion.jda.api.exceptions.ErrorResponseException; import net.dv8tion.jda.api.requests.ErrorResponse; import net.dv8tion.jda.api.requests.RestAction; -import net.dv8tion.jda.api.requests.restaction.MessageAction; +import net.dv8tion.jda.api.requests.restaction.MessageCreateAction; +import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder; +import net.dv8tion.jda.api.utils.messages.MessageCreateData; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.togetherjava.tjbot.commands.MessageReceiverAdapter; @@ -163,14 +166,11 @@ private RestAction handleEvent(ThreadChannel threadChannel, Message message, .flatMap(any -> notifyUser(threadChannel, message)) .flatMap(any -> message.delete()) .flatMap(any -> helper.sendExplanationMessage(threadChannel)) - .map(any -> { - helper.scheduleUncategorizedAdviceCheck(threadChannel.getIdLong(), - author.getIdLong()); - return null; - }); + .onSuccess(any -> helper.scheduleUncategorizedAdviceCheck(threadChannel.getIdLong(), + author.getIdLong())); } - private static MessageAction sendInitialMessage(ThreadChannel threadChannel, + private static MessageCreateAction sendInitialMessage(ThreadChannel threadChannel, Message originalMessage, String title) { String content = originalMessage.getContentRaw(); Member author = originalMessage.getMember(); @@ -181,17 +181,20 @@ private static MessageAction sendInitialMessage(ThreadChannel threadChannel, .setColor(HelpSystemHelper.AMBIENT_COLOR) .build(); - Message threadMessage = new MessageBuilder( - """ - %s has a question about '**%s**' and will send the details now. + MessageCreateData threadMessage = new MessageCreateBuilder() + .setContent( + """ + %s has a question about '**%s**' and will send the details now. - Please use `/help-thread change category` to greatly increase the visibility of the question.""" - .formatted(author, title)).setEmbeds(embed).build(); + Please use `/help-thread change category` to greatly increase the visibility of the question.""" + .formatted(author, title)) + .setEmbeds(embed) + .build(); return threadChannel.sendMessage(threadMessage); } - private static MessageAction notifyUser(IMentionable threadChannel, Message message) { + private static MessageCreateAction notifyUser(IMentionable threadChannel, Message message) { return message.getChannel() .sendMessage( """ diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/help/OnGuildLeaveCloseThreadListener.java b/application/src/main/java/org/togetherjava/tjbot/commands/help/OnGuildLeaveCloseThreadListener.java index 3da99a69e7..0d68901753 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/help/OnGuildLeaveCloseThreadListener.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/help/OnGuildLeaveCloseThreadListener.java @@ -2,7 +2,7 @@ import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.MessageEmbed; -import net.dv8tion.jda.api.entities.ThreadChannel; +import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel; import net.dv8tion.jda.api.events.guild.member.GuildMemberRemoveEvent; import net.dv8tion.jda.api.hooks.ListenerAdapter; import org.slf4j.Logger; diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/mathcommands/TeXCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/mathcommands/TeXCommand.java index 3e6d707e9c..ead51436f8 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/mathcommands/TeXCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/mathcommands/TeXCommand.java @@ -6,6 +6,7 @@ import net.dv8tion.jda.api.interactions.commands.OptionType; import net.dv8tion.jda.api.interactions.components.buttons.Button; import net.dv8tion.jda.api.interactions.components.buttons.ButtonStyle; +import net.dv8tion.jda.api.utils.FileUpload; import org.scilab.forge.jlatexmath.ParseException; import org.scilab.forge.jlatexmath.TeXConstants; import org.scilab.forge.jlatexmath.TeXFormula; @@ -110,7 +111,8 @@ private void sendImage(IDeferrableCallback event, String userID, Image image) throws IOException { ByteArrayOutputStream renderedTextImageStream = getRenderedTextImageStream(image); event.getHook() - .editOriginal(renderedTextImageStream.toByteArray(), "tex.png") + .editOriginalAttachments( + FileUpload.fromData(renderedTextImageStream.toByteArray(), "tex.png")) .setActionRow(Button.of(ButtonStyle.DANGER, generateComponentId(userID), "Delete")) .queue(); } diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/mathcommands/wolframalpha/WolframAlphaCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/mathcommands/wolframalpha/WolframAlphaCommand.java index c599368bb0..fb549df9ce 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/mathcommands/wolframalpha/WolframAlphaCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/mathcommands/wolframalpha/WolframAlphaCommand.java @@ -1,18 +1,18 @@ package org.togetherjava.tjbot.commands.mathcommands.wolframalpha; import io.mikael.urlbuilder.UrlBuilder; -import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.interactions.callbacks.IDeferrableCallback; import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.requests.restaction.WebhookMessageUpdateAction; import org.togetherjava.tjbot.commands.CommandVisibility; +import net.dv8tion.jda.api.utils.FileUpload; import org.togetherjava.tjbot.commands.SlashCommandAdapter; import org.togetherjava.tjbot.config.Config; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; +import java.util.List; import java.util.concurrent.CompletableFuture; /** @@ -74,13 +74,11 @@ public void onSlashCommand(SlashCommandInteractionEvent event) { private static void sendResponse(WolframAlphaHandler.HandlerResponse response, IDeferrableCallback event) { - WebhookMessageUpdateAction action = - event.getHook().editOriginalEmbeds(response.embeds()); + List files = response.attachments() + .stream() + .map(attachment -> FileUpload.fromData(attachment.data(), attachment.name())) + .toList(); - for (WolframAlphaHandler.Attachment attachment : response.attachments()) { - action = action.addFile(attachment.data(), attachment.name()); - } - - action.queue(); + event.getHook().editOriginalEmbeds(response.embeds()).setFiles(files).queue(); } } diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/mathcommands/wolframalpha/WolframAlphaHandler.java b/application/src/main/java/org/togetherjava/tjbot/commands/mathcommands/wolframalpha/WolframAlphaHandler.java index 2d53992e68..749ddee1fe 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/mathcommands/wolframalpha/WolframAlphaHandler.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/mathcommands/wolframalpha/WolframAlphaHandler.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.dataformat.xml.XmlMapper; import io.mikael.urlbuilder.UrlBuilder; import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.MessageEmbed; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,18 +37,12 @@ final class WolframAlphaHandler { * Discord and do not provide a nice user experience anymore. */ private static final int MAX_IMAGE_HEIGHT_PX = 400; - /** - * Maximum amount of embeds Discord supports. - *

- * This should be replaced with a constant provided by JDA, once it does offer one. - */ - private static final int MAX_EMBEDS = 10; /** * Maximum amount of tiles to send. *

* One embed is used as initial description and summary. */ - private static final int MAX_TILES = MAX_EMBEDS - 1; + private static final int MAX_TILES = Message.MAX_EMBED_COUNT - 1; private final String query; private final String userApiQuery; diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/mediaonly/MediaOnlyChannelListener.java b/application/src/main/java/org/togetherjava/tjbot/commands/mediaonly/MediaOnlyChannelListener.java index b2bce6613f..af29d1013f 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/mediaonly/MediaOnlyChannelListener.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/mediaonly/MediaOnlyChannelListener.java @@ -1,12 +1,13 @@ package org.togetherjava.tjbot.commands.mediaonly; import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.MessageBuilder; import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.MessageEmbed; import net.dv8tion.jda.api.entities.MessageType; import net.dv8tion.jda.api.events.message.MessageReceivedEvent; import net.dv8tion.jda.api.requests.RestAction; +import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder; +import net.dv8tion.jda.api.utils.messages.MessageCreateData; import org.togetherjava.tjbot.commands.MessageReceiverAdapter; import org.togetherjava.tjbot.config.Config; @@ -59,10 +60,10 @@ private RestAction dmUser(Message message) { .setColor(Color.ORANGE) .build(); - Message dmMessage = new MessageBuilder( + MessageCreateData dmMessage = new MessageCreateBuilder().setContent( "Hey there, you posted a message without media (image, video, link) in a media-only channel. Please see the description of the channel for details and then repost with media attached, thanks 😀") - .setEmbeds(originalMessageEmbed) - .build(); + .setEmbeds(originalMessageEmbed) + .build(); return message.getAuthor() .openPrivateChannel() diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/moderation/AuditCommand.java b/application/src/main/java/org/togetherjava/tjbot/commands/moderation/AuditCommand.java index 8fceb3adb6..f8e9f560bc 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/moderation/AuditCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/moderation/AuditCommand.java @@ -2,17 +2,21 @@ import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.JDA; -import net.dv8tion.jda.api.MessageBuilder; -import net.dv8tion.jda.api.entities.*; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.MessageEmbed; +import net.dv8tion.jda.api.entities.User; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; import net.dv8tion.jda.api.interactions.callbacks.IReplyCallback; import net.dv8tion.jda.api.interactions.commands.OptionMapping; import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.components.ActionRow; import net.dv8tion.jda.api.interactions.components.buttons.Button; import net.dv8tion.jda.api.requests.RestAction; import net.dv8tion.jda.api.utils.TimeUtil; +import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder; +import net.dv8tion.jda.api.utils.messages.MessageEditBuilder; +import net.dv8tion.jda.api.utils.messages.MessageRequest; import net.dv8tion.jda.internal.requests.CompletedRestAction; import org.togetherjava.tjbot.commands.CommandVisibility; import org.togetherjava.tjbot.commands.SlashCommandAdapter; @@ -21,6 +25,7 @@ import java.time.Instant; import java.time.ZoneOffset; import java.util.*; +import java.util.function.Supplier; import java.util.stream.Collectors; /** @@ -68,8 +73,10 @@ public void onSlashCommand(SlashCommandInteractionEvent event) { return; } - auditUser(guild.getIdLong(), target.getIdLong(), event.getMember().getIdLong(), -1, - event.getJDA()).flatMap(event::reply).queue(); + auditUser(MessageCreateBuilder::new, guild.getIdLong(), target.getIdLong(), + event.getMember().getIdLong(), -1, event.getJDA()).map(MessageCreateBuilder::build) + .flatMap(event::reply) + .queue(); } private boolean handleChecks(Member bot, Member author, @Nullable Member target, @@ -86,7 +93,8 @@ private boolean handleChecks(Member bot, Member author, @Nullable Member target, * can contain {@link AuditCommand#MAX_PAGE_LENGTH} actions, {@code -1} encodes the last * page */ - private RestAction auditUser(long guildId, long targetId, long callerId, + private > RestAction auditUser( + Supplier messageBuilderSupplier, long guildId, long targetId, long callerId, int pageNumber, JDA jda) { List actions = actionsStore.getActionsByTargetAscending(guildId, targetId); List> groupedActions = groupActionsByPages(actions); @@ -103,8 +111,8 @@ private RestAction auditUser(long guildId, long targetId, long callerId .map(user -> createSummaryEmbed(user, actions)) .flatMap(auditEmbed -> attachEmbedFields(auditEmbed, groupedActions, pageNumberInLimits, totalPages, jda)) - .map(auditEmbed -> attachPageTurnButtons(auditEmbed, pageNumberInLimits, totalPages, - guildId, targetId, callerId)); + .map(auditEmbed -> attachPageTurnButtons(messageBuilderSupplier, auditEmbed, + pageNumberInLimits, totalPages, guildId, targetId, callerId)); } private List> groupActionsByPages(List actions) { @@ -197,20 +205,22 @@ private static String formatTime(Instant when) { return TimeUtil.getDateTimeString(when.atOffset(ZoneOffset.UTC)); } - private Message attachPageTurnButtons(EmbedBuilder auditEmbed, int pageNumber, int totalPages, - long guildId, long targetId, long callerId) { - var messageBuilder = new MessageBuilder(auditEmbed.build()); + private > R attachPageTurnButtons( + Supplier messageBuilderSupplier, EmbedBuilder auditEmbed, int pageNumber, + int totalPages, long guildId, long targetId, long callerId) { + var messageBuilder = messageBuilderSupplier.get(); + messageBuilder.setEmbeds(auditEmbed.build()); if (totalPages <= 1) { - return messageBuilder.build(); + return messageBuilder; } - ActionRow pageTurnButtons = + List