Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement access and retrieval of message_reference #1686

Merged
merged 19 commits into from
Jul 30, 2021
27 changes: 20 additions & 7 deletions src/main/java/net/dv8tion/jda/api/entities/Message.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import net.dv8tion.jda.api.requests.restaction.pagination.ReactionPaginationAction;
import net.dv8tion.jda.api.utils.AttachmentOption;
import net.dv8tion.jda.internal.JDAImpl;
import net.dv8tion.jda.internal.entities.MessageReference;
import net.dv8tion.jda.internal.requests.FunctionalCallback;
import net.dv8tion.jda.internal.requests.Requester;
import net.dv8tion.jda.internal.utils.Checks;
Expand Down Expand Up @@ -214,17 +215,29 @@ public interface Message extends ISnowflake, Formattable
"(?:\\?\\S*)?(?:#\\S*)?", // Useless query or URN appendix
Pattern.CASE_INSENSITIVE);

@Nullable
MessageReference getMessageReference();

/**
* Referenced message.
* This returns the id of the referenced message, never null
arynxd marked this conversation as resolved.
Show resolved Hide resolved
*
* <p>This will have different meaning depending on the {@link #getType() type} of message.
* Usually, this is a {@link MessageType#INLINE_REPLY INLINE_REPLY} reference.
* This can be null even if the type is {@link MessageType#INLINE_REPLY INLINE_REPLY}, when the message it references doesn't exist or discord wasn't able to resolve it in time.
* @throws java.lang.IllegalStateException
* If this message does not have a reference
*
* @return The referenced message, or null
* @return The referenced message id
*/
@Nullable
Message getReferencedMessage();
arynxd marked this conversation as resolved.
Show resolved Hide resolved
long getReferencedMessageIdLong();
arynxd marked this conversation as resolved.
Show resolved Hide resolved

/**
* This returns the id of the referenced message, never null
*
* @throws java.lang.IllegalStateException
* If this message does not have a reference
*
* @return The referenced message id
*/
@Nonnull
String getReferencedMessageId();

