Skip to content

Commit 1070f23

Browse files
authored
fix: allow forwarded messages with media in media-only channels (#1419)
* fix: allow forwarded messages with media in media-only channels * fix: address review comments * fix: remove unused import * fix: apply code formatting
1 parent 1b44779 commit 1070f23

File tree

2 files changed

+78
-2
lines changed

2 files changed

+78
-2
lines changed

application/src/main/java/org/togetherjava/tjbot/features/mediaonly/MediaOnlyChannelListener.java

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import org.togetherjava.tjbot.features.MessageReceiverAdapter;
1414

1515
import java.awt.Color;
16+
import java.util.List;
1617
import java.util.concurrent.TimeUnit;
1718
import java.util.regex.Pattern;
1819

@@ -51,9 +52,39 @@ public void onMessageReceived(MessageReceivedEvent event) {
5152
}
5253
}
5354

55+
/**
56+
* Checks whether the given message has no media attached.
57+
* <p>
58+
* A message is considered to have media if it contains attachments, embeds, or a URL in its
59+
* text content. For forwarded messages, the snapshots are also checked for media.
60+
*
61+
* @param message the message to check
62+
* @return {@code true} if the message has no media, {@code false} otherwise
63+
*/
5464
private boolean messageHasNoMediaAttached(Message message) {
55-
return message.getAttachments().isEmpty() && message.getEmbeds().isEmpty()
56-
&& !message.getContentRaw().contains("http");
65+
if (hasMedia(message.getAttachments(), message.getEmbeds(), message.getContentRaw())) {
66+
return false;
67+
}
68+
69+
return message.getMessageSnapshots()
70+
.stream()
71+
.noneMatch(snapshot -> hasMedia(snapshot.getAttachments(), snapshot.getEmbeds(),
72+
snapshot.getContentRaw()));
73+
}
74+
75+
/**
76+
* Checks whether the given content contains any media.
77+
* <p>
78+
* Media is considered present if there are attachments, embeds, or a URL (identified by
79+
* {@code "http"}) in the text content.
80+
*
81+
* @param attachments the attachments of the message or snapshot
82+
* @param embeds the embeds of the message or snapshot
83+
* @param content the raw text content of the message or snapshot
84+
*/
85+
private boolean hasMedia(List<Message.Attachment> attachments, List<MessageEmbed> embeds,
86+
String content) {
87+
return !attachments.isEmpty() || !embeds.isEmpty() || content.contains("http");
5788
}
5889

5990
private MessageCreateData createNotificationMessage(Message message) {

application/src/test/java/org/togetherjava/tjbot/features/mediaonly/MediaOnlyChannelListenerTest.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import net.dv8tion.jda.api.entities.Message;
55
import net.dv8tion.jda.api.entities.MessageEmbed;
66
import net.dv8tion.jda.api.entities.channel.ChannelType;
7+
import net.dv8tion.jda.api.entities.messages.MessageSnapshot;
78
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
89
import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder;
910
import net.dv8tion.jda.api.utils.messages.MessageCreateData;
@@ -112,4 +113,48 @@ private MessageReceivedEvent sendMessage(MessageCreateData message,
112113
mediaOnlyChannelListener.onMessageReceived(event);
113114
return event;
114115
}
116+
117+
118+
@Test
119+
void keepsForwardedMessageWithAttachment() {
120+
// GIVEN a forwarded message that contains an attachment inside the snapshot
121+
MessageCreateData message = new MessageCreateBuilder().setContent("any").build();
122+
123+
MessageSnapshot snapshot = mock(MessageSnapshot.class);
124+
when(snapshot.getAttachments()).thenReturn(List.of(mock(Message.Attachment.class)));
125+
when(snapshot.getEmbeds()).thenReturn(List.of());
126+
when(snapshot.getContentRaw()).thenReturn("");
127+
128+
// WHEN sending the forwarded message
129+
MessageReceivedEvent event = sendMessageWithSnapshots(message, List.of(snapshot));
130+
131+
// THEN it does not get deleted
132+
verify(event.getMessage(), never()).delete();
133+
}
134+
135+
@Test
136+
void deletesForwardedMessageWithoutMedia() {
137+
// GIVEN a forwarded message that contains no media inside the snapshot
138+
MessageCreateData message = new MessageCreateBuilder().setContent("any").build();
139+
140+
MessageSnapshot snapshot = mock(MessageSnapshot.class);
141+
when(snapshot.getAttachments()).thenReturn(List.of());
142+
when(snapshot.getEmbeds()).thenReturn(List.of());
143+
when(snapshot.getContentRaw()).thenReturn("just some text, no media");
144+
145+
// WHEN sending the forwarded message
146+
MessageReceivedEvent event = sendMessageWithSnapshots(message, List.of(snapshot));
147+
148+
// THEN it gets deleted
149+
verify(event.getMessage()).delete();
150+
}
151+
152+
private MessageReceivedEvent sendMessageWithSnapshots(MessageCreateData message,
153+
List<MessageSnapshot> snapshots) {
154+
MessageReceivedEvent event =
155+
jdaTester.createMessageReceiveEvent(message, List.of(), ChannelType.TEXT);
156+
when(event.getMessage().getMessageSnapshots()).thenReturn(snapshots);
157+
mediaOnlyChannelListener.onMessageReceived(event);
158+
return event;
159+
}
115160
}

0 commit comments

Comments
 (0)