Skip to content

Commit

Permalink
Support embed deserialization from JSON data (#2471)
Browse files Browse the repository at this point in the history
  • Loading branch information
MinnDevelopment committed Jun 8, 2023
1 parent c56cde1 commit 9cc7988
Show file tree
Hide file tree
Showing 2 changed files with 150 additions and 4 deletions.
74 changes: 70 additions & 4 deletions src/main/java/net/dv8tion/jda/api/EmbedBuilder.java
Expand Up @@ -18,6 +18,8 @@
import net.dv8tion.jda.api.entities.EmbedType;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.utils.data.DataArray;
import net.dv8tion.jda.api.utils.data.DataObject;
import net.dv8tion.jda.internal.entities.EntityBuilder;
import net.dv8tion.jda.internal.utils.Checks;
import net.dv8tion.jda.internal.utils.Helpers;
Expand All @@ -27,6 +29,7 @@
import java.awt.*;
import java.time.OffsetDateTime;
import java.time.temporal.TemporalAccessor;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;
Expand All @@ -45,7 +48,7 @@ public class EmbedBuilder
public final static String ZERO_WIDTH_SPACE = "\u200E";
public final static Pattern URL_PATTERN = Pattern.compile("\\s*(https?|attachment)://\\S+\\s*", Pattern.CASE_INSENSITIVE);

private final List<MessageEmbed.Field> fields = new LinkedList<>();
private final List<MessageEmbed.Field> fields = new ArrayList<>();
private final StringBuilder description = new StringBuilder();
private int color = Role.DEFAULT_COLOR_RAW;
private String url, title;
Expand Down Expand Up @@ -84,6 +87,69 @@ public EmbedBuilder(@Nullable MessageEmbed embed)
copyFrom(embed);
}

/**
* Creates an instance of this builder from the provided {@link DataObject}.
*
* <p>This is the inverse of {@link MessageEmbed#toData()}.
*
* @param data
* The serialized embed object
*
* @throws IllegalArgumentException
* If the provided data is {@code null} or invalid
* @throws net.dv8tion.jda.api.exceptions.ParsingException
* If the provided data is malformed
*
* @return The new builder instance
*/
@Nonnull
public static EmbedBuilder fromData(@Nonnull DataObject data)
{
Checks.notNull(data, "DataObject");
EmbedBuilder builder = new EmbedBuilder();

builder.setTitle(data.getString("title", null));
builder.setUrl(data.getString("url", null));
builder.setDescription(data.getString("description", ""));
builder.setTimestamp(data.isNull("timestamp") ? null : OffsetDateTime.parse(data.getString("timestamp")));
builder.setColor(data.getInt("color", Role.DEFAULT_COLOR_RAW));

data.optObject("thumbnail").ifPresent(thumbnail ->
builder.setThumbnail(thumbnail.getString("url"))
);

data.optObject("author").ifPresent(author ->
builder.setAuthor(
author.getString("name", ""),
author.getString("url", null),
author.getString("icon_url", null)
)
);

data.optObject("footer").ifPresent(footer ->
builder.setFooter(
footer.getString("text", ""),
footer.getString("icon_url", null)
)
);

data.optObject("image").ifPresent(image ->
builder.setImage(image.getString("url"))
);

data.optArray("fields").ifPresent(arr ->
arr.stream(DataArray::getObject).forEach(field ->
builder.addField(
field.getString("name", ZERO_WIDTH_SPACE),
field.getString("value", ZERO_WIDTH_SPACE),
field.getBoolean("inline", false)
)
)
);

return builder;
}

