-
Notifications
You must be signed in to change notification settings - Fork 24
delete blacklisted attachments from message and replace with webhook #520
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package net.discordjug.javabot.listener; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import net.discordjug.javabot.data.config.BotConfig; | ||
import net.discordjug.javabot.data.config.GuildConfig; | ||
import net.discordjug.javabot.util.ExceptionLogger; | ||
import net.discordjug.javabot.util.WebhookUtil; | ||
import net.dv8tion.jda.api.entities.Message; | ||
import net.dv8tion.jda.api.entities.channel.ChannelType; | ||
import net.dv8tion.jda.api.entities.channel.attribute.IWebhookContainer; | ||
import net.dv8tion.jda.api.entities.channel.middleman.StandardGuildChannel; | ||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | ||
import net.dv8tion.jda.api.hooks.ListenerAdapter; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
@RequiredArgsConstructor | ||
public class BlacklistedMessageAttachmentListener extends ListenerAdapter { | ||
|
||
private final BotConfig botConfig; | ||
|
||
@Override | ||
public void onMessageReceived(@NotNull MessageReceivedEvent event) { | ||
if (event.getAuthor().isBot() || event.getAuthor().isSystem()) return; | ||
GuildConfig guildConfig = botConfig.get(event.getGuild()); | ||
List<String> blacklistedMessageExtensions = guildConfig.getBlacklistedMessageExtensions(); | ||
Message message = event.getMessage(); | ||
List<Message.Attachment> attachments = message.getAttachments(); | ||
List<Message.Attachment> allowedAttachments = new ArrayList<>(); | ||
attachments.forEach(attachment -> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could be done nicely using the stream API, for example List<Message.Attachment> allowedAttachments = attachments
.stream()
.filter(this::isAllowedAttachment)
.toList(); |
||
boolean contains = blacklistedMessageExtensions.contains(attachment.getContentType()); | ||
if (!contains) { | ||
allowedAttachments.add(attachment); | ||
} | ||
}); | ||
if (message.getAttachments().size() != allowedAttachments.size()) { | ||
IWebhookContainer tc = null; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
if (event.isFromType(ChannelType.TEXT)) { | ||
tc = event.getChannel().asTextChannel(); | ||
} | ||
if (event.isFromThread()) { | ||
StandardGuildChannel parentChannel = event.getChannel() | ||
.asThreadChannel() | ||
.getParentChannel() | ||
.asStandardGuildChannel(); | ||
tc = (IWebhookContainer) parentChannel; | ||
} | ||
if (tc == null) { | ||
return; | ||
} | ||
long threadId = event.isFromThread() ? event.getChannel().getIdLong() : 0; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That can be merged with the previous |
||
WebhookUtil.ensureWebhookExists( | ||
tc, | ||
wh -> WebhookUtil.replaceMemberMessageWithAttachments( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add a small embed to the message saying that unwanted attachments were removed. |
||
wh, | ||
event.getMessage(), | ||
event.getMessage().getContentRaw(), | ||
threadId, | ||
allowedAttachments | ||
), | ||
e -> ExceptionLogger.capture( | ||
e, | ||
"Error creating webhook for UnformattedCodeListener" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This message is incorrect here. |
||
) | ||
); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -137,6 +137,59 @@ private static CompletableFuture<ReadonlyMessage> mirrorMessageToWebhook(@NotNul | |
}); | ||
} | ||
|
||
/** | ||
* Resends a specific message using a webhook with a custom content. | ||
* | ||
* @param webhook the webhook used for sending the message | ||
* @param originalMessage the message to copy | ||
* @param newMessageContent the new (custom) content | ||
* @param threadId the thread to send the message in or {@code 0} if the | ||
* message should be sent directly | ||
* @param components A nullable list of {@link LayoutComponent}s. | ||
* @param attachments A list of {@link Message.Attachment}s. | ||
* @return a {@link CompletableFuture} representing the action of sending | ||
* the message | ||
*/ | ||
public static CompletableFuture<ReadonlyMessage> mirrorMessageToWebhookWithAttachments(@NotNull Webhook webhook, @NotNull Message originalMessage, String newMessageContent, long threadId, @Nullable List<LayoutComponent> components, List<Message.Attachment> attachments) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please don't duplicate code. Instead, you can add an |
||
return originalMessage | ||
.getGuild() | ||
.retrieveMember(originalMessage.getAuthor()) | ||
.submit() | ||
.exceptionally(e -> null)//if the member cannot be found, use no member information | ||
.thenCompose(member -> | ||
mirrorMessageToWebhookWithAttachments(webhook, originalMessage, newMessageContent, threadId, components, attachments, member)); | ||
} | ||
|
||
private static CompletableFuture<ReadonlyMessage> mirrorMessageToWebhookWithAttachments(@NotNull Webhook webhook, Message originalMessage, String newMessageContent, long threadId, | ||
List<LayoutComponent> components, List<Message.Attachment> attachments, Member member) { | ||
WebhookMessageBuilder message = new WebhookMessageBuilder().setContent(newMessageContent) | ||
.setAllowedMentions(AllowedMentions.none()) | ||
.setAvatarUrl(transformOrNull(member, Member::getEffectiveAvatarUrl)) | ||
.setUsername(transformOrNull(member, Member::getEffectiveName)); | ||
JDAWebhookClient client = new WebhookClientBuilder(webhook.getIdLong(), webhook.getToken()).setThreadId(threadId) | ||
.buildJDA(); | ||
if (components != null && !components.isEmpty()) { | ||
message.addComponents(components); | ||
} | ||
|
||
@SuppressWarnings("unchecked") | ||
CompletableFuture<?>[] futures = new CompletableFuture<?>[attachments.size()]; | ||
for (int i = 0; i < attachments.size(); i++) { | ||
Attachment attachment = attachments.get(i); | ||
futures[i] = attachment.getProxy() | ||
.download() | ||
.thenAccept(is -> message.addFile((attachment.isSpoiler() ? "SPOILER_" : "") + attachment.getFileName(), is)); | ||
} | ||
return CompletableFuture.allOf(futures) | ||
.thenCompose(unused -> sendMessage(client, message)) | ||
.whenComplete((result, err) -> { | ||
client.close(); | ||
if (err != null) { | ||
ExceptionLogger.capture(err, WebhookUtil.class.getSimpleName()); | ||
} | ||
}); | ||
} | ||
|
||
private static <T, R> R transformOrNull(T toTransform, Function<T, R> transformer) { | ||
return toTransform == null ? null : transformer.apply(toTransform); | ||
} | ||
|
@@ -165,4 +218,22 @@ public static void replaceMemberMessage(Webhook webhook, Message originalMessage | |
return null; | ||
}); | ||
} | ||
|
||
/** | ||
* Method for replacing a user's guild message through a webhook while also replacing the attachments. | ||
* | ||
* @param webhook a reference to a webhook | ||
* @param originalMessage a reference to the {@link Message} object that should be replaced | ||
* @param newMessageContent a String containing the new message's content | ||
* @param threadId id of the thread in which the message should be replaced | ||
* @param attachments attachments to be added to the message | ||
*/ | ||
public static void replaceMemberMessageWithAttachments(Webhook webhook, Message originalMessage, String newMessageContent, long threadId, List<Message.Attachment> attachments) { | ||
WebhookUtil.mirrorMessageToWebhookWithAttachments(webhook, originalMessage, newMessageContent, threadId, null, attachments) | ||
.thenAccept(unused -> originalMessage.delete().queue()) | ||
.exceptionally(e -> { | ||
ExceptionLogger.capture(e, WebhookUtil.class.getSimpleName()); | ||
return null; | ||
}); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason for the use of MIME types instead of extensions?
If you are using MIME types, why is the variable called "extensions"?