From 01afa91065f3ebce9ed47184a161377b85a2cd53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Tue, 8 Jun 2021 18:34:54 +0200 Subject: [PATCH 01/10] Support multi-embeds in MessageAction --- .../jda/api/entities/MessageChannel.java | 300 ++++++++++++++++++ .../requests/restaction/MessageAction.java | 53 ++++ .../internal/entities/TextChannelImpl.java | 11 + .../restaction/MessageActionImpl.java | 39 ++- 4 files changed, 395 insertions(+), 8 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/api/entities/MessageChannel.java b/src/main/java/net/dv8tion/jda/api/entities/MessageChannel.java index 56e041af38..9ba520aaa7 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/MessageChannel.java +++ b/src/main/java/net/dv8tion/jda/api/entities/MessageChannel.java @@ -15,6 +15,9 @@ */ package net.dv8tion.jda.api.entities; +import net.dv8tion.jda.annotations.DeprecatedSince; +import net.dv8tion.jda.annotations.ForRemoval; +import net.dv8tion.jda.annotations.ReplaceWith; import net.dv8tion.jda.api.AccountType; import net.dv8tion.jda.api.exceptions.AccountTypeException; import net.dv8tion.jda.api.requests.RestAction; @@ -400,9 +403,15 @@ default MessageAction sendMessageFormat(@Nonnull String format, @Nonnull Object. * * @see net.dv8tion.jda.api.MessageBuilder * @see net.dv8tion.jda.api.EmbedBuilder + * + * @deprecated This is deprecated in favor of {@link #sendMessageEmbeds(MessageEmbed...)} */ @Nonnull @CheckReturnValue + @Deprecated + @ForRemoval(deadline="5.0.0") + @ReplaceWith("sendMessageEmbeds(embed)") + @DeprecatedSince("4.4.0") default MessageAction sendMessage(@Nonnull MessageEmbed embed) { Checks.notNull(embed, "Provided embed"); @@ -411,6 +420,93 @@ default MessageAction sendMessage(@Nonnull MessageEmbed embed) return new MessageActionImpl(getJDA(), route, this).embed(embed); } + /** + * Sends up to 10 specified {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbeds} as a {@link net.dv8tion.jda.api.entities.Message Message} + * to this channel. + *
This will fail if this channel is an instance of {@link net.dv8tion.jda.api.entities.TextChannel TextChannel} and + * the currently logged in account does not have permissions to send a message to this channel. + *
To determine if you are able to send a message in a {@link net.dv8tion.jda.api.entities.TextChannel TextChannel} use + * {@link net.dv8tion.jda.api.entities.Member#hasPermission(GuildChannel, net.dv8tion.jda.api.Permission...) + * guild.getSelfMember().hasPermission(channel, Permission.MESSAGE_WRITE)}. + * + *

For {@link net.dv8tion.jda.api.requests.ErrorResponse} information, refer to {@link #sendMessage(Message)}. + * + * @param embeds + * the {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbeds} to send + * + * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException + * If this is a {@link net.dv8tion.jda.api.entities.TextChannel TextChannel} and the logged in account does + * not have + *

+ * @throws java.lang.IllegalArgumentException + * If any of the provided embeds is {@code null} or if the provided {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbed} + * is not {@link net.dv8tion.jda.api.entities.MessageEmbed#isSendable() sendable} + * @throws java.lang.UnsupportedOperationException + * If this is a {@link net.dv8tion.jda.api.entities.PrivateChannel PrivateChannel} + * and both the currently logged in account and the target user are bots. + * + * @return {@link MessageAction MessageAction} + *
The newly created Message after it has been sent to Discord. + * + * @see net.dv8tion.jda.api.MessageBuilder + * @see net.dv8tion.jda.api.EmbedBuilder + */ + @Nonnull + @CheckReturnValue + default MessageAction sendMessageEmbeds(@Nonnull MessageEmbed... embeds) + { + Route.CompiledRoute route = Route.Messages.SEND_MESSAGE.compile(getId()); + return new MessageActionImpl(getJDA(), route, this).setEmbeds(embeds); + } + + /** + * Sends up to 10 specified {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbeds} as a {@link net.dv8tion.jda.api.entities.Message Message} + * to this channel. + *
This will fail if this channel is an instance of {@link net.dv8tion.jda.api.entities.TextChannel TextChannel} and + * the currently logged in account does not have permissions to send a message to this channel. + *
To determine if you are able to send a message in a {@link net.dv8tion.jda.api.entities.TextChannel TextChannel} use + * {@link net.dv8tion.jda.api.entities.Member#hasPermission(GuildChannel, net.dv8tion.jda.api.Permission...) + * guild.getSelfMember().hasPermission(channel, Permission.MESSAGE_WRITE)}. + * + *

For {@link net.dv8tion.jda.api.requests.ErrorResponse} information, refer to {@link #sendMessage(Message)}. + * + * @param embeds + * the {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbeds} to send + * + * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException + * If this is a {@link net.dv8tion.jda.api.entities.TextChannel TextChannel} and the logged in account does + * not have + *

+ * @throws java.lang.IllegalArgumentException + * If any of the provided embeds is {@code null} or if the provided {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbed} + * is not {@link net.dv8tion.jda.api.entities.MessageEmbed#isSendable() sendable} + * @throws java.lang.UnsupportedOperationException + * If this is a {@link net.dv8tion.jda.api.entities.PrivateChannel PrivateChannel} + * and both the currently logged in account and the target user are bots. + * + * @return {@link MessageAction MessageAction} + *
The newly created Message after it has been sent to Discord. + * + * @see net.dv8tion.jda.api.MessageBuilder + * @see net.dv8tion.jda.api.EmbedBuilder + */ + @Nonnull + @CheckReturnValue + default MessageAction sendMessageEmbeds(@Nonnull Collection embeds) + { + Route.CompiledRoute route = Route.Messages.SEND_MESSAGE.compile(getId()); + return new MessageActionImpl(getJDA(), route, this).setEmbeds(embeds); + } + + /** * Sends a specified {@link net.dv8tion.jda.api.entities.Message Message} to this channel. *
This will fail if this channel is an instance of {@link net.dv8tion.jda.api.entities.TextChannel TextChannel} and @@ -2956,6 +3052,10 @@ default MessageAction editMessageFormatById(long messageId, @Nonnull String form */ @Nonnull @CheckReturnValue + @Deprecated + @ForRemoval(deadline = "5.0.0") + @ReplaceWith("editMessageEmbedsById(messageId, newEmbed)") + @DeprecatedSince("4.4.0") default MessageAction editMessageById(@Nonnull String messageId, @Nonnull MessageEmbed newEmbed) { Checks.isSnowflake(messageId, "Message ID"); @@ -3010,11 +3110,211 @@ default MessageAction editMessageById(@Nonnull String messageId, @Nonnull Messag */ @Nonnull @CheckReturnValue + @Deprecated + @ForRemoval(deadline = "5.0.0") + @ReplaceWith("editMessageEmbedsById(messageId, newEmbed)") + @DeprecatedSince("4.4.0") default MessageAction editMessageById(long messageId, @Nonnull MessageEmbed newEmbed) { return editMessageById(Long.toUnsignedString(messageId), newEmbed); } + /** + * Attempts to edit a message by its id in this MessageChannel. + * + *

The following {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} are possible: + *

+ * + * @param messageId + * The id referencing the Message that should be edited + * @param newEmbeds + * The new {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbeds} for the edited message + * + * @throws IllegalArgumentException + * + * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException + * If this is a TextChannel and this account does not have + * {@link net.dv8tion.jda.api.Permission#MESSAGE_READ Permission.MESSAGE_READ} + * or {@link net.dv8tion.jda.api.Permission#MESSAGE_WRITE Permission.MESSAGE_WRITE} + * + * @return {@link MessageAction MessageAction} + *
The modified Message after it has been sent to discord + */ + @Nonnull + @CheckReturnValue + default MessageAction editMessageEmbedsById(@Nonnull String messageId, @Nonnull MessageEmbed... newEmbeds) + { + Checks.noneNull(newEmbeds, "MessageEmbeds"); + return editMessageEmbedsById(messageId, Arrays.asList(newEmbeds)); + } + + /** + * Attempts to edit a message by its id in this MessageChannel. + * + *

The following {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} are possible: + *

+ * + * @param messageId + * The id referencing the Message that should be edited + * @param newEmbeds + * The new {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbeds} for the edited message + * + * @throws IllegalArgumentException + * + * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException + * If this is a TextChannel and this account does not have + * {@link net.dv8tion.jda.api.Permission#MESSAGE_READ Permission.MESSAGE_READ} + * or {@link net.dv8tion.jda.api.Permission#MESSAGE_WRITE Permission.MESSAGE_WRITE} + * + * @return {@link MessageAction MessageAction} + *
The modified Message after it has been sent to discord + */ + @Nonnull + @CheckReturnValue + default MessageAction editMessageEmbedsById(long messageId, @Nonnull MessageEmbed... newEmbeds) + { + return editMessageEmbedsById(Long.toUnsignedString(messageId), newEmbeds); + } + + /** + * Attempts to edit a message by its id in this MessageChannel. + * + *

The following {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} are possible: + *

+ * + * @param messageId + * The id referencing the Message that should be edited + * @param newEmbeds + * The new {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbeds} for the edited message + * + * @throws IllegalArgumentException + * + * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException + * If this is a TextChannel and this account does not have + * {@link net.dv8tion.jda.api.Permission#MESSAGE_READ Permission.MESSAGE_READ} + * or {@link net.dv8tion.jda.api.Permission#MESSAGE_WRITE Permission.MESSAGE_WRITE} + * + * @return {@link MessageAction MessageAction} + *
The modified Message after it has been sent to discord + */ + @Nonnull + @CheckReturnValue + default MessageAction editMessageEmbedsById(@Nonnull String messageId, @Nonnull Collection newEmbeds) + { + Checks.isSnowflake(messageId, "Message ID"); + Route.CompiledRoute route = Route.Messages.EDIT_MESSAGE.compile(getId(), messageId); + return new MessageActionImpl(getJDA(), route, this).setEmbeds(newEmbeds); + } + + /** + * Attempts to edit a message by its id in this MessageChannel. + * + *

The following {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} are possible: + *

+ * + * @param messageId + * The id referencing the Message that should be edited + * @param newEmbeds + * The new {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbeds} for the edited message + * + * @throws IllegalArgumentException + * + * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException + * If this is a TextChannel and this account does not have + * {@link net.dv8tion.jda.api.Permission#MESSAGE_READ Permission.MESSAGE_READ} + * or {@link net.dv8tion.jda.api.Permission#MESSAGE_WRITE Permission.MESSAGE_WRITE} + * + * @return {@link MessageAction MessageAction} + *
The modified Message after it has been sent to discord + */ + @Nonnull + @CheckReturnValue + default MessageAction editMessageEmbedsById(long messageId, @Nonnull Collection newEmbeds) + { + return editMessageEmbedsById(Long.toUnsignedString(messageId), newEmbeds); + } + + @Override default void formatTo(Formatter formatter, int flags, int width, int precision) { diff --git a/src/main/java/net/dv8tion/jda/api/requests/restaction/MessageAction.java b/src/main/java/net/dv8tion/jda/api/requests/restaction/MessageAction.java index 94a7c695c6..dc480cab23 100644 --- a/src/main/java/net/dv8tion/jda/api/requests/restaction/MessageAction.java +++ b/src/main/java/net/dv8tion/jda/api/requests/restaction/MessageAction.java @@ -16,6 +16,9 @@ package net.dv8tion.jda.api.requests.restaction; +import net.dv8tion.jda.annotations.DeprecatedSince; +import net.dv8tion.jda.annotations.ForRemoval; +import net.dv8tion.jda.annotations.ReplaceWith; import net.dv8tion.jda.api.MessageBuilder; import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.MessageChannel; @@ -437,11 +440,61 @@ default MessageAction reference(@Nonnull Message message) * If the provided MessageEmbed is an unknown implementation this operation will fail as we are unable to deserialize it. * * @return Updated MessageAction for chaining convenience + * + * @deprecated This is deprecated in favor of {@link #setEmbeds(MessageEmbed...)} */ @Nonnull @CheckReturnValue + @Deprecated + @ForRemoval(deadline="5.0.0") + @ReplaceWith("setEmbeds(embed)") + @DeprecatedSince("4.4.0") MessageAction embed(@Nullable final MessageEmbed embed); + /** + * Sets the {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbeds} + * that should be used for this Message. + * Refer to {@link net.dv8tion.jda.api.EmbedBuilder EmbedBuilder} for more information. + * + * @param embeds + * The {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbeds} that should + * be attached to this message, {@code Collections.emptyList()} to use no embed. + * + * @throws java.lang.IllegalArgumentException + * If any of the provided MessageEmbeds is not sendable according to + * {@link net.dv8tion.jda.api.entities.MessageEmbed#isSendable() MessageEmbed.isSendable()}! + * If the provided MessageEmbed is an unknown implementation this operation will fail as we are unable to deserialize it. + * + * @return Updated MessageAction for chaining convenience + */ + @Nonnull + @CheckReturnValue + MessageAction setEmbeds(@Nonnull Collection embeds); + + /** + * Sets the {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbeds} + * that should be used for this Message. + * Refer to {@link net.dv8tion.jda.api.EmbedBuilder EmbedBuilder} for more information. + * + * @param embeds + * The {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbeds} that should + * be attached to this message, {@code Collections.emptyList()} to use no embed. + * + * @throws java.lang.IllegalArgumentException + * If any of the provided MessageEmbeds is not sendable according to + * {@link net.dv8tion.jda.api.entities.MessageEmbed#isSendable() MessageEmbed.isSendable()}! + * If the provided MessageEmbed is an unknown implementation this operation will fail as we are unable to deserialize it. + * + * @return Updated MessageAction for chaining convenience + */ + @Nonnull + @CheckReturnValue + default MessageAction setEmbeds(@Nonnull MessageEmbed... embeds) + { + Checks.noneNull(embeds, "MessageEmbeds"); + return setEmbeds(Arrays.asList(embeds)); + } + /** * {@inheritDoc} * @throws java.lang.IllegalArgumentException diff --git a/src/main/java/net/dv8tion/jda/internal/entities/TextChannelImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/TextChannelImpl.java index d52ca87edb..e45f783955 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/TextChannelImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/TextChannelImpl.java @@ -585,6 +585,7 @@ public MessageAction editMessageById(@Nonnull String messageId, @Nonnull CharSeq @Nonnull @Override + @Deprecated public MessageAction editMessageById(@Nonnull String messageId, @Nonnull MessageEmbed newEmbed) { checkPermission(Permission.MESSAGE_READ); @@ -593,6 +594,16 @@ public MessageAction editMessageById(@Nonnull String messageId, @Nonnull Message return TextChannel.super.editMessageById(messageId, newEmbed); } + @Nonnull + @Override + public MessageAction editMessageEmbedsById(@Nonnull String messageId, @Nonnull Collection newEmbeds) + { + checkPermission(Permission.MESSAGE_READ); + checkPermission(Permission.MESSAGE_WRITE); + checkPermission(Permission.MESSAGE_EMBED_LINKS); + return TextChannel.super.editMessageEmbedsById(messageId, newEmbeds); + } + @Nonnull @Override public MessageAction editMessageById(@Nonnull String id, @Nonnull Message newContent) diff --git a/src/main/java/net/dv8tion/jda/internal/requests/restaction/MessageActionImpl.java b/src/main/java/net/dv8tion/jda/internal/requests/restaction/MessageActionImpl.java index b7b93d474e..f7c71b99e8 100644 --- a/src/main/java/net/dv8tion/jda/internal/requests/restaction/MessageActionImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/requests/restaction/MessageActionImpl.java @@ -61,7 +61,7 @@ public class MessageActionImpl extends RestActionImpl implements Messag protected final AllowedMentionsImpl allowedMentions = new AllowedMentionsImpl(); protected List components; protected List retainedAttachments; - protected MessageEmbed embed = null; + protected List embeds = null; protected String nonce = null; protected boolean tts = false, override = false; protected boolean failOnInvalidReply = defaultFailOnInvalidReply; @@ -125,7 +125,7 @@ public MessageChannel getChannel() public boolean isEmpty() { return Helpers.isBlank(content) - && (embed == null || embed.isEmpty() || !hasPermission(Permission.MESSAGE_EMBED_LINKS)); + && (embeds == null || embeds.isEmpty() || !hasPermission(Permission.MESSAGE_EMBED_LINKS)); } @Override @@ -220,8 +220,31 @@ public MessageActionImpl embed(final MessageEmbed embed) Checks.check(embed.isSendable(), "Provided Message contains an empty embed or an embed with a length greater than %d characters, which is the max for bot accounts!", MessageEmbed.EMBED_MAX_LENGTH_BOT); + if (this.embeds == null) + this.embeds = new ArrayList<>(); + this.embeds.add(embed); } - this.embed = embed; + else + { + this.embeds = null; + } + return this; + } + + @Nonnull + @Override + public MessageAction setEmbeds(@Nonnull Collection embeds) + { + Checks.noneNull(embeds, "MessageEmbeds"); + embeds.forEach(embed -> + Checks.check(embed.isSendable(), + "Provided Message contains an empty embed or an embed with a length greater than %d characters, which is the max for bot accounts!", + MessageEmbed.EMBED_MAX_LENGTH_BOT) + ); + if (this.embeds == null) + this.embeds = new ArrayList<>(); + this.embeds.clear(); + this.embeds.addAll(embeds); return this; } @@ -467,10 +490,10 @@ protected DataObject getJSON() final DataObject obj = DataObject.empty(); if (override) { - if (embed == null) - obj.putNull("embed"); + if (embeds == null) + obj.putNull("embeds"); else - obj.put("embed", embed); + obj.put("embeds", DataArray.fromCollection(embeds)); if (content.length() == 0) obj.putNull("content"); else @@ -493,8 +516,8 @@ protected DataObject getJSON() } else { - if (embed != null) - obj.put("embed", embed); + if (embeds != null) + obj.put("embeds", DataArray.fromCollection(embeds)); if (content.length() > 0) obj.put("content", content.toString()); if (nonce != null) From 919b1298b9f4902485c58c45c1d8471dafb23194 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Tue, 8 Jun 2021 20:14:26 +0200 Subject: [PATCH 02/10] Add check for embed count --- .../java/net/dv8tion/jda/api/entities/MessageChannel.java | 8 ++++---- .../jda/api/requests/restaction/MessageAction.java | 4 ++-- .../internal/requests/restaction/MessageActionImpl.java | 1 + 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/api/entities/MessageChannel.java b/src/main/java/net/dv8tion/jda/api/entities/MessageChannel.java index 9ba520aaa7..50ae69af86 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/MessageChannel.java +++ b/src/main/java/net/dv8tion/jda/api/entities/MessageChannel.java @@ -3144,7 +3144,7 @@ default MessageAction editMessageById(long messageId, @Nonnull MessageEmbed newE * @param messageId * The id referencing the Message that should be edited * @param newEmbeds - * The new {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbeds} for the edited message + * Up to 10 new {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbeds} for the edited message * * @throws IllegalArgumentException *
    @@ -3193,7 +3193,7 @@ default MessageAction editMessageEmbedsById(@Nonnull String messageId, @Nonnull * @param messageId * The id referencing the Message that should be edited * @param newEmbeds - * The new {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbeds} for the edited message + * Up to 10 new {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbeds} for the edited message * * @throws IllegalArgumentException *
      @@ -3241,7 +3241,7 @@ default MessageAction editMessageEmbedsById(long messageId, @Nonnull MessageEmbe * @param messageId * The id referencing the Message that should be edited * @param newEmbeds - * The new {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbeds} for the edited message + * Up to 10 new {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbeds} for the edited message * * @throws IllegalArgumentException *
        @@ -3291,7 +3291,7 @@ default MessageAction editMessageEmbedsById(@Nonnull String messageId, @Nonnull * @param messageId * The id referencing the Message that should be edited * @param newEmbeds - * The new {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbeds} for the edited message + * Up to 10 new {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbeds} for the edited message * * @throws IllegalArgumentException *
          diff --git a/src/main/java/net/dv8tion/jda/api/requests/restaction/MessageAction.java b/src/main/java/net/dv8tion/jda/api/requests/restaction/MessageAction.java index dc480cab23..a8bfce9499 100644 --- a/src/main/java/net/dv8tion/jda/api/requests/restaction/MessageAction.java +++ b/src/main/java/net/dv8tion/jda/api/requests/restaction/MessageAction.java @@ -452,7 +452,7 @@ default MessageAction reference(@Nonnull Message message) MessageAction embed(@Nullable final MessageEmbed embed); /** - * Sets the {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbeds} + * Sets up to 10 {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbeds} * that should be used for this Message. * Refer to {@link net.dv8tion.jda.api.EmbedBuilder EmbedBuilder} for more information. * @@ -472,7 +472,7 @@ default MessageAction reference(@Nonnull Message message) MessageAction setEmbeds(@Nonnull Collection embeds); /** - * Sets the {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbeds} + * Sets up to 10 {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbeds} * that should be used for this Message. * Refer to {@link net.dv8tion.jda.api.EmbedBuilder EmbedBuilder} for more information. * diff --git a/src/main/java/net/dv8tion/jda/internal/requests/restaction/MessageActionImpl.java b/src/main/java/net/dv8tion/jda/internal/requests/restaction/MessageActionImpl.java index f7c71b99e8..31e87a581b 100644 --- a/src/main/java/net/dv8tion/jda/internal/requests/restaction/MessageActionImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/requests/restaction/MessageActionImpl.java @@ -241,6 +241,7 @@ public MessageAction setEmbeds(@Nonnull Collection embed "Provided Message contains an empty embed or an embed with a length greater than %d characters, which is the max for bot accounts!", MessageEmbed.EMBED_MAX_LENGTH_BOT) ); + Checks.check(embeds.size() <= 10, "Cannot have more than 10 embeds in a message!"); if (this.embeds == null) this.embeds = new ArrayList<>(); this.embeds.clear(); From 985f06a6d1f5a2cb0b66d216a1481913766a7d17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Wed, 9 Jun 2021 17:33:57 +0200 Subject: [PATCH 03/10] Improve length checks for embeds --- .../net/dv8tion/jda/api/entities/MessageEmbed.java | 10 +++++----- .../requests/restaction/MessageActionImpl.java | 1 + .../requests/restaction/WebhookMessageActionImpl.java | 9 ++++++++- .../restaction/WebhookMessageUpdateActionImpl.java | 8 +++++++- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/api/entities/MessageEmbed.java b/src/main/java/net/dv8tion/jda/api/entities/MessageEmbed.java index c7508d5ad8..3381fa2125 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/MessageEmbed.java +++ b/src/main/java/net/dv8tion/jda/api/entities/MessageEmbed.java @@ -356,17 +356,17 @@ public int getLength() length = 0; if (title != null) - length += title.length(); + length += Helpers.codePointLength(title); if (description != null) - length += description.length(); + length += Helpers.codePointLength(description); if (author != null) - length += author.getName().length(); + length += Helpers.codePointLength(author.getName()); if (footer != null) - length += footer.getText().length(); + length += Helpers.codePointLength(footer.getText()); if (fields != null) { for (Field f : fields) - length += f.getName().length() + f.getValue().length(); + length += Helpers.codePointLength(f.getName()) + Helpers.codePointLength(f.getValue()); } return length; diff --git a/src/main/java/net/dv8tion/jda/internal/requests/restaction/MessageActionImpl.java b/src/main/java/net/dv8tion/jda/internal/requests/restaction/MessageActionImpl.java index 31e87a581b..8078f6d8f7 100644 --- a/src/main/java/net/dv8tion/jda/internal/requests/restaction/MessageActionImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/requests/restaction/MessageActionImpl.java @@ -242,6 +242,7 @@ public MessageAction setEmbeds(@Nonnull Collection embed MessageEmbed.EMBED_MAX_LENGTH_BOT) ); Checks.check(embeds.size() <= 10, "Cannot have more than 10 embeds in a message!"); + Checks.check(embeds.stream().mapToInt(MessageEmbed::getLength).sum() <= MessageEmbed.EMBED_MAX_LENGTH_BOT, "The sum of all MessageEmbeds may not exceed %d!", MessageEmbed.EMBED_MAX_LENGTH_BOT); if (this.embeds == null) this.embeds = new ArrayList<>(); this.embeds.clear(); diff --git a/src/main/java/net/dv8tion/jda/internal/requests/restaction/WebhookMessageActionImpl.java b/src/main/java/net/dv8tion/jda/internal/requests/restaction/WebhookMessageActionImpl.java index 2e86ba3664..e14863edfc 100644 --- a/src/main/java/net/dv8tion/jda/internal/requests/restaction/WebhookMessageActionImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/requests/restaction/WebhookMessageActionImpl.java @@ -41,6 +41,7 @@ import java.io.InputStream; import java.util.*; import java.util.function.Function; +import java.util.stream.Stream; public class WebhookMessageActionImpl extends TriggerRestAction @@ -128,8 +129,14 @@ public WebhookMessageActionImpl setTTS(boolean tts) @Override public WebhookMessageActionImpl addEmbeds(@Nonnull Collection embeds) { - Checks.noneNull(embeds, "Message Embeds"); + Checks.noneNull(embeds, "MessageEmbeds"); + embeds.forEach(embed -> + Checks.check(embed.isSendable(), + "Provided Message contains an empty embed or an embed with a length greater than %d characters, which is the max for bot accounts!", + MessageEmbed.EMBED_MAX_LENGTH_BOT) + ); Checks.check(this.embeds.size() + embeds.size() <= 10, "Cannot have more than 10 embeds in a message!"); + Checks.check(Stream.concat(embeds.stream(), this.embeds.stream()).mapToInt(MessageEmbed::getLength).sum() <= MessageEmbed.EMBED_MAX_LENGTH_BOT, "The sum of all MessageEmbeds may not exceed %d!", MessageEmbed.EMBED_MAX_LENGTH_BOT); this.embeds.addAll(embeds); return this; } diff --git a/src/main/java/net/dv8tion/jda/internal/requests/restaction/WebhookMessageUpdateActionImpl.java b/src/main/java/net/dv8tion/jda/internal/requests/restaction/WebhookMessageUpdateActionImpl.java index 1e9d592d57..c6eb8d193a 100644 --- a/src/main/java/net/dv8tion/jda/internal/requests/restaction/WebhookMessageUpdateActionImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/requests/restaction/WebhookMessageUpdateActionImpl.java @@ -80,7 +80,13 @@ public WebhookMessageUpdateAction setContent(@Nullable String content) public WebhookMessageUpdateAction setEmbeds(@Nonnull Collection embeds) { Checks.noneNull(embeds, "MessageEmbeds"); - Checks.check(embeds.size() <= 10, "Cannot have more than 10 embeds in one message!"); + embeds.forEach(embed -> + Checks.check(embed.isSendable(), + "Provided Message contains an empty embed or an embed with a length greater than %d characters, which is the max for bot accounts!", + MessageEmbed.EMBED_MAX_LENGTH_BOT) + ); + Checks.check(embeds.size() <= 10, "Cannot have more than 10 embeds in a message!"); + Checks.check(embeds.stream().mapToInt(MessageEmbed::getLength).sum() <= MessageEmbed.EMBED_MAX_LENGTH_BOT, "The sum of all MessageEmbeds may not exceed %d!", MessageEmbed.EMBED_MAX_LENGTH_BOT); this.embeds.clear(); this.embeds.addAll(embeds); set |= EMBEDS; From 6e811b5a62c8cfa552d942973f6b72a357b13af2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Thu, 10 Jun 2021 10:14:28 +0200 Subject: [PATCH 04/10] Update documentation --- .../net/dv8tion/jda/api/EmbedBuilder.java | 10 +- .../net/dv8tion/jda/api/MessageBuilder.java | 2 +- .../net/dv8tion/jda/api/entities/Message.java | 94 ++++++++++++++++++- .../jda/api/entities/MessageChannel.java | 12 +-- .../requests/restaction/MessageAction.java | 8 +- .../internal/entities/ReceivedMessage.java | 4 +- .../restaction/MessageActionImpl.java | 9 +- 7 files changed, 115 insertions(+), 24 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/api/EmbedBuilder.java b/src/main/java/net/dv8tion/jda/api/EmbedBuilder.java index 28dea90c92..074ecf4345 100644 --- a/src/main/java/net/dv8tion/jda/api/EmbedBuilder.java +++ b/src/main/java/net/dv8tion/jda/api/EmbedBuilder.java @@ -59,7 +59,7 @@ public class EmbedBuilder /** * Constructs a new EmbedBuilder instance, which can be used to create {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbeds}. - * These can then be sent to a channel using {@link net.dv8tion.jda.api.entities.MessageChannel#sendMessage(MessageEmbed)}. + * These can then be sent to a channel using {@link net.dv8tion.jda.api.entities.MessageChannel#sendMessageEmbeds(MessageEmbed...)}. *
          Every part of an embed can be removed or cleared by providing {@code null} to the setter method. */ public EmbedBuilder() { } @@ -480,7 +480,7 @@ public EmbedBuilder setColor(int color) * InputStream file = new URL("https://http.cat/500").openStream(); * embed.setThumbnail("attachment://cat.png") // we specify this in sendFile as "cat.png" * .setDescription("This is a cute cat :3"); - * channel.sendFile(file, "cat.png").embed(embed.build()).queue(); + * channel.sendFile(file, "cat.png").setEmbeds(embed.build()).queue(); * * * @param url @@ -526,7 +526,7 @@ public EmbedBuilder setThumbnail(@Nullable String url) * InputStream file = new URL("https://http.cat/500").openStream(); * embed.setImage("attachment://cat.png") // we specify this in sendFile as "cat.png" * .setDescription("This is a cute cat :3"); - * channel.sendFile(file, "cat.png").embed(embed.build()).queue(); + * channel.sendFile(file, "cat.png").setEmbeds(embed.build()).queue(); * * * @param url @@ -623,7 +623,7 @@ public EmbedBuilder setAuthor(@Nullable String name, @Nullable String url) * InputStream file = new URL("https://http.cat/500").openStream(); * embed.setAuthor("Minn", null, "attachment://cat.png") // we specify this in sendFile as "cat.png" * .setDescription("This is a cute cat :3"); - * channel.sendFile(file, "cat.png").embed(embed.build()).queue(); + * channel.sendFile(file, "cat.png").setEmbeds(embed.build()).queue(); * * * @param name @@ -699,7 +699,7 @@ public EmbedBuilder setFooter(@Nullable String text) * InputStream file = new URL("https://http.cat/500").openStream(); * embed.setFooter("Cool footer!", "attachment://cat.png") // we specify this in sendFile as "cat.png" * .setDescription("This is a cute cat :3"); - * channel.sendFile(file, "cat.png").embed(embed.build()).queue(); + * channel.sendFile(file, "cat.png").setEmbeds(embed.build()).queue(); * * * @param text diff --git a/src/main/java/net/dv8tion/jda/api/MessageBuilder.java b/src/main/java/net/dv8tion/jda/api/MessageBuilder.java index 17dd60211f..d5aa346227 100644 --- a/src/main/java/net/dv8tion/jda/api/MessageBuilder.java +++ b/src/main/java/net/dv8tion/jda/api/MessageBuilder.java @@ -1212,7 +1212,7 @@ public MessageAction sendTo(@Nonnull MessageChannel channel) } final Route.CompiledRoute route = Route.Messages.SEND_MESSAGE.compile(channel.getId()); final MessageActionImpl action = new MessageActionImpl(channel.getJDA(), route, channel, builder); - return action.tts(isTTS).embed(embed).nonce(nonce); + return action.tts(isTTS).setEmbeds(embed).nonce(nonce); } /** diff --git a/src/main/java/net/dv8tion/jda/api/entities/Message.java b/src/main/java/net/dv8tion/jda/api/entities/Message.java index ad7c54ca4f..807df829c4 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/Message.java +++ b/src/main/java/net/dv8tion/jda/api/entities/Message.java @@ -15,6 +15,9 @@ */ package net.dv8tion.jda.api.entities; +import net.dv8tion.jda.annotations.DeprecatedSince; +import net.dv8tion.jda.annotations.ForRemoval; +import net.dv8tion.jda.annotations.ReplaceWith; import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.exceptions.HttpException; @@ -1002,10 +1005,97 @@ default List
        * @throws java.lang.IllegalArgumentException - * If any of the provided embeds is {@code null} or if the provided {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbed} - * is not {@link net.dv8tion.jda.api.entities.MessageEmbed#isSendable() sendable} + * If null is provided, any of the embeds are not {@link MessageEmbed#isSendable() sendable}, more than 10 embeds are provided, + * or the sum of {@link MessageEmbed#getLength()} is greater than {@link MessageEmbed#EMBED_MAX_LENGTH_BOT} * @throws java.lang.UnsupportedOperationException * If this is a {@link net.dv8tion.jda.api.entities.PrivateChannel PrivateChannel} * and both the currently logged in account and the target user are bots. @@ -455,8 +457,13 @@ default MessageAction sendMessage(@Nonnull MessageEmbed embed) */ @Nonnull @CheckReturnValue - default MessageAction sendMessageEmbeds(@Nonnull MessageEmbed... embeds) + default MessageAction sendMessageEmbeds(@Nonnull MessageEmbed embed, @Nonnull MessageEmbed... other) { + Checks.notNull(embed, "MessageEmbeds"); + Checks.noneNull(other, "MessageEmbeds"); + List embeds = new ArrayList<>(1 + other.length); + embeds.add(embed); + Collections.addAll(embeds, other); return new MessageActionImpl(getJDA(), null, this).setEmbeds(embeds); } @@ -472,7 +479,7 @@ default MessageAction sendMessageEmbeds(@Nonnull MessageEmbed... embeds) *

        For {@link net.dv8tion.jda.api.requests.ErrorResponse} information, refer to {@link #sendMessage(Message)}. * * @param embeds - * the {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbeds} to send + * The {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbeds} to send * * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException * If this is a {@link net.dv8tion.jda.api.entities.TextChannel TextChannel} and the logged in account does From 97bd6cfb379287dfbd814a0c53cafa2f72a0d8b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Tue, 15 Jun 2021 12:49:51 +0200 Subject: [PATCH 10/10] Fix javadoc errors --- src/main/java/net/dv8tion/jda/api/EmbedBuilder.java | 2 +- src/main/java/net/dv8tion/jda/api/entities/Message.java | 8 ++++---- .../java/net/dv8tion/jda/api/entities/MessageChannel.java | 2 +- .../jda/api/requests/restaction/MessageAction.java | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/api/EmbedBuilder.java b/src/main/java/net/dv8tion/jda/api/EmbedBuilder.java index 4f69a21bab..50aabe5ce5 100644 --- a/src/main/java/net/dv8tion/jda/api/EmbedBuilder.java +++ b/src/main/java/net/dv8tion/jda/api/EmbedBuilder.java @@ -57,7 +57,7 @@ public class EmbedBuilder /** * Constructs a new EmbedBuilder instance, which can be used to create {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbeds}. - * These can then be sent to a channel using {@link net.dv8tion.jda.api.entities.MessageChannel#sendMessageEmbeds(MessageEmbed...)}. + * These can then be sent to a channel using {@link net.dv8tion.jda.api.entities.MessageChannel#sendMessageEmbeds(MessageEmbed, MessageEmbed...)}. *
        Every part of an embed can be removed or cleared by providing {@code null} to the setter method. */ public EmbedBuilder() { } diff --git a/src/main/java/net/dv8tion/jda/api/entities/Message.java b/src/main/java/net/dv8tion/jda/api/entities/Message.java index fa188c9589..bec743fb14 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/Message.java +++ b/src/main/java/net/dv8tion/jda/api/entities/Message.java @@ -1215,7 +1215,7 @@ default MessageAction reply(@Nonnull CharSequence content) *
        By default there won't be any error thrown if the referenced message does not exist. * This behavior can be changed with {@link MessageAction#failOnInvalidReply(boolean)}. * - *

        For further info, see {@link MessageChannel#sendMessageEmbeds(MessageEmbed...)} and {@link MessageAction#reference(Message)}. + *

        For further info, see {@link MessageChannel#sendMessageEmbeds(MessageEmbed, MessageEmbed...)} and {@link MessageAction#reference(Message)}. * * @param content * The content of the reply message @@ -1224,7 +1224,7 @@ default MessageAction reply(@Nonnull CharSequence content) * * @since 4.2.1 * - * @deprecated Use {@link #replyEmbeds(MessageEmbed...)} instead + * @deprecated Use {@link #replyEmbeds(MessageEmbed, MessageEmbed...)} instead */ @Nonnull @CheckReturnValue @@ -1244,7 +1244,7 @@ default MessageAction reply(@Nonnull MessageEmbed content) *
        By default there won't be any error thrown if the referenced message does not exist. * This behavior can be changed with {@link MessageAction#failOnInvalidReply(boolean)}. * - *

        For further info, see {@link MessageChannel#sendMessageEmbeds(MessageEmbed...)} and {@link MessageAction#reference(Message)}. + *

        For further info, see {@link MessageChannel#sendMessageEmbeds(MessageEmbed, MessageEmbed...)} and {@link MessageAction#reference(Message)}. * * @param embed * The embed to reply with @@ -1276,7 +1276,7 @@ default MessageAction replyEmbeds(@Nonnull MessageEmbed embed, @Nonnull MessageE *
        By default there won't be any error thrown if the referenced message does not exist. * This behavior can be changed with {@link MessageAction#failOnInvalidReply(boolean)}. * - *

        For further info, see {@link MessageChannel#sendMessageEmbeds(MessageEmbed...)} and {@link MessageAction#reference(Message)}. + *

        For further info, see {@link MessageChannel#sendMessageEmbeds(MessageEmbed, MessageEmbed...)} and {@link MessageAction#reference(Message)}. * * @param embeds * The embeds to reply with diff --git a/src/main/java/net/dv8tion/jda/api/entities/MessageChannel.java b/src/main/java/net/dv8tion/jda/api/entities/MessageChannel.java index 9688c6a626..40c26775b1 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/MessageChannel.java +++ b/src/main/java/net/dv8tion/jda/api/entities/MessageChannel.java @@ -403,7 +403,7 @@ default MessageAction sendMessageFormat(@Nonnull String format, @Nonnull Object. * @see net.dv8tion.jda.api.MessageBuilder * @see net.dv8tion.jda.api.EmbedBuilder * - * @deprecated This is deprecated in favor of {@link #sendMessageEmbeds(MessageEmbed...)} + * @deprecated This is deprecated in favor of {@link #sendMessageEmbeds(MessageEmbed, MessageEmbed...)} */ @Nonnull @CheckReturnValue diff --git a/src/main/java/net/dv8tion/jda/api/requests/restaction/MessageAction.java b/src/main/java/net/dv8tion/jda/api/requests/restaction/MessageAction.java index bba27d248b..72b91f1626 100644 --- a/src/main/java/net/dv8tion/jda/api/requests/restaction/MessageAction.java +++ b/src/main/java/net/dv8tion/jda/api/requests/restaction/MessageAction.java @@ -86,7 +86,7 @@ * @see Message#editMessageFormat(String, Object...) * @see net.dv8tion.jda.api.entities.MessageChannel#sendMessage(Message) * @see net.dv8tion.jda.api.entities.MessageChannel#sendMessage(CharSequence) - * @see net.dv8tion.jda.api.entities.MessageChannel#sendMessageEmbeds(MessageEmbed...) + * @see net.dv8tion.jda.api.entities.MessageChannel#sendMessageEmbeds(MessageEmbed, MessageEmbed...) * @see net.dv8tion.jda.api.entities.MessageChannel#sendMessageFormat(String, Object...) * @see net.dv8tion.jda.api.entities.MessageChannel#sendFile(File, AttachmentOption...) * @see net.dv8tion.jda.api.entities.MessageChannel#sendFile(File, String, AttachmentOption...)