/**
* Returns a {@link net.dv8tion.jda.api.entities.MessageEmbed MessageEmbed}
* that has been checked as being valid for sending.
Expand Down Expand Up @@ -654,7 +720,7 @@ public EmbedBuilder setAuthor(@Nullable String name, @Nullable String url, @Null
}
else
{
Checks.check(name.length() <= MessageEmbed.AUTHOR_MAX_LENGTH, "Name cannot be longer than %d characters.", MessageEmbed.AUTHOR_MAX_LENGTH);
Checks.notLonger(name, MessageEmbed.AUTHOR_MAX_LENGTH, "Name");
urlCheck(url);
urlCheck(iconUrl);
this.author = new MessageEmbed.AuthorInfo(name, url, iconUrl, null);
Expand Down Expand Up @@ -729,7 +795,7 @@ public EmbedBuilder setFooter(@Nullable String text, @Nullable String iconUrl)
}
else
{
Checks.check(text.length() <= MessageEmbed.TEXT_MAX_LENGTH, "Text cannot be longer than %d characters.", MessageEmbed.TEXT_MAX_LENGTH);
Checks.notLonger(text, MessageEmbed.TEXT_MAX_LENGTH, "Text");
urlCheck(iconUrl);
this.footer = new MessageEmbed.Footer(text, iconUrl, null);
}
Expand Down Expand Up @@ -838,7 +904,7 @@ private void urlCheck(@Nullable String url)
{
if (url != null)
{
Checks.check(url.length() <= MessageEmbed.URL_MAX_LENGTH, "URL cannot be longer than %d characters.", MessageEmbed.URL_MAX_LENGTH);
Checks.notLonger(url, MessageEmbed.URL_MAX_LENGTH, "URL");
Checks.check(URL_PATTERN.matcher(url).matches(), "URL must be a valid http(s) or attachment url.");
}
}
Expand Down
@@ -0,0 +1,80 @@
/*
* Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package net.dv8tion.jda.entities;

import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.EmbedType;
import net.dv8tion.jda.api.entities.MessageEmbed;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class MessageSerializationTest
{
@Test
void testEmbedSerialization()
{
EmbedBuilder builder = new EmbedBuilder();
builder.setDescription("Description Text");
builder.setTitle("Title Text", "https://example.com/title");
builder.setAuthor("Author Text", "https://example.com/author", "https://example.com/author_icon");
builder.setFooter("Footer Text", "https://example.com/footer_icon");
builder.setImage("https://example.com/image");
builder.setThumbnail("https://example.com/thumbnail");
builder.addField("Field 1", "Field 1 Text", true);
builder.addField("Field 2", "Field 2 Text", false);
builder.addField("Field 3", "Field 3 Text", true);

MessageEmbed embed = builder.build();

MessageEmbed dataEmbed = EmbedBuilder.fromData(embed.toData()).build();

Assertions.assertEquals(embed.getType(), dataEmbed.getType());
Assertions.assertEquals(EmbedType.RICH, embed.getType());

Assertions.assertEquals(embed.getDescription(), dataEmbed.getDescription());
Assertions.assertEquals(embed.getTitle(), dataEmbed.getTitle());
Assertions.assertEquals(embed.getUrl(), dataEmbed.getUrl());
Assertions.assertEquals(embed.getAuthor(), dataEmbed.getAuthor());
Assertions.assertEquals(embed.getFooter(), dataEmbed.getFooter());
Assertions.assertEquals(embed.getImage(), dataEmbed.getImage());
Assertions.assertEquals(embed.getThumbnail(), dataEmbed.getThumbnail());
Assertions.assertEquals(embed.getFields(), dataEmbed.getFields());

Assertions.assertEquals(embed, dataEmbed);

Assertions.assertEquals("Description Text", dataEmbed.getDescription());
Assertions.assertEquals("Title Text", dataEmbed.getTitle());
Assertions.assertEquals("https://example.com/title", dataEmbed.getUrl());
Assertions.assertEquals("Author Text", dataEmbed.getAuthor().getName());
Assertions.assertEquals("https://example.com/author", dataEmbed.getAuthor().getUrl());
Assertions.assertEquals("https://example.com/author_icon", dataEmbed.getAuthor().getIconUrl());
Assertions.assertEquals("Footer Text", dataEmbed.getFooter().getText());
Assertions.assertEquals("https://example.com/footer_icon", dataEmbed.getFooter().getIconUrl());
Assertions.assertEquals("https://example.com/image", dataEmbed.getImage().getUrl());
Assertions.assertEquals("https://example.com/thumbnail", dataEmbed.getThumbnail().getUrl());
Assertions.assertEquals(3, dataEmbed.getFields().size());
Assertions.assertEquals("Field 1", dataEmbed.getFields().get(0).getName());
Assertions.assertEquals("Field 1 Text", dataEmbed.getFields().get(0).getValue());
Assertions.assertTrue(dataEmbed.getFields().get(0).isInline());
Assertions.assertEquals("Field 2", dataEmbed.getFields().get(1).getName());
Assertions.assertEquals("Field 2 Text", dataEmbed.getFields().get(1).getValue());
Assertions.assertFalse(dataEmbed.getFields().get(1).isInline());
Assertions.assertEquals("Field 3", dataEmbed.getFields().get(2).getName());
Assertions.assertEquals("Field 3 Text", dataEmbed.getFields().get(2).getValue());
Assertions.assertTrue(dataEmbed.getFields().get(2).isInline());
}
}

0 comments on commit 9cc7988

Please sign in to comment.