Skip to content

Commit 32d1e9b

Browse files
authored
Merge pull request #402 from danthe1st/private-thread-dm-alternative
send notification in private thread when DM is unavailable
2 parents c3ca6ed + f12ef12 commit 32d1e9b

File tree

5 files changed

+46
-10
lines changed

5 files changed

+46
-10
lines changed

src/main/java/net/javadiscord/javabot/data/config/guild/ModerationConfig.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@ public class ModerationConfig extends GuildConfigItem {
5555
*/
5656
private int maxWarnSeverity = 100;
5757

58+
/**
59+
* ID of the channel where direct user notifications should be sent to (using private threads).
60+
* @see net.javadiscord.javabot.systems.notification.UserNotificationService
61+
*/
62+
private long notificationThreadChannelId;
63+
5864
/**
5965
* Invite links AutoMod should exclude.
6066
*/
@@ -104,4 +110,8 @@ public Role getAdminRole() {
104110
public Role getExpertRole() {
105111
return this.getGuild().getRoleById(this.expertRoleId);
106112
}
113+
114+
public TextChannel getNotificationThreadChannel() {
115+
return this.getGuild().getTextChannelById(this.notificationThreadChannelId);
116+
}
107117
}

src/main/java/net/javadiscord/javabot/systems/moderation/ModerationService.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public void warn(User user, WarnSeverity severity, String reason, Member warnedB
8888
warnRepository.insert(new Warn(user.getIdLong(), warnedBy.getIdLong(), severity, reason));
8989
int totalSeverity = warnRepository.getTotalSeverityWeight(user.getIdLong(), LocalDateTime.now().minusDays(moderationConfig.getWarnTimeoutDays()));
9090
MessageEmbed warnEmbed = buildWarnEmbed(user, warnedBy, severity, totalSeverity, reason);
91-
notificationService.withUser(user).sendDirectMessage(c -> c.sendMessageEmbeds(warnEmbed));
91+
notificationService.withUser(user, warnedBy.getGuild()).sendDirectMessage(c -> c.sendMessageEmbeds(warnEmbed));
9292
notificationService.withGuild(moderationConfig.getGuild()).sendToModerationLog(c -> c.sendMessageEmbeds(warnEmbed));
9393
if (!quiet && channel.getIdLong() != moderationConfig.getLogChannelId()) {
9494
channel.sendMessageEmbeds(warnEmbed).queue();
@@ -108,12 +108,12 @@ public void warn(User user, WarnSeverity severity, String reason, Member warnedB
108108
* @param user The user to clear warns from.
109109
* @param clearedBy The user who cleared the warns.
110110
*/
111-
public void discardAllWarns(User user, User clearedBy) {
111+
public void discardAllWarns(User user, Member clearedBy) {
112112
asyncPool.execute(() -> {
113113
try {
114114
warnRepository.discardAll(user.getIdLong());
115-
MessageEmbed embed = buildClearWarnsEmbed(user, clearedBy);
116-
notificationService.withUser(user).sendDirectMessage(c -> c.sendMessageEmbeds(embed));
115+
MessageEmbed embed = buildClearWarnsEmbed(user, clearedBy.getUser());
116+
notificationService.withUser(user, clearedBy.getGuild()).sendDirectMessage(c -> c.sendMessageEmbeds(embed));
117117
notificationService.withGuild(moderationConfig.getGuild()).sendToModerationLog(c -> c.sendMessageEmbeds(embed));
118118
} catch (DataAccessException e) {
119119
ExceptionLogger.capture(e, ModerationService.class.getSimpleName());
@@ -189,7 +189,7 @@ public List<Warn> getAllWarns(long userId) {
189189
public void timeout(@Nonnull Member member, @Nonnull String reason, @Nonnull Member timedOutBy, @Nonnull Duration duration, @Nonnull MessageChannel channel, boolean quiet) {
190190
MessageEmbed timeoutEmbed = buildTimeoutEmbed(member, timedOutBy, reason, duration);
191191
member.getGuild().timeoutFor(member, duration).queue(s -> {
192-
notificationService.withUser(member.getUser()).sendDirectMessage(c -> c.sendMessageEmbeds(timeoutEmbed));
192+
notificationService.withUser(member.getUser(), timedOutBy.getGuild()).sendDirectMessage(c -> c.sendMessageEmbeds(timeoutEmbed));
193193
notificationService.withGuild(member.getGuild()).sendToModerationLog(c -> c.sendMessageEmbeds(timeoutEmbed));
194194
if (!quiet) channel.sendMessageEmbeds(timeoutEmbed).queue();
195195
}, ExceptionLogger::capture);
@@ -207,7 +207,7 @@ public void timeout(@Nonnull Member member, @Nonnull String reason, @Nonnull Mem
207207
public void removeTimeout(Member member, String reason, Member removedBy, MessageChannel channel, boolean quiet) {
208208
MessageEmbed removeTimeoutEmbed = buildTimeoutRemovedEmbed(member, removedBy, reason);
209209
removedBy.getGuild().removeTimeout(member).queue(s -> {
210-
notificationService.withUser(member.getUser()).sendDirectMessage(c -> c.sendMessageEmbeds(removeTimeoutEmbed));
210+
notificationService.withUser(member.getUser(), removedBy.getGuild()).sendDirectMessage(c -> c.sendMessageEmbeds(removeTimeoutEmbed));
211211
notificationService.withGuild(member.getGuild()).sendToModerationLog(c -> c.sendMessageEmbeds(removeTimeoutEmbed));
212212
if (!quiet) channel.sendMessageEmbeds(removeTimeoutEmbed).queue();
213213
}, ExceptionLogger::capture);

src/main/java/net/javadiscord/javabot/systems/moderation/warn/DiscardAllWarnsSubcommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public void execute(@NotNull SlashCommandInteractionEvent event) {
5454
return;
5555
}
5656
User target = userMapping.getAsUser();
57-
new ModerationService(notificationService, botConfig, event.getInteraction(), warnRepository, asyncPool).discardAllWarns(target, event.getUser());
57+
new ModerationService(notificationService, botConfig, event.getInteraction(), warnRepository, asyncPool).discardAllWarns(target, event.getMember());
5858
Responses.success(event, "Warns Discarded", "Successfully discarded all warns from **%s**.", target.getAsTag()).queue();
5959
}
6060
}

src/main/java/net/javadiscord/javabot/systems/notification/NotificationService.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ public class NotificationService {
3333
return new UserNotificationService(user);
3434
}
3535

36+
@Contract("_ -> new")
37+
public @NotNull UserNotificationService withUser(User user, Guild guild) {
38+
return new UserNotificationService(user, botConfig.get(guild).getModerationConfig());
39+
}
40+
3641
public @NotNull QOTWGuildNotificationService withQOTW(Guild guild) {
3742
return new QOTWGuildNotificationService(this, guild);
3843
}
Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
package net.javadiscord.javabot.systems.notification;
22

33
import lombok.AccessLevel;
4+
import lombok.AllArgsConstructor;
45
import lombok.RequiredArgsConstructor;
56
import lombok.extern.slf4j.Slf4j;
67
import net.dv8tion.jda.api.entities.User;
8+
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
9+
import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel.AutoArchiveDuration;
710
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
811
import net.dv8tion.jda.api.requests.restaction.MessageCreateAction;
12+
import net.javadiscord.javabot.data.config.guild.ModerationConfig;
13+
914
import org.jetbrains.annotations.NotNull;
1015

1116
import java.util.function.Function;
@@ -15,18 +20,34 @@
1520
*/
1621
@Slf4j
1722
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
23+
@AllArgsConstructor(access = AccessLevel.PACKAGE)
1824
public final class UserNotificationService extends NotificationService.MessageChannelNotification {
1925
private final User user;
26+
private ModerationConfig config;
2027

2128
/**
2229
* Sends a notification to a {@link User}s' {@link net.dv8tion.jda.api.entities.channel.concrete.PrivateChannel}.
2330
*
2431
* @param function The {@link Function} to use which MUST return a {@link MessageCreateAction}.
2532
*/
2633
public void sendDirectMessage(@NotNull Function<MessageChannel, MessageCreateAction> function) {
27-
user.openPrivateChannel().queue(
28-
channel -> send(channel, function),
29-
error -> log.error("Could not open PrivateChannel with user " + user.getAsTag(), error)
34+
user.openPrivateChannel().flatMap(function::apply).queue(
35+
msg -> {},
36+
error -> {
37+
log.error("Could not open PrivateChannel with user " + user.getAsTag(), error);
38+
if(config != null) {
39+
TextChannel container = config.getNotificationThreadChannel();
40+
if(container != null) {
41+
container
42+
.createThreadChannel("JavaBot notification", true)
43+
.setAutoArchiveDuration(AutoArchiveDuration.TIME_1_HOUR)
44+
.queue(c -> {
45+
c.addThreadMember(user).queue();
46+
send(c, function);
47+
});
48+
}
49+
}
50+
}
3051
);
3152
}
3253
}

0 commit comments

Comments
 (0)