/**
* An immutable list of all mentioned {@link net.dv8tion.jda.api.entities.User Users}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
import java.time.OffsetDateTime;
import java.util.*;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use javax.annotations


public abstract class AbstractMessage implements Message
{
protected static final String UNSUPPORTED = "This operation is not supported for Messages of this type!";
Expand Down Expand Up @@ -104,9 +107,27 @@ protected void appendFormat(Formatter formatter, int width, int precision, boole
}
}


@NotNull
arynxd marked this conversation as resolved.
Show resolved Hide resolved
@Override
public String getReferencedMessageId()
{
unsupported();
return null;
}

@Override
public Message getReferencedMessage()
public long getReferencedMessageIdLong()
{
unsupported();
arynxd marked this conversation as resolved.
Show resolved Hide resolved
return 0;
}

@Nullable
@Override
public MessageReference getMessageReference()
{
unsupported();
return null;
}

Expand Down
19 changes: 17 additions & 2 deletions src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -1219,6 +1219,20 @@ else if (MISSING_CHANNEL.equals(ex.getMessage()))
}
}

MessageReference messageReference = null;

if (!jsonObject.isNull("message_reference")) // always contains the channel + message id for a referenced message
{ // used for when referenced_message is not provided
DataObject messageReferenceJson = jsonObject.getObject("message_reference");

messageReference = new MessageReference(
messageReferenceJson.getLong("message_id"),
messageReferenceJson.getLong("channel_id"),
referencedMessage,
api
arynxd marked this conversation as resolved.
Show resolved Hide resolved
);
}

List<ActionRow> components = Collections.emptyList();
Optional<DataArray> componentsArrayOpt = jsonObject.optArray("components");
if (componentsArrayOpt.isPresent())
Expand All @@ -1232,15 +1246,16 @@ else if (MISSING_CHANNEL.equals(ex.getMessage()))

if (type == MessageType.UNKNOWN)
throw new IllegalArgumentException(UNKNOWN_MESSAGE_TYPE);

arynxd marked this conversation as resolved.
Show resolved Hide resolved
if (!type.isSystem())
{
message = new ReceivedMessage(id, channel, type, referencedMessage, fromWebhook,
message = new ReceivedMessage(id, channel, type, messageReference, fromWebhook,
mentionsEveryone, mentionedUsers, mentionedRoles, tts, pinned,
content, nonce, user, member, activity, editTime, reactions, attachments, embeds, stickers, components, flags);
}
else
{
message = new SystemMessage(id, channel, type, fromWebhook,
message = new SystemMessage(id, channel, type, messageReference, fromWebhook,
mentionsEveryone, mentionedUsers, mentionedRoles, tts, pinned,
content, nonce, user, member, activity, editTime, reactions, attachments, embeds, stickers, flags);
return message; // We don't need to parse mentions for system messages, they are always empty anyway
Expand Down
117 changes: 117 additions & 0 deletions src/main/java/net/dv8tion/jda/internal/entities/MessageReference.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package net.dv8tion.jda.internal.entities;
arynxd marked this conversation as resolved.
Show resolved Hide resolved

import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageType;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.requests.RestAction;
import net.dv8tion.jda.internal.JDAImpl;
import net.dv8tion.jda.internal.requests.RestActionImpl;
import net.dv8tion.jda.internal.requests.Route;
import org.jetbrains.annotations.Nullable;

import javax.annotation.Nonnull;

public class MessageReference
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Class level docs, and most of the methods are missing annotations

{
private final long messageId;
private final long channelId;
private final Message referencedMessage;
private final JDA api;

public MessageReference(long messageId, long channelId, @Nullable Message referencedMessage, JDA api)
{
this.messageId = messageId;
this.channelId = channelId;
this.referencedMessage = referencedMessage;
this.api = api;
}

/**
* Retrieves the referenced message for this message. If one is already present, it will be returned.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing docs for error responses

*
* @throws java.lang.IllegalStateException
* If this message does not have a reference
*
* @return {@link net.dv8tion.jda.api.requests.RestAction RestAction} - Type: {@link net.dv8tion.jda.api.entities.Message}
*/
@Nonnull
public RestAction<Message> retrieveReferencedMessage() {
arynxd marked this conversation as resolved.
Show resolved Hide resolved
Route.CompiledRoute route = Route.Messages.GET_MESSAGE.compile(getChannelId(), getMessageId());
JDAImpl jda = (JDAImpl) getJDA();

return new RestActionImpl<>(jda, route,
(response, request) -> jda.getEntityBuilder().createMessage(response.getObject(), getChannel(), false));
}

/**
* Referenced message.
*
* <p>This will have different meaning depending on the {@link Message#getType() type} of message.
* Usually, this is a {@link MessageType#INLINE_REPLY INLINE_REPLY} reference.
* This can be null even if the type is {@link MessageType#INLINE_REPLY INLINE_REPLY}, when the message it references doesn't exist or discord wasn't able to resolve it in time.
*
* @return The referenced message, or null
*/
@Nullable
public Message getReferencedMessage()
{
return referencedMessage;
}

/**
* This will return the channel from which this message originates.
arynxd marked this conversation as resolved.
Show resolved Hide resolved
* <br>
* Messages from other servers can be referenced, in which case JDA may not have the channel cached.
arynxd marked this conversation as resolved.
Show resolved Hide resolved
*
* @return The channel for this message reference, or null
arynxd marked this conversation as resolved.
Show resolved Hide resolved
*/
@Nullable
public TextChannel getChannel() {
arynxd marked this conversation as resolved.
Show resolved Hide resolved
return api.getTextChannelById(getChannelIdLong());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not good. What if the message came from a private channel? Why is this not stored in the object?

}

/**
* Returns the message id for this reference.
* @return The message id
arynxd marked this conversation as resolved.
Show resolved Hide resolved
*/
public long getMessageIdLong()
{
return messageId;
}

/**
* Returns the channel id for this reference.
* @return The channel id
arynxd marked this conversation as resolved.
Show resolved Hide resolved
*/
public long getChannelIdLong()
{
return channelId;
}

/**
* Returns the message id for this reference.
* @return The message id
arynxd marked this conversation as resolved.
Show resolved Hide resolved
*/
public String getMessageId()
{
return Long.toUnsignedString(getMessageIdLong());
}

/**
* Returns the channel id for this reference.
* @return The channel id
arynxd marked this conversation as resolved.
Show resolved Hide resolved
*/
public String getChannelId()
{
return Long.toUnsignedString(getChannelIdLong());
}

/**
* Returns the JDA instance related to this message reference.
* @return The corresponding JDA instance
arynxd marked this conversation as resolved.
Show resolved Hide resolved
*/
public JDA getJDA() {
arynxd marked this conversation as resolved.
Show resolved Hide resolved
return api;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import net.dv8tion.jda.api.utils.data.DataObject;
import net.dv8tion.jda.internal.JDAImpl;
import net.dv8tion.jda.internal.requests.CompletedRestAction;
import net.dv8tion.jda.internal.requests.RestActionImpl;
import net.dv8tion.jda.internal.requests.Route;
import net.dv8tion.jda.internal.requests.restaction.AuditableRestActionImpl;
import net.dv8tion.jda.internal.requests.restaction.MessageActionImpl;
Expand All @@ -57,7 +58,7 @@ public class ReceivedMessage extends AbstractMessage
protected final long id;
protected final MessageType type;
protected final MessageChannel channel;
protected final Message referencedMessage;
protected final MessageReference messageReference;
protected final boolean fromWebhook;
protected final boolean mentionsEveryone;
protected final boolean pinned;
Expand Down Expand Up @@ -88,15 +89,16 @@ public class ReceivedMessage extends AbstractMessage
protected List<String> invites = null;

public ReceivedMessage(
long id, MessageChannel channel, MessageType type, Message referencedMessage,
long id, MessageChannel channel, MessageType type, MessageReference messageReference,
boolean fromWebhook, boolean mentionsEveryone, TLongSet mentionedUsers, TLongSet mentionedRoles, boolean tts, boolean pinned,
String content, String nonce, User author, Member member, MessageActivity activity, OffsetDateTime editTime,
List<MessageReaction> reactions, List<Attachment> attachments, List<MessageEmbed> embeds, List<MessageSticker> stickers, List<ActionRow> components, int flags)
{
super(content, nonce, tts);
this.id = id;
this.channel = channel;
this.referencedMessage = referencedMessage;
this.messageReference = messageReference;

arynxd marked this conversation as resolved.
Show resolved Hide resolved
this.type = type;
this.api = (channel != null) ? (JDAImpl) channel.getJDA() : null;
this.fromWebhook = fromWebhook;
Expand Down Expand Up @@ -129,10 +131,15 @@ public JDA getJDA()
return api;
}

/**
* Returns the {@link MessageReference} for this Message. This will be null if this Message has no reference.
* @return The message reference.
arynxd marked this conversation as resolved.
Show resolved Hide resolved
*/
@Nullable
@Override
public Message getReferencedMessage()
public MessageReference getMessageReference()
{
return referencedMessage;
return messageReference;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,17 @@
public class SystemMessage extends ReceivedMessage
{
public SystemMessage(
long id, MessageChannel channel, MessageType type,
long id, MessageChannel channel, MessageType type, MessageReference messageReference,
boolean fromWebhook, boolean mentionsEveryone, TLongSet mentionedUsers, TLongSet mentionedRoles,
boolean tts, boolean pinned,
String content, String nonce, User author, Member member, MessageActivity activity, OffsetDateTime editTime,
List<MessageReaction> reactions, List<Attachment> attachments, List<MessageEmbed> embeds, List<MessageSticker> stickers, int flags)
{
super(id, channel, type, null, fromWebhook, mentionsEveryone, mentionedUsers, mentionedRoles,
super(id, channel, type, messageReference, fromWebhook, mentionsEveryone, mentionedUsers, mentionedRoles,
tts, pinned, content, nonce, author, member, activity, editTime, reactions, attachments, embeds, stickers, Collections.emptyList(), flags);
}


arynxd marked this conversation as resolved.
Show resolved Hide resolved
@Nonnull
@Override
public RestAction<Void> pin()
Expand